@relayprotocol/relay-kit-ui 10.0.1 → 11.0.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/_cjs/src/components/common/TokenSelector/PaymentMethod.js +9 -9
- package/_cjs/src/components/common/TokenSelector/PaymentMethod.js.map +1 -1
- package/_cjs/src/components/common/TokenSelector/TokenSelector.js +8 -8
- package/_cjs/src/components/common/TokenSelector/TokenSelector.js.map +1 -1
- package/_cjs/src/components/widgets/SwapWidgetRenderer.js +6 -39
- package/_cjs/src/components/widgets/SwapWidgetRenderer.js.map +1 -1
- package/_cjs/src/constants/walletCompatibility.js +3 -1
- package/_cjs/src/constants/walletCompatibility.js.map +1 -1
- package/_cjs/src/hooks/index.js +5 -3
- package/_cjs/src/hooks/index.js.map +1 -1
- package/_cjs/src/hooks/useCodexBalances.js +305 -0
- package/_cjs/src/hooks/useCodexBalances.js.map +1 -0
- package/_cjs/src/hooks/useCurrencyBalance.js +18 -74
- package/_cjs/src/hooks/useCurrencyBalance.js.map +1 -1
- package/_cjs/src/hooks/useEnhancedTokensList.js.map +1 -1
- package/_cjs/src/hooks/useMultiWalletBalances.js +19 -37
- package/_cjs/src/hooks/useMultiWalletBalances.js.map +1 -1
- package/_cjs/src/hooks/useSolanaBalance.js +60 -0
- package/_cjs/src/hooks/useSolanaBalance.js.map +1 -0
- package/_cjs/src/providers/RelayKitProvider.js +1 -1
- package/_cjs/src/providers/RelayKitProvider.js.map +1 -1
- package/_cjs/src/version.js +1 -1
- package/_cjs/src/version.js.map +1 -1
- package/_cjs/tsconfig.build.tsbuildinfo +1 -1
- package/_esm/src/components/common/TokenSelector/PaymentMethod.js +9 -9
- package/_esm/src/components/common/TokenSelector/PaymentMethod.js.map +1 -1
- package/_esm/src/components/common/TokenSelector/TokenSelector.js +10 -10
- package/_esm/src/components/common/TokenSelector/TokenSelector.js.map +1 -1
- package/_esm/src/components/widgets/SwapWidgetRenderer.js +6 -41
- package/_esm/src/components/widgets/SwapWidgetRenderer.js.map +1 -1
- package/_esm/src/constants/walletCompatibility.js +3 -1
- package/_esm/src/constants/walletCompatibility.js.map +1 -1
- package/_esm/src/hooks/index.js +3 -2
- package/_esm/src/hooks/index.js.map +1 -1
- package/_esm/src/hooks/useCodexBalances.js +311 -0
- package/_esm/src/hooks/useCodexBalances.js.map +1 -0
- package/_esm/src/hooks/useCurrencyBalance.js +18 -74
- package/_esm/src/hooks/useCurrencyBalance.js.map +1 -1
- package/_esm/src/hooks/useEnhancedTokensList.js.map +1 -1
- package/_esm/src/hooks/useMultiWalletBalances.js +18 -39
- package/_esm/src/hooks/useMultiWalletBalances.js.map +1 -1
- package/_esm/src/hooks/useSolanaBalance.js +58 -0
- package/_esm/src/hooks/useSolanaBalance.js.map +1 -0
- package/_esm/src/providers/RelayKitProvider.js +1 -1
- package/_esm/src/providers/RelayKitProvider.js.map +1 -1
- package/_esm/src/version.js +1 -1
- package/_esm/src/version.js.map +1 -1
- package/_esm/tsconfig.build.tsbuildinfo +1 -1
- package/_types/src/components/common/TokenSelector/PaymentMethod.d.ts.map +1 -1
- package/_types/src/components/common/TokenSelector/TokenSelector.d.ts.map +1 -1
- package/_types/src/components/widgets/SwapWidgetRenderer.d.ts.map +1 -1
- package/_types/src/constants/walletCompatibility.d.ts.map +1 -1
- package/_types/src/hooks/index.d.ts +3 -2
- package/_types/src/hooks/index.d.ts.map +1 -1
- package/_types/src/hooks/useCodexBalances.d.ts +45 -0
- package/_types/src/hooks/useCodexBalances.d.ts.map +1 -0
- package/_types/src/hooks/useCurrencyBalance.d.ts +0 -1
- package/_types/src/hooks/useCurrencyBalance.d.ts.map +1 -1
- package/_types/src/hooks/useEnhancedTokensList.d.ts +1 -1
- package/_types/src/hooks/useEnhancedTokensList.d.ts.map +1 -1
- package/_types/src/hooks/useMultiWalletBalances.d.ts +3 -12
- package/_types/src/hooks/useMultiWalletBalances.d.ts.map +1 -1
- package/_types/src/hooks/{useEclipseBalance.d.ts → useSolanaBalance.d.ts} +2 -2
- package/_types/src/hooks/useSolanaBalance.d.ts.map +1 -0
- package/_types/src/providers/RelayKitProvider.d.ts +3 -3
- package/_types/src/providers/RelayKitProvider.d.ts.map +1 -1
- package/_types/src/version.d.ts +1 -1
- package/_types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/_cjs/src/hooks/useDuneBalances.js +0 -100
- package/_cjs/src/hooks/useDuneBalances.js.map +0 -1
- package/_cjs/src/hooks/useEclipseBalance.js +0 -47
- package/_cjs/src/hooks/useEclipseBalance.js.map +0 -1
- package/_esm/src/hooks/useDuneBalances.js +0 -102
- package/_esm/src/hooks/useDuneBalances.js.map +0 -1
- package/_esm/src/hooks/useEclipseBalance.js +0 -44
- package/_esm/src/hooks/useEclipseBalance.js.map +0 -1
- package/_types/src/hooks/useDuneBalances.d.ts +0 -25
- package/_types/src/hooks/useDuneBalances.d.ts.map +0 -1
- package/_types/src/hooks/useEclipseBalance.d.ts.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo, useContext } from 'react';
|
|
2
2
|
import { useQueries } from '@tanstack/react-query';
|
|
3
|
-
import {} from './
|
|
3
|
+
import { CODEX_SVM_NETWORK_ID, fetchCodexBalances, getEvmNetworkIds, getSvmNativeChains } from './useCodexBalances.js';
|
|
4
|
+
import useRelayClient from './useRelayClient.js';
|
|
4
5
|
import { isDeadAddress } from '@relayprotocol/relay-sdk';
|
|
5
6
|
import { ProviderOptionsContext } from '../providers/RelayKitProvider.js';
|
|
6
7
|
import { isAddress } from 'viem';
|
|
@@ -9,7 +10,7 @@ import { isValidAddress as validateAddress } from '../utils/address.js';
|
|
|
9
10
|
/**
|
|
10
11
|
* Fetches and merges balances for linked wallets
|
|
11
12
|
*/
|
|
12
|
-
export const useMultiWalletBalances = (linkedWallets, primaryAddress
|
|
13
|
+
export const useMultiWalletBalances = (linkedWallets, primaryAddress) => {
|
|
13
14
|
const walletAddresses = useMemo(() => {
|
|
14
15
|
const addresses = new Set();
|
|
15
16
|
if (primaryAddress && !isDeadAddress(primaryAddress)) {
|
|
@@ -26,50 +27,28 @@ export const useMultiWalletBalances = (linkedWallets, primaryAddress, evmChainId
|
|
|
26
27
|
return Array.from(addresses);
|
|
27
28
|
}, [primaryAddress, linkedWallets]);
|
|
28
29
|
const providerOptions = useContext(ProviderOptionsContext);
|
|
30
|
+
const relayClient = useRelayClient();
|
|
29
31
|
const balanceQueries = useQueries({
|
|
30
32
|
queries: walletAddresses.map((address) => {
|
|
31
33
|
const isEvmAddress = isAddress(address);
|
|
32
34
|
const isSvmAddress = isSolanaAddress(address);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
35
|
+
const networks = isSvmAddress
|
|
36
|
+
? [CODEX_SVM_NETWORK_ID]
|
|
37
|
+
: getEvmNetworkIds(relayClient?.chains);
|
|
37
38
|
return {
|
|
38
|
-
queryKey: ['
|
|
39
|
+
queryKey: ['useCodexBalances', address],
|
|
39
40
|
queryFn: async () => {
|
|
40
41
|
if (!isSvmAddress && !isEvmAddress) {
|
|
41
42
|
return null;
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
headers: providerOptions?.duneConfig?.apiKey
|
|
45
|
-
? {
|
|
46
|
-
'X-Sim-Api-Key': providerOptions.duneConfig.apiKey
|
|
47
|
-
}
|
|
48
|
-
: {}
|
|
49
|
-
});
|
|
50
|
-
if (!response.ok) {
|
|
51
|
-
throw new Error(`Failed to fetch balance for ${address}`);
|
|
52
|
-
}
|
|
53
|
-
const data = await response.json();
|
|
54
|
-
if (data?.balances) {
|
|
55
|
-
// Filter out invalid amounts like useDuneBalances does
|
|
56
|
-
const validBalances = data.balances.filter((balance) => {
|
|
57
|
-
try {
|
|
58
|
-
BigInt(balance.amount);
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
catch (e) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
return {
|
|
66
|
-
...data,
|
|
67
|
-
balances: validBalances
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return data;
|
|
44
|
+
return fetchCodexBalances(address, providerOptions?.codexConfig ?? {}, networks, isSvmAddress ? getSvmNativeChains(relayClient?.chains) : undefined);
|
|
71
45
|
},
|
|
72
|
-
enabled: Boolean(address &&
|
|
46
|
+
enabled: Boolean(address &&
|
|
47
|
+
address.trim() !== '' &&
|
|
48
|
+
(isEvmAddress || isSvmAddress) &&
|
|
49
|
+
networks.length > 0 &&
|
|
50
|
+
(providerOptions?.codexConfig?.apiKey !== undefined ||
|
|
51
|
+
providerOptions?.codexConfig?.apiBaseUrl !== undefined)),
|
|
73
52
|
staleTime: 60000,
|
|
74
53
|
gcTime: 60000,
|
|
75
54
|
retry: 1
|
|
@@ -77,7 +56,7 @@ export const useMultiWalletBalances = (linkedWallets, primaryAddress, evmChainId
|
|
|
77
56
|
})
|
|
78
57
|
});
|
|
79
58
|
// Merge all balance data with proper parallelization - no more 5-wallet limit!
|
|
80
|
-
const { mergedBalanceMap,
|
|
59
|
+
const { mergedBalanceMap, mergedTokens, isLoadingBalances } = useMemo(() => {
|
|
81
60
|
const mergedMap = {};
|
|
82
61
|
const allBalances = [];
|
|
83
62
|
let anyLoading = false;
|
|
@@ -111,13 +90,13 @@ export const useMultiWalletBalances = (linkedWallets, primaryAddress, evmChainId
|
|
|
111
90
|
});
|
|
112
91
|
return {
|
|
113
92
|
mergedBalanceMap: mergedMap,
|
|
114
|
-
|
|
93
|
+
mergedTokens: allBalances.length > 0 ? { balances: allBalances } : undefined,
|
|
115
94
|
isLoadingBalances: anyLoading
|
|
116
95
|
};
|
|
117
96
|
}, [balanceQueries]);
|
|
118
97
|
return {
|
|
119
98
|
balanceMap: mergedBalanceMap,
|
|
120
|
-
data:
|
|
99
|
+
data: mergedTokens,
|
|
121
100
|
isLoading: isLoadingBalances
|
|
122
101
|
};
|
|
123
102
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMultiWalletBalances.js","sourceRoot":"","sources":["../../../src/hooks/useMultiWalletBalances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"useMultiWalletBalances.js","sourceRoot":"","sources":["../../../src/hooks/useMultiWalletBalances.ts"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useContext } from 'react'\nimport { useQueries } from '@tanstack/react-query'\nimport {\n CODEX_SVM_NETWORK_ID,\n fetchCodexBalances,\n getEvmNetworkIds,\n getSvmNativeChains,\n type BalanceMap,\n type WalletBalanceResponse\n} from './useCodexBalances.js'\nimport useRelayClient from './useRelayClient.js'\nimport { isDeadAddress } from '@relayprotocol/relay-sdk'\nimport { ProviderOptionsContext } from '../providers/RelayKitProvider.js'\nimport { isAddress } from 'viem'\nimport { isSolanaAddress } from '../utils/solana.js'\nimport { isValidAddress as validateAddress } from '../utils/address.js'\nimport type { LinkedWallet } from '../types/index.js'\n\n/**\n * Fetches and merges balances for linked wallets\n */\nexport const useMultiWalletBalances = (\n linkedWallets?: LinkedWallet[],\n primaryAddress?: string\n) => {\n const walletAddresses = useMemo(() => {\n const addresses = new Set<string>()\n\n if (primaryAddress && !isDeadAddress(primaryAddress)) {\n const matchingWallet = linkedWallets?.find(\n (wallet) =>\n wallet.address === primaryAddress ||\n (wallet.vmType === 'evm' &&\n wallet.address.toLowerCase() === primaryAddress.toLowerCase())\n )\n\n if (matchingWallet) {\n const isValid = validateAddress(\n matchingWallet.vmType,\n primaryAddress,\n undefined,\n matchingWallet.connector\n )\n\n if (isValid) {\n addresses.add(primaryAddress)\n }\n }\n }\n\n return Array.from(addresses)\n }, [primaryAddress, linkedWallets])\n\n const providerOptions = useContext(ProviderOptionsContext)\n const relayClient = useRelayClient()\n\n const balanceQueries = useQueries({\n queries: walletAddresses.map((address) => {\n const isEvmAddress = isAddress(address)\n const isSvmAddress = isSolanaAddress(address)\n const networks = isSvmAddress\n ? [CODEX_SVM_NETWORK_ID]\n : getEvmNetworkIds(relayClient?.chains)\n\n return {\n queryKey: ['useCodexBalances', address],\n queryFn: async (): Promise<WalletBalanceResponse> => {\n if (!isSvmAddress && !isEvmAddress) {\n return null\n }\n\n return fetchCodexBalances(\n address,\n providerOptions?.codexConfig ?? {},\n networks,\n isSvmAddress ? getSvmNativeChains(relayClient?.chains) : undefined\n )\n },\n enabled: Boolean(\n address &&\n address.trim() !== '' &&\n (isEvmAddress || isSvmAddress) &&\n networks.length > 0 &&\n (providerOptions?.codexConfig?.apiKey !== undefined ||\n providerOptions?.codexConfig?.apiBaseUrl !== undefined)\n ),\n staleTime: 60000,\n gcTime: 60000,\n retry: 1\n }\n })\n })\n\n // Merge all balance data with proper parallelization - no more 5-wallet limit!\n const { mergedBalanceMap, mergedTokens, isLoadingBalances } = useMemo(() => {\n const mergedMap: BalanceMap = {}\n const allBalances: NonNullable<WalletBalanceResponse>['balances'] = []\n let anyLoading = false\n\n balanceQueries.forEach((query) => {\n if (query.isLoading) anyLoading = true\n\n if (query.data?.balances) {\n const balanceMap: BalanceMap = {}\n query.data.balances.forEach((balance) => {\n const key = `${balance.chain_id}:${balance.address.toLowerCase()}`\n balanceMap[key] = balance\n })\n\n Object.entries(balanceMap).forEach(([key, balance]) => {\n if (mergedMap[key]) {\n // Token exists in multiple wallets - sum the amounts\n const existingAmount = BigInt(mergedMap[key].amount)\n const newAmount = BigInt(balance.amount)\n const totalAmount = existingAmount + newAmount\n\n mergedMap[key] = {\n ...balance,\n amount: totalAmount.toString(),\n value_usd:\n (mergedMap[key].value_usd || 0) + (balance.value_usd || 0)\n }\n } else {\n mergedMap[key] = balance\n }\n })\n\n allBalances.push(...query.data.balances)\n }\n })\n\n return {\n mergedBalanceMap: mergedMap,\n mergedTokens:\n allBalances.length > 0 ? { balances: allBalances } : undefined,\n isLoadingBalances: anyLoading\n }\n }, [balanceQueries])\n\n return {\n balanceMap: mergedBalanceMap,\n data: mergedTokens,\n isLoading: isLoadingBalances\n }\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
const SOLANA_NATIVE_ADDRESS = '11111111111111111111111111111111';
|
|
3
|
+
export default (address, currency, rpcUrl, queryOptions) => {
|
|
4
|
+
const queryKey = ['useSolanaBalance', address, currency, rpcUrl];
|
|
5
|
+
const response = useQuery({
|
|
6
|
+
queryKey,
|
|
7
|
+
queryFn: async () => {
|
|
8
|
+
if (!rpcUrl || !address || !currency) {
|
|
9
|
+
throw new Error('Missing address, currency or rpcUrl');
|
|
10
|
+
}
|
|
11
|
+
const isNative = currency === SOLANA_NATIVE_ADDRESS;
|
|
12
|
+
const payload = isNative
|
|
13
|
+
? {
|
|
14
|
+
jsonrpc: '2.0',
|
|
15
|
+
id: 1,
|
|
16
|
+
method: 'getBalance',
|
|
17
|
+
params: [address]
|
|
18
|
+
}
|
|
19
|
+
: {
|
|
20
|
+
jsonrpc: '2.0',
|
|
21
|
+
id: 1,
|
|
22
|
+
method: 'getTokenAccountsByOwner',
|
|
23
|
+
params: [address, { mint: currency }, { encoding: 'jsonParsed' }]
|
|
24
|
+
};
|
|
25
|
+
const response = await fetch(rpcUrl, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: {
|
|
28
|
+
'Content-Type': 'application/json'
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify(payload)
|
|
31
|
+
});
|
|
32
|
+
const data = await response.json();
|
|
33
|
+
if (data.error) {
|
|
34
|
+
throw new Error(data.error.message);
|
|
35
|
+
}
|
|
36
|
+
if (isNative) {
|
|
37
|
+
return {
|
|
38
|
+
balance: BigInt(data.result?.value ?? 0)
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const accounts = (data.result?.value ?? []);
|
|
42
|
+
const balance = accounts.reduce((total, account) => total +
|
|
43
|
+
BigInt(account?.account?.data?.parsed?.info?.tokenAmount?.amount ?? 0), BigInt(0));
|
|
44
|
+
return { balance };
|
|
45
|
+
},
|
|
46
|
+
...queryOptions,
|
|
47
|
+
enabled: address !== undefined &&
|
|
48
|
+
currency !== undefined &&
|
|
49
|
+
rpcUrl !== undefined &&
|
|
50
|
+
(queryOptions?.enabled ?? true)
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
...response,
|
|
54
|
+
balance: response.data?.balance,
|
|
55
|
+
queryKey
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=useSolanaBalance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSolanaBalance.js","sourceRoot":"","sources":["../../../src/hooks/useSolanaBalance.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGT,MAAM,uBAAuB,CAAA;AAE9B,MAAM,qBAAqB,GAAG,kCAAkC,CAAA;AA4BhE,eAAe,CACb,OAAgB,EAChB,QAAiB,EACjB,MAAe,EACf,YAAoC,EACpC,EAAE;IACF,MAAM,QAAQ,GAAG,CAAC,kBAAkB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;IAEhE,MAAM,QAAQ,GAAI,QAAsB,CAAC;QACvC,QAAQ;QACR,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;YACxD,CAAC;YAED,MAAM,QAAQ,GAAG,QAAQ,KAAK,qBAAqB,CAAA;YACnD,MAAM,OAAO,GAAG,QAAQ;gBACtB,CAAC,CAAC;oBACE,OAAO,EAAE,KAAK;oBACd,EAAE,EAAE,CAAC;oBACL,MAAM,EAAE,YAAY;oBACpB,MAAM,EAAE,CAAC,OAAO,CAAC;iBAClB;gBACH,CAAC,CAAC;oBACE,OAAO,EAAE,KAAK;oBACd,EAAE,EAAE,CAAC;oBACL,MAAM,EAAE,yBAAyB;oBACjC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;iBAClE,CAAA;YAEL,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;gBACnC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CAAC,CAAA;YAEF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAElC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACrC,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC;iBACzC,CAAA;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAmB,CAAA;YAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAC7B,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACjB,KAAK;gBACL,MAAM,CACJ,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC,CAC/D,EACH,MAAM,CAAC,CAAC,CAAC,CACV,CAAA;YAED,OAAO,EAAE,OAAO,EAAE,CAAA;QACpB,CAAC;QACD,GAAG,YAAY;QACf,OAAO,EACL,OAAO,KAAK,SAAS;YACrB,QAAQ,KAAK,SAAS;YACtB,MAAM,KAAK,SAAS;YACpB,CAAC,YAAY,EAAE,OAAO,IAAI,IAAI,CAAC;KAClC,CAAC,CAAA;IAEF,OAAO;QACL,GAAG,QAAQ;QACX,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO;QAC/B,QAAQ;KAIT,CAAA;AACH,CAAC,CAAA","sourcesContent":["import {\n useQuery,\n type DefaultError,\n type QueryKey\n} from '@tanstack/react-query'\n\nconst SOLANA_NATIVE_ADDRESS = '11111111111111111111111111111111'\n\ntype BalanceResponse = {\n balance: bigint\n}\n\ntype TokenAccount = {\n account?: {\n data?: {\n parsed?: {\n info?: {\n tokenAmount?: {\n amount?: string\n }\n }\n }\n }\n }\n}\n\ntype QueryType = typeof useQuery<\n BalanceResponse | undefined,\n DefaultError,\n BalanceResponse | undefined,\n QueryKey\n>\ntype QueryOptions = Parameters<QueryType>['0']\n\nexport default (\n address?: string,\n currency?: string,\n rpcUrl?: string,\n queryOptions?: Partial<QueryOptions>\n) => {\n const queryKey = ['useSolanaBalance', address, currency, rpcUrl]\n\n const response = (useQuery as QueryType)({\n queryKey,\n queryFn: async () => {\n if (!rpcUrl || !address || !currency) {\n throw new Error('Missing address, currency or rpcUrl')\n }\n\n const isNative = currency === SOLANA_NATIVE_ADDRESS\n const payload = isNative\n ? {\n jsonrpc: '2.0',\n id: 1,\n method: 'getBalance',\n params: [address]\n }\n : {\n jsonrpc: '2.0',\n id: 1,\n method: 'getTokenAccountsByOwner',\n params: [address, { mint: currency }, { encoding: 'jsonParsed' }]\n }\n\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n })\n\n const data = await response.json()\n\n if (data.error) {\n throw new Error(data.error.message)\n }\n\n if (isNative) {\n return {\n balance: BigInt(data.result?.value ?? 0)\n }\n }\n\n const accounts = (data.result?.value ?? []) as TokenAccount[]\n const balance = accounts.reduce(\n (total, account) =>\n total +\n BigInt(\n account?.account?.data?.parsed?.info?.tokenAmount?.amount ?? 0\n ),\n BigInt(0)\n )\n\n return { balance }\n },\n ...queryOptions,\n enabled:\n address !== undefined &&\n currency !== undefined &&\n rpcUrl !== undefined &&\n (queryOptions?.enabled ?? true)\n })\n\n return {\n ...response,\n balance: response.data?.balance,\n queryKey\n } as ReturnType<QueryType> & {\n balance: bigint | undefined\n queryKey: (string | undefined)[]\n }\n}\n"]}
|
|
@@ -130,7 +130,7 @@ export const RelayKitProvider = function ({ children, options, theme }) {
|
|
|
130
130
|
const providerOptions = useMemo(() => ({
|
|
131
131
|
appName: options.appName,
|
|
132
132
|
appFees: options.appFees,
|
|
133
|
-
|
|
133
|
+
codexConfig: options.codexConfig,
|
|
134
134
|
vmConnectorKeyOverrides: options.vmConnectorKeyOverrides,
|
|
135
135
|
privateChainIds: options.privateChainIds,
|
|
136
136
|
themeScheme: options.themeScheme,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RelayKitProvider.js","sourceRoot":"","sources":["../../../src/providers/RelayKitProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo\n} from 'react'\nimport type { FC, ReactElement, ReactNode } from 'react'\nimport { RelayClientProvider } from './RelayClientProvider.js'\nimport { isRelayApiUrl, MAINNET_RELAY_API } from '@relayprotocol/relay-sdk'\nimport type { RelayClientOptions, paths } from '@relayprotocol/relay-sdk'\nimport type { RelayKitTheme } from '../themes/index.js'\nimport { generateCssVars } from '../utils/theme.js'\n\nexport type AppFees =\n paths['/quote/v2']['post']['requestBody']['content']['application/json']['appFees']\n\n/**\n * Haptic feedback intensity/type for UI interactions.\n *\n * - `light` — Subtle tap for minor interactions: token selection, chain starring, toggle switches, max button clicks\n * - `medium` — Noticeable tap for deliberate actions: swap CTA button press\n * - `heavy` — Strong tap for emphatic interactions: long-press actions\n * - `selection` — Ultra-light discrete tick for picker-like interactions: tab switches, chain filter selection\n * - `success` — Distinct success pattern: swap completed, onramp completed\n * - `error` — Distinct error pattern: swap failed, approval failed, onramp failed\n * - `warning` — Alert pattern: unverified token modal shown\n */\nexport type HapticEventType =\n | 'light'\n | 'medium'\n | 'heavy'\n | 'selection'\n | 'success'\n | 'error'\n | 'warning'\n\ntype RelayKitProviderOptions = {\n /**\n * Silences the client-side API key warnings shown when `baseApiUrl` points\n * directly at the Relay API instead of a proxy.\n *\n * This only silences the warnings — it does not change behavior. A proxy is\n * the only supported configuration: the requests hooks never send\n * `x-api-key` from the browser, so `GET /requests/v3` requires `baseApiUrl`\n * to point at your backend proxy (which injects the key server-side). Setting\n * an `apiKey` alongside a Relay `baseApiUrl` also exposes that key via other\n * SDK calls (e.g. quotes). Only set this to `true` if you accept that\n * exposure (e.g. a public, rate-limited key).\n */\n acknowledgeApiKeyExposure?: boolean\n /**\n * The name of the application\n */\n appName?: string\n /**\n * An array of fee objects composing of a recipient address and the fee in BPS\n */\n appFees?: AppFees\n duneConfig?: {\n /**\n * The base url for the dune api, if omitted the default will be used. Override this config to protect your api key via a proxy.\n */\n apiBaseUrl?: string\n /**\n * This key is used to fetch token balances, to improve the general UX and suggest relevant tokens\n * Can be omitted and the ui will continue to function. Refer to the dune docs on how to get an api key\n */\n apiKey?: string\n }\n /**\n * An objecting mapping either a VM type (evm, svm, bvm) or a chain id to a connector key (metamask, backpacksol, etc).\n * Connector keys are used for differentiating which wallet maps to which vm/chain.\n * Only relevant for eclipse/solana at the moment.\n */\n vmConnectorKeyOverrides?: {\n [key in number | 'evm' | 'svm' | 'bvm']?: string[]\n }\n /**\n * An array of private chain ids to be used when querying the chains api within relay kit.\n */\n privateChainIds?: string[]\n /**\n * The icon theme to use for the chain icons. Defaults to light.\n */\n themeScheme?: 'dark' | 'light'\n /**\n * The loader to use for the loading spinner. Defaults to relay.\n */\n loader?: (options?: {\n width?: number | string\n height?: number | string\n fill?: string\n }) => ReactElement\n /**\n * Optional callback for haptic feedback on UI interactions.\n * Relay Kit does not bundle any haptics library — integrators provide their own implementation.\n *\n * @example\n * ```tsx\n * import { useWebHaptics } from 'web-haptics/react'\n *\n * function App() {\n * const { trigger } = useWebHaptics()\n *\n * return (\n * <RelayKitProvider\n * options={{\n * ...otherOptions,\n * onHapticEvent: (type) => {\n * // Map Relay Kit types to your haptics library\n * const map = { light: 'nudge', medium: 'buzz', heavy: 'buzz', success: 'success', error: 'error', warning: 'error' }\n * trigger(map[type] ?? type)\n * }\n * }}\n * >\n * <SwapWidget />\n * </RelayKitProvider>\n * )\n * }\n * ```\n */\n onHapticEvent?: (type: HapticEventType) => void\n}\n\nexport interface RelayKitProviderProps {\n children: ReactNode\n options: RelayClientOptions & RelayKitProviderOptions\n theme?: RelayKitTheme\n}\n\nexport const ProviderOptionsContext = createContext<RelayKitProviderOptions>({})\n\nexport type ThemeOverridesMap = {\n [key: string]: string | ThemeOverridesMap\n}\n\nexport const themeOverrides: ThemeOverridesMap = {\n font: '--relay-fonts-body',\n fontHeading: '--relay-fonts-heading',\n primaryColor: '--relay-colors-primary-color',\n focusColor: '--relay-colors-focus-color',\n subtleBackgroundColor: '--relay-colors-subtle-background-color',\n subtleBorderColor: '--relay-colors-subtle-border-color',\n text: {\n default: '--relay-colors-text-default',\n subtle: '--relay-colors-text-subtle',\n error: '--relay-colors-text-error',\n success: '--relay-colors-text-success'\n },\n buttons: {\n borderRadius: '--relay-radii-button-border-radius',\n primary: {\n color: '--relay-colors-primary-button-color',\n background: '--relay-colors-primary-button-background',\n hover: {\n color: '--relay-colors-primary-button-hover-color',\n background: '--relay-colors-primary-button-hover-background'\n }\n },\n secondary: {\n color: '--relay-colors-secondary-button-color',\n background: '--relay-colors-secondary-button-background',\n hover: {\n color: '--relay-colors-secondary-button-hover-color',\n background: '--relay-colors-secondary-button-hover-background'\n }\n },\n white: {\n color: '--relay-colors-primary-button-color',\n background: '--relay-colors-primary-button-background',\n hover: {\n color: '--relay-colors-primary-button-hover-color',\n background: '--relay-colors-primary-button-hover-background'\n }\n },\n disabled: {\n color: '--relay-colors-button-disabled-color',\n background: '--relay-colors-button-disabled-background'\n },\n cta: {\n fontStyle: '--relay-fonts-button-cta-font-style'\n }\n },\n input: {\n background: '--relay-colors-input-background',\n borderRadius: '--relay-radii-input-border-radius',\n color: '--relay-colors-input-color'\n },\n skeleton: {\n background: '--relay-colors-skeleton-background'\n },\n anchor: {\n color: '--relay-colors-anchor-color',\n hover: {\n color: '--relay-colors-anchor-hover-color'\n }\n },\n dropdown: {\n background: '--relay-colors-dropdown-background',\n borderRadius: '--relay-radii-dropdown-border-radius',\n border: '--relay-borders-dropdown-border'\n },\n widget: {\n background: '--relay-colors-widget-background',\n borderRadius: '--relay-radii-widget-border-radius',\n border: '--relay-borders-widget-border',\n boxShadow: '--relay-shadows-widget-box-shadow',\n card: {\n background: '--relay-colors-widget-card-background',\n borderRadius: '--relay-radii-widget-card-border-radius',\n border: '--relay-borders-widget-card-border',\n gutter: '--relay-spacing-widget-card-section-gutter'\n },\n selector: {\n background: '--relay-colors-widget-selector-background',\n hover: {\n background: '--relay-colors-widget-selector-hover-background'\n }\n },\n swapCurrencyButtonBorderColor:\n '--relay-colors-widget-swap-currency-button-border-color',\n swapCurrencyButtonBorderWidth:\n '--relay-borders-widget-swap-currency-button-border-width',\n swapCurrencyButtonBorderRadius:\n '--relay-radii-widget-swap-currency-button-border-radius'\n },\n modal: {\n background: '--relay-colors-modal-background',\n borderRadius: '--relay-radii-modal-border-radius',\n border: '--relay-borders-modal-border'\n }\n}\n\n// Tracks base URLs we've already warned about so the message logs once, not on\n// every mount/render (incl. React StrictMode double-invocation).\nconst warnedApiKeyExposure = new Set<string>()\n\nexport const RelayKitProvider: FC<RelayKitProviderProps> = function ({\n children,\n options,\n theme\n}: RelayKitProviderProps) {\n // Warn when the Relay API is called directly instead of through a proxy.\n // GET /requests/v3 requires an API key, which must not be shipped to the\n // browser — integrators should proxy Relay API calls through their own\n // backend and point `baseApiUrl` at it. Runs client-side only (useEffect) and\n // re-checks only when the relevant options change.\n useEffect(() => {\n if (options.acknowledgeApiKeyExposure) return\n const baseApiUrl = options.baseApiUrl ?? MAINNET_RELAY_API\n // A proxy setup uses a non-Relay baseApiUrl, which is the desired state.\n if (!isRelayApiUrl(baseApiUrl)) return\n if (warnedApiKeyExposure.has(baseApiUrl)) return\n warnedApiKeyExposure.add(baseApiUrl)\n\n if (options.apiKey) {\n console.error(\n '[RelayKit] Your Relay API key is being sent from the browser because `baseApiUrl` points directly at the Relay API. ' +\n 'Proxy Relay API calls through your own backend that injects the `x-api-key` header, and set `baseApiUrl` to that proxy. ' +\n 'Pass `acknowledgeApiKeyExposure: true` to silence this.'\n )\n } else {\n console.warn(\n '[RelayKit] `baseApiUrl` points directly at the Relay API with no proxy. ' +\n 'GET /requests/v3 requires an API key and will fail without one — set `baseApiUrl` to a proxy on your backend that injects the `x-api-key` header. ' +\n 'Pass `acknowledgeApiKeyExposure: true` to silence this.'\n )\n }\n }, [options.acknowledgeApiKeyExposure, options.baseApiUrl, options.apiKey])\n\n const providerOptions = useMemo(\n () => ({\n appName: options.appName,\n appFees: options.appFees,\n duneConfig: options.duneConfig,\n vmConnectorKeyOverrides: options.vmConnectorKeyOverrides,\n privateChainIds: options.privateChainIds,\n themeScheme: options.themeScheme,\n loader: options.loader,\n onHapticEvent: options.onHapticEvent\n }),\n [options]\n )\n\n // Generate the CSS variable declarations\n const cssVariables = useMemo(\n () => generateCssVars(theme, themeOverrides),\n [theme]\n )\n\n return (\n <ProviderOptionsContext.Provider value={providerOptions}>\n <RelayClientProvider options={options}>\n <style\n dangerouslySetInnerHTML={{\n __html: `.relay-kit-reset {\n ${cssVariables}\n }`\n }}\n />\n {children}\n </RelayClientProvider>\n </ProviderOptionsContext.Provider>\n )\n}\n\n/**\n * Hook that returns a stable haptic event callback from the RelayKitProvider context.\n * Wraps the integrator's callback in a try-catch to prevent haptic errors from breaking the UI.\n */\nexport function useHapticEvent() {\n const { onHapticEvent } = useContext(ProviderOptionsContext)\n return useCallback(\n (type: HapticEventType) => {\n try {\n onHapticEvent?.(type)\n } catch (e) {\n console.error('Error in onHapticEvent', type, e)\n }\n },\n [onHapticEvent]\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RelayKitProvider.js","sourceRoot":"","sources":["../../../src/providers/RelayKitProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo\n} from 'react'\nimport type { FC, ReactElement, ReactNode } from 'react'\nimport { RelayClientProvider } from './RelayClientProvider.js'\nimport { isRelayApiUrl, MAINNET_RELAY_API } from '@relayprotocol/relay-sdk'\nimport type { RelayClientOptions, paths } from '@relayprotocol/relay-sdk'\nimport type { RelayKitTheme } from '../themes/index.js'\nimport { generateCssVars } from '../utils/theme.js'\n\nexport type AppFees =\n paths['/quote/v2']['post']['requestBody']['content']['application/json']['appFees']\n\n/**\n * Haptic feedback intensity/type for UI interactions.\n *\n * - `light` — Subtle tap for minor interactions: token selection, chain starring, toggle switches, max button clicks\n * - `medium` — Noticeable tap for deliberate actions: swap CTA button press\n * - `heavy` — Strong tap for emphatic interactions: long-press actions\n * - `selection` — Ultra-light discrete tick for picker-like interactions: tab switches, chain filter selection\n * - `success` — Distinct success pattern: swap completed, onramp completed\n * - `error` — Distinct error pattern: swap failed, approval failed, onramp failed\n * - `warning` — Alert pattern: unverified token modal shown\n */\nexport type HapticEventType =\n | 'light'\n | 'medium'\n | 'heavy'\n | 'selection'\n | 'success'\n | 'error'\n | 'warning'\n\ntype RelayKitProviderOptions = {\n /**\n * Silences the client-side API key warnings shown when `baseApiUrl` points\n * directly at the Relay API instead of a proxy.\n *\n * This only silences the warnings — it does not change behavior. A proxy is\n * the only supported configuration: the requests hooks never send\n * `x-api-key` from the browser, so `GET /requests/v3` requires `baseApiUrl`\n * to point at your backend proxy (which injects the key server-side). Setting\n * an `apiKey` alongside a Relay `baseApiUrl` also exposes that key via other\n * SDK calls (e.g. quotes). Only set this to `true` if you accept that\n * exposure (e.g. a public, rate-limited key).\n */\n acknowledgeApiKeyExposure?: boolean\n /**\n * The name of the application\n */\n appName?: string\n /**\n * An array of fee objects composing of a recipient address and the fee in BPS\n */\n appFees?: AppFees\n codexConfig?: {\n /**\n * The base url for the codex graphql api, if omitted the default (https://graph.codex.io) will be used. Override this config to protect your api key via a proxy.\n */\n apiBaseUrl?: string\n /**\n * This key is used to fetch token balances, to improve the general UX and suggest relevant tokens\n * Can be omitted and the ui will continue to function. Refer to the codex docs (https://docs.codex.io) on how to get an api key\n */\n apiKey?: string\n }\n /**\n * An objecting mapping either a VM type (evm, svm, bvm) or a chain id to a connector key (metamask, backpacksol, etc).\n * Connector keys are used for differentiating which wallet maps to which vm/chain.\n * Only relevant for eclipse/solana at the moment.\n */\n vmConnectorKeyOverrides?: {\n [key in number | 'evm' | 'svm' | 'bvm']?: string[]\n }\n /**\n * An array of private chain ids to be used when querying the chains api within relay kit.\n */\n privateChainIds?: string[]\n /**\n * The icon theme to use for the chain icons. Defaults to light.\n */\n themeScheme?: 'dark' | 'light'\n /**\n * The loader to use for the loading spinner. Defaults to relay.\n */\n loader?: (options?: {\n width?: number | string\n height?: number | string\n fill?: string\n }) => ReactElement\n /**\n * Optional callback for haptic feedback on UI interactions.\n * Relay Kit does not bundle any haptics library — integrators provide their own implementation.\n *\n * @example\n * ```tsx\n * import { useWebHaptics } from 'web-haptics/react'\n *\n * function App() {\n * const { trigger } = useWebHaptics()\n *\n * return (\n * <RelayKitProvider\n * options={{\n * ...otherOptions,\n * onHapticEvent: (type) => {\n * // Map Relay Kit types to your haptics library\n * const map = { light: 'nudge', medium: 'buzz', heavy: 'buzz', success: 'success', error: 'error', warning: 'error' }\n * trigger(map[type] ?? type)\n * }\n * }}\n * >\n * <SwapWidget />\n * </RelayKitProvider>\n * )\n * }\n * ```\n */\n onHapticEvent?: (type: HapticEventType) => void\n}\n\nexport interface RelayKitProviderProps {\n children: ReactNode\n options: RelayClientOptions & RelayKitProviderOptions\n theme?: RelayKitTheme\n}\n\nexport const ProviderOptionsContext = createContext<RelayKitProviderOptions>({})\n\nexport type ThemeOverridesMap = {\n [key: string]: string | ThemeOverridesMap\n}\n\nexport const themeOverrides: ThemeOverridesMap = {\n font: '--relay-fonts-body',\n fontHeading: '--relay-fonts-heading',\n primaryColor: '--relay-colors-primary-color',\n focusColor: '--relay-colors-focus-color',\n subtleBackgroundColor: '--relay-colors-subtle-background-color',\n subtleBorderColor: '--relay-colors-subtle-border-color',\n text: {\n default: '--relay-colors-text-default',\n subtle: '--relay-colors-text-subtle',\n error: '--relay-colors-text-error',\n success: '--relay-colors-text-success'\n },\n buttons: {\n borderRadius: '--relay-radii-button-border-radius',\n primary: {\n color: '--relay-colors-primary-button-color',\n background: '--relay-colors-primary-button-background',\n hover: {\n color: '--relay-colors-primary-button-hover-color',\n background: '--relay-colors-primary-button-hover-background'\n }\n },\n secondary: {\n color: '--relay-colors-secondary-button-color',\n background: '--relay-colors-secondary-button-background',\n hover: {\n color: '--relay-colors-secondary-button-hover-color',\n background: '--relay-colors-secondary-button-hover-background'\n }\n },\n white: {\n color: '--relay-colors-primary-button-color',\n background: '--relay-colors-primary-button-background',\n hover: {\n color: '--relay-colors-primary-button-hover-color',\n background: '--relay-colors-primary-button-hover-background'\n }\n },\n disabled: {\n color: '--relay-colors-button-disabled-color',\n background: '--relay-colors-button-disabled-background'\n },\n cta: {\n fontStyle: '--relay-fonts-button-cta-font-style'\n }\n },\n input: {\n background: '--relay-colors-input-background',\n borderRadius: '--relay-radii-input-border-radius',\n color: '--relay-colors-input-color'\n },\n skeleton: {\n background: '--relay-colors-skeleton-background'\n },\n anchor: {\n color: '--relay-colors-anchor-color',\n hover: {\n color: '--relay-colors-anchor-hover-color'\n }\n },\n dropdown: {\n background: '--relay-colors-dropdown-background',\n borderRadius: '--relay-radii-dropdown-border-radius',\n border: '--relay-borders-dropdown-border'\n },\n widget: {\n background: '--relay-colors-widget-background',\n borderRadius: '--relay-radii-widget-border-radius',\n border: '--relay-borders-widget-border',\n boxShadow: '--relay-shadows-widget-box-shadow',\n card: {\n background: '--relay-colors-widget-card-background',\n borderRadius: '--relay-radii-widget-card-border-radius',\n border: '--relay-borders-widget-card-border',\n gutter: '--relay-spacing-widget-card-section-gutter'\n },\n selector: {\n background: '--relay-colors-widget-selector-background',\n hover: {\n background: '--relay-colors-widget-selector-hover-background'\n }\n },\n swapCurrencyButtonBorderColor:\n '--relay-colors-widget-swap-currency-button-border-color',\n swapCurrencyButtonBorderWidth:\n '--relay-borders-widget-swap-currency-button-border-width',\n swapCurrencyButtonBorderRadius:\n '--relay-radii-widget-swap-currency-button-border-radius'\n },\n modal: {\n background: '--relay-colors-modal-background',\n borderRadius: '--relay-radii-modal-border-radius',\n border: '--relay-borders-modal-border'\n }\n}\n\n// Tracks base URLs we've already warned about so the message logs once, not on\n// every mount/render (incl. React StrictMode double-invocation).\nconst warnedApiKeyExposure = new Set<string>()\n\nexport const RelayKitProvider: FC<RelayKitProviderProps> = function ({\n children,\n options,\n theme\n}: RelayKitProviderProps) {\n // Warn when the Relay API is called directly instead of through a proxy.\n // GET /requests/v3 requires an API key, which must not be shipped to the\n // browser — integrators should proxy Relay API calls through their own\n // backend and point `baseApiUrl` at it. Runs client-side only (useEffect) and\n // re-checks only when the relevant options change.\n useEffect(() => {\n if (options.acknowledgeApiKeyExposure) return\n const baseApiUrl = options.baseApiUrl ?? MAINNET_RELAY_API\n // A proxy setup uses a non-Relay baseApiUrl, which is the desired state.\n if (!isRelayApiUrl(baseApiUrl)) return\n if (warnedApiKeyExposure.has(baseApiUrl)) return\n warnedApiKeyExposure.add(baseApiUrl)\n\n if (options.apiKey) {\n console.error(\n '[RelayKit] Your Relay API key is being sent from the browser because `baseApiUrl` points directly at the Relay API. ' +\n 'Proxy Relay API calls through your own backend that injects the `x-api-key` header, and set `baseApiUrl` to that proxy. ' +\n 'Pass `acknowledgeApiKeyExposure: true` to silence this.'\n )\n } else {\n console.warn(\n '[RelayKit] `baseApiUrl` points directly at the Relay API with no proxy. ' +\n 'GET /requests/v3 requires an API key and will fail without one — set `baseApiUrl` to a proxy on your backend that injects the `x-api-key` header. ' +\n 'Pass `acknowledgeApiKeyExposure: true` to silence this.'\n )\n }\n }, [options.acknowledgeApiKeyExposure, options.baseApiUrl, options.apiKey])\n\n const providerOptions = useMemo(\n () => ({\n appName: options.appName,\n appFees: options.appFees,\n codexConfig: options.codexConfig,\n vmConnectorKeyOverrides: options.vmConnectorKeyOverrides,\n privateChainIds: options.privateChainIds,\n themeScheme: options.themeScheme,\n loader: options.loader,\n onHapticEvent: options.onHapticEvent\n }),\n [options]\n )\n\n // Generate the CSS variable declarations\n const cssVariables = useMemo(\n () => generateCssVars(theme, themeOverrides),\n [theme]\n )\n\n return (\n <ProviderOptionsContext.Provider value={providerOptions}>\n <RelayClientProvider options={options}>\n <style\n dangerouslySetInnerHTML={{\n __html: `.relay-kit-reset {\n ${cssVariables}\n }`\n }}\n />\n {children}\n </RelayClientProvider>\n </ProviderOptionsContext.Provider>\n )\n}\n\n/**\n * Hook that returns a stable haptic event callback from the RelayKitProvider context.\n * Wraps the integrator's callback in a try-catch to prevent haptic errors from breaking the UI.\n */\nexport function useHapticEvent() {\n const { onHapticEvent } = useContext(ProviderOptionsContext)\n return useCallback(\n (type: HapticEventType) => {\n try {\n onHapticEvent?.(type)\n } catch (e) {\n console.error('Error in onHapticEvent', type, e)\n }\n },\n [onHapticEvent]\n )\n}\n"]}
|
package/_esm/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const UI_VERSION = '
|
|
1
|
+
export const UI_VERSION = '11.0.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/_esm/src/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["export const UI_VERSION = '
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["export const UI_VERSION = '11.0.0';\n"]}
|