diff --git a/src/features/wallet/components/create-wallet.tsx b/src/features/wallet/components/create-wallet.tsx index 338211e56..2d9625da0 100644 --- a/src/features/wallet/components/create-wallet.tsx +++ b/src/features/wallet/components/create-wallet.tsx @@ -36,6 +36,7 @@ const CreateWallet: React.FC<{ setWalletData: React.Dispatch { const intl = useIntl(); const api = useApi(); + const [relays, setRelays] = useState([]); + const [initialMints, setInitialMints] = useState([]); const [mints, setMints] = useState([]); const fetchWallet = async () => { @@ -28,24 +35,37 @@ const WalletMints = () => { if (data) { const normalizedData = baseWalletSchema.parse(data); setMints(normalizedData.mints); + setInitialMints(normalizedData.mints); + setRelays(normalizedData.relays); } } catch (error) { - toast.error(intl.formatMessage(messages.error)); + toast.error(intl.formatMessage(messages.loadingError)); } }; const handleClick = async () =>{ - try { - const response = await api.post('/api/v1/ditto/cashu/wallet'); - const data: WalletData = await response.json(); - if (data) { - const normalizedData = baseWalletSchema.parse(data); - setMints(normalizedData.mints); - } + if (mints.length <= 0) { + toast.error(intl.formatMessage(messages.empty)); + return; + } + if (mints.some((mint) => !isURL(mint))) { + toast.error(intl.formatMessage(messages.url)); + return; + } + + if (JSON.stringify(initialMints) === JSON.stringify(mints)) { + return; + } + try { + await api.put('/api/v1/ditto/cashu/wallet', { mints: mints, relays: relays }); + + toast.success(intl.formatMessage(messages.sucess)); } catch (error) { - toast.error('Wallet not found'); + const errorMessage = error instanceof Error ? error.message : intl.formatMessage(messages.error); + toast.error(errorMessage); + console.error(error); } }; @@ -56,7 +76,7 @@ const WalletMints = () => { return ( - + diff --git a/src/features/wallet/components/wallet-relays.tsx b/src/features/wallet/components/wallet-relays.tsx index 49172cbf4..0e362bafb 100644 --- a/src/features/wallet/components/wallet-relays.tsx +++ b/src/features/wallet/components/wallet-relays.tsx @@ -8,10 +8,15 @@ import { RelayEditor } from 'soapbox/features/wallet/components/editable-lists.t import { useApi } from 'soapbox/hooks/useApi.ts'; import { WalletData, baseWalletSchema } from 'soapbox/schemas/wallet.ts'; import toast from 'soapbox/toast.tsx'; +import { isURL } from 'soapbox/utils/auth.ts'; const messages = defineMessages({ title: { id: 'wallet.relays', defaultMessage: 'Wallet Relays' }, - error: { id: 'wallet.loading_error', defaultMessage: 'An unexpected error occurred while loading your wallet data.' }, + loadingError: { id: 'wallet.loading_error', defaultMessage: 'An unexpected error occurred while loading your wallet data.' }, + error: { id: 'wallet.relays.error', defaultMessage: 'Failed to update mints.' }, + empty: { id: 'wallet.relays.empty', defaultMessage: 'At least one relay is required.' }, + url: { id: 'wallet.invalid_url', defaultMessage: 'All strings must be valid URLs.' }, + sucess: { id: 'wallet.relays.sucess', defaultMessage: 'Relays updated with success!' }, send: { id: 'common.send', defaultMessage: 'Send' }, }); @@ -19,7 +24,9 @@ const WalletRelays = () => { const intl = useIntl(); const api = useApi(); - const [relays, setRelays] = useState(['teste.com']); + const [relays, setRelays] = useState([]); + const [initialRelays, setInitialRelays] = useState([]); + const [mints, setMints] = useState([]); const fetchWallet = async () => { try { @@ -27,25 +34,38 @@ const WalletRelays = () => { const data: WalletData = await response.json(); if (data) { const normalizedData = baseWalletSchema.parse(data); + setMints(normalizedData.mints); setRelays(normalizedData.relays); + setInitialRelays(normalizedData.relays); } } catch (error) { - toast.error(intl.formatMessage(messages.error)); + toast.error(intl.formatMessage(messages.loadingError)); } }; const handleClick = async () =>{ - try { - const response = await api.post('/api/v1/ditto/cashu/wallet'); - const data: WalletData = await response.json(); - if (data) { - const normalizedData = baseWalletSchema.parse(data); - setRelays(normalizedData.relays); - } + if (relays.length <= 0) { + toast.error(intl.formatMessage(messages.empty)); + return; + } + if (relays.some((relay) => !isURL(relay))) { + toast.error(intl.formatMessage(messages.url)); + return; + } + + if (JSON.stringify(initialRelays) === JSON.stringify(relays)) { + return; + } + + try { + await api.put('/api/v1/ditto/cashu/wallet', { mints: mints, relays: relays }); + toast.success(intl.formatMessage(messages.sucess)); } catch (error) { - toast.error('Wallet not found'); + const errorMessage = error instanceof Error ? error.message : intl.formatMessage(messages.error); + toast.error(errorMessage); + console.error(error); } }; diff --git a/src/locales/en.json b/src/locales/en.json index ae3bff6b8..1836cc499 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1139,22 +1139,6 @@ "mute_modal.duration": "Duration", "mute_modal.hide_notifications": "Hide notifications from this user?", "mutes.empty.groups": "You haven't muted any groups yet.", - "wallet": "Wallet", - "wallet.balance.cashu": "{amount} sats", - "wallet.balance.exchange_button": "Exchange", - "wallet.balance.mint.paid_message": "Your mint was successful, and your sats are now in your balance. Enjoy!", - "wallet.balance.mint.unpaid_message": "Your mint is still unpaid. Complete the payment to receive your sats.", - "wallet.balance.mint_button": "Mint", - "wallet.balance.withdraw_button": "Withdraw", - "wallet.create_wallet.button": "Create wallet", - "wallet.create_wallet.question": "Do you want create one?", - "wallet.create_wallet.title": "You don't have a wallet", - "wallet.loading_error": "An unexpected error occurred while loading your wallet data.", - "wallet.management": "Wallet Management", - "wallet.mints": "Mints", - "wallet.relays": "Wallet Relays", - "wallet.payment": "Payment Method", - "wallet.transactions": "Transactions", "navbar.login.action": "Log in", "navbar.login.email.placeholder": "E-mail address", "navbar.login.forgot_password": "Forgot password?", @@ -1275,8 +1259,6 @@ "notifications.filter.statuses": "Updates from people you follow", "notifications.group": "{count, plural, one {# notification} other {# notifications}}", "notifications.queue_label": "Click to see {count} new {count, plural, one {notification} other {notifications}}", - "zap.send_to": "Send zaps to {target}", - "payment_method.send_to": "Send {method} to {target}", "oauth_consumer.tooltip": "Sign in with {provider}", "oauth_consumers.title": "Other ways to sign in", "onboarding.avatar.subtitle": "Just have fun with it.", @@ -1313,6 +1295,10 @@ "password_reset.reset": "Reset password", "patron.donate": "Donate", "patron.title": "Funding Goal", + "payment_method.button.text.raw": "{method} {amount} sats", + "payment_method.comment_input.placeholder": "Optional comment", + "payment_method.send_to": "Send {method} to {target}", + "payment_method.split_message.deducted": "{amountDeducted} sats will deducted*", "pinned_accounts.title": "{name}’s choices", "pinned_statuses.none": "No pins to show.", "poll.choose_multiple": "Choose as many as you'd like.", @@ -1726,14 +1712,37 @@ "video.pause": "Pause", "video.play": "Play", "video.unmute": "Unmute sound", + "wallet": "Wallet", + "wallet.balance.cashu": "{amount} sats", + "wallet.balance.exchange_button": "Exchange", + "wallet.balance.expired": "Expired", + "wallet.balance.mint.paid_message": "Your mint was successful, and your sats are now in your balance. Enjoy!", + "wallet.balance.mint.payment": "Make the payment to complete:", + "wallet.balance.mint.unpaid_message": "Your mint is still unpaid. Complete the payment to receive your sats.", + "wallet.balance.mint_button": "Mint", + "wallet.balance.withdraw_button": "Withdraw", + "wallet.create_wallet.button": "Create wallet", + "wallet.create_wallet.question": "Do you want create one?", + "wallet.create_wallet.title": "You don't have a wallet", + "wallet.invalid_url": "All strings must be valid URLs.", + "wallet.loading_error": "An unexpected error occurred while loading your wallet data.", + "wallet.management": "Wallet Management", + "wallet.mints": "Mints", + "wallet.mints.empty": "At least one mint is required.", + "wallet.mints.error": "Failed to update mints.", + "wallet.mints.sucess": "Mints updated with success!", + "wallet.payment": "Payment Method", + "wallet.relays": "Wallet Relays", + "wallet.relays.empty": "At least one relay is required.", + "wallet.relays.error": "Failed to update mints.", + "wallet.relays.sucess": "Relays updated with success!", + "wallet.transactions": "Transactions", "who_to_follow.title": "People To Follow", - "payment_method.button.text.raw": "{method} {amount} sats", "zap.button.text.rounded": "{method} {amount}K sats", - "payment_method.comment_input.placeholder": "Optional comment", "zap.finish": "Finish", "zap.next": "Next", "zap.open_wallet": "Open Wallet", - "payment_method.split_message.deducted": "{amountDeducted} sats will deducted*", + "zap.send_to": "Send zaps to {target}", "zap.split_message.receiver": "{receiver} will receive {amountReceiver} sats*", "zap_split.question": "Why am I paying this?", "zap_split.text": "Your support will help us build an unstoppable empire and rule the galaxy!",