aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-01-29 15:19:38 -0800
committerAdam Soltys <[email protected]>2024-01-29 15:19:38 -0800
commitb54d3afc6465acd5e518a8b4970be1ab75b361b1 (patch)
treec2ab7a8d91140ec6a60bd2b76e25c68a0355ee38 /src
parenta7dd56863aada46964a4277f0a5940de68c332b5 (diff)
downloadcoinos-ui-b54d3afc6465acd5e518a8b4970be1ab75b361b1.tar.gz
coinos-ui-b54d3afc6465acd5e518a8b4970be1ab75b361b1.zip
autowithdrawals
Diffstat (limited to 'src')
-rw-r--r--src/components/Numpad.svelte7
-rw-r--r--src/locales/de.json11
-rw-r--r--src/locales/el.json11
-rw-r--r--src/locales/en.json687
-rw-r--r--src/locales/es.json11
-rw-r--r--src/locales/fa.json11
-rw-r--r--src/locales/fr.json11
-rw-r--r--src/locales/ja.json11
-rw-r--r--src/locales/pt.json11
-rw-r--r--src/locales/ru.json11
-rw-r--r--src/locales/zh.json11
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.server.js2
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_pos.svelte150
-rw-r--r--src/routes/(app)/send/[...text]/+page.svelte11
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.server.js1
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.svelte11
16 files changed, 608 insertions, 360 deletions
diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte
index 713f2e4d..9119999f 100644
--- a/src/components/Numpad.svelte
+++ b/src/components/Numpad.svelte
@@ -6,6 +6,7 @@
export let amount,
currency,
+ element,
fiat = !amount,
rate,
submit = undefined;
@@ -45,6 +46,9 @@
const numPad = ["1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "0", "<"];
const handleInput = (value) => {
+ if (selecting) amount = 0;
+ selecting = false;
+
if (fiat) {
if (amountFiat === 0 && value !== "." && value !== "<" && value !== "0") {
amountFiat = value;
@@ -161,12 +165,14 @@
}, 0);
};
+ let selecting;
let select = (e) => {
let range = document.createRange();
range.selectNodeContents(e.target);
let sel = getSelection();
sel.removeAllRanges();
sel.addRange(range);
+ selecting = true;
};
let blur = () => {
@@ -195,6 +201,7 @@
on:input={input}
on:keydown={keydown}
class="outline-none my-auto"
+ bind:this={element}
/>
</div>
<div class="mt-2">
diff --git a/src/locales/de.json b/src/locales/de.json
index 23f6d5c3..9cedddd4 100644
--- a/src/locales/de.json
+++ b/src/locales/de.json
@@ -273,7 +273,16 @@
"hours": "Std.",
"publishNip5": "Nostr-Identität veröffentlichen",
"nip5a": "Verwenden",
- "nip5b": "als Ihre öffentlich verifizierte Nostr-Adresse"
+ "nip5b": "als Ihre öffentlich verifizierte Nostr-Adresse",
+ "destination": "Adresse für automatische Auszahlung",
+ "destinationDesc": "Die Adresse, an die Auszahlungen gesendet werden",
+ "destinationPlaceholder": "Geben Sie eine Bitcoin-, Liquid- oder Lightning-Adresse ein",
+ "reserve": "Reservebetrag",
+ "reserveDesc": "Der Betrag, der nach Abschluss der Auszahlung auf Ihrem Konto verbleibt",
+ "threshold": "Automatischer Auszahlungsschwellenwert",
+ "thresholdDesc": "Wenn Ihr Guthaben diesen Betrag überschreitet, wird eine Auszahlung ausgelöst",
+ "autoWithdraw": "Automatische Auszahlung",
+ "autoWithdrawDescription": "Ermöglichen Sie Auszahlungen an eine externe Adresse, wenn Ihr Guthaben einen bestimmten Schwellenwert erreicht"
},
"support": {
"header": "Support",
diff --git a/src/locales/el.json b/src/locales/el.json
index b85cf2c5..b8e18069 100644
--- a/src/locales/el.json
+++ b/src/locales/el.json
@@ -274,7 +274,16 @@
"revealSeed": "Αποκαλύψτε τη φράση σπόρων",
"publishNip5": "Δημοσίευση ταυτότητας nostr",
"nip5a": "Χρήση",
- "nip5b": "ως δημόσια επαληθευμένη διεύθυνση nostr"
+ "nip5b": "ως δημόσια επαληθευμένη διεύθυνση nostr",
+ "destination": "Διεύθυνση αυτόματης απόσυρσης",
+ "destinationDesc": "Η διεύθυνση στην οποία θα αποστέλλονται οι αναλήψεις",
+ "destinationPlaceholder": "Εισαγάγετε μια διεύθυνση Bitcoin, Liquid ή Lightning",
+ "reserve": "Ποσό επιφύλαξης",
+ "reserveDesc": "Το ποσό που θα μείνει στον λογαριασμό σας μετά την ολοκλήρωση της ανάληψης",
+ "threshold": "Όριο αυτόματης απόσυρσης",
+ "thresholdDesc": "Όταν το υπόλοιπό σας υπερβεί αυτό το ποσό, θα ενεργοποιηθεί η ανάληψη",
+ "autoWithdraw": "Αυτόματη απόσυρση",
+ "autoWithdrawDescription": "Ενεργοποιήστε τις αναλήψεις σε μια εξωτερική διεύθυνση όταν το υπόλοιπό σας φτάσει σε ένα δεδομένο όριο"
},
"support": {
"header": "Υποστήριξη",
diff --git a/src/locales/en.json b/src/locales/en.json
index acd94905..c4d9dcdd 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -1,341 +1,350 @@
{
- "404": {
- "404": "404",
- "pageNotFound": "Page not found."
- },
- "about": {
- "header": "About",
- "team": {
- "header": "The Team",
- "adam": {
- "name": "Adam Soltys",
- "position": "Founder and CTO",
- "bio": "Adam is a software engineer who believes that the adoption of sound money will drive global prosperity. He lives in North Vancouver with his wife, daughter, and son."
- },
- "cole": {
- "name": "Cole",
- "position": "Business Development",
- "bio": "Cole is a driven individual with a passion for freedom. He came across bitcoin in 2016 and studied it in depth. Now he wants to introduce the lightning network to as many users as possible."
- }
- },
- "locations": {
- "header": "Locations",
- "description": "Here are some businesses that are accepting bitcoin with Coinos. We hope that yours will be next!"
- }
- },
- "error": {
- "header": "Error",
- "message": "Please try again or contact support.",
- "signIn": "Please sign in to continue.",
- "unrecognizedInput": "Unrecognized input"
- },
- "faq": {
- "header": "FAQ",
- "cost": {
- "question": "What does it cost?",
- "answer": "Receiving payments into your account is free. Withdrawals to external wallets incur a small fee that varies depending on network conditions."
- },
- "compatibility": {
- "question": "Do I need any special device or software?",
- "answer": "No, Coinos works anywhere that has Internet. Merchants might use it on a tablet or put up a QR code for customers to scan with their phone."
- },
- "safety": {
- "question": "When do my funds settle?",
- "answer": "Lightning payments are settled instantly. You can withdraw your balance to another wallet within seconds. On-chain deposits take 5-10 minutes to confirm on average."
- },
- "pos": {
- "question": "Can Coinos integrate with my existing PoS?",
- "answer": "We recommend entering sales into your existing PoS as cash transactions."
- },
- "bitcoin": {
- "question": "What can I do with Bitcoin?",
- "answer": "Spend it at other merchants or pay your expenses with it by getting your staff, suppliers and landlord to take it."
- }
- },
- "footer": {
- "company": "Company",
- "followUs": "Follow Us",
- "github": "GitHub",
- "linktree": "Linktree",
- "jobs": "Jobs",
- "support": "Support",
- "telegram": "Telegram",
- "twitter": "Twitter",
- "documentation": "Documentation"
- },
- "howItWorks": {
- "header": "How it works",
- "step1": {
- "header": "1. Create your account",
- "description": "A username and password is all you need to get started."
- },
- "step2": {
- "header": "2. Ask for payments",
- "description": "The same as you normally would, but with bitcoin."
- },
- "step3": {
- "header": "3. That's all!",
- "description": "Spend your coin immediately or watch it grow in value."
- }
- },
- "invoice": {
- "addTip": "Add a tip",
- "addTipq": "Add a tip?",
- "done": "Done",
- "paymentSuccessful": "Payment received!",
- "invoice": "Invoice",
- "total": "Total",
- "tip": "Tip"
- },
- "jobs": {
- "header": "Jobs",
- "subheader": "Current Openings",
- "pitch1": "Coinos is actively looking for developers to join our growing team (full-time or part-time, remote working OK).",
- "pitch2": "Excited about working on open source bitcoin? Then take a look at our repositories on",
- "github": "GitHub",
- "pitch3": "If you think you can make an impact, we'd love to hear from you. Send us your resume to"
- },
- "landing": {
- "header_before_icon": "The",
- "header_with_icon": "easiest",
- "header_after_icon": "way to get started with bitcoin.",
- "subheader": "A free web wallet and payment page for everyone.",
- "info1": {
- "title": "Instant payments via Lightning",
- "description": "We make it easy for merchants to receive retail payments. No waiting for bank settlements or worrying about chargebacks. Instant settlement, in seconds. Say goodbye to 3% card fees."
- },
- "info2": {
- "title": "Simple to use",
- "description1": "Just enter an amount in your local currency, share the QR code and you’re done.",
- "description2": "We do all the heavy lifting so you can focus on your business.",
- "description3": "You always have the option of taking custody of your funds by withdrawing instantly at any time."
- },
- "info3": {
- "title": "Brand it your way!",
- "description": "Customize your profile page look and feel, or keep it on default - it's totally up to you."
- }
- },
- "login": {
- "forgot": "Forgot password?",
- "reset": "Password reset",
- "optional": "Optional",
- "submit": "Submit",
- "token": "2FA Token",
- "username": "Username",
- "password": "Password",
- "newPassword": "New password",
- "email": "Email",
- "passwordRecommendation": "We recommend using a long, random password if you intend to keep funds in your account.",
- "forgotUserOrPassword": "Forgot password?",
- "haveAccount": "Already have an account?",
- "noAccount": "Don't have an account?",
- "register": "Register",
- "signIn": "Sign In",
- "failed": "Login failed"
- },
- "nav": {
- "about": "About",
- "docs": "Docs",
- "messages": "Messages",
- "funds": "Funds",
- "map": "Map",
- "merch": "Swag",
- "profile": "Profile",
- "startInSeconds": "Start in Seconds",
- "account": "Account",
- "signIn": "Sign In",
- "signOut": "Sign out",
- "dashboard": "Dashboard",
- "settings": "Settings",
- "support": "Support"
- },
- "news": {
- "header": "News",
- "subheader": "Latest Updates"
- },
- "user": {
- "profilePage": "Profile page",
- "nostrPubkey": "Nostr pubkey",
- "requestPayment": "Request Payment",
- "welcome": "Welcome! Your account balance is empty. You can start by making a deposit or by asking someone to pay you.",
- "showBalance": "Show Balance",
- "bitcoin": "Bitcoin",
- "lightning": "Lightning",
- "invoice": "Invoice",
- "unfollow": "Unfollow",
- "following": "Following",
- "follow": "Follow",
- "followers": "Followers",
- "remove": "Remove",
- "noNotes": "No notes yet",
- "message": "Message",
- "messages": "Messages",
- "feed": "Feed",
- "notes": "Notes",
- "pay": "Pay",
- "scanToPayBTC": "Scan to pay with bitcoin",
- "this": "This",
- "lightningAddress": "Lightning address",
- "dashboard": {
- "go": "Go",
- "dashboard": "Dashboard",
- "accountBalance": "Account Balance",
- "conversionFeeWarning": "You will be charged a 1% withdrawal fee on the amount.",
- "fetchingRate": "fetching rate...",
- "send": "Send",
- "receive": "Receive",
- "withdraw": "Send",
- "deposit": "Deposit",
- "voucher": "Voucher"
- },
- "receive": {
- "lessThan1BTCWarning": "Please enter an amount less than 1 bitcoin.",
- "showQR": "Show QR"
- },
- "send": {
- "makeQR": "QR",
- "contacts": "Contacts",
- "scan": "Scan",
- "paste": "Paste",
- "next": "Next",
- "placeholder": "Paste a bitcoin address, lightning invoice or coinos username"
- },
- "settings": {
- "shopify": "Shopify integration",
- "notifications": "Payment notifications",
- "notificationsDesc": "Receive an email whenever a payment lands in your account",
- "seedPhrase": "Seed phrase",
- "nostrKeys": "Nostr key",
- "nostrDescription": "Your nostr key is used to sign and decrypt messages, keep it safe or someone may be able to impersonate you.",
- "seedDescription": "This 12 word seed phrase is used to derive your nostr private key and your self-custodial wallet keys which determine your auto-withdrawal addresses. Back it up and don't let anyone see it.",
- "emailDescription": "For password resets and payment notifications only",
- "hideNsec": "Hide nostr secret key",
- "saved": "Settings saved!",
- "verifying": "Verification email sent",
- "verified": "Email verified!",
- "revealNsec": "Reveal nostr secret key",
- "hideSeed": "Hide seed phrase",
- "revealSeed": "Reveal seed phrase",
- "saveSettings": "Save Settings",
- "bannerImage": "Banner Image",
- "profileImage": "Profile Image",
- "oneTimeCode": "Enter one-time code",
- "accountId": "Account Secret",
- "header": "Settings",
- "ACCOUNT": "ACCOUNT",
- "POINT_OF_SALE": "PREFERENCES",
- "SECURITY": "SECURITY",
- "locale": "Language",
- "username": "Username",
- "email": "Email",
- "newPassword": "Change Password",
- "about": "About",
- "aboutPlaceholder": "A little something about you or your business address and hours",
- "emailNotifications": "Email Notifications",
- "emailNotificationsDescription": "Get notified via email when a change occurs on your account or when people send you payments.",
- "smsNotifications": "SMS Notifications",
- "smsNotificationsDescription": "Coinos will send you text notifications when this is enabled.",
- "theme": "Color Theme",
- "tipPrompt": "Prompt for tips",
- "tipPromptDescription": "Ask people if they want to add a tip before paying their invoices",
- "displayName": "Display name",
- "themeDescription": "Select from the default color themes.",
- "localCurrency": "Currency",
- "btcUnit": "Display bitcoin in:",
- "bitcoin": "bitcoin",
- "minutes": "minutes",
- "hour": "hour",
- "hours": "hours",
- "satoshis": "Satoshis",
- "securityPIN": "Security PIN",
- "securityPINDescription": "Set a security pin that will be used to unlock your settings and to send outgoing payments.",
- "setPIN": "Set PIN",
- "autoLock": "Timeout",
- "autoLockDescription": "Time after which your PIN needs to be re-entered:",
- "twofa": "2-Factor Authentication",
- "twofaDescription": "Add an extra level of security to your device by enabling 2-factor authentication.",
- "twofaSetup": "Set up 2FA",
- "twofaDisable": "Disable 2FA",
- "select": "Select",
- "verifyPIN": "Verify PIN",
- "enablePIN": "Enable PIN",
- "disablePIN": "Disable PIN",
- "publishNip5": "Publish nostr identity",
- "nip5a": "Use",
- "nip5b": "as your publicly verified nostr address"
- },
- "support": {
- "header": "Support",
- "email": "Email",
- "accountName": "Account Name",
- "message": "Message",
- "send": "Send"
- }
- },
- "payments": {
- "networkFee": "Network fee",
- "platformFee": "Platform fee",
- "fastest": "Fastest",
- "fast": "Fast",
- "medium": "Medium",
- "slow": "Slow",
- "create": "Create",
- "fund": "Fund",
- "addFunds": "Add Funds",
- "takeFunds": "Take Funds",
- "show": "Show",
- "hide": "Hide",
- "qr": "QR",
- "copyLink": "Copy Link",
- "copyText": "Copy Text",
- "openLink": "Open wallet",
- "moreOptions": "More options",
- "total": "Total",
- "gainLoss": "Gain/Loss",
- "presentValue": "Present Value",
- "amount": "Amount",
- "date": "Date",
- "id": "Transaction ID",
- "details": "Transaction Details",
- "header": "Payments",
- "preimage": "Proof of payment",
- "maxfee": "Max routing fee",
- "type": "Type",
- "time": "Time",
- "sent": "Sent",
- "received": "Received",
- "empty": "No transactions yet.",
- "send": "Send",
- "next": "Next",
- "sendTo": "Send to",
- "to": "to",
- "pay": "Pay",
- "requesting": "is requesting",
- "sentInvoiceTo": "Sent invoice to",
- "sentRequestTo": "Request sent!",
- "pleasePay": "Please pay",
- "day": "Day",
- "week": "Week",
- "month": "Month",
- "all": "All",
- "export": "Export",
- "invoice": "Invoice",
- "readyToPay": "is ready to pay",
- "describeOrder": "Use this field to describe your order",
- "requestAnInvoice": "Request Invoice",
- "submit": "Submit",
- "isRequesting": "is requesting",
- "invoiceFrom": "Invoice from",
- "awaiting": "Awaiting",
- "tapAnywhere": "Tap anywhere to continue",
- "from": "from",
- "redeem": "Redeem",
- "redeemed": "Redeemed",
- "redeemedBy": "Redeemed by",
- "sendMessage": "Write a message...",
- "fundsClaimed": "Funds claimed!",
- "print": "Print",
- "onlyLbtc": "We only support",
- "dontDeposit": "don't deposit other assets yet"
- }
+ "404": {
+ "404": "404",
+ "pageNotFound": "Page not found."
+ },
+ "about": {
+ "header": "About",
+ "team": {
+ "header": "The Team",
+ "adam": {
+ "name": "Adam Soltys",
+ "position": "Founder and CTO",
+ "bio": "Adam is a software engineer who believes that the adoption of sound money will drive global prosperity. He lives in North Vancouver with his wife, daughter, and son."
+ },
+ "cole": {
+ "name": "Cole",
+ "position": "Business Development",
+ "bio": "Cole is a driven individual with a passion for freedom. He came across bitcoin in 2016 and studied it in depth. Now he wants to introduce the lightning network to as many users as possible."
+ }
+ },
+ "locations": {
+ "header": "Locations",
+ "description": "Here are some businesses that are accepting bitcoin with Coinos. We hope that yours will be next!"
+ }
+ },
+ "error": {
+ "header": "Error",
+ "message": "Please try again or contact support.",
+ "signIn": "Please sign in to continue.",
+ "unrecognizedInput": "Unrecognized input"
+ },
+ "faq": {
+ "header": "FAQ",
+ "cost": {
+ "question": "What does it cost?",
+ "answer": "Receiving payments into your account is free. Withdrawals to external wallets incur a small fee that varies depending on network conditions."
+ },
+ "compatibility": {
+ "question": "Do I need any special device or software?",
+ "answer": "No, Coinos works anywhere that has Internet. Merchants might use it on a tablet or put up a QR code for customers to scan with their phone."
+ },
+ "safety": {
+ "question": "When do my funds settle?",
+ "answer": "Lightning payments are settled instantly. You can withdraw your balance to another wallet within seconds. On-chain deposits take 5-10 minutes to confirm on average."
+ },
+ "pos": {
+ "question": "Can Coinos integrate with my existing PoS?",
+ "answer": "We recommend entering sales into your existing PoS as cash transactions."
+ },
+ "bitcoin": {
+ "question": "What can I do with Bitcoin?",
+ "answer": "Spend it at other merchants or pay your expenses with it by getting your staff, suppliers and landlord to take it."
+ }
+ },
+ "footer": {
+ "company": "Company",
+ "followUs": "Follow Us",
+ "github": "GitHub",
+ "linktree": "Linktree",
+ "jobs": "Jobs",
+ "support": "Support",
+ "telegram": "Telegram",
+ "twitter": "Twitter",
+ "documentation": "Documentation"
+ },
+ "howItWorks": {
+ "header": "How it works",
+ "step1": {
+ "header": "1. Create your account",
+ "description": "A username and password is all you need to get started."
+ },
+ "step2": {
+ "header": "2. Ask for payments",
+ "description": "The same as you normally would, but with bitcoin."
+ },
+ "step3": {
+ "header": "3. That's all!",
+ "description": "Spend your coin immediately or watch it grow in value."
+ }
+ },
+ "invoice": {
+ "addTip": "Add a tip",
+ "addTipq": "Add a tip?",
+ "done": "Done",
+ "paymentSuccessful": "Payment received!",
+ "invoice": "Invoice",
+ "total": "Total",
+ "tip": "Tip"
+ },
+ "jobs": {
+ "header": "Jobs",
+ "subheader": "Current Openings",
+ "pitch1": "Coinos is actively looking for developers to join our growing team (full-time or part-time, remote working OK).",
+ "pitch2": "Excited about working on open source bitcoin? Then take a look at our repositories on",
+ "github": "GitHub",
+ "pitch3": "If you think you can make an impact, we'd love to hear from you. Send us your resume to"
+ },
+ "landing": {
+ "header_before_icon": "The",
+ "header_with_icon": "easiest",
+ "header_after_icon": "way to get started with bitcoin.",
+ "subheader": "A free web wallet and payment page for everyone.",
+ "info1": {
+ "title": "Instant payments via Lightning",
+ "description": "We make it easy for merchants to receive retail payments. No waiting for bank settlements or worrying about chargebacks. Instant settlement, in seconds. Say goodbye to 3% card fees."
+ },
+ "info2": {
+ "title": "Simple to use",
+ "description1": "Just enter an amount in your local currency, share the QR code and you’re done.",
+ "description2": "We do all the heavy lifting so you can focus on your business.",
+ "description3": "You always have the option of taking custody of your funds by withdrawing instantly at any time."
+ },
+ "info3": {
+ "title": "Brand it your way!",
+ "description": "Customize your profile page look and feel, or keep it on default - it's totally up to you."
+ }
+ },
+ "login": {
+ "forgot": "Forgot password?",
+ "reset": "Password reset",
+ "optional": "Optional",
+ "submit": "Submit",
+ "token": "2FA Token",
+ "username": "Username",
+ "password": "Password",
+ "newPassword": "New password",
+ "email": "Email",
+ "passwordRecommendation": "We recommend using a long, random password if you intend to keep funds in your account.",
+ "forgotUserOrPassword": "Forgot password?",
+ "haveAccount": "Already have an account?",
+ "noAccount": "Don't have an account?",
+ "register": "Register",
+ "signIn": "Sign In",
+ "failed": "Login failed"
+ },
+ "nav": {
+ "about": "About",
+ "docs": "Docs",
+ "messages": "Messages",
+ "funds": "Funds",
+ "map": "Map",
+ "merch": "Swag",
+ "profile": "Profile",
+ "startInSeconds": "Start in Seconds",
+ "account": "Account",
+ "signIn": "Sign In",
+ "signOut": "Sign out",
+ "dashboard": "Dashboard",
+ "settings": "Settings",
+ "support": "Support"
+ },
+ "news": {
+ "header": "News",
+ "subheader": "Latest Updates"
+ },
+ "user": {
+ "profilePage": "Profile page",
+ "nostrPubkey": "Nostr pubkey",
+ "requestPayment": "Request Payment",
+ "welcome": "Welcome! Your account balance is empty. You can start by making a deposit or by asking someone to pay you.",
+ "showBalance": "Show Balance",
+ "bitcoin": "Bitcoin",
+ "lightning": "Lightning",
+ "invoice": "Invoice",
+ "unfollow": "Unfollow",
+ "following": "Following",
+ "follow": "Follow",
+ "followers": "Followers",
+ "remove": "Remove",
+ "noNotes": "No notes yet",
+ "message": "Message",
+ "messages": "Messages",
+ "feed": "Feed",
+ "notes": "Notes",
+ "pay": "Pay",
+ "scanToPayBTC": "Scan to pay with bitcoin",
+ "this": "This",
+ "lightningAddress": "Lightning address",
+ "dashboard": {
+ "go": "Go",
+ "dashboard": "Dashboard",
+ "accountBalance": "Account Balance",
+ "conversionFeeWarning": "You will be charged a 1% withdrawal fee on the amount.",
+ "fetchingRate": "fetching rate...",
+ "send": "Send",
+ "receive": "Receive",
+ "withdraw": "Send",
+ "deposit": "Deposit",
+ "voucher": "Voucher"
+ },
+ "receive": {
+ "lessThan1BTCWarning": "Please enter an amount less than 1 bitcoin.",
+ "showQR": "Show QR"
+ },
+ "send": {
+ "makeQR": "QR",
+ "contacts": "Contacts",
+ "scan": "Scan",
+ "paste": "Paste",
+ "next": "Next",
+ "placeholder": "Enter an address, invoice or username"
+ },
+ "settings": {
+ "destination": "Auto-withdrawal address",
+ "destinationDesc": "The address that withdrawals will be sent to",
+ "destinationPlaceholder": "Enter a Bitcoin, Liquid or Lightning address",
+ "reserve": "Reserve amount",
+ "reserveDesc": "The amount to be left in your account after the withdrawal is complete",
+ "shopify": "Shopify integration",
+ "threshold": "Auto-withdrawal threshold",
+ "thresholdDesc": "When your balance exceeds this amount, a withdrawal will be triggered",
+ "autoWithdraw": "Autowithdrawal",
+ "autoWithdrawDescription": "Enable withdrawals to an external address when your balance reaches a given threshold",
+ "notifications": "Payment notifications",
+ "notificationsDesc": "Receive an email whenever a payment lands in your account",
+ "seedPhrase": "Seed phrase",
+ "nostrKeys": "Nostr key",
+ "nostrDescription": "Your nostr key is used to sign and decrypt messages, keep it safe or someone may be able to impersonate you.",
+ "seedDescription": "This 12 word seed phrase is used to derive your nostr private key and your self-custodial wallet keys which determine your auto-withdrawal addresses. Back it up and don't let anyone see it.",
+ "emailDescription": "For password resets and payment notifications only",
+ "hideNsec": "Hide nostr secret key",
+ "saved": "Settings saved!",
+ "verifying": "Verification email sent",
+ "verified": "Email verified!",
+ "revealNsec": "Reveal nostr secret key",
+ "hideSeed": "Hide seed phrase",
+ "revealSeed": "Reveal seed phrase",
+ "saveSettings": "Save Settings",
+ "bannerImage": "Banner Image",
+ "profileImage": "Profile Image",
+ "oneTimeCode": "Enter one-time code",
+ "accountId": "Account Secret",
+ "header": "Settings",
+ "ACCOUNT": "ACCOUNT",
+ "POINT_OF_SALE": "PREFERENCES",
+ "SECURITY": "SECURITY",
+ "locale": "Language",
+ "username": "Username",
+ "email": "Email",
+ "newPassword": "Change Password",
+ "about": "About",
+ "aboutPlaceholder": "A little something about you or your business address and hours",
+ "emailNotifications": "Email Notifications",
+ "emailNotificationsDescription": "Get notified via email when a change occurs on your account or when people send you payments.",
+ "smsNotifications": "SMS Notifications",
+ "smsNotificationsDescription": "Coinos will send you text notifications when this is enabled.",
+ "theme": "Color Theme",
+ "tipPrompt": "Prompt for tips",
+ "tipPromptDescription": "Ask people if they want to add a tip before paying their invoices",
+ "displayName": "Display name",
+ "themeDescription": "Select from the default color themes.",
+ "localCurrency": "Currency",
+ "btcUnit": "Display bitcoin in:",
+ "bitcoin": "bitcoin",
+ "minutes": "minutes",
+ "hour": "hour",
+ "hours": "hours",
+ "satoshis": "Satoshis",
+ "securityPIN": "Security PIN",
+ "securityPINDescription": "Set a security pin that will be used to unlock your settings and to send outgoing payments.",
+ "setPIN": "Set PIN",
+ "autoLock": "Timeout",
+ "autoLockDescription": "Time after which your PIN needs to be re-entered:",
+ "twofa": "2-Factor Authentication",
+ "twofaDescription": "Add an extra level of security to your device by enabling 2-factor authentication.",
+ "twofaSetup": "Set up 2FA",
+ "twofaDisable": "Disable 2FA",
+ "select": "Select",
+ "verifyPIN": "Verify PIN",
+ "enablePIN": "Enable PIN",
+ "disablePIN": "Disable PIN",
+ "publishNip5": "Publish nostr identity",
+ "nip5a": "Use",
+ "nip5b": "as your publicly verified nostr address"
+ },
+ "support": {
+ "header": "Support",
+ "email": "Email",
+ "accountName": "Account Name",
+ "message": "Message",
+ "send": "Send"
+ }
+ },
+ "payments": {
+ "networkFee": "Network fee",
+ "platformFee": "Platform fee",
+ "fastest": "Fastest",
+ "fast": "Fast",
+ "medium": "Medium",
+ "slow": "Slow",
+ "create": "Create",
+ "fund": "Fund",
+ "addFunds": "Add Funds",
+ "takeFunds": "Take Funds",
+ "show": "Show",
+ "hide": "Hide",
+ "qr": "QR",
+ "copyLink": "Copy Link",
+ "copyText": "Copy Text",
+ "openLink": "Open wallet",
+ "moreOptions": "More options",
+ "total": "Total",
+ "gainLoss": "Gain/Loss",
+ "presentValue": "Present Value",
+ "amount": "Amount",
+ "date": "Date",
+ "id": "Transaction ID",
+ "details": "Transaction Details",
+ "header": "Payments",
+ "preimage": "Proof of payment",
+ "maxfee": "Max routing fee",
+ "type": "Type",
+ "time": "Time",
+ "sent": "Sent",
+ "received": "Received",
+ "empty": "No transactions yet.",
+ "send": "Send",
+ "next": "Next",
+ "sendTo": "Send to",
+ "to": "to",
+ "pay": "Pay",
+ "requesting": "is requesting",
+ "sentInvoiceTo": "Sent invoice to",
+ "sentRequestTo": "Request sent!",
+ "pleasePay": "Please pay",
+ "day": "Day",
+ "week": "Week",
+ "month": "Month",
+ "all": "All",
+ "export": "Export",
+ "invoice": "Invoice",
+ "readyToPay": "is ready to pay",
+ "describeOrder": "Use this field to describe your order",
+ "requestAnInvoice": "Request Invoice",
+ "submit": "Submit",
+ "isRequesting": "is requesting",
+ "invoiceFrom": "Invoice from",
+ "awaiting": "Awaiting",
+ "tapAnywhere": "Tap anywhere to continue",
+ "from": "from",
+ "redeem": "Redeem",
+ "redeemed": "Redeemed",
+ "redeemedBy": "Redeemed by",
+ "sendMessage": "Write a message...",
+ "fundsClaimed": "Funds claimed!",
+ "print": "Print",
+ "onlyLbtc": "We only support",
+ "dontDeposit": "don't deposit other assets yet"
+ }
}
diff --git a/src/locales/es.json b/src/locales/es.json
index 6f661f69..9239ed80 100644
--- a/src/locales/es.json
+++ b/src/locales/es.json
@@ -262,7 +262,16 @@
"nip5b": "como su dirección nostr verificada públicamente",
"minutes": "minutos",
"hour": "hora",
- "hours": "horas"
+ "hours": "horas",
+ "destination": "Dirección de retiro automático",
+ "destinationDesc": "La dirección a la que se enviarán los retiros",
+ "destinationPlaceholder": "Ingrese una dirección Bitcoin, Liquid o Lightning",
+ "reserve": "Monto de reserva",
+ "reserveDesc": "El monto que quedará en su cuenta una vez completado el retiro",
+ "threshold": "Umbral de retiro automático",
+ "thresholdDesc": "Cuando su saldo exceda esta cantidad, se activará un retiro",
+ "autoWithdraw": "Retiro automático",
+ "autoWithdrawDescription": "Habilite retiros a una dirección externa cuando su saldo alcance un umbral determinado"
},
"support": {
"header": "Soporte",
diff --git a/src/locales/fa.json b/src/locales/fa.json
index 702901f3..4d148d4d 100644
--- a/src/locales/fa.json
+++ b/src/locales/fa.json
@@ -262,7 +262,16 @@
"disablePIN": "غیرفعال کردن پین",
"publishNip5": "انتشار هویت nostr",
"nip5a": "استفاده کنید",
- "nip5b": "به عنوان آدرس nostr که به طور عمومی تأیید شده است"
+ "nip5b": "به عنوان آدرس nostr که به طور عمومی تأیید شده است",
+ "destination": "آدرس برداشت خودکار",
+ "destinationDesc": "آدرسی که برداشت ها به آن ارسال می شود",
+ "destinationPlaceholder": "آدرس بیت کوین، مایع یا لایتنینگ را وارد کنید",
+ "reserve": "مقدار رزرو کنید",
+ "reserveDesc": "مبلغی که پس از اتمام برداشت در حساب شما باقی می ماند",
+ "threshold": "آستانه برداشت خودکار",
+ "thresholdDesc": "وقتی موجودی شما از این مقدار بیشتر شود، برداشت آغاز می شود",
+ "autoWithdraw": "برداشت خودکار",
+ "autoWithdrawDescription": "زمانی که موجودی شما به آستانه معینی رسید، برداشت به یک آدرس خارجی را فعال کنید"
},
"support": {
"header": "حمایت کردن",
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 3ad1ec14..7340d114 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -231,7 +231,16 @@
"publishNip5": "Publie identité nostr",
"nip5a": "Utilise",
"nip5b": "comme votre addresse nostr verifié publiquement",
- "shopify": "Intégration Shopify"
+ "shopify": "Intégration Shopify",
+ "destination": "Adresse de retrait automatique",
+ "destinationDesc": "L'adresse à laquelle les retraits seront envoyés",
+ "destinationPlaceholder": "Entrez une adresse Bitcoin, Liquid ou Lightning",
+ "reserve": "Montant de la réserve",
+ "reserveDesc": "Le montant qui restera sur votre compte une fois le retrait terminé",
+ "threshold": "Seuil de retrait automatique",
+ "thresholdDesc": "Lorsque votre solde dépasse ce montant, un retrait sera déclenché",
+ "autoWithdraw": "Retrait automatique",
+ "autoWithdrawDescription": "Activez les retraits vers une adresse externe lorsque votre solde atteint un seuil donné"
},
"support": {
"header": "Assistance",
diff --git a/src/locales/ja.json b/src/locales/ja.json
index 7ad0710e..58c4d357 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -262,7 +262,16 @@
"disablePIN": "PIN を無効にする",
"publishNip5": "nostr のアイデンティティを公開する",
"nip5a": "使用",
- "nip5b": "公的に確認された nostr アドレスとして"
+ "nip5b": "公的に確認された nostr アドレスとして",
+ "destination": "自動出金アドレス",
+ "destinationDesc": "出金先のアドレス",
+ "destinationPlaceholder": "ビットコイン、リキッド、またはライトニング アドレスを入力してください",
+ "reserve": "積立金額",
+ "reserveDesc": "出金完了後にアカウントに残る金額",
+ "threshold": "自動出金基準額",
+ "thresholdDesc": "残高がこの金額を超えると引き出しがトリガーされます",
+ "autoWithdraw": "自動引き出し",
+ "autoWithdrawDescription": "残高が指定されたしきい値に達したときに外部アドレスへの出金を有効にする"
},
"support": {
"header": "サポート",
diff --git a/src/locales/pt.json b/src/locales/pt.json
index 2cdce81d..d1355880 100644
--- a/src/locales/pt.json
+++ b/src/locales/pt.json
@@ -281,7 +281,16 @@
"revealSeed": "Revelar frase-semente",
"publishNip5": "Publicar identidade nostr",
"nip5a": "Usar",
- "nip5b": "como seu endereço nostr verificado publicamente"
+ "nip5b": "como seu endereço nostr verificado publicamente",
+ "destination": "Endereço de retirada automática",
+ "destinationDesc": "O endereço para onde os saques serão enviados",
+ "destinationPlaceholder": "Insira um endereço Bitcoin, Liquid ou Lightning",
+ "reserve": "Valor da reserva",
+ "reserveDesc": "O valor que restará em sua conta após a conclusão do saque",
+ "threshold": "Limite de retirada automática",
+ "thresholdDesc": "Quando o seu saldo exceder esse valor, um saque será acionado",
+ "autoWithdraw": "Retirada automática",
+ "autoWithdrawDescription": "Habilite saques para um endereço externo quando seu saldo atingir um determinado limite"
},
"support": {
"header": "Suporte",
diff --git a/src/locales/ru.json b/src/locales/ru.json
index b183ffc5..52103b79 100644
--- a/src/locales/ru.json
+++ b/src/locales/ru.json
@@ -261,7 +261,16 @@
"disablePIN": "Отключить ПИН-код",
"publishNip5": "Опубликовать личность nostr",
"nip5a": "Использовать",
- "nip5b": "в качестве вашего общедоступного адреса nostr"
+ "nip5b": "в качестве вашего общедоступного адреса nostr",
+ "destination": "Адрес автоматического вывода средств",
+ "destinationDesc": "Адрес, на который будут отправлены выплаты",
+ "destinationPlaceholder": "Введите адрес Bitcoin, Liquid или Lightning",
+ "reserve": "Резервная сумма",
+ "reserveDesc": "Сумма, которая останется на вашем счете после завершения вывода средств",
+ "threshold": "Порог автоматического вывода средств",
+ "thresholdDesc": "Когда ваш баланс превысит эту сумму, будет запущен вывод средств.",
+ "autoWithdraw": "Автовывод",
+ "autoWithdrawDescription": "Включите вывод средств на внешний адрес, когда ваш баланс достигнет заданного порога."
},
"support": {
"header": "Поддерживать",
diff --git a/src/locales/zh.json b/src/locales/zh.json
index f44cbb26..0553a774 100644
--- a/src/locales/zh.json
+++ b/src/locales/zh.json
@@ -262,7 +262,16 @@
"disablePIN": "禁用 PIN 码",
"publishNip5": "发布 nostr 身份",
"nip5a": "使用",
- "nip5b": "作为您公开验证的 nostr 地址"
+ "nip5b": "作为您公开验证的 nostr 地址",
+ "destination": "自动提现地址",
+ "destinationDesc": "提款将发送至的地址",
+ "destinationPlaceholder": "输入比特币、Liquid 或闪电地址",
+ "reserve": "储备金额",
+ "reserveDesc": "提款完成后您账户中剩余的金额",
+ "threshold": "自动提现门槛",
+ "thresholdDesc": "当您的余额超过此金额时,将触发提款",
+ "autoWithdraw": "自动提款",
+ "autoWithdrawDescription": "当您的余额达到给定阈值时,启用向外部地址提款"
},
"support": {
"header": "支持",
diff --git a/src/routes/(app)/[username]/settings/[...tab]/+page.server.js b/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
index 8b44f452..23d2ba9b 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
@@ -16,8 +16,10 @@ export const actions = {
form.notify = form.notify === "on";
form.nip5 = form.nip5 === "on";
form.prompt = form.prompt === "on";
+ form.autowithdraw = form.autowithdraw === "on";
}
+ console.log("FORM", form.reserve)
let user = { ...(await get("/me", auth(cookies))), ...form };
try {
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
index 4fd61918..4eca2979 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
@@ -1,5 +1,7 @@
<script>
+ import { tick } from "svelte";
import Icon from "$comp/Icon.svelte";
+ import Numpad from "$comp/Numpad.svelte";
import LocaleSelector from "$comp/LocaleSelector.svelte";
import Toggle from "$comp/Toggle.svelte";
import { locale, t } from "$lib/translations";
@@ -8,8 +10,34 @@
export let user, rates, submit;
+ let { currency } = user;
+ let rate = rates[currency];
+
let fiats = Object.keys(rates);
- $: user.language = $locale
+ $: user.language = $locale;
+ let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click());
+
+ let editingReserve, editingThreshold, doneReserve, doneThreshold;
+ let doneEditing = () => {
+ editingReserve = false;
+ editingThreshold = false;
+ };
+
+ let editReserve = async () => {
+ editingReserve = true;
+ await tick();
+ reserveEl.focus();
+ };
+
+ let editThreshold = async () => {
+ editingThreshold = true;
+ await tick();
+ thresholdEl.focus();
+ };
+
+ if (!user.threshold) user.threshold = 1000000;
+ if (!user.reserve) user.reserve = 100000;
+ let reserveEl, thresholdEl;
</script>
<div>
@@ -66,6 +94,126 @@
</p>
</div>
+<div>
+ <div class="flex justify-between items-center">
+ <span class="font-bold">{$t("user.settings.autoWithdraw")}</span>
+ <Toggle id="autowithdraw" bind:value={user.autowithdraw} />
+ </div>
+ <p class="text-secondary mt-1 w-9/12">
+ {$t("user.settings.autoWithdrawDescription")}
+ </p>
+</div>
+
+{#if user.autowithdraw}
+ <div class="mb-2">
+ <label for="display" class="font-bold mb-1 block"
+ >{$t("user.settings.destination")}</label
+ >
+ <textarea
+ name="destination"
+ placeholder={$t("user.settings.destinationPlaceholder")}
+ on:keypress={keypress}
+ class="w-full p-4 border rounded-xl h-48"
+ bind:value={user.destination}
+ />
+ </div>
+
+ <div>
+ <label for="display" class="font-bold mb-1 block"
+ >{$t("user.settings.threshold")}</label
+ >
+ <button type="button" class="flex w-full" on:click={editThreshold}>
+ <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-primary">
+ ⚡️
+ </div>
+ <div
+ class="border-l-0 rounded-l-none pl-2 w-full p-4 border rounded-2xl text-left"
+ >{user.threshold}</div>
+ <input type="hidden" name="reserve" bind:value={user.reserve} />
+ </button>
+ <p class="text-secondary mt-1">
+ {$t("user.settings.thresholdDesc")}
+ </p>
+ </div>
+
+ <div>
+ <label for="display" class="font-bold mb-1 block"
+ >{$t("user.settings.reserve")}</label
+ >
+ <button type="button" class="flex w-full" on:click={editReserve}>
+ <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-primary">
+ ⚡️
+ </div>
+ <div
+ class="border-l-0 rounded-l-none pl-2 w-full p-4 border rounded-2xl text-left"
+ >
+ {user.reserve}
+ </div>
+ <input type="hidden" name="reserve" bind:value={user.reserve} />
+ </button>
+ <p class="text-secondary mt-1">
+ {$t("user.settings.reserveDesc")}
+ </p>
+ </div>
+{/if}
+
+{#if editingThreshold}
+ <div
+ class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50"
+ >
+ <div
+ class="relative top-40 mx-auto p-5 border shadow-lg rounded-md bg-white space-y-5 w-lg max-w-lg"
+ >
+ <h1 class="text-center text-2xl font-semibold">
+ {$t("user.settings.threshold")}
+ </h1>
+ <Numpad
+ bind:amount={user.threshold}
+ bind:currency
+ bind:rate
+ bind:submit={doneReserve}
+ bind:element={thresholdEl}
+ />
+
+ <button
+ bind:this={doneReserve}
+ type="button"
+ on:click={doneEditing}
+ class="p-4 bg-black text-white rounded-2xl text-lg font-semibold w-full"
+ >Ok</button
+ >
+ </div>
+ </div>
+{/if}
+
+{#if editingReserve}
+ <div
+ class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50"
+ >
+ <div
+ class="relative top-40 mx-auto p-5 border shadow-lg rounded-md bg-white space-y-5 w-lg max-w-lg text-center"
+ >
+ <h1 class="text-2xl font-semibold">
+ {$t("user.settings.reserve")}
+ </h1>
+ <Numpad
+ bind:amount={user.reserve}
+ bind:currency
+ bind:rate
+ bind:submit={doneReserve}
+ bind:element={reserveEl}
+ />
+ <button
+ bind:this={doneReserve}
+ type="button"
+ on:click={doneEditing}
+ class="p-4 bg-black text-white rounded-2xl text-lg font-semibold w-full"
+ >Ok</button
+ >
+ </div>
+ </div>
+{/if}
+
<a href="./shopify">
<button
type="button"
diff --git a/src/routes/(app)/send/[...text]/+page.svelte b/src/routes/(app)/send/[...text]/+page.svelte
index 41b58bfb..489650a5 100644
--- a/src/routes/(app)/send/[...text]/+page.svelte
+++ b/src/routes/(app)/send/[...text]/+page.svelte
@@ -9,7 +9,7 @@
import Avatar from "$comp/Avatar.svelte";
import Icon from "$comp/Icon.svelte";
import Spinner from "$comp/Spinner.svelte";
- import { back, fail } from "$lib/utils";
+ import { back, fail, focus } from "$lib/utils";
export let data;
export let form;
@@ -18,10 +18,9 @@
let { contacts } = data;
let w;
- let el, textarea, text;
- let placeholder = $t("user.send.placeholder");
+ let el, text;
+
- $: $page && setTimeout(() => w > 800 && textarea?.focus(), 0);
let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click());
let paste = async () => {
@@ -48,12 +47,12 @@
<div class="mb-2">
<textarea
+ use:focus
name="text"
- {placeholder}
+ placeholder={$t("user.send.placeholder")}
on:keypress={keypress}
class="w-full p-4 border rounded-xl h-48"
bind:value={text}
- bind:this={textarea}
/>
</div>
diff --git a/src/routes/(app)/send/invoice/[id]/+page.server.js b/src/routes/(app)/send/invoice/[id]/+page.server.js
index 88017362..c6b0a9a4 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.server.js
+++ b/src/routes/(app)/send/invoice/[id]/+page.server.js
@@ -41,6 +41,7 @@ export const actions = {
await post("/payments", body, auth(cookies));
} catch (e) {
+ console.log("payment failed", params, e);
return fail(400, { message: e.message });
}
diff --git a/src/routes/(app)/send/invoice/[id]/+page.svelte b/src/routes/(app)/send/invoice/[id]/+page.svelte
index e857f717..dd637d70 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/send/invoice/[id]/+page.svelte
@@ -35,8 +35,8 @@
amountFiat = af;
};
- let loading;
- let submit = () => (loading = true);
+ let submitting;
+ let submit = () => (submitting = true);
let external = async () => {
let invoice = { type: "lightning", amount, currency };
@@ -52,8 +52,8 @@
$: update(form);
let update = () => {
- if (form?.message.includes("pin")) $pin = undefined;
- loading = false;
+ if (form?.message?.includes("pin")) $pin = undefined;
+ submitting = false;
};
// onMount(async () => {
@@ -152,8 +152,9 @@
use:focus
type="submit"
class="opacity-100 hover:opacity-80'} rounded-2xl border py-3 font-bold mx-auto mt-2 bg-black text-white px-4 w-24"
+ disabled={submitting}
>
- {#if loading}
+ {#if submitting}
<Spinner />
{:else}
{$t("payments.send")}