Skip to content

Commit 84d89b0

Browse files
authored
feat: support token list for invoicing components (#303)
1 parent 943880f commit 84d89b0

File tree

7 files changed

+152
-82
lines changed

7 files changed

+152
-82
lines changed

packages/create-invoice-form/src/lib/create-invoice-form.svelte

+72-30
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import { calculateInvoiceTotals } from "@requestnetwork/shared-utils/invoiceTotals";
2121
import {
2222
getCurrencySupportedNetworksForConversion,
23+
initializeCreateInvoiceCurrencyManager,
2324
initializeCurrencyManager,
2425
} from "@requestnetwork/shared-utils/initCurrencyManager";
2526
// Components
@@ -29,6 +30,7 @@
2930
import Modal from "@requestnetwork/shared-components/modal.svelte";
3031
import { EncryptionTypes, CipherProviderTypes } from "@requestnetwork/types";
3132
import { onDestroy, onMount, tick } from "svelte";
33+
import { CurrencyManager } from "@requestnetwork/currency";
3234
3335
interface CipherProvider extends CipherProviderTypes.ICipherProvider {
3436
disconnectWallet: () => void;
@@ -37,7 +39,7 @@
3739
export let config: IConfig;
3840
export let wagmiConfig: WagmiConfig;
3941
export let requestNetwork: RequestNetwork | null | undefined;
40-
export let currencies: CurrencyTypes.CurrencyInput[] = [];
42+
export let currencies: string[] = [];
4143
let cipherProvider: CipherProvider | undefined;
4244
4345
let account: GetAccountReturnType | undefined =
@@ -46,7 +48,7 @@
4648
let activeConfig = config ? config : defaultConfig;
4749
let mainColor = activeConfig.colors.main;
4850
let secondaryColor = activeConfig.colors.secondary;
49-
let currencyManager = initializeCurrencyManager(currencies);
51+
let currencyManager: CurrencyManager;
5052
5153
let invoiceCurrencyDropdown: { clear: () => void };
5254
let networkDropdown: { clear: () => void };
@@ -58,10 +60,54 @@
5860
let currency: CurrencyTypes.CurrencyDefinition | undefined = undefined;
5961
let invoiceCurrency: CurrencyTypes.CurrencyDefinition | undefined = undefined;
6062
63+
let defaultCurrencies: any[] = [];
64+
65+
onMount(async () => {
66+
currencyManager = await initializeCreateInvoiceCurrencyManager(currencies);
67+
68+
defaultCurrencies = Object.values(
69+
currencyManager.knownCurrencies.reduce(
70+
(
71+
unique: { [x: string]: any },
72+
currency: { symbol: string | number }
73+
) => {
74+
const baseSymbol = String(currency.symbol).split("-")[0];
75+
if (!unique[baseSymbol]) {
76+
unique[baseSymbol] = {
77+
...currency,
78+
symbol: baseSymbol,
79+
};
80+
}
81+
return unique;
82+
},
83+
{}
84+
)
85+
);
86+
87+
unwatchAccount = watchAccount(wagmiConfig, {
88+
onChange(
89+
account: GetAccountReturnType,
90+
previousAccount: GetAccountReturnType
91+
) {
92+
tick().then(() => {
93+
handleWalletChange(account, previousAccount);
94+
});
95+
},
96+
});
97+
});
98+
6199
const handleNetworkChange = (newNetwork: string) => {
62100
if (newNetwork) {
63101
currencyDropdown.clear();
64-
invoiceCurrency = invoiceCurrency?.type !== Types.RequestLogic.CURRENCY.ISO4217 ? currencyManager.knownCurrencies.find(currency => invoiceCurrency?.symbol === currency.symbol && currency.network === newNetwork) : invoiceCurrency;
102+
invoiceCurrency =
103+
invoiceCurrency?.type !== Types.RequestLogic.CURRENCY.ISO4217
104+
? currencyManager.knownCurrencies.find(
105+
(currency) =>
106+
currency.symbol.split("-")[0] ===
107+
invoiceCurrency?.symbol.split("-")[0] &&
108+
currency.network === newNetwork
109+
)
110+
: invoiceCurrency;
65111
network = newNetwork;
66112
currency = undefined;
67113
@@ -77,7 +123,7 @@
77123
currencyManager?.getConversionPath(
78124
invoiceCurrency,
79125
currency,
80-
currency?.network,
126+
currency?.network
81127
)?.length > 0;
82128
83129
return (
@@ -88,8 +134,14 @@
88134
}
89135
90136
// For other currency types (like ERC20)
91-
return invoiceCurrency.hash === currency?.hash;
92-
},
137+
// Compare base symbols (without network suffix)
138+
const invoiceBaseSymbol = invoiceCurrency.symbol.split("-")[0];
139+
const currencyBaseSymbol = currency.symbol.split("-")[0];
140+
return (
141+
invoiceBaseSymbol === currencyBaseSymbol &&
142+
currency.network === newNetwork
143+
);
144+
}
93145
);
94146
}
95147
};
@@ -98,18 +150,9 @@
98150
let canSubmit = false;
99151
let appStatus: APP_STATUS[] = [];
100152
let formData = getInitialFormData();
101-
// Remove duplicate currencies and filter out currencies with '-' in the symbol
102-
let defaultCurrencies = Object.values(currencyManager.knownCurrencies.reduce(
103-
(unique: { [x: string]: any; }, currency: { symbol: string | number; }) => {
104-
if (!unique[currency.symbol] && !currency.symbol.includes('-')) unique[currency.symbol] = currency;
105-
106-
return unique;
107-
},
108-
{},
109-
));
110153
111154
const handleInvoiceCurrencyChange = (
112-
value: CurrencyTypes.CurrencyDefinition,
155+
value: CurrencyTypes.CurrencyDefinition
113156
) => {
114157
if (value !== invoiceCurrency) {
115158
networkDropdown.clear();
@@ -124,10 +167,16 @@
124167
if (invoiceCurrency.type === Types.RequestLogic.CURRENCY.ISO4217) {
125168
networks = (getCurrencySupportedNetworksForConversion(
126169
invoiceCurrency.hash,
127-
currencyManager,
170+
currencyManager
128171
) ?? []) as string[];
129172
} else {
130-
networks = currencyManager.knownCurrencies.filter(currency => currency.symbol === invoiceCurrency?.symbol).map(currency => currency.network);
173+
const baseSymbol = invoiceCurrency.symbol.split("-")[0];
174+
networks = currencyManager.knownCurrencies
175+
.filter((currency) => {
176+
const currencyBaseSymbol = currency.symbol.split("-")[0];
177+
return currencyBaseSymbol === baseSymbol;
178+
})
179+
.map((currency) => currency.network);
131180
}
132181
}
133182
};
@@ -152,7 +201,10 @@
152201
cipherProvider?.disconnectWallet();
153202
};
154203
155-
const handleWalletChange = (account: GetAccountReturnType, previousAccount: GetAccountReturnType) => {
204+
const handleWalletChange = (
205+
account: GetAccountReturnType,
206+
previousAccount: GetAccountReturnType
207+
) => {
156208
if (account?.address !== previousAccount?.address) {
157209
handleWalletDisconnection();
158210
handleWalletConnection();
@@ -163,16 +215,6 @@
163215
}
164216
};
165217
166-
onMount(() => {
167-
unwatchAccount = watchAccount(wagmiConfig, {
168-
onChange(account: GetAccountReturnType, previousAccount: GetAccountReturnType) {
169-
tick().then(() => {
170-
handleWalletChange(account, previousAccount);
171-
});
172-
},
173-
});
174-
});
175-
176218
let unwatchAccount: WatchAccountReturnType | undefined;
177219
178220
onDestroy(() => {
@@ -261,7 +303,7 @@
261303
paymentNetwork: requestCreateParameters.paymentNetwork,
262304
contentData: requestCreateParameters.contentData,
263305
},
264-
[payeeEncryptionParams, payerEncryptionParams],
306+
[payeeEncryptionParams, payerEncryptionParams]
265307
);
266308
} else {
267309
request = await requestNetwork.createRequest({

packages/create-invoice-form/src/lib/react/CreateInvoiceForm.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface CreateInvoiceFormProps {
88
config: IConfig;
99
wagmiConfig: WagmiConfig;
1010
requestNetwork: RequestNetwork | null | undefined;
11-
currencies?: CurrencyTypes.CurrencyInput[];
11+
currencies: string[];
1212
}
1313

1414
/**
@@ -25,7 +25,7 @@ export interface CreateInvoiceFormProps {
2525
* config={config}
2626
* wagmiConfig={wagmiConfig}
2727
* requestNetwork={requestNetwork}
28-
* currencies={currencies}
28+
* currencies={['ETH-MAINNET', 'USDC-MAINNET', 'USDC-MATIC']}
2929
* />
3030
*/
3131
declare const CreateInvoiceForm: React.FC<CreateInvoiceFormProps>;

packages/create-invoice-form/src/lib/utils/prepareRequest.ts

+22-10
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ interface IRequestParams {
1515
address: `0x${string}` | undefined;
1616
}
1717

18-
const getPaymentNetwork = (invoiceCurrency: CurrencyTypes.CurrencyDefinition, currency: CurrencyTypes.CurrencyDefinition, formData: CustomFormData) => {
18+
const getPaymentNetwork = (
19+
invoiceCurrency: CurrencyTypes.CurrencyDefinition,
20+
currency: CurrencyTypes.CurrencyDefinition,
21+
formData: CustomFormData
22+
) => {
1923
if (
2024
invoiceCurrency.type === Types.RequestLogic.CURRENCY.ISO4217 &&
2125
currency.type === Types.RequestLogic.CURRENCY.ETH
@@ -52,7 +56,7 @@ const getPaymentNetwork = (invoiceCurrency: CurrencyTypes.CurrencyDefinition, cu
5256
feeAddress: zeroAddress,
5357
feeAmount: "0",
5458
},
55-
}
59+
};
5660
} else if (currency.type === Types.RequestLogic.CURRENCY.ERC20) {
5761
return {
5862
id: Types.Extension.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT,
@@ -62,7 +66,7 @@ const getPaymentNetwork = (invoiceCurrency: CurrencyTypes.CurrencyDefinition, cu
6266
feeAddress: zeroAddress,
6367
feeAmount: "0",
6468
},
65-
}
69+
};
6670
} else {
6771
throw new Error("Unsupported payment network");
6872
}
@@ -76,13 +80,19 @@ export const prepareRequestParams = ({
7680
invoiceTotals,
7781
}: IRequestParams): Types.ICreateRequestParameters => {
7882
const isERC20 = currency.type === Types.RequestLogic.CURRENCY.ERC20;
79-
const isERC20InvoiceCurrency = invoiceCurrency.type === Types.RequestLogic.CURRENCY.ERC20;
83+
const isERC20InvoiceCurrency =
84+
invoiceCurrency.type === Types.RequestLogic.CURRENCY.ERC20;
8085
return {
8186
requestInfo: {
8287
currency: {
8388
type: invoiceCurrency.type,
84-
value: isERC20InvoiceCurrency ? invoiceCurrency.address : invoiceCurrency.symbol,
85-
network: invoiceCurrency.network,
89+
value: isERC20InvoiceCurrency
90+
? invoiceCurrency.address
91+
: invoiceCurrency.symbol,
92+
network:
93+
invoiceCurrency.network === "fiat"
94+
? undefined
95+
: invoiceCurrency.network,
8696
},
8797
expectedAmount: parseUnits(
8898
invoiceTotals.totalAmount.toString(),
@@ -122,15 +132,17 @@ export const prepareRequestParams = ({
122132
discount:
123133
item.discount != null
124134
? parseUnits(
125-
item.discount.toString(),
126-
invoiceCurrency.decimals
127-
).toString()
135+
item.discount.toString(),
136+
invoiceCurrency.decimals
137+
).toString()
128138
: undefined,
129139
tax: {
130140
type: "percentage",
131141
amount: item.tax.amount.toString(),
132142
},
133-
currency: isERC20InvoiceCurrency ? invoiceCurrency.address : invoiceCurrency.symbol,
143+
currency: isERC20InvoiceCurrency
144+
? invoiceCurrency.address
145+
: invoiceCurrency.symbol,
134146
})),
135147
paymentTerms: {
136148
dueDate: new Date(formData.dueDate).toISOString(),

packages/invoice-dashboard/src/lib/react/InvoiceDashboard.d.ts

-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export interface InvoiceDashboardProps {
88
config: IConfig;
99
wagmiConfig: WagmiConfig;
1010
requestNetwork: RequestNetwork | null | undefined;
11-
currencies?: CurrencyTypes.CurrencyInput[];
1211
}
1312
/**
1413
* InvoiceDashboard is a React component that integrates with the Request Network to manage and display invoices.
@@ -25,9 +24,6 @@ export interface InvoiceDashboardProps {
2524
* config={config}
2625
* wagmiConfig={wagmiConfig}
2726
* requestNetwork={requestNetwork}
28-
* currencies={currencies}
29-
* isDecryptionEnabled={isDecryptionEnabled}
30-
* enableDecryption={enableDecryption}
3127
* />
3228
*/
3329
declare const InvoiceDashboard: React.FC<InvoiceDashboardProps>;

packages/invoice-dashboard/src/lib/view-requests.svelte

+3-4
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
export let config: IConfig;
6464
export let wagmiConfig: WagmiConfig;
6565
export let requestNetwork: RequestNetwork | null | undefined;
66-
export let currencies: CurrencyTypes.CurrencyInput[] = [];
6766
6867
let cipherProvider: CipherProvider | undefined;
6968
@@ -182,8 +181,8 @@
182181
183182
$: isRequestPayed, getOneRequest(activeRequest);
184183
185-
onMount(() => {
186-
currencyManager = initializeCurrencyManager(currencies);
184+
onMount(async () => {
185+
currencyManager = await initializeCurrencyManager();
187186
});
188187
189188
const getRequests = async (
@@ -901,7 +900,7 @@
901900
{wagmiConfig}
902901
bind:isRequestPayed
903902
{requestNetwork}
904-
{currencyManager}
903+
bind:currencyManager
905904
config={activeConfig}
906905
request={activeRequest}
907906
/>

0 commit comments

Comments
 (0)