@openfort/react 1.1.4 → 1.3.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 +15 -0
- package/build/assets/logos.js +9 -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/Common/SolanaChain/index.d.ts +8 -0
- package/build/components/Common/SolanaChain/index.js +40 -0
- package/build/components/Common/SolanaChain/index.js.map +1 -0
- package/build/components/ConnectModal/index.js +16 -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 +92 -0
- package/build/components/Openfort/types.js +23 -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/coinbaseApi.d.ts +1 -1
- package/build/components/Pages/Buy/coinbaseApi.js +2 -13
- package/build/components/Pages/Buy/coinbaseApi.js.map +1 -1
- package/build/components/Pages/Buy/evmCurrencies.d.ts +11 -0
- package/build/components/Pages/Buy/evmCurrencies.js +27 -0
- package/build/components/Pages/Buy/evmCurrencies.js.map +1 -0
- package/build/components/Pages/Buy/index.js +11 -3
- package/build/components/Pages/Buy/index.js.map +1 -1
- package/build/components/Pages/Buy/onrampApi.d.ts +8 -1
- package/build/components/Pages/Buy/onrampApi.js +24 -14
- package/build/components/Pages/Buy/onrampApi.js.map +1 -1
- package/build/components/Pages/Buy/solanaCurrencies.d.ts +9 -0
- package/build/components/Pages/Buy/solanaCurrencies.js +25 -0
- package/build/components/Pages/Buy/solanaCurrencies.js.map +1 -0
- package/build/components/Pages/Buy/stripeApi.d.ts +1 -1
- package/build/components/Pages/Buy/stripeApi.js +2 -13
- package/build/components/Pages/Buy/stripeApi.js.map +1 -1
- package/build/components/Pages/BuyComplete/index.js +7 -1
- package/build/components/Pages/BuyComplete/index.js.map +1 -1
- package/build/components/Pages/BuyProcessing/index.js +9 -5
- package/build/components/Pages/BuyProcessing/index.js.map +1 -1
- package/build/components/Pages/BuySelectProvider/index.js +11 -6
- package/build/components/Pages/BuySelectProvider/index.js.map +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 +11 -5
- 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 +111 -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 +25 -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 +114 -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 +34 -0
- package/build/components/Pages/Deposit/useDepositRoute.js +106 -0
- package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -0
- package/build/components/Pages/Deposit/useFundingTarget.d.ts +11 -0
- package/build/components/Pages/Deposit/useFundingTarget.js +25 -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 +229 -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 +20 -0
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +139 -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 +107 -0
- package/build/components/Pages/DepositWallet/index.js.map +1 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +50 -0
- package/build/components/Pages/DepositWallet/walletDeeplinks.js +109 -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/SolanaSelectToken.d.ts +1 -0
- package/build/components/Pages/SelectToken/SolanaSelectToken.js +50 -0
- package/build/components/Pages/SelectToken/SolanaSelectToken.js.map +1 -0
- package/build/components/Pages/SelectToken/index.js +13 -2
- package/build/components/Pages/SelectToken/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 +89 -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/Send/utils.js +4 -1
- package/build/components/Pages/Send/utils.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 +121 -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/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 +100 -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 +73 -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 +61 -0
- package/build/solana/transfer.js +219 -0
- package/build/solana/transfer.js.map +1 -0
- package/build/solana/types.d.ts +8 -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 +13 -1
|
@@ -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;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { SDKConfiguration } from '@openfort/openfort-js';
|
|
2
|
+
import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
+
import { useOpenfort } from '../../components/Openfort/useOpenfort.js';
|
|
4
|
+
import { useOpenfortCore } from '../../openfort/useOpenfort.js';
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
import { createFetchFundingClient } from './fundingClient.js';
|
|
7
|
+
|
|
8
|
+
/** Pay-links aren't exposed by the SDK funding namespace yet (CEX is API-deferred). */
|
|
9
|
+
const sdkPayLinkUnavailable = async () => {
|
|
10
|
+
throw new Error('Exchange pay-links are not available through the SDK yet');
|
|
11
|
+
};
|
|
12
|
+
const TERMINAL = ['succeeded', 'bounced', 'expired'];
|
|
13
|
+
const POLL_MS = 4000;
|
|
14
|
+
/**
|
|
15
|
+
* Poll a session until it reaches a terminal state, pushing each update through
|
|
16
|
+
* `onUpdate`. Shared by `fund` (after a payment method is set) and `track` (the
|
|
17
|
+
* CEX rail, watching a hosted Coinbase deposit settle). `isCurrent` guards a
|
|
18
|
+
* stale loop from clobbering newer state after reset/unmount.
|
|
19
|
+
*/
|
|
20
|
+
async function pollUntilTerminal(client, onUpdate, start, isCurrent) {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
let current = start;
|
|
23
|
+
let prev = current.status;
|
|
24
|
+
while (!TERMINAL.includes(current.status)) {
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_MS));
|
|
26
|
+
if (!isCurrent())
|
|
27
|
+
return current;
|
|
28
|
+
current = await client.sessions.get(current.id, { clientSecret: current.clientSecret });
|
|
29
|
+
if (!isCurrent())
|
|
30
|
+
return current;
|
|
31
|
+
onUpdate(current);
|
|
32
|
+
if (current.status !== prev) {
|
|
33
|
+
logger.log('[funding] status', { sessionId: current.id, prev, status: current.status });
|
|
34
|
+
prev = current.status;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (current.status === 'succeeded') {
|
|
38
|
+
logger.log('[funding] terminal: delivered', {
|
|
39
|
+
sessionId: current.id,
|
|
40
|
+
status: current.status,
|
|
41
|
+
txHash: (_c = (_b = (_a = current.metadata) === null || _a === void 0 ? void 0 : _a.txHash) !== null && _b !== void 0 ? _b : current.externalId) !== null && _c !== void 0 ? _c : null,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// bounced = source delivered but Relay refunded; expired = nothing arrived in time.
|
|
46
|
+
logger.warn('[funding] terminal: failed', { sessionId: current.id, status: current.status });
|
|
47
|
+
}
|
|
48
|
+
return current;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* React surface over the funding session API.
|
|
52
|
+
*
|
|
53
|
+
* @returns Session state plus `fund` (run the deposit flow) and `reset`.
|
|
54
|
+
*/
|
|
55
|
+
function useFunding(options) {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
const { uiConfig, publishableKey } = useOpenfort();
|
|
58
|
+
const { client: coreClient } = useOpenfortCore();
|
|
59
|
+
// The funding JSON API defaults to the Openfort backend (api.openfort.io);
|
|
60
|
+
// integrators can point the crypto rails at a custom service via
|
|
61
|
+
// uiConfig.fundingBaseUrl. The CEX rail always uses the backend (Coinbase pay-link).
|
|
62
|
+
const backendUrl = ((_a = SDKConfiguration.getInstance()) === null || _a === void 0 ? void 0 : _a.backendUrl) || 'https://api.openfort.io';
|
|
63
|
+
const baseUrl = (options === null || options === void 0 ? void 0 : options.useBackendUrl) ? backendUrl : uiConfig.fundingBaseUrl || backendUrl;
|
|
64
|
+
const injected = options === null || options === void 0 ? void 0 : options.client;
|
|
65
|
+
// Resolve the client, in order of preference:
|
|
66
|
+
// 1. an explicitly injected client (tests / custom backends),
|
|
67
|
+
// 2. the SDK's `openfort.funding` namespace once available,
|
|
68
|
+
// 3. the fetch adapter over uiConfig.fundingBaseUrl.
|
|
69
|
+
// The SDK namespace covers sessions; pay-links stay on the backend adapter
|
|
70
|
+
// until the API exposes them (CEX is deferred), so we compose the two.
|
|
71
|
+
const client = useMemo(() => {
|
|
72
|
+
var _a;
|
|
73
|
+
if (injected)
|
|
74
|
+
return injected;
|
|
75
|
+
const sdkFunding = coreClient === null || coreClient === void 0 ? void 0 : coreClient.funding;
|
|
76
|
+
const fetchClient = baseUrl ? createFetchFundingClient(baseUrl, publishableKey) : null;
|
|
77
|
+
if (sdkFunding) {
|
|
78
|
+
return { sessions: sdkFunding.sessions, payLink: (_a = fetchClient === null || fetchClient === void 0 ? void 0 : fetchClient.payLink) !== null && _a !== void 0 ? _a : sdkPayLinkUnavailable };
|
|
79
|
+
}
|
|
80
|
+
return fetchClient;
|
|
81
|
+
}, [injected, coreClient, baseUrl, publishableKey]);
|
|
82
|
+
const isAvailable = client != null;
|
|
83
|
+
const [session, setSession] = useState(null);
|
|
84
|
+
const [error, setError] = useState(null);
|
|
85
|
+
const [loading, setLoading] = useState(false);
|
|
86
|
+
// Generation guard: only the latest fund()/reset() updates state, so
|
|
87
|
+
// re-selecting a source mid-poll can't be clobbered by a stale request.
|
|
88
|
+
const generation = useRef(0);
|
|
89
|
+
// Stop any in-flight poll loop on unmount — without this the loop keeps
|
|
90
|
+
// hitting the network until the session turns terminal (up to its 24h TTL).
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
return () => {
|
|
93
|
+
generation.current += 1;
|
|
94
|
+
logger.log('[funding] unmounted — poll loop stopped');
|
|
95
|
+
};
|
|
96
|
+
}, []);
|
|
97
|
+
const reset = useCallback(() => {
|
|
98
|
+
generation.current += 1;
|
|
99
|
+
logger.log('[funding] reset');
|
|
100
|
+
setSession(null);
|
|
101
|
+
setError(null);
|
|
102
|
+
setLoading(false);
|
|
103
|
+
}, []);
|
|
104
|
+
const fund = useCallback(async (target, paymentMethod) => {
|
|
105
|
+
var _a;
|
|
106
|
+
generation.current += 1;
|
|
107
|
+
const gen = generation.current;
|
|
108
|
+
const isCurrent = () => generation.current === gen;
|
|
109
|
+
setError(null);
|
|
110
|
+
setLoading(true);
|
|
111
|
+
logger.log('[funding] fund() start', {
|
|
112
|
+
chain: target.chain,
|
|
113
|
+
currency: target.currency,
|
|
114
|
+
address: target.address,
|
|
115
|
+
paymentMethod: paymentMethod.type,
|
|
116
|
+
sourceChain: paymentMethod.source.chain,
|
|
117
|
+
amount: paymentMethod.source.amount,
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
if (!client) {
|
|
121
|
+
throw new Error('Funding is not configured (set uiConfig.fundingBaseUrl)');
|
|
122
|
+
}
|
|
123
|
+
const created = await client.sessions.create({ target });
|
|
124
|
+
logger.log('[funding] session created', { sessionId: created.id, status: created.status });
|
|
125
|
+
const current = await client.sessions.setPaymentMethod(created.id, {
|
|
126
|
+
clientSecret: created.clientSecret,
|
|
127
|
+
paymentMethod,
|
|
128
|
+
});
|
|
129
|
+
if (!isCurrent())
|
|
130
|
+
return current;
|
|
131
|
+
setSession(current);
|
|
132
|
+
setLoading(false);
|
|
133
|
+
logger.log('[funding] payment method set', {
|
|
134
|
+
sessionId: current.id,
|
|
135
|
+
status: current.status,
|
|
136
|
+
receiverAddress: (_a = current.paymentMethod) === null || _a === void 0 ? void 0 : _a.receiverAddress,
|
|
137
|
+
});
|
|
138
|
+
// The session status encodes both hops: waiting_payment (awaiting the source
|
|
139
|
+
// deposit, e.g. the Coinbase withdrawal) → processing (deposit arrived on-chain,
|
|
140
|
+
// Relay bridging) → succeeded / bounced (Relay refunded) / expired (no deposit).
|
|
141
|
+
return pollUntilTerminal(client, setSession, current, isCurrent);
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
145
|
+
if (isCurrent()) {
|
|
146
|
+
setError(err);
|
|
147
|
+
setLoading(false);
|
|
148
|
+
logger.error('[funding] fund() failed', err);
|
|
149
|
+
}
|
|
150
|
+
throw err;
|
|
151
|
+
}
|
|
152
|
+
}, [client]);
|
|
153
|
+
const createSession = useCallback(async (target) => {
|
|
154
|
+
if (!client)
|
|
155
|
+
throw new Error('Funding is not configured (set uiConfig.fundingBaseUrl)');
|
|
156
|
+
const created = await client.sessions.create({ target });
|
|
157
|
+
logger.log('[funding] session created (cex)', { sessionId: created.id, status: created.status });
|
|
158
|
+
return created;
|
|
159
|
+
}, [client]);
|
|
160
|
+
const track = useCallback(async (toTrack) => {
|
|
161
|
+
if (!client)
|
|
162
|
+
throw new Error('Funding is not configured (set uiConfig.fundingBaseUrl)');
|
|
163
|
+
generation.current += 1;
|
|
164
|
+
const gen = generation.current;
|
|
165
|
+
const isCurrent = () => generation.current === gen;
|
|
166
|
+
setError(null);
|
|
167
|
+
try {
|
|
168
|
+
const start = await client.sessions.get(toTrack.id, { clientSecret: toTrack.clientSecret });
|
|
169
|
+
if (!isCurrent())
|
|
170
|
+
return start;
|
|
171
|
+
setSession(start);
|
|
172
|
+
logger.log('[funding] track() start', { sessionId: start.id, status: start.status });
|
|
173
|
+
return await pollUntilTerminal(client, setSession, start, isCurrent);
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
177
|
+
if (isCurrent()) {
|
|
178
|
+
setError(err);
|
|
179
|
+
logger.error('[funding] track() failed', err);
|
|
180
|
+
}
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
}, [client]);
|
|
184
|
+
const payLink = useCallback(async (params) => {
|
|
185
|
+
if (!client)
|
|
186
|
+
throw new Error('Funding is not configured (set uiConfig.fundingBaseUrl)');
|
|
187
|
+
return client.payLink(params);
|
|
188
|
+
}, [client]);
|
|
189
|
+
return {
|
|
190
|
+
session,
|
|
191
|
+
status: (_b = session === null || session === void 0 ? void 0 : session.status) !== null && _b !== void 0 ? _b : 'idle',
|
|
192
|
+
error,
|
|
193
|
+
loading,
|
|
194
|
+
isAvailable,
|
|
195
|
+
fund,
|
|
196
|
+
createSession,
|
|
197
|
+
track,
|
|
198
|
+
payLink,
|
|
199
|
+
reset,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export { useFunding };
|
|
204
|
+
//# sourceMappingURL=useFunding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFunding.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** A source currency available on a chain (sourced live from Relay via the backend). */
|
|
2
|
+
export type FundingCurrency = {
|
|
3
|
+
symbol: string;
|
|
4
|
+
/** Contract address, or the zero address for the chain's native asset. */
|
|
5
|
+
address: string;
|
|
6
|
+
decimals: number;
|
|
7
|
+
logo: string | null;
|
|
8
|
+
/** True for the chain's native currency (ETH, SOL, POL, BNB, …). */
|
|
9
|
+
native: boolean;
|
|
10
|
+
};
|
|
11
|
+
/** A source chain the funding backend (Relay) can route from. */
|
|
12
|
+
export type FundingChain = {
|
|
13
|
+
/** CAIP-2 chain id, e.g. "eip155:8453". */
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
logo: string | null;
|
|
17
|
+
/** "evm" | "svm" — used to gate Solana sources and the CEX tab. */
|
|
18
|
+
vmType: string;
|
|
19
|
+
currencies: FundingCurrency[];
|
|
20
|
+
};
|
|
21
|
+
type UseFundingChains = {
|
|
22
|
+
chains: FundingChain[];
|
|
23
|
+
loading: boolean;
|
|
24
|
+
error: Error | null;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The chains/currencies the funding backend supports, fetched from
|
|
28
|
+
* `GET /v2/funding/chains` (a live passthrough of Relay's `/chains`), then
|
|
29
|
+
* narrowed to a curated subset. The provider dictionary is dynamic; the client
|
|
30
|
+
* just selects from it via `uiConfig.funding.{sourceChains,sourceCurrencies}`,
|
|
31
|
+
* defaulting to {@link DEFAULT_SOURCE_CHAINS} / {@link DEFAULT_SOURCE_CURRENCIES}.
|
|
32
|
+
*
|
|
33
|
+
* Reads the base URL from `uiConfig.fundingBaseUrl`, mirroring `useFunding`.
|
|
34
|
+
* Returns an empty list when funding isn't configured.
|
|
35
|
+
*/
|
|
36
|
+
export declare function useFundingChains(): UseFundingChains;
|
|
37
|
+
/**
|
|
38
|
+
* Narrow the fetched chains to a selection. `sourceChains` is a CAIP-2 allowlist
|
|
39
|
+
* (also defines order); `sourceCurrencies` is a symbol allowlist where the
|
|
40
|
+
* sentinel `'native'` matches each chain's native currency. Chains left with no
|
|
41
|
+
* currency are dropped, and selected chains the rail doesn't support are skipped.
|
|
42
|
+
*/
|
|
43
|
+
export declare function curateChains(chains: FundingChain[], sourceChains: string[] | undefined, sourceCurrencies: string[] | undefined): FundingChain[];
|
|
44
|
+
/** Nominal source amount (in base units) used only to mint an open, route-bound deposit address.
|
|
45
|
+
* The open address accepts any amount >= the route minimum afterward, so this is just a quote seed.
|
|
46
|
+
* Stablecoins use 1 whole unit (~$1, clears mainnet route minimums); native tokens are far pricier
|
|
47
|
+
* per unit (1 ETH ≈ thousands), so they use 0.01 of a unit to avoid minting/QR-prefilling 1 whole ETH. */
|
|
48
|
+
export declare function nominalUnits(decimals: number, native?: boolean): string;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { SDKConfiguration } from '@openfort/openfort-js';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { useOpenfort } from '../../components/Openfort/useOpenfort.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sensible default source chains — the common funding origins. Override with
|
|
7
|
+
* `uiConfig.funding.sourceChains`. Intersected with what the rail supports.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_SOURCE_CHAINS = [
|
|
10
|
+
'eip155:42161', // Arbitrum
|
|
11
|
+
'eip155:8453', // Base
|
|
12
|
+
'eip155:56', // BNB Chain
|
|
13
|
+
'eip155:1', // Ethereum
|
|
14
|
+
'eip155:10', // Optimism
|
|
15
|
+
'eip155:137', // Polygon
|
|
16
|
+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', // Solana
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Default source currencies: the chain's `'native'` currency plus the major
|
|
20
|
+
* stablecoins. Override with `uiConfig.funding.sourceCurrencies`.
|
|
21
|
+
*/
|
|
22
|
+
const DEFAULT_SOURCE_CURRENCIES = ['native', 'USDC', 'USDT'];
|
|
23
|
+
/**
|
|
24
|
+
* The chains/currencies the funding backend supports, fetched from
|
|
25
|
+
* `GET /v2/funding/chains` (a live passthrough of Relay's `/chains`), then
|
|
26
|
+
* narrowed to a curated subset. The provider dictionary is dynamic; the client
|
|
27
|
+
* just selects from it via `uiConfig.funding.{sourceChains,sourceCurrencies}`,
|
|
28
|
+
* defaulting to {@link DEFAULT_SOURCE_CHAINS} / {@link DEFAULT_SOURCE_CURRENCIES}.
|
|
29
|
+
*
|
|
30
|
+
* Reads the base URL from `uiConfig.fundingBaseUrl`, mirroring `useFunding`.
|
|
31
|
+
* Returns an empty list when funding isn't configured.
|
|
32
|
+
*/
|
|
33
|
+
function useFundingChains() {
|
|
34
|
+
var _a, _b, _c, _d, _e;
|
|
35
|
+
const { uiConfig } = useOpenfort();
|
|
36
|
+
// Defaults to the SDK backend (api.openfort.io); override for a custom funding service.
|
|
37
|
+
const baseUrl = uiConfig.fundingBaseUrl || ((_a = SDKConfiguration.getInstance()) === null || _a === void 0 ? void 0 : _a.backendUrl) || 'https://api.openfort.io';
|
|
38
|
+
const sourceChains = (_c = (_b = uiConfig.funding) === null || _b === void 0 ? void 0 : _b.sourceChains) !== null && _c !== void 0 ? _c : DEFAULT_SOURCE_CHAINS;
|
|
39
|
+
const sourceCurrencies = (_e = (_d = uiConfig.funding) === null || _d === void 0 ? void 0 : _d.sourceCurrencies) !== null && _e !== void 0 ? _e : DEFAULT_SOURCE_CURRENCIES;
|
|
40
|
+
const [state, setState] = useState({ chains: [], loading: true, error: null });
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
let cancelled = false;
|
|
43
|
+
setState((s) => ({ ...s, loading: true }));
|
|
44
|
+
fetch(`${baseUrl}/v2/funding/chains`)
|
|
45
|
+
.then((r) => {
|
|
46
|
+
if (!r.ok)
|
|
47
|
+
throw new Error(`Failed to load chains (${r.status})`);
|
|
48
|
+
return r.json();
|
|
49
|
+
})
|
|
50
|
+
.then((d) => {
|
|
51
|
+
var _a;
|
|
52
|
+
if (!cancelled)
|
|
53
|
+
setState({ chains: (_a = d.chains) !== null && _a !== void 0 ? _a : [], loading: false, error: null });
|
|
54
|
+
})
|
|
55
|
+
.catch((e) => {
|
|
56
|
+
if (!cancelled)
|
|
57
|
+
setState({ chains: [], loading: false, error: e instanceof Error ? e : new Error(String(e)) });
|
|
58
|
+
});
|
|
59
|
+
return () => {
|
|
60
|
+
cancelled = true;
|
|
61
|
+
};
|
|
62
|
+
}, [baseUrl]);
|
|
63
|
+
// Narrow the provider dictionary to the selected subset (cheap, O(chains)).
|
|
64
|
+
return { ...state, chains: curateChains(state.chains, sourceChains, sourceCurrencies) };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Narrow the fetched chains to a selection. `sourceChains` is a CAIP-2 allowlist
|
|
68
|
+
* (also defines order); `sourceCurrencies` is a symbol allowlist where the
|
|
69
|
+
* sentinel `'native'` matches each chain's native currency. Chains left with no
|
|
70
|
+
* currency are dropped, and selected chains the rail doesn't support are skipped.
|
|
71
|
+
*/
|
|
72
|
+
function curateChains(chains, sourceChains, sourceCurrencies) {
|
|
73
|
+
let out = chains;
|
|
74
|
+
if (sourceCurrencies && sourceCurrencies.length > 0) {
|
|
75
|
+
const allow = new Set(sourceCurrencies.map((s) => s.toLowerCase()));
|
|
76
|
+
const allowNative = allow.has('native');
|
|
77
|
+
out = out
|
|
78
|
+
.map((c) => ({
|
|
79
|
+
...c,
|
|
80
|
+
currencies: c.currencies.filter((cur) => (allowNative && cur.native) || allow.has(cur.symbol.toLowerCase())),
|
|
81
|
+
}))
|
|
82
|
+
.filter((c) => c.currencies.length > 0);
|
|
83
|
+
}
|
|
84
|
+
if (sourceChains && sourceChains.length > 0) {
|
|
85
|
+
const byId = new Map(out.map((c) => [c.id, c]));
|
|
86
|
+
out = sourceChains.map((id) => byId.get(id)).filter((c) => c !== undefined);
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
/** Nominal source amount (in base units) used only to mint an open, route-bound deposit address.
|
|
91
|
+
* The open address accepts any amount >= the route minimum afterward, so this is just a quote seed.
|
|
92
|
+
* Stablecoins use 1 whole unit (~$1, clears mainnet route minimums); native tokens are far pricier
|
|
93
|
+
* per unit (1 ETH ≈ thousands), so they use 0.01 of a unit to avoid minting/QR-prefilling 1 whole ETH. */
|
|
94
|
+
function nominalUnits(decimals, native = false) {
|
|
95
|
+
const zeros = native ? Math.max(0, decimals - 2) : decimals;
|
|
96
|
+
return `1${'0'.repeat(zeros)}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { curateChains, nominalUnits, useFundingChains };
|
|
100
|
+
//# sourceMappingURL=useFundingChains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFundingChains.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -3,7 +3,7 @@ import { useEffect } from 'react';
|
|
|
3
3
|
import { createPublicClient, http, formatEther } from 'viem';
|
|
4
4
|
import { useOpenfort } from '../components/Openfort/useOpenfort.js';
|
|
5
5
|
import { DEFAULT_TESTNET_CHAIN_ID } from '../core/ConnectionStrategy.js';
|
|
6
|
-
import { useAsyncData } from '../shared/hooks/useAsyncData.js';
|
|
6
|
+
import { invalidateAsyncData, useAsyncData } from '../shared/hooks/useAsyncData.js';
|
|
7
7
|
import { formatSol } from '../solana/hooks/utils.js';
|
|
8
8
|
import { getDefaultEthereumRpcUrl, getDefaultSolanaRpcUrl, getNativeCurrency } from '../utils/rpc.js';
|
|
9
9
|
|
|
@@ -11,6 +11,11 @@ import { getDefaultEthereumRpcUrl, getDefaultSolanaRpcUrl, getNativeCurrency } f
|
|
|
11
11
|
const BALANCE_INVALIDATE_EVENT = 'openfort:balance-invalidate';
|
|
12
12
|
/** Dispatches balance invalidation so all useBalance instances refetch. Call after mint/send. */
|
|
13
13
|
function invalidateBalance() {
|
|
14
|
+
// Token/asset balances come from useEthereumWalletAssets → useAsyncData, which
|
|
15
|
+
// doesn't listen to the event below. Drop their cache too so the next render
|
|
16
|
+
// (e.g. landing on the asset inventory after a deposit) refetches fresh.
|
|
17
|
+
invalidateAsyncData('walletAssets');
|
|
18
|
+
invalidateAsyncData('wallet-assets');
|
|
14
19
|
if (typeof window !== 'undefined') {
|
|
15
20
|
window.dispatchEvent(new CustomEvent(BALANCE_INVALIDATE_EVENT));
|
|
16
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBalance.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useBalance.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export { default as ChainIcon } from './components/Common/Chain';
|
|
|
45
45
|
export { OpenfortButton } from './components/ConnectButton';
|
|
46
46
|
export { OpenfortProvider } from './components/Openfort/OpenfortProvider';
|
|
47
47
|
export type { CustomizableRoutes, MultiChainAsset } from './components/Openfort/types';
|
|
48
|
-
export { LinkWalletOnSignUpOption, UIAuthProvider as AuthProvider } from './components/Openfort/types';
|
|
48
|
+
export { FundingMethod, LinkWalletOnSignUpOption, UIAuthProvider as AuthProvider } from './components/Openfort/types';
|
|
49
49
|
export { embeddedWalletId } from './constants/openfort';
|
|
50
50
|
export { OpenfortError, OpenfortReactErrorType, OpenfortReactErrorType as OpenfortErrorType, } from './core/errors';
|
|
51
51
|
export type { ConnectedEmbeddedEthereumWallet, EthereumWalletState, SetActiveEthereumWalletOptions, UseEmbeddedEthereumWalletOptions, } from './ethereum/types';
|
|
@@ -58,7 +58,10 @@ export type { StoreCredentialsResult } from './hooks/openfort/auth/useOAuth';
|
|
|
58
58
|
export { useOAuth } from './hooks/openfort/auth/useOAuth';
|
|
59
59
|
export { usePhoneOtpAuth } from './hooks/openfort/auth/usePhoneOtpAuth';
|
|
60
60
|
export { useSignOut } from './hooks/openfort/auth/useSignOut';
|
|
61
|
+
export type { FundingClient } from './hooks/openfort/fundingClient';
|
|
61
62
|
export { type SignAuthorizationParameters, type SignAuthorizationReturnType, use7702Authorization, } from './hooks/openfort/use7702Authorization';
|
|
63
|
+
export type { FundingSession, FundingTarget, PaymentMethod, PaymentMethodInput, UseFunding, UseFundingOptions, } from './hooks/openfort/useFunding';
|
|
64
|
+
export { useFunding } from './hooks/openfort/useFunding';
|
|
62
65
|
export { useGrantPermissions } from './hooks/openfort/useGrantPermissions';
|
|
63
66
|
export { useRevokePermissions } from './hooks/openfort/useRevokePermissions';
|
|
64
67
|
export { useUI } from './hooks/openfort/useUI';
|