From 2cbdaa0f868fcf5b55c82f51822837198eebe8da Mon Sep 17 00:00:00 2001 From: Aimen Sahnoun Date: Mon, 2 Sep 2024 15:10:34 +0300 Subject: [PATCH 1/6] fix: refactor to use correct currencymanager methods and display currency correctly --- .../src/lib/view-requests.svelte | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/packages/invoice-dashboard/src/lib/view-requests.svelte b/packages/invoice-dashboard/src/lib/view-requests.svelte index b6a7f74f..001cf7b5 100644 --- a/packages/invoice-dashboard/src/lib/view-requests.svelte +++ b/packages/invoice-dashboard/src/lib/view-requests.svelte @@ -53,7 +53,12 @@ let isRequestPayed = false; let currentTab = "All"; let requests: Types.IRequestDataWithEvents[] | undefined = []; - let activeRequest: Types.IRequestDataWithEvents | undefined; + let activeRequest: + | (Types.IRequestDataWithEvents & { + formattedAmount: string; + currencySymbol: string; + }) + | undefined; let currencyManager: CurrencyManager; let columns = { @@ -194,6 +199,34 @@ currentPage * itemsPerPage ); + $: processedRequests = paginatedRequests?.map( + ( + request + ): Types.IRequestDataWithEvents & { + formattedAmount: string; + currencySymbol: string; + } => { + const currencyInfo = + request.currencyInfo.type === Types.RequestLogic.CURRENCY.ETH + ? currencyManager.getNativeCurrency( + request.currencyInfo.type, + request.currencyInfo.network! + ) + : currencyManager.fromAddress( + request.currencyInfo.value, + request.currencyInfo.network + ); + return { + ...request, + formattedAmount: formatUnits( + BigInt(request.expectedAmount), + currencyInfo?.decimals ?? 18 + ), + currencySymbol: currencyInfo!.symbol, + }; + } + ); + const goToPage = (page: number) => { if (page >= 1 && page <= totalPages) { currentPage = page; @@ -237,7 +270,10 @@ const handleRequestSelect = ( e: Event, - request: Types.IRequestDataWithEvents + request: Types.IRequestDataWithEvents & { + formattedAmount: string; + currencySymbol: string; + } ) => { activeRequest = request; }; @@ -421,8 +457,8 @@ - {#if paginatedRequests} - {#each paginatedRequests as request} + {#if processedRequests} + {#each processedRequests as request} handleRequestSelect(e, request)} @@ -481,19 +517,8 @@ {/if} - {formatUnits( - BigInt(request.expectedAmount), - // FIXME: Use a non deprecated function - currencyManager.from( - request.currencyInfo.value, - request.currencyInfo.network - )?.decimals ?? 18 - )} - - {currencyManager.from( - request.currencyInfo.value, - request.currencyInfo.network - )?.symbol} + {request.formattedAmount} + {request.currencySymbol} {checkStatus(request)} Date: Mon, 2 Sep 2024 15:11:03 +0300 Subject: [PATCH 2/6] feat: add support for creating and paying native currencies --- .../create-invoice-form/src/lib/utils/prepareRequest.ts | 5 ++++- .../src/lib/dashboard/invoice-view.svelte | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/create-invoice-form/src/lib/utils/prepareRequest.ts b/packages/create-invoice-form/src/lib/utils/prepareRequest.ts index 8ab34bdd..f441135f 100644 --- a/packages/create-invoice-form/src/lib/utils/prepareRequest.ts +++ b/packages/create-invoice-form/src/lib/utils/prepareRequest.ts @@ -40,7 +40,10 @@ export const prepareRequestParams = ({ timestamp: Utils.getCurrentTimestampInSecond(), }, paymentNetwork: { - id: Types.Extension.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT, + id: + currency.type === Types.RequestLogic.CURRENCY.ETH + ? Types.Extension.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT + : Types.Extension.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT, parameters: { paymentNetworkName: currency.network, paymentAddress: formData.payeeAddress, diff --git a/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte b/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte index b9b9f974..c120f713 100644 --- a/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte +++ b/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte @@ -119,7 +119,12 @@ ); signer = walletClientToSigner(wallet); requestData = singleRequest?.getData(); - approved = await checkApproval(requestData, signer); + + if (requestData.currencyInfo.type === Types.RequestLogic.CURRENCY.ERC20) { + approved = await checkApproval(requestData, signer); + } else { + approved = true; + } isPaid = requestData?.balance?.balance! >= requestData?.expectedAmount; loading = false; } catch (err: any) { From 413368e3659edbe160a39fc5f7ef89e6fdea8b9a Mon Sep 17 00:00:00 2001 From: Aimen Sahnoun Date: Mon, 2 Sep 2024 22:19:56 +0300 Subject: [PATCH 3/6] feat: add support for all currencies that checkout supports --- .../src/lib/utils/prepareRequest.ts | 198 +++++++++--------- .../src/lib/utils/currencies.ts | 2 + .../payment-widget/src/lib/utils/request.ts | 2 +- shared/utils/initCurrencyManager.ts | 49 ++++- 4 files changed, 146 insertions(+), 105 deletions(-) diff --git a/packages/create-invoice-form/src/lib/utils/prepareRequest.ts b/packages/create-invoice-form/src/lib/utils/prepareRequest.ts index f441135f..202b94b3 100644 --- a/packages/create-invoice-form/src/lib/utils/prepareRequest.ts +++ b/packages/create-invoice-form/src/lib/utils/prepareRequest.ts @@ -18,108 +18,112 @@ export const prepareRequestParams = ({ currency, formData, invoiceTotals, -}: IRequestParams): Types.ICreateRequestParameters => ({ - requestInfo: { - currency: { - type: currency.type, - value: currency.address, - network: currency.network, - }, - expectedAmount: parseUnits( - invoiceTotals.totalAmount.toFixed(2), - currency.decimals - ).toString(), - payee: { - type: Types.Identity.TYPE.ETHEREUM_ADDRESS, - value: formData.creatorId, - }, - payer: { - type: Types.Identity.TYPE.ETHEREUM_ADDRESS, - value: formData.payerAddress, - }, - timestamp: Utils.getCurrentTimestampInSecond(), - }, - paymentNetwork: { - id: - currency.type === Types.RequestLogic.CURRENCY.ETH - ? Types.Extension.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT - : Types.Extension.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT, - parameters: { - paymentNetworkName: currency.network, - paymentAddress: formData.payeeAddress, - feeAddress: zeroAddress, - feeAmount: "0", - }, - }, - contentData: { - meta: { - format: "rnf_invoice", - version: "0.0.3", - }, - miscellaneous: - formData.miscellaneous.labels.length > 0 - ? formData.miscellaneous - : undefined, - creationDate: new Date(formData.issuedOn).toISOString(), - invoiceNumber: formData.invoiceNumber, - note: formData.note.length > 0 ? formData.note : undefined, - invoiceItems: formData.items.map((item) => ({ - name: item.description, - quantity: Number(item.quantity), - unitPrice: parseUnits( - item.unitPrice.toString(), - currency.decimals - ).toString(), - discount: parseUnits( - item.discount.toString(), +}: IRequestParams): Types.ICreateRequestParameters => { + const isERC20 = currency.type === Types.RequestLogic.CURRENCY.ERC20; + + return { + requestInfo: { + currency: { + type: currency.type, + value: isERC20 ? currency.address : "eth", + network: currency.network, + }, + expectedAmount: parseUnits( + invoiceTotals.totalAmount.toFixed(2), currency.decimals ).toString(), - tax: { - type: "percentage", - amount: item.tax.amount.toString(), + payee: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: formData.creatorId, + }, + payer: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: formData.payerAddress, }, - currency: currency.address, - })), - paymentTerms: { - dueDate: new Date(formData.dueDate).toISOString(), + timestamp: Utils.getCurrentTimestampInSecond(), }, - buyerInfo: { - firstName: formData?.buyerInfo?.firstName || undefined, - lastName: formData?.buyerInfo?.lastName || undefined, - address: { - "country-name": - formData?.buyerInfo?.address?.["country-name"] || undefined, - locality: formData?.buyerInfo?.address?.locality || undefined, - "postal-code": - formData?.buyerInfo?.address?.["postal-code"] || undefined, - region: formData?.buyerInfo?.address?.region || undefined, - "street-address": - formData?.buyerInfo?.address?.["street-address"] || undefined, + paymentNetwork: { + id: + currency.type === Types.RequestLogic.CURRENCY.ETH + ? Types.Extension.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT + : Types.Extension.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT, + parameters: { + paymentNetworkName: currency.network, + paymentAddress: formData.payeeAddress, + feeAddress: zeroAddress, + feeAmount: "0", }, - businessName: formData?.buyerInfo?.businessName || undefined, - taxRegistration: formData?.buyerInfo?.taxRegistration || undefined, - email: formData?.buyerInfo?.email || undefined, }, - sellerInfo: { - firstName: formData?.sellerInfo?.firstName || undefined, - lastName: formData?.sellerInfo?.lastName || undefined, - address: { - "country-name": - formData?.sellerInfo?.address?.["country-name"] || undefined, - locality: formData?.sellerInfo?.address?.locality || undefined, - "postal-code": - formData?.sellerInfo?.address?.["postal-code"] || undefined, - region: formData?.sellerInfo?.address?.region || undefined, - "street-address": - formData?.sellerInfo?.address?.["street-address"] || undefined, + contentData: { + meta: { + format: "rnf_invoice", + version: "0.0.3", + }, + miscellaneous: + formData.miscellaneous.labels.length > 0 + ? formData.miscellaneous + : undefined, + creationDate: new Date(formData.issuedOn).toISOString(), + invoiceNumber: formData.invoiceNumber, + note: formData.note.length > 0 ? formData.note : undefined, + invoiceItems: formData.items.map((item) => ({ + name: item.description, + quantity: Number(item.quantity), + unitPrice: parseUnits( + item.unitPrice.toString(), + currency.decimals + ).toString(), + discount: parseUnits( + item.discount.toString(), + currency.decimals + ).toString(), + tax: { + type: "percentage", + amount: item.tax.amount.toString(), + }, + currency: isERC20 ? currency.address : currency.symbol, + })), + paymentTerms: { + dueDate: new Date(formData.dueDate).toISOString(), + }, + buyerInfo: { + firstName: formData?.buyerInfo?.firstName || undefined, + lastName: formData?.buyerInfo?.lastName || undefined, + address: { + "country-name": + formData?.buyerInfo?.address?.["country-name"] || undefined, + locality: formData?.buyerInfo?.address?.locality || undefined, + "postal-code": + formData?.buyerInfo?.address?.["postal-code"] || undefined, + region: formData?.buyerInfo?.address?.region || undefined, + "street-address": + formData?.buyerInfo?.address?.["street-address"] || undefined, + }, + businessName: formData?.buyerInfo?.businessName || undefined, + taxRegistration: formData?.buyerInfo?.taxRegistration || undefined, + email: formData?.buyerInfo?.email || undefined, }, - businessName: formData?.sellerInfo?.businessName || undefined, - taxRegistration: formData?.sellerInfo?.taxRegistration || undefined, - email: formData?.sellerInfo?.email || undefined, + sellerInfo: { + firstName: formData?.sellerInfo?.firstName || undefined, + lastName: formData?.sellerInfo?.lastName || undefined, + address: { + "country-name": + formData?.sellerInfo?.address?.["country-name"] || undefined, + locality: formData?.sellerInfo?.address?.locality || undefined, + "postal-code": + formData?.sellerInfo?.address?.["postal-code"] || undefined, + region: formData?.sellerInfo?.address?.region || undefined, + "street-address": + formData?.sellerInfo?.address?.["street-address"] || undefined, + }, + businessName: formData?.sellerInfo?.businessName || undefined, + taxRegistration: formData?.sellerInfo?.taxRegistration || undefined, + email: formData?.sellerInfo?.email || undefined, + }, + }, + signer: { + type: Types.Identity.TYPE.ETHEREUM_ADDRESS, + value: signer, }, - }, - signer: { - type: Types.Identity.TYPE.ETHEREUM_ADDRESS, - value: signer, - }, -}); + }; +}; diff --git a/packages/payment-widget/src/lib/utils/currencies.ts b/packages/payment-widget/src/lib/utils/currencies.ts index bf68f9b6..b4bb8943 100644 --- a/packages/payment-widget/src/lib/utils/currencies.ts +++ b/packages/payment-widget/src/lib/utils/currencies.ts @@ -47,6 +47,8 @@ export const CURRENCY_ID = { "ETH-OPTIMISM_OPTIMISM": "ETH-optimism-optimism", MNT_MANTLE: "MNT-mantle", "ETH-SEPOLIA_SEPOLIA": "ETH-sepolia-sepolia", + FUSDT_SEPOLIA: "fUSDT-sepolia", + FUSDC_SEPOLIA: "fUSDC-sepolia", "ETH-ZKSYNC_ZKSYNCERA": "ETH-zksync-zksyncera", "ETH-BASE_BASE": "ETH-base-base", } as const; diff --git a/packages/payment-widget/src/lib/utils/request.ts b/packages/payment-widget/src/lib/utils/request.ts index 5bbf0f43..21142bab 100644 --- a/packages/payment-widget/src/lib/utils/request.ts +++ b/packages/payment-widget/src/lib/utils/request.ts @@ -90,7 +90,7 @@ export const prepareRequestParameters = ({ type: "percentage", amount: "0", }, - currency: currencyValue, + currency: isERC20 ? currency.address : currency.symbol, }, ], diff --git a/shared/utils/initCurrencyManager.ts b/shared/utils/initCurrencyManager.ts index 5dd0f640..88cd57fa 100644 --- a/shared/utils/initCurrencyManager.ts +++ b/shared/utils/initCurrencyManager.ts @@ -9,6 +9,40 @@ const defaultCurrencyIds = [ "USDT-matic", "DAI-matic", "USDC-matic", + "AXS-mainnet", + "AUDIO-mainnet", + "RAI-mainnet", + "SYLO-mainnet", + "LDO-mainnet", + "UST-mainnet", + "MNT-mainnet", + "MIR-mainnet", + "INJ-mainnet", + "OCEAN-mainnet", + "ANKR-mainnet", + "RLY-mainnet", + "DAI-bsc", + "BUSD-bsc", + "USDC-xdai", + "USDC-avalanche", + "USDT-avalanche", + "USDC-optimism", + "USDT-optimism", + "DAI-optimism", + "USDC-multichain-moonbeam", + "USDC-wormhole-moonbeam", + "ETH-mainnet", + "REQ-mainnet", + "MATIC-matic", + "FTM-fantom", + "AVAX-avalanche", + "ETH-optimism-optimism", + "MNT-mantle", + "ETH-sepolia-sepolia", + "ETH-zksync-zksyncera", + "ETH-base-base", + "fUSDT-sepolia", + "fUSDC-sepolia", ]; export function initializeCurrencyManager( @@ -16,13 +50,14 @@ export function initializeCurrencyManager( ): CurrencyManager { let currenciesToUse: any[]; - if (customCurrencies?.length > 0) { - currenciesToUse = customCurrencies; - } else { - const defaultCurrencies = CurrencyManager.getDefaultList().filter( - (currency) => defaultCurrencyIds.includes(currency.id) - ); - currenciesToUse = defaultCurrencies; + const defaultCurrencies = CurrencyManager.getDefaultList().filter( + (currency) => defaultCurrencyIds.includes(currency.id) + ); + + currenciesToUse = defaultCurrencies; + + if (customCurrencies.length > 0) { + currenciesToUse.push(...customCurrencies); } return new CurrencyManager(currenciesToUse); From 675e59ec54184773411fe40bf657fc88a0ee506b Mon Sep 17 00:00:00 2001 From: Aimen Sahnoun Date: Mon, 2 Sep 2024 22:45:23 +0300 Subject: [PATCH 4/6] feat: enable switching to newly supported networks --- .../src/lib/dashboard/invoice-view.svelte | 46 +++++++++---------- .../src/lib/view-requests.svelte | 37 ++++++--------- .../src/utils/getCurrency.ts | 14 ++++++ 3 files changed, 52 insertions(+), 45 deletions(-) create mode 100644 packages/invoice-dashboard/src/utils/getCurrency.ts diff --git a/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte b/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte index c120f713..36d52619 100644 --- a/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte +++ b/packages/invoice-dashboard/src/lib/dashboard/invoice-view.svelte @@ -1,49 +1,43 @@