@openfort/react 1.1.4 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/assets/icons.js +1 -1
- package/build/assets/logos.d.ts +12 -0
- package/build/assets/logos.js +7 -0
- package/build/assets/logos.js.map +1 -1
- package/build/components/Common/CopyToClipboard/CopyIconButton.d.ts +3 -1
- package/build/components/Common/CopyToClipboard/CopyIconButton.js +4 -4
- package/build/components/Common/CustomQRCode/index.d.ts +1 -1
- package/build/components/Common/CustomQRCode/index.js +3 -3
- package/build/components/Common/CustomQRCode/styles.d.ts +1 -0
- package/build/components/Common/CustomQRCode/styles.js +4 -4
- package/build/components/Common/CustomQRCode/types.d.ts +2 -0
- package/build/components/Common/Modal/styles.js +4 -1
- package/build/components/Common/Modal/styles.js.map +1 -1
- package/build/components/ConnectModal/index.js +14 -2
- package/build/components/ConnectModal/index.js.map +1 -1
- package/build/components/Openfort/OpenfortProvider.js +4 -1
- package/build/components/Openfort/OpenfortProvider.js.map +1 -1
- package/build/components/Openfort/types.d.ts +86 -0
- package/build/components/Openfort/types.js +22 -1
- package/build/components/Openfort/types.js.map +1 -1
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.d.ts +6 -0
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.js +42 -0
- package/build/components/Pages/AssetInventory/SolanaAssetInventory.js.map +1 -0
- package/build/components/Pages/Buy/index.js +3 -2
- package/build/components/Pages/Buy/index.js.map +1 -1
- package/build/components/Pages/BuySelectProvider/index.js +1 -1
- package/build/components/Pages/Connected/EthereumConnected.js +8 -32
- package/build/components/Pages/Connected/EthereumConnected.js.map +1 -1
- package/build/components/Pages/Connected/SolanaConnected.js +9 -4
- package/build/components/Pages/Connected/SolanaConnected.js.map +1 -1
- package/build/components/Pages/Deposit/AddressPageLink.d.ts +7 -0
- package/build/components/Pages/Deposit/AddressPageLink.js +17 -0
- package/build/components/Pages/Deposit/AddressPageLink.js.map +1 -0
- package/build/components/Pages/Deposit/AssetChainLogo.d.ts +9 -0
- package/build/components/Pages/Deposit/AssetChainLogo.js +24 -0
- package/build/components/Pages/Deposit/AssetChainLogo.js.map +1 -0
- package/build/components/Pages/Deposit/DepositAddressBlock.d.ts +21 -0
- package/build/components/Pages/Deposit/DepositAddressBlock.js +28 -0
- package/build/components/Pages/Deposit/DepositAddressBlock.js.map +1 -0
- package/build/components/Pages/Deposit/DepositProgress.d.ts +15 -0
- package/build/components/Pages/Deposit/DepositProgress.js +110 -0
- package/build/components/Pages/Deposit/DepositProgress.js.map +1 -0
- package/build/components/Pages/Deposit/DepositStatus.d.ts +9 -0
- package/build/components/Pages/Deposit/DepositStatus.js +43 -0
- package/build/components/Pages/Deposit/DepositStatus.js.map +1 -0
- package/build/components/Pages/Deposit/DepositSuccess.d.ts +6 -0
- package/build/components/Pages/Deposit/DepositSuccess.js +24 -0
- package/build/components/Pages/Deposit/DepositSuccess.js.map +1 -0
- package/build/components/Pages/Deposit/Details.d.ts +12 -0
- package/build/components/Pages/Deposit/Details.js +40 -0
- package/build/components/Pages/Deposit/Details.js.map +1 -0
- package/build/components/Pages/Deposit/LogoSelect.d.ts +12 -0
- package/build/components/Pages/Deposit/LogoSelect.js +95 -0
- package/build/components/Pages/Deposit/LogoSelect.js.map +1 -0
- package/build/components/Pages/Deposit/OrDivider.d.ts +2 -0
- package/build/components/Pages/Deposit/OrDivider.js +10 -0
- package/build/components/Pages/Deposit/OrDivider.js.map +1 -0
- package/build/components/Pages/Deposit/RouteSelectors.d.ts +13 -0
- package/build/components/Pages/Deposit/RouteSelectors.js +19 -0
- package/build/components/Pages/Deposit/RouteSelectors.js.map +1 -0
- package/build/components/Pages/Deposit/cexChains.d.ts +9 -0
- package/build/components/Pages/Deposit/cexChains.js +23 -0
- package/build/components/Pages/Deposit/cexChains.js.map +1 -0
- package/build/components/Pages/Deposit/formStyles.d.ts +24 -0
- package/build/components/Pages/Deposit/formStyles.js +83 -0
- package/build/components/Pages/Deposit/formStyles.js.map +1 -0
- package/build/components/Pages/Deposit/index.d.ts +7 -0
- package/build/components/Pages/Deposit/index.js +100 -0
- package/build/components/Pages/Deposit/index.js.map +1 -0
- package/build/components/Pages/Deposit/paymentOptions.d.ts +49 -0
- package/build/components/Pages/Deposit/paymentOptions.js +63 -0
- package/build/components/Pages/Deposit/paymentOptions.js.map +1 -0
- package/build/components/Pages/Deposit/sources.d.ts +17 -0
- package/build/components/Pages/Deposit/sources.js +22 -0
- package/build/components/Pages/Deposit/sources.js.map +1 -0
- package/build/components/Pages/Deposit/styles.d.ts +25 -0
- package/build/components/Pages/Deposit/styles.js +167 -0
- package/build/components/Pages/Deposit/styles.js.map +1 -0
- package/build/components/Pages/Deposit/useDepositRoute.d.ts +35 -0
- package/build/components/Pages/Deposit/useDepositRoute.js +107 -0
- package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -0
- package/build/components/Pages/Deposit/useFundingTarget.d.ts +13 -0
- package/build/components/Pages/Deposit/useFundingTarget.js +27 -0
- package/build/components/Pages/Deposit/useFundingTarget.js.map +1 -0
- package/build/components/Pages/DepositCex/index.d.ts +11 -0
- package/build/components/Pages/DepositCex/index.js +230 -0
- package/build/components/Pages/DepositCex/index.js.map +1 -0
- package/build/components/Pages/DepositCrypto/index.d.ts +8 -0
- package/build/components/Pages/DepositCrypto/index.js +31 -0
- package/build/components/Pages/DepositCrypto/index.js.map +1 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.d.ts +17 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +148 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -0
- package/build/components/Pages/DepositWallet/index.d.ts +9 -0
- package/build/components/Pages/DepositWallet/index.js +102 -0
- package/build/components/Pages/DepositWallet/index.js.map +1 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +48 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.js +107 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.js.map +1 -0
- package/build/components/Pages/ExportKey/index.js +10 -2
- package/build/components/Pages/ExportKey/index.js.map +1 -1
- package/build/components/Pages/NoAssetsAvailable/index.js +5 -21
- package/build/components/Pages/NoAssetsAvailable/index.js.map +1 -1
- package/build/components/Pages/SelectToken/styles.js +1 -1
- package/build/components/Pages/Send/SolanaSend.d.ts +1 -0
- package/build/components/Pages/Send/SolanaSend.js +88 -0
- package/build/components/Pages/Send/SolanaSend.js.map +1 -0
- package/build/components/Pages/Send/index.d.ts +2 -1
- package/build/components/Pages/Send/index.js +0 -1
- package/build/components/Pages/Send/index.js.map +1 -1
- package/build/components/Pages/SendConfirmation/EstimatedFees.js +5 -3
- package/build/components/Pages/SendConfirmation/EstimatedFees.js.map +1 -1
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.d.ts +1 -0
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +77 -0
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -0
- package/build/components/Pages/SendConfirmation/index.js +4 -3
- package/build/components/Pages/SendConfirmation/index.js.map +1 -1
- package/build/components/Pages/SendConfirmation/styles.d.ts +5 -0
- package/build/components/Pages/SendConfirmation/styles.js +39 -1
- package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
- package/build/constants/logos.js +1 -0
- package/build/constants/logos.js.map +1 -1
- package/build/ethereum/hooks/useEthereumWalletAssets.js +212 -95
- package/build/ethereum/hooks/useEthereumWalletAssets.js.map +1 -1
- package/build/hooks/openfort/fundingClient.d.ts +34 -0
- package/build/hooks/openfort/fundingClient.js +60 -0
- package/build/hooks/openfort/fundingClient.js.map +1 -0
- package/build/hooks/openfort/useFunding.d.ts +159 -0
- package/build/hooks/openfort/useFunding.js +204 -0
- package/build/hooks/openfort/useFunding.js.map +1 -0
- package/build/hooks/openfort/useFundingChains.d.ts +49 -0
- package/build/hooks/openfort/useFundingChains.js +102 -0
- package/build/hooks/openfort/useFundingChains.js.map +1 -0
- package/build/hooks/useBalance.js +6 -1
- package/build/hooks/useBalance.js.map +1 -1
- package/build/index.d.ts +4 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/shared/hooks/useAsyncData.d.ts +11 -0
- package/build/shared/hooks/useAsyncData.js +60 -13
- package/build/shared/hooks/useAsyncData.js.map +1 -1
- package/build/solana/hooks/useSolanaWalletAssets.d.ts +24 -0
- package/build/solana/hooks/useSolanaWalletAssets.js +86 -0
- package/build/solana/hooks/useSolanaWalletAssets.js.map +1 -0
- package/build/solana/transfer.d.ts +32 -0
- package/build/solana/transfer.js +125 -0
- package/build/solana/transfer.js.map +1 -0
- package/build/utils/index.d.ts +2 -1
- package/build/utils/index.js +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/build/wagmi/defaultConnectors.js +5 -1
- package/build/wagmi/defaultConnectors.js.map +1 -1
- package/package.json +9 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { useCallback, useMemo } from 'react';
|
|
2
|
-
import { numberToHex, custom, createWalletClient, formatUnits } from 'viem';
|
|
2
|
+
import { numberToHex, custom, createWalletClient, formatUnits, createPublicClient, http, erc20Abi } from 'viem';
|
|
3
3
|
import { erc7811Actions } from 'viem/experimental';
|
|
4
4
|
import { useOpenfort } from '../../components/Openfort/useOpenfort.js';
|
|
5
5
|
import { OpenfortError, OpenfortReactErrorType } from '../../types.js';
|
|
6
6
|
import { useUser } from '../../hooks/openfort/useUser.js';
|
|
7
7
|
import { openfortKeys } from '../../query/queryKeys.js';
|
|
8
8
|
import { useAsyncData } from '../../shared/hooks/useAsyncData.js';
|
|
9
|
+
import { getDefaultEthereumRpcUrl } from '../../utils/rpc.js';
|
|
9
10
|
import { useEthereumEmbeddedWallet } from './useEthereumEmbeddedWallet.js';
|
|
10
11
|
|
|
11
12
|
function getUsdValue(asset) {
|
|
@@ -17,6 +18,84 @@ function getUsdValue(asset) {
|
|
|
17
18
|
const amount = Number.parseFloat(formatUnits(asset.balance, decimals));
|
|
18
19
|
return Number.isFinite(amount) ? amount * fiat.value : 0;
|
|
19
20
|
}
|
|
21
|
+
/** Stablecoins approximated at $1 in fallback mode (no price feed available). */
|
|
22
|
+
const STABLECOIN_SYMBOLS = new Set(['USDC', 'USDT', 'DAI']);
|
|
23
|
+
/**
|
|
24
|
+
* Canonical Multicall3 address — same on every major chain. Passed explicitly so
|
|
25
|
+
* multicall works even when the SDK's chain config doesn't declare a multicall3.
|
|
26
|
+
*/
|
|
27
|
+
const MULTICALL3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11';
|
|
28
|
+
/**
|
|
29
|
+
* Reads native + configured ERC-20 balances directly from the chain RPC.
|
|
30
|
+
*
|
|
31
|
+
* Fallback for when Openfort's ERC-7811 asset proxy is unavailable: the widget
|
|
32
|
+
* still shows on-chain balances (no fiat valuation — that comes from the proxy,
|
|
33
|
+
* except stablecoins which are approximated at $1). Tokens that don't exist on
|
|
34
|
+
* the chain are skipped.
|
|
35
|
+
*/
|
|
36
|
+
async function readEvmAssetsViaRpc(args) {
|
|
37
|
+
const { address, chain, rpcUrl, tokens } = args;
|
|
38
|
+
const client = createPublicClient({ chain, transport: http(rpcUrl) });
|
|
39
|
+
const out = [];
|
|
40
|
+
// Native balance — one call. Skipped silently if it fails (best-effort).
|
|
41
|
+
try {
|
|
42
|
+
const native = await client.getBalance({ address });
|
|
43
|
+
out.push({
|
|
44
|
+
type: 'native',
|
|
45
|
+
address: 'native',
|
|
46
|
+
balance: native,
|
|
47
|
+
metadata: {
|
|
48
|
+
symbol: chain.nativeCurrency.symbol,
|
|
49
|
+
decimals: chain.nativeCurrency.decimals,
|
|
50
|
+
fiat: { value: 0, currency: 'USD' },
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// native read failed for this chain — skip it
|
|
56
|
+
}
|
|
57
|
+
if (tokens.length === 0)
|
|
58
|
+
return out;
|
|
59
|
+
// Batch every token's balanceOf/decimals/symbol/name into ONE multicall request
|
|
60
|
+
// (via Multicall3) instead of 4 calls per token — keeps us well under public-RPC
|
|
61
|
+
// rate limits (429s) that previously broke the fallback.
|
|
62
|
+
const contracts = tokens.flatMap((token) => [
|
|
63
|
+
{ address: token, abi: erc20Abi, functionName: 'balanceOf', args: [address] },
|
|
64
|
+
{ address: token, abi: erc20Abi, functionName: 'decimals' },
|
|
65
|
+
{ address: token, abi: erc20Abi, functionName: 'symbol' },
|
|
66
|
+
{ address: token, abi: erc20Abi, functionName: 'name' },
|
|
67
|
+
]);
|
|
68
|
+
try {
|
|
69
|
+
const results = await client.multicall({ contracts, allowFailure: true, multicallAddress: MULTICALL3_ADDRESS });
|
|
70
|
+
tokens.forEach((token, i) => {
|
|
71
|
+
const balance = results[i * 4];
|
|
72
|
+
const decimals = results[i * 4 + 1];
|
|
73
|
+
const symbol = results[i * 4 + 2];
|
|
74
|
+
const name = results[i * 4 + 3];
|
|
75
|
+
if ((balance === null || balance === void 0 ? void 0 : balance.status) !== 'success' || (decimals === null || decimals === void 0 ? void 0 : decimals.status) !== 'success' || (symbol === null || symbol === void 0 ? void 0 : symbol.status) !== 'success')
|
|
76
|
+
return;
|
|
77
|
+
const sym = symbol.result;
|
|
78
|
+
out.push({
|
|
79
|
+
type: 'erc20',
|
|
80
|
+
address: token,
|
|
81
|
+
balance: balance.result,
|
|
82
|
+
metadata: {
|
|
83
|
+
name: ((name === null || name === void 0 ? void 0 : name.status) === 'success' ? name.result : sym),
|
|
84
|
+
symbol: sym,
|
|
85
|
+
decimals: decimals.result,
|
|
86
|
+
// No price feed in fallback mode; approximate stablecoins at $1 so the
|
|
87
|
+
// USD total isn't blank. Other tokens show their amount without a value.
|
|
88
|
+
fiat: STABLECOIN_SYMBOLS.has(sym.toUpperCase()) ? { value: 1, currency: 'USD' } : undefined,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Multicall request itself failed (RPC throttled, or no Multicall3 on the chain).
|
|
95
|
+
// Return whatever we have (native) rather than throwing away the whole fetch.
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
20
99
|
/**
|
|
21
100
|
* Returns wallet assets (tokens, NFTs) for the connected Ethereum address.
|
|
22
101
|
* Uses ERC-7811 via Openfort's authenticated RPC proxy.
|
|
@@ -116,7 +195,7 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, multiChain = false,
|
|
|
116
195
|
? ['wallet-assets', 'multi', address, customAssetsMultiChain]
|
|
117
196
|
: [...openfortKeys.walletAssets(chainId, customAssetsToFetch, address)],
|
|
118
197
|
queryFn: async () => {
|
|
119
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
198
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
|
|
120
199
|
if (multiChain) {
|
|
121
200
|
if (!address) {
|
|
122
201
|
throw new OpenfortError('No wallet address available', OpenfortReactErrorType.UNEXPECTED_ERROR);
|
|
@@ -146,7 +225,19 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, multiChain = false,
|
|
|
146
225
|
: null;
|
|
147
226
|
const responses = await Promise.all([defaultRequest, customRequest].filter(Boolean));
|
|
148
227
|
const [defaultData, customData] = await Promise.all(responses.map((r) => r.json()));
|
|
149
|
-
|
|
228
|
+
if (defaultData === null || defaultData === void 0 ? void 0 : defaultData.error) {
|
|
229
|
+
// ERC-7811 asset proxy failed — fall back to per-chain RPC reads.
|
|
230
|
+
const out = [];
|
|
231
|
+
for (const c of chains) {
|
|
232
|
+
const tokens = ((_c = (_b = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.assets) === null || _b === void 0 ? void 0 : _b[c.id]) !== null && _c !== void 0 ? _c : []);
|
|
233
|
+
const rpcUrl = (_f = (_e = (_d = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _d === void 0 ? void 0 : _d.rpcUrls) === null || _e === void 0 ? void 0 : _e[c.id]) !== null && _f !== void 0 ? _f : getDefaultEthereumRpcUrl(c.id);
|
|
234
|
+
const rpcAssets = await readEvmAssetsViaRpc({ address: address, chain: c, rpcUrl, tokens });
|
|
235
|
+
for (const a of rpcAssets)
|
|
236
|
+
out.push({ ...a, chainId: c.id });
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
const result = { ...((_g = defaultData.result) !== null && _g !== void 0 ? _g : {}) };
|
|
150
241
|
if ((customData === null || customData === void 0 ? void 0 : customData.result) && typeof customData.result === 'object') {
|
|
151
242
|
for (const [chainKey, assets] of Object.entries(customData.result)) {
|
|
152
243
|
if (!Array.isArray(assets))
|
|
@@ -157,7 +248,7 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, multiChain = false,
|
|
|
157
248
|
else {
|
|
158
249
|
const existing = new Map(result[chainKey].map((a) => { var _a; return [(_a = a.address) !== null && _a !== void 0 ? _a : '', a]; }));
|
|
159
250
|
for (const asset of assets) {
|
|
160
|
-
existing.set((
|
|
251
|
+
existing.set((_h = asset.address) !== null && _h !== void 0 ? _h : '', asset);
|
|
161
252
|
}
|
|
162
253
|
result[chainKey] = Array.from(existing.values());
|
|
163
254
|
}
|
|
@@ -172,28 +263,28 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, multiChain = false,
|
|
|
172
263
|
if (a.type === 'erc20') {
|
|
173
264
|
const asset = {
|
|
174
265
|
type: 'erc20',
|
|
175
|
-
address: ((
|
|
176
|
-
balance: BigInt((
|
|
266
|
+
address: ((_j = a.address) !== null && _j !== void 0 ? _j : '0x0'),
|
|
267
|
+
balance: BigInt((_k = a.balance) !== null && _k !== void 0 ? _k : 0),
|
|
177
268
|
metadata: {
|
|
178
|
-
name: ((
|
|
179
|
-
symbol: ((
|
|
180
|
-
decimals: (
|
|
181
|
-
fiat: (
|
|
269
|
+
name: ((_l = a.metadata) === null || _l === void 0 ? void 0 : _l.name) || 'Unknown Token',
|
|
270
|
+
symbol: ((_m = a.metadata) === null || _m === void 0 ? void 0 : _m.symbol) || 'UNKNOWN',
|
|
271
|
+
decimals: (_o = a.metadata) === null || _o === void 0 ? void 0 : _o.decimals,
|
|
272
|
+
fiat: (_p = a.metadata) === null || _p === void 0 ? void 0 : _p.fiat,
|
|
182
273
|
},
|
|
183
274
|
raw: a,
|
|
184
275
|
};
|
|
185
276
|
allAssets.push({ ...asset, chainId: cid });
|
|
186
277
|
}
|
|
187
278
|
else if (a.type === 'native') {
|
|
188
|
-
const meta = ((
|
|
279
|
+
const meta = ((_q = a.metadata) !== null && _q !== void 0 ? _q : {});
|
|
189
280
|
const asset = {
|
|
190
281
|
type: 'native',
|
|
191
282
|
address: 'native',
|
|
192
|
-
balance: BigInt((
|
|
283
|
+
balance: BigInt((_r = a.balance) !== null && _r !== void 0 ? _r : 0),
|
|
193
284
|
metadata: {
|
|
194
285
|
symbol: meta.symbol || 'ETH',
|
|
195
286
|
decimals: meta.decimals,
|
|
196
|
-
fiat: (
|
|
287
|
+
fiat: (_s = meta.fiat) !== null && _s !== void 0 ? _s : { value: 0, currency: 'USD' },
|
|
197
288
|
},
|
|
198
289
|
raw: a,
|
|
199
290
|
};
|
|
@@ -210,92 +301,118 @@ const useEthereumWalletAssets = ({ assets: hookCustomAssets, multiChain = false,
|
|
|
210
301
|
error: new Error('Address, chainId, or chain not available'),
|
|
211
302
|
});
|
|
212
303
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
});
|
|
222
|
-
const hexChainId = numberToHex(chainId);
|
|
223
|
-
const customAssetsPromise = customAssetsToFetch.length > 0
|
|
224
|
-
? extendedClient.getAssets({
|
|
304
|
+
try {
|
|
305
|
+
const customClient = createWalletClient({
|
|
306
|
+
account: address,
|
|
307
|
+
chain,
|
|
308
|
+
transport: customTransport(),
|
|
309
|
+
});
|
|
310
|
+
const extendedClient = customClient.extend(erc7811Actions());
|
|
311
|
+
const defaultAssetsPromise = extendedClient.getAssets({
|
|
225
312
|
chainIds: [chainId],
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
313
|
+
});
|
|
314
|
+
const hexChainId = numberToHex(chainId);
|
|
315
|
+
const customAssetsPromise = customAssetsToFetch.length > 0
|
|
316
|
+
? extendedClient.getAssets({
|
|
317
|
+
chainIds: [chainId],
|
|
318
|
+
assets: {
|
|
319
|
+
[hexChainId]: customAssetsToFetch.map((a) => ({
|
|
320
|
+
address: a,
|
|
321
|
+
type: 'erc20',
|
|
322
|
+
})),
|
|
323
|
+
},
|
|
324
|
+
})
|
|
325
|
+
: Promise.resolve({ [hexChainId]: [] });
|
|
326
|
+
const [defaultAssetsRaw, customAssets] = await Promise.all([defaultAssetsPromise, customAssetsPromise]);
|
|
327
|
+
// ERC-7811 response keys may be hex (e.g. "0x14a34") or numeric depending on the RPC
|
|
328
|
+
const rawByChain = defaultAssetsRaw;
|
|
329
|
+
const customByChain = customAssets;
|
|
330
|
+
const rawChainAssets = (_u = (_t = rawByChain[hexChainId]) !== null && _t !== void 0 ? _t : rawByChain[String(chainId)]) !== null && _u !== void 0 ? _u : [];
|
|
331
|
+
const customChainAssets = (_w = (_v = customByChain[hexChainId]) !== null && _v !== void 0 ? _v : customByChain[String(chainId)]) !== null && _w !== void 0 ? _w : [];
|
|
332
|
+
const defaultAssets = rawChainAssets.map((a) => {
|
|
333
|
+
var _a;
|
|
334
|
+
let asset;
|
|
335
|
+
if (a.type === 'erc20') {
|
|
336
|
+
const meta = a.metadata;
|
|
337
|
+
asset = {
|
|
229
338
|
type: 'erc20',
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
339
|
+
address: a.address,
|
|
340
|
+
balance: a.balance,
|
|
341
|
+
metadata: {
|
|
342
|
+
name: (meta === null || meta === void 0 ? void 0 : meta.name) || 'Unknown Token',
|
|
343
|
+
symbol: (meta === null || meta === void 0 ? void 0 : meta.symbol) || 'UNKNOWN',
|
|
344
|
+
decimals: meta === null || meta === void 0 ? void 0 : meta.decimals,
|
|
345
|
+
fiat: meta === null || meta === void 0 ? void 0 : meta.fiat,
|
|
346
|
+
},
|
|
347
|
+
raw: a,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
else if (a.type === 'native') {
|
|
351
|
+
const meta = a.metadata;
|
|
352
|
+
asset = {
|
|
353
|
+
type: 'native',
|
|
354
|
+
address: 'native',
|
|
355
|
+
balance: a.balance,
|
|
356
|
+
metadata: (meta === null || meta === void 0 ? void 0 : meta.fiat)
|
|
357
|
+
? { symbol: (_a = meta.symbol) !== null && _a !== void 0 ? _a : '', decimals: meta.decimals, fiat: meta.fiat }
|
|
358
|
+
: undefined,
|
|
359
|
+
raw: a,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
throw new OpenfortError('Unsupported asset type', OpenfortReactErrorType.UNEXPECTED_ERROR, { error: a });
|
|
364
|
+
}
|
|
365
|
+
return asset;
|
|
366
|
+
});
|
|
367
|
+
const mergedAssets = [...defaultAssets];
|
|
368
|
+
const customAssetsForChain = customChainAssets.flatMap((asset) => {
|
|
369
|
+
var _a, _b;
|
|
370
|
+
if (asset.type !== 'erc20')
|
|
371
|
+
return [];
|
|
372
|
+
if (!((_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.assets))
|
|
373
|
+
return [{ ...asset, raw: asset }];
|
|
374
|
+
const configAsset = (_b = walletConfig.ethereum.assets[chainId]) === null || _b === void 0 ? void 0 : _b.find((a) => a.toLowerCase() === asset.address.toLowerCase());
|
|
375
|
+
if (!configAsset)
|
|
376
|
+
return [{ ...asset, raw: asset }];
|
|
377
|
+
return [
|
|
378
|
+
{
|
|
379
|
+
type: 'erc20',
|
|
380
|
+
address: asset.address,
|
|
381
|
+
balance: asset.balance,
|
|
382
|
+
metadata: asset.metadata,
|
|
383
|
+
raw: asset,
|
|
254
384
|
},
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const mergedAssets = [...defaultAssets];
|
|
274
|
-
const customAssetsForChain = customChainAssets.flatMap((asset) => {
|
|
275
|
-
var _a, _b;
|
|
276
|
-
if (asset.type !== 'erc20')
|
|
277
|
-
return [];
|
|
278
|
-
if (!((_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.assets))
|
|
279
|
-
return [{ ...asset, raw: asset }];
|
|
280
|
-
const configAsset = (_b = walletConfig.ethereum.assets[chainId]) === null || _b === void 0 ? void 0 : _b.find((a) => a.toLowerCase() === asset.address.toLowerCase());
|
|
281
|
-
if (!configAsset)
|
|
282
|
-
return [{ ...asset, raw: asset }];
|
|
283
|
-
return [
|
|
284
|
-
{
|
|
285
|
-
type: 'erc20',
|
|
286
|
-
address: asset.address,
|
|
287
|
-
balance: asset.balance,
|
|
288
|
-
metadata: asset.metadata,
|
|
289
|
-
raw: asset,
|
|
290
|
-
},
|
|
291
|
-
];
|
|
292
|
-
});
|
|
293
|
-
customAssetsForChain.forEach((asset) => {
|
|
294
|
-
if (!mergedAssets.find((a) => a.address === asset.address)) {
|
|
295
|
-
mergedAssets.push(asset);
|
|
385
|
+
];
|
|
386
|
+
});
|
|
387
|
+
customAssetsForChain.forEach((asset) => {
|
|
388
|
+
if (!mergedAssets.find((a) => a.address === asset.address)) {
|
|
389
|
+
mergedAssets.push(asset);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
if (mergedAssets.length === 0 && customAssetsToFetch.length > 0) {
|
|
393
|
+
// Proxy succeeded but returned nothing while we expect tokens — read direct.
|
|
394
|
+
const rpcUrl = (_z = (_y = (_x = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _x === void 0 ? void 0 : _x.rpcUrls) === null || _y === void 0 ? void 0 : _y[chainId]) !== null && _z !== void 0 ? _z : getDefaultEthereumRpcUrl(chainId);
|
|
395
|
+
const fb = await readEvmAssetsViaRpc({
|
|
396
|
+
address: address,
|
|
397
|
+
chain,
|
|
398
|
+
rpcUrl,
|
|
399
|
+
tokens: customAssetsToFetch,
|
|
400
|
+
});
|
|
401
|
+
if (fb.length > 0)
|
|
402
|
+
return fb;
|
|
296
403
|
}
|
|
297
|
-
|
|
298
|
-
|
|
404
|
+
return mergedAssets;
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
// ERC-7811 asset proxy failed — fall back to direct chain-RPC balance reads.
|
|
408
|
+
const rpcUrl = (_2 = (_1 = (_0 = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _0 === void 0 ? void 0 : _0.rpcUrls) === null || _1 === void 0 ? void 0 : _1[chainId]) !== null && _2 !== void 0 ? _2 : getDefaultEthereumRpcUrl(chainId);
|
|
409
|
+
return (await readEvmAssetsViaRpc({
|
|
410
|
+
address: address,
|
|
411
|
+
chain,
|
|
412
|
+
rpcUrl,
|
|
413
|
+
tokens: customAssetsToFetch,
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
299
416
|
},
|
|
300
417
|
enabled: multiChain ? isConnected && !!address : isConnected && !!chainId && !!chain && !!address,
|
|
301
418
|
staleTime,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEthereumWalletAssets.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useEthereumWalletAssets.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { FundingSession, FundingTarget, PayLinkParams, PaymentMethodInput } from './useFunding';
|
|
2
|
+
/**
|
|
3
|
+
* The funding client surface, mirroring the planned `openfort.funding.*`
|
|
4
|
+
* namespace in `@openfort/openfort-js`:
|
|
5
|
+
*
|
|
6
|
+
* openfort.funding.sessions.create({ target })
|
|
7
|
+
* openfort.funding.sessions.setPaymentMethod(id, { clientSecret, paymentMethod })
|
|
8
|
+
* openfort.funding.sessions.get(id, { clientSecret? })
|
|
9
|
+
* openfort.funding.payLink(params)
|
|
10
|
+
*
|
|
11
|
+
* `useFunding` depends only on this interface. Today it's backed by the
|
|
12
|
+
* fetch adapter below (the standalone funding service); once the SDK ships the
|
|
13
|
+
* namespace, the adapter is swapped for `coreClient.funding` with no hook change.
|
|
14
|
+
*/
|
|
15
|
+
export type FundingClient = {
|
|
16
|
+
sessions: {
|
|
17
|
+
create(params: {
|
|
18
|
+
target: FundingTarget;
|
|
19
|
+
}): Promise<FundingSession>;
|
|
20
|
+
setPaymentMethod(id: string, params: {
|
|
21
|
+
clientSecret: string;
|
|
22
|
+
paymentMethod: PaymentMethodInput;
|
|
23
|
+
}): Promise<FundingSession>;
|
|
24
|
+
get(id: string, params?: {
|
|
25
|
+
clientSecret?: string;
|
|
26
|
+
}): Promise<FundingSession>;
|
|
27
|
+
};
|
|
28
|
+
payLink(params: PayLinkParams): Promise<string>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Fetch-backed funding client against the standalone funding service at
|
|
32
|
+
* `baseUrl`. Temporary: replaced by the SDK's `funding` namespace at cutover.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createFetchFundingClient(baseUrl: string, publishableKey?: string): FundingClient;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { logger } from '../../utils/logger.js';
|
|
2
|
+
|
|
3
|
+
async function readJson(res) {
|
|
4
|
+
var _a;
|
|
5
|
+
if (!res.ok) {
|
|
6
|
+
// The API returns { error: { type, message } }; the standalone prototype
|
|
7
|
+
// returned a flat { error: string }. Handle both so the real rail message
|
|
8
|
+
// surfaces instead of "[object Object]".
|
|
9
|
+
const body = (await res.json().catch(() => ({})));
|
|
10
|
+
const message = typeof body.error === 'string' ? body.error : (_a = body.error) === null || _a === void 0 ? void 0 : _a.message;
|
|
11
|
+
logger.error('[funding:client] request failed', { status: res.status, message });
|
|
12
|
+
throw new Error(message !== null && message !== void 0 ? message : `Funding request failed (${res.status})`);
|
|
13
|
+
}
|
|
14
|
+
return res.json();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fetch-backed funding client against the standalone funding service at
|
|
18
|
+
* `baseUrl`. Temporary: replaced by the SDK's `funding` namespace at cutover.
|
|
19
|
+
*/
|
|
20
|
+
function createFetchFundingClient(baseUrl, publishableKey) {
|
|
21
|
+
// The /v2/funding session API is publishable-key authenticated. The standalone
|
|
22
|
+
// prototype accepted no auth, so the key is optional and only attached when set.
|
|
23
|
+
const authHeaders = () => publishableKey ? { authorization: `Bearer ${publishableKey}` } : {};
|
|
24
|
+
return {
|
|
25
|
+
sessions: {
|
|
26
|
+
async create({ target }) {
|
|
27
|
+
const res = await fetch(`${baseUrl}/v2/funding/sessions`, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: { 'content-type': 'application/json', ...authHeaders() },
|
|
30
|
+
body: JSON.stringify({ target }),
|
|
31
|
+
});
|
|
32
|
+
return readJson(res);
|
|
33
|
+
},
|
|
34
|
+
async setPaymentMethod(id, { clientSecret, paymentMethod }) {
|
|
35
|
+
const res = await fetch(`${baseUrl}/v2/funding/sessions/${encodeURIComponent(id)}/payment_methods`, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: { 'content-type': 'application/json', ...authHeaders() },
|
|
38
|
+
body: JSON.stringify({ clientSecret, paymentMethod }),
|
|
39
|
+
});
|
|
40
|
+
return readJson(res);
|
|
41
|
+
},
|
|
42
|
+
async get(id, params) {
|
|
43
|
+
const query = (params === null || params === void 0 ? void 0 : params.clientSecret) ? `?clientSecret=${encodeURIComponent(params.clientSecret)}` : '';
|
|
44
|
+
return readJson(await fetch(`${baseUrl}/v2/funding/sessions/${encodeURIComponent(id)}${query}`, { headers: authHeaders() }));
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
async payLink(params) {
|
|
48
|
+
const res = await fetch(`${baseUrl}/v2/funding/pay_link`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: { 'content-type': 'application/json', ...authHeaders() },
|
|
51
|
+
body: JSON.stringify(params),
|
|
52
|
+
});
|
|
53
|
+
const data = await readJson(res);
|
|
54
|
+
return data.url;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { createFetchFundingClient };
|
|
60
|
+
//# sourceMappingURL=fundingClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fundingClient.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { type FundingClient } from './fundingClient';
|
|
2
|
+
/**
|
|
3
|
+
* Funding session client — adapted from the openfort-funding prototype.
|
|
4
|
+
*
|
|
5
|
+
* A session is one deposit attempt against a destination. The client creates a
|
|
6
|
+
* session, sets one payment method (a source the user commits to sending from),
|
|
7
|
+
* then polls until the session reaches a terminal state. The response carries
|
|
8
|
+
* everything the UI (or an agent) needs: a receiver address, a scannable URI,
|
|
9
|
+
* prefilled wallet deeplinks, and CEX guidance.
|
|
10
|
+
*
|
|
11
|
+
* The hook depends on a {@link FundingClient}, not on `fetch` directly. Today the
|
|
12
|
+
* default client is the fetch adapter over `uiConfig.fundingBaseUrl`; once
|
|
13
|
+
* `@openfort/openfort-js` ships the `funding` namespace, the resolution below
|
|
14
|
+
* swaps to `coreClient.funding` with no change to this hook.
|
|
15
|
+
*/
|
|
16
|
+
/** Where funds should land. CAIP-2 chain + token contract (or native) + wallet. */
|
|
17
|
+
export type FundingTarget = {
|
|
18
|
+
/** CAIP-2 chain id, e.g. "eip155:8453" for Base. */
|
|
19
|
+
chain: string;
|
|
20
|
+
/** Token contract address, or the zero address for the chain's native asset. */
|
|
21
|
+
currency: string;
|
|
22
|
+
/** Destination wallet that receives the bridged funds. */
|
|
23
|
+
address: string;
|
|
24
|
+
};
|
|
25
|
+
/** The route the user commits to sending from. */
|
|
26
|
+
export type FundingSource = {
|
|
27
|
+
/** CAIP-2 chain id the user sends from, e.g. "eip155:137". */
|
|
28
|
+
chain: string;
|
|
29
|
+
/** Token contract the user sends, or the zero address for native. */
|
|
30
|
+
currency: string;
|
|
31
|
+
/** Amount in the source token's smallest unit (wei, lamports, base units). */
|
|
32
|
+
amount: string;
|
|
33
|
+
};
|
|
34
|
+
/** Session lifecycle, mirroring the prototype's vocabulary. */
|
|
35
|
+
export type SessionStatus = 'requires_payment_method' | 'waiting_payment' | 'processing' | 'succeeded' | 'bounced' | 'expired';
|
|
36
|
+
export type FundingFee = {
|
|
37
|
+
kind: 'gas' | 'relayerGas' | 'relayerService' | 'app';
|
|
38
|
+
amount: string;
|
|
39
|
+
currency: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Payment-method-per-source input. `evm` and `solana` are self-custody wallet
|
|
43
|
+
* sends (they get wallet deeplinks); `cex` is an exchange withdrawal (no
|
|
44
|
+
* deeplink — exchanges can't be deeplinked into).
|
|
45
|
+
*/
|
|
46
|
+
export type PaymentMethodInput = {
|
|
47
|
+
type: 'evm';
|
|
48
|
+
source: FundingSource;
|
|
49
|
+
} | {
|
|
50
|
+
type: 'solana';
|
|
51
|
+
source: FundingSource;
|
|
52
|
+
} | {
|
|
53
|
+
type: 'cex';
|
|
54
|
+
cex: string;
|
|
55
|
+
source: FundingSource;
|
|
56
|
+
};
|
|
57
|
+
export type PaymentMethodType = PaymentMethodInput['type'];
|
|
58
|
+
/** A prefilled deeplink into a source wallet app (e.g. Trust Wallet). */
|
|
59
|
+
export type WalletDeeplink = {
|
|
60
|
+
app: string;
|
|
61
|
+
label: string;
|
|
62
|
+
url: string;
|
|
63
|
+
};
|
|
64
|
+
/** Per-exchange guidance for the guided CEX flow. */
|
|
65
|
+
export type CexGuidance = {
|
|
66
|
+
exchange: string;
|
|
67
|
+
network: string;
|
|
68
|
+
minWithdrawal: string | null;
|
|
69
|
+
requiresMemo: boolean;
|
|
70
|
+
};
|
|
71
|
+
/** A resolved payment method — what the UI renders and the agent reads. */
|
|
72
|
+
export type PaymentMethod = {
|
|
73
|
+
type: PaymentMethodType;
|
|
74
|
+
source: FundingSource;
|
|
75
|
+
/** Address the user (or their CEX/wallet) sends to. */
|
|
76
|
+
receiverAddress: string;
|
|
77
|
+
/** Provider-side id used to track settlement. */
|
|
78
|
+
providerRequestId: string;
|
|
79
|
+
/** BIP-21 / EIP-681 URI for QR. Scanner support for amount/token varies. */
|
|
80
|
+
addressUri: string;
|
|
81
|
+
/** Prefilled deeplinks for source wallet apps, when available. */
|
|
82
|
+
deeplinks: WalletDeeplink[];
|
|
83
|
+
/** Guidance for the "cex" type; null otherwise. */
|
|
84
|
+
cex: CexGuidance | null;
|
|
85
|
+
fees: FundingFee[];
|
|
86
|
+
/** Minimum to send for this route (source base units), or null. */
|
|
87
|
+
minAmount: string | null;
|
|
88
|
+
};
|
|
89
|
+
/** A single deposit attempt. */
|
|
90
|
+
export type FundingSession = {
|
|
91
|
+
id: string;
|
|
92
|
+
clientSecret: string;
|
|
93
|
+
target: FundingTarget;
|
|
94
|
+
status: SessionStatus;
|
|
95
|
+
amountUnits: string | null;
|
|
96
|
+
metadata: Record<string, string> | null;
|
|
97
|
+
externalId: string | null;
|
|
98
|
+
createdAt: number;
|
|
99
|
+
expiresAt: number;
|
|
100
|
+
paymentMethod: PaymentMethod | null;
|
|
101
|
+
};
|
|
102
|
+
export type UseFunding = {
|
|
103
|
+
session: FundingSession | null;
|
|
104
|
+
status: SessionStatus | 'idle';
|
|
105
|
+
error: Error | null;
|
|
106
|
+
/** True while a session is being created and its deposit address fetched. */
|
|
107
|
+
loading: boolean;
|
|
108
|
+
/** True when a funding client is resolved (injected, or uiConfig.fundingBaseUrl set). */
|
|
109
|
+
isAvailable: boolean;
|
|
110
|
+
/** Create a session, set a payment method, and poll until terminal. */
|
|
111
|
+
fund: (target: FundingTarget, paymentMethod: PaymentMethodInput) => Promise<FundingSession>;
|
|
112
|
+
/** Create a bare session for a target (no payment method, no polling). Used by
|
|
113
|
+
* the Coinbase CEX rail, which only needs the session id + secret to mint a
|
|
114
|
+
* pay-link; the destination is bound to the session so the client can't redirect funds. */
|
|
115
|
+
createSession: (target: FundingTarget) => Promise<FundingSession>;
|
|
116
|
+
/** Poll an already-created session (id + clientSecret) until it reaches a
|
|
117
|
+
* terminal state, surfacing `status`/`session` updates as it goes. Used by the
|
|
118
|
+
* CEX rail, which hands off to a hosted Coinbase flow and then watches the
|
|
119
|
+
* bound session settle to drive the success/failed screen. */
|
|
120
|
+
track: (session: {
|
|
121
|
+
id: string;
|
|
122
|
+
clientSecret: string;
|
|
123
|
+
}) => Promise<FundingSession>;
|
|
124
|
+
/** Resolve a hosted Coinbase pay URL for an existing session. Coinbase delivers
|
|
125
|
+
* to the session's bound destination, so only the amount (and optional asset) is client-supplied. */
|
|
126
|
+
payLink: (params: PayLinkParams) => Promise<string>;
|
|
127
|
+
/** Reset to the idle state (e.g. when leaving the Deposit flow). */
|
|
128
|
+
reset: () => void;
|
|
129
|
+
};
|
|
130
|
+
/** Parameters for a Coinbase pay-link request. The destination (chain, currency,
|
|
131
|
+
* address) is bound to the session server-side; the client only chooses how much. */
|
|
132
|
+
export type PayLinkParams = {
|
|
133
|
+
/** Session the pay-link settles into — pins the destination so it can't be redirected. */
|
|
134
|
+
sessionId: string;
|
|
135
|
+
/** Secret returned when the session was created; authorizes this pay-link. */
|
|
136
|
+
clientSecret: string;
|
|
137
|
+
/** Amount in the destination asset's units (≈ USD for USDC). Coinbase enforces its own minimum. */
|
|
138
|
+
amount: string;
|
|
139
|
+
/** Destination asset ticker. Optional — the backend defaults to USDC. */
|
|
140
|
+
asset?: string;
|
|
141
|
+
};
|
|
142
|
+
/** Options for {@link useFunding}. */
|
|
143
|
+
export type UseFundingOptions = {
|
|
144
|
+
/** Inject a funding client (tests, or a custom backend). Defaults to the
|
|
145
|
+
* fetch adapter over `uiConfig.fundingBaseUrl`. */
|
|
146
|
+
client?: FundingClient;
|
|
147
|
+
/**
|
|
148
|
+
* Resolve the base URL from the Openfort API backend (`SDKConfiguration.backendUrl`)
|
|
149
|
+
* instead of `uiConfig.fundingBaseUrl`. The CEX (Coinbase pay-link) rail is served
|
|
150
|
+
* by the API, not the standalone funding service — `DepositCex` opts in.
|
|
151
|
+
*/
|
|
152
|
+
useBackendUrl?: boolean;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* React surface over the funding session API.
|
|
156
|
+
*
|
|
157
|
+
* @returns Session state plus `fund` (run the deposit flow) and `reset`.
|
|
158
|
+
*/
|
|
159
|
+
export declare function useFunding(options?: UseFundingOptions): UseFunding;
|