@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.
Files changed (80) hide show
  1. package/_cjs/src/components/common/TokenSelector/PaymentMethod.js +9 -9
  2. package/_cjs/src/components/common/TokenSelector/PaymentMethod.js.map +1 -1
  3. package/_cjs/src/components/common/TokenSelector/TokenSelector.js +8 -8
  4. package/_cjs/src/components/common/TokenSelector/TokenSelector.js.map +1 -1
  5. package/_cjs/src/components/widgets/SwapWidgetRenderer.js +6 -39
  6. package/_cjs/src/components/widgets/SwapWidgetRenderer.js.map +1 -1
  7. package/_cjs/src/constants/walletCompatibility.js +3 -1
  8. package/_cjs/src/constants/walletCompatibility.js.map +1 -1
  9. package/_cjs/src/hooks/index.js +5 -3
  10. package/_cjs/src/hooks/index.js.map +1 -1
  11. package/_cjs/src/hooks/useCodexBalances.js +305 -0
  12. package/_cjs/src/hooks/useCodexBalances.js.map +1 -0
  13. package/_cjs/src/hooks/useCurrencyBalance.js +18 -74
  14. package/_cjs/src/hooks/useCurrencyBalance.js.map +1 -1
  15. package/_cjs/src/hooks/useEnhancedTokensList.js.map +1 -1
  16. package/_cjs/src/hooks/useMultiWalletBalances.js +19 -37
  17. package/_cjs/src/hooks/useMultiWalletBalances.js.map +1 -1
  18. package/_cjs/src/hooks/useSolanaBalance.js +60 -0
  19. package/_cjs/src/hooks/useSolanaBalance.js.map +1 -0
  20. package/_cjs/src/providers/RelayKitProvider.js +1 -1
  21. package/_cjs/src/providers/RelayKitProvider.js.map +1 -1
  22. package/_cjs/src/version.js +1 -1
  23. package/_cjs/src/version.js.map +1 -1
  24. package/_cjs/tsconfig.build.tsbuildinfo +1 -1
  25. package/_esm/src/components/common/TokenSelector/PaymentMethod.js +9 -9
  26. package/_esm/src/components/common/TokenSelector/PaymentMethod.js.map +1 -1
  27. package/_esm/src/components/common/TokenSelector/TokenSelector.js +10 -10
  28. package/_esm/src/components/common/TokenSelector/TokenSelector.js.map +1 -1
  29. package/_esm/src/components/widgets/SwapWidgetRenderer.js +6 -41
  30. package/_esm/src/components/widgets/SwapWidgetRenderer.js.map +1 -1
  31. package/_esm/src/constants/walletCompatibility.js +3 -1
  32. package/_esm/src/constants/walletCompatibility.js.map +1 -1
  33. package/_esm/src/hooks/index.js +3 -2
  34. package/_esm/src/hooks/index.js.map +1 -1
  35. package/_esm/src/hooks/useCodexBalances.js +311 -0
  36. package/_esm/src/hooks/useCodexBalances.js.map +1 -0
  37. package/_esm/src/hooks/useCurrencyBalance.js +18 -74
  38. package/_esm/src/hooks/useCurrencyBalance.js.map +1 -1
  39. package/_esm/src/hooks/useEnhancedTokensList.js.map +1 -1
  40. package/_esm/src/hooks/useMultiWalletBalances.js +18 -39
  41. package/_esm/src/hooks/useMultiWalletBalances.js.map +1 -1
  42. package/_esm/src/hooks/useSolanaBalance.js +58 -0
  43. package/_esm/src/hooks/useSolanaBalance.js.map +1 -0
  44. package/_esm/src/providers/RelayKitProvider.js +1 -1
  45. package/_esm/src/providers/RelayKitProvider.js.map +1 -1
  46. package/_esm/src/version.js +1 -1
  47. package/_esm/src/version.js.map +1 -1
  48. package/_esm/tsconfig.build.tsbuildinfo +1 -1
  49. package/_types/src/components/common/TokenSelector/PaymentMethod.d.ts.map +1 -1
  50. package/_types/src/components/common/TokenSelector/TokenSelector.d.ts.map +1 -1
  51. package/_types/src/components/widgets/SwapWidgetRenderer.d.ts.map +1 -1
  52. package/_types/src/constants/walletCompatibility.d.ts.map +1 -1
  53. package/_types/src/hooks/index.d.ts +3 -2
  54. package/_types/src/hooks/index.d.ts.map +1 -1
  55. package/_types/src/hooks/useCodexBalances.d.ts +45 -0
  56. package/_types/src/hooks/useCodexBalances.d.ts.map +1 -0
  57. package/_types/src/hooks/useCurrencyBalance.d.ts +0 -1
  58. package/_types/src/hooks/useCurrencyBalance.d.ts.map +1 -1
  59. package/_types/src/hooks/useEnhancedTokensList.d.ts +1 -1
  60. package/_types/src/hooks/useEnhancedTokensList.d.ts.map +1 -1
  61. package/_types/src/hooks/useMultiWalletBalances.d.ts +3 -12
  62. package/_types/src/hooks/useMultiWalletBalances.d.ts.map +1 -1
  63. package/_types/src/hooks/{useEclipseBalance.d.ts → useSolanaBalance.d.ts} +2 -2
  64. package/_types/src/hooks/useSolanaBalance.d.ts.map +1 -0
  65. package/_types/src/providers/RelayKitProvider.d.ts +3 -3
  66. package/_types/src/providers/RelayKitProvider.d.ts.map +1 -1
  67. package/_types/src/version.d.ts +1 -1
  68. package/_types/tsconfig.build.tsbuildinfo +1 -1
  69. package/package.json +1 -1
  70. package/_cjs/src/hooks/useDuneBalances.js +0 -100
  71. package/_cjs/src/hooks/useDuneBalances.js.map +0 -1
  72. package/_cjs/src/hooks/useEclipseBalance.js +0 -47
  73. package/_cjs/src/hooks/useEclipseBalance.js.map +0 -1
  74. package/_esm/src/hooks/useDuneBalances.js +0 -102
  75. package/_esm/src/hooks/useDuneBalances.js.map +0 -1
  76. package/_esm/src/hooks/useEclipseBalance.js +0 -44
  77. package/_esm/src/hooks/useEclipseBalance.js.map +0 -1
  78. package/_types/src/hooks/useDuneBalances.d.ts +0 -25
  79. package/_types/src/hooks/useDuneBalances.d.ts.map +0 -1
  80. package/_types/src/hooks/useEclipseBalance.d.ts.map +0 -1
@@ -1,14 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMultiWalletBalances = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const react_1 = require("react");
5
6
  const react_query_1 = require("@tanstack/react-query");
7
+ const useCodexBalances_js_1 = require("./useCodexBalances.js");
8
+ const useRelayClient_js_1 = tslib_1.__importDefault(require("./useRelayClient.js"));
6
9
  const relay_sdk_1 = require("@relayprotocol/relay-sdk");
7
10
  const RelayKitProvider_js_1 = require("../providers/RelayKitProvider.js");
8
11
  const viem_1 = require("viem");
9
12
  const solana_js_1 = require("../utils/solana.js");
10
13
  const address_js_1 = require("../utils/address.js");
11
- const useMultiWalletBalances = (linkedWallets, primaryAddress, evmChainIds = 'mainnet') => {
14
+ const useMultiWalletBalances = (linkedWallets, primaryAddress) => {
12
15
  const walletAddresses = (0, react_1.useMemo)(() => {
13
16
  const addresses = new Set();
14
17
  if (primaryAddress && !(0, relay_sdk_1.isDeadAddress)(primaryAddress)) {
@@ -25,56 +28,35 @@ const useMultiWalletBalances = (linkedWallets, primaryAddress, evmChainIds = 'ma
25
28
  return Array.from(addresses);
26
29
  }, [primaryAddress, linkedWallets]);
27
30
  const providerOptions = (0, react_1.useContext)(RelayKitProvider_js_1.ProviderOptionsContext);
31
+ const relayClient = (0, useRelayClient_js_1.default)();
28
32
  const balanceQueries = (0, react_query_1.useQueries)({
29
33
  queries: walletAddresses.map((address) => {
30
34
  const isEvmAddress = (0, viem_1.isAddress)(address);
31
35
  const isSvmAddress = (0, solana_js_1.isSolanaAddress)(address);
32
- let url = `${providerOptions?.duneConfig?.apiBaseUrl ?? 'https://api.sim.dune.com'}/v1/evm/balances/${address.toLowerCase()}?chain_ids=${evmChainIds}&exclude_spam_tokens=true`;
33
- if (isSvmAddress) {
34
- url = `${providerOptions?.duneConfig?.apiBaseUrl ?? 'https://api.sim.dune.com'}/beta/svm/balances/${address}?chain_ids=all&exclude_spam_tokens=true`;
35
- }
36
+ const networks = isSvmAddress
37
+ ? [useCodexBalances_js_1.CODEX_SVM_NETWORK_ID]
38
+ : (0, useCodexBalances_js_1.getEvmNetworkIds)(relayClient?.chains);
36
39
  return {
37
- queryKey: ['useDuneBalances', address],
40
+ queryKey: ['useCodexBalances', address],
38
41
  queryFn: async () => {
39
42
  if (!isSvmAddress && !isEvmAddress) {
40
43
  return null;
41
44
  }
42
- const response = await fetch(url, {
43
- headers: providerOptions?.duneConfig?.apiKey
44
- ? {
45
- 'X-Sim-Api-Key': providerOptions.duneConfig.apiKey
46
- }
47
- : {}
48
- });
49
- if (!response.ok) {
50
- throw new Error(`Failed to fetch balance for ${address}`);
51
- }
52
- const data = await response.json();
53
- if (data?.balances) {
54
- const validBalances = data.balances.filter((balance) => {
55
- try {
56
- BigInt(balance.amount);
57
- return true;
58
- }
59
- catch (e) {
60
- return false;
61
- }
62
- });
63
- return {
64
- ...data,
65
- balances: validBalances
66
- };
67
- }
68
- return data;
45
+ return (0, useCodexBalances_js_1.fetchCodexBalances)(address, providerOptions?.codexConfig ?? {}, networks, isSvmAddress ? (0, useCodexBalances_js_1.getSvmNativeChains)(relayClient?.chains) : undefined);
69
46
  },
70
- enabled: Boolean(address && address.trim() !== '' && (isEvmAddress || isSvmAddress)),
47
+ enabled: Boolean(address &&
48
+ address.trim() !== '' &&
49
+ (isEvmAddress || isSvmAddress) &&
50
+ networks.length > 0 &&
51
+ (providerOptions?.codexConfig?.apiKey !== undefined ||
52
+ providerOptions?.codexConfig?.apiBaseUrl !== undefined)),
71
53
  staleTime: 60000,
72
54
  gcTime: 60000,
73
55
  retry: 1
74
56
  };
75
57
  })
76
58
  });
77
- const { mergedBalanceMap, mergedDuneTokens, isLoadingBalances } = (0, react_1.useMemo)(() => {
59
+ const { mergedBalanceMap, mergedTokens, isLoadingBalances } = (0, react_1.useMemo)(() => {
78
60
  const mergedMap = {};
79
61
  const allBalances = [];
80
62
  let anyLoading = false;
@@ -107,13 +89,13 @@ const useMultiWalletBalances = (linkedWallets, primaryAddress, evmChainIds = 'ma
107
89
  });
108
90
  return {
109
91
  mergedBalanceMap: mergedMap,
110
- mergedDuneTokens: allBalances.length > 0 ? { balances: allBalances } : undefined,
92
+ mergedTokens: allBalances.length > 0 ? { balances: allBalances } : undefined,
111
93
  isLoadingBalances: anyLoading
112
94
  };
113
95
  }, [balanceQueries]);
114
96
  return {
115
97
  balanceMap: mergedBalanceMap,
116
- data: mergedDuneTokens,
98
+ data: mergedTokens,
117
99
  isLoading: isLoadingBalances
118
100
  };
119
101
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useMultiWalletBalances.js","sourceRoot":"","sources":["../../../src/hooks/useMultiWalletBalances.ts"],"names":[],"mappings":";;;AAAA,iCAA2C;AAC3C,uDAAkD;AAElD,wDAAwD;AACxD,0EAAyE;AACzE,+BAAgC;AAChC,kDAAoD;AACpD,oDAAuE;AAMhE,MAAM,sBAAsB,GAAG,CACpC,aAA8B,EAC9B,cAAuB,EACvB,cAAqC,SAAS,EAC9C,EAAE;IACF,MAAM,eAAe,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,IAAI,cAAc,IAAI,CAAC,IAAA,yBAAa,EAAC,cAAc,CAAC,EAAE,CAAC;YACrD,MAAM,cAAc,GAAG,aAAa,EAAE,IAAI,CACxC,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,OAAO,KAAK,cAAc;gBACjC,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK;oBACtB,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,WAAW,EAAE,CAAC,CACnE,CAAA;YAED,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,OAAO,GAAG,IAAA,2BAAe,EAC7B,cAAc,CAAC,MAAM,EACrB,cAAc,EACd,SAAS,EACT,cAAc,CAAC,SAAS,CACzB,CAAA;gBAED,IAAI,OAAO,EAAE,CAAC;oBACZ,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC9B,CAAC,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,CAAA;IAEnC,MAAM,eAAe,GAAG,IAAA,kBAAU,EAAC,4CAAsB,CAAC,CAAA;IAE1D,MAAM,cAAc,GAAG,IAAA,wBAAU,EAAC;QAChC,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACvC,MAAM,YAAY,GAAG,IAAA,gBAAS,EAAC,OAAO,CAAC,CAAA;YACvC,MAAM,YAAY,GAAG,IAAA,2BAAe,EAAC,OAAO,CAAC,CAAA;YAE7C,IAAI,GAAG,GAAG,GACR,eAAe,EAAE,UAAU,EAAE,UAAU,IAAI,0BAC7C,oBAAoB,OAAO,CAAC,WAAW,EAAE,cAAc,WAAW,2BAA2B,CAAA;YAE7F,IAAI,YAAY,EAAE,CAAC;gBACjB,GAAG,GAAG,GACJ,eAAe,EAAE,UAAU,EAAE,UAAU,IAAI,0BAC7C,sBAAsB,OAAO,yCAAyC,CAAA;YACxE,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC;gBACtC,OAAO,EAAE,KAAK,IAAkC,EAAE;oBAChD,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,EAAE,CAAC;wBACnC,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;wBAChC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM;4BAC1C,CAAC,CAAC;gCACE,eAAe,EAAE,eAAe,CAAC,UAAU,CAAC,MAAM;6BACnD;4BACH,CAAC,CAAC,EAAE;qBACP,CAAC,CAAA;oBAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;wBACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAA;oBAC3D,CAAC;oBAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;oBAElC,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC;wBAEnB,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAY,EAAE,EAAE;4BAC1D,IAAI,CAAC;gCACH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;gCACtB,OAAO,IAAI,CAAA;4BACb,CAAC;4BAAC,OAAO,CAAC,EAAE,CAAC;gCACX,OAAO,KAAK,CAAA;4BACd,CAAC;wBACH,CAAC,CAAC,CAAA;wBAEF,OAAO;4BACL,GAAG,IAAI;4BACP,QAAQ,EAAE,aAAa;yBACD,CAAA;oBAC1B,CAAC;oBAED,OAAO,IAA2B,CAAA;gBACpC,CAAC;gBACD,OAAO,EAAE,OAAO,CACd,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,CACnE;gBACD,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,CAAC;aACT,CAAA;QACH,CAAC,CAAC;KACH,CAAC,CAAA;IAGF,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAC7D,IAAA,eAAO,EAAC,GAAG,EAAE;QACX,MAAM,SAAS,GAAe,EAAE,CAAA;QAChC,MAAM,WAAW,GAAiD,EAAE,CAAA;QACpE,IAAI,UAAU,GAAG,KAAK,CAAA;QAEtB,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC/B,IAAI,KAAK,CAAC,SAAS;gBAAE,UAAU,GAAG,IAAI,CAAA;YAEtC,IAAI,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;gBACzB,MAAM,UAAU,GAAe,EAAE,CAAA;gBACjC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACtC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAA;oBAClE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAA;gBAC3B,CAAC,CAAC,CAAA;gBAEF,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE;oBACpD,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;wBAEnB,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;wBACpD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;wBACxC,MAAM,WAAW,GAAG,cAAc,GAAG,SAAS,CAAA;wBAE9C,SAAS,CAAC,GAAG,CAAC,GAAG;4BACf,GAAG,OAAO;4BACV,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE;4BAC9B,SAAS,EACP,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;yBAC7D,CAAA;oBACH,CAAC;yBAAM,CAAC;wBACN,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAA;oBAC1B,CAAC;gBACH,CAAC,CAAC,CAAA;gBAEF,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,OAAO;YACL,gBAAgB,EAAE,SAAS;YAC3B,gBAAgB,EACd,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS;YAChE,iBAAiB,EAAE,UAAU;SAC9B,CAAA;IACH,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAA;IAEtB,OAAO;QACL,UAAU,EAAE,gBAAgB;QAC5B,IAAI,EAAE,gBAAgB;QACtB,SAAS,EAAE,iBAAiB;KAC7B,CAAA;AACH,CAAC,CAAA;AAxJY,QAAA,sBAAsB,0BAwJlC","sourcesContent":["import { useMemo, useContext } from 'react'\nimport { useQueries } from '@tanstack/react-query'\nimport { type BalanceMap, type DuneBalanceResponse } from './useDuneBalances.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 evmChainIds: 'mainnet' | 'testnet' = 'mainnet'\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\n const balanceQueries = useQueries({\n queries: walletAddresses.map((address) => {\n const isEvmAddress = isAddress(address)\n const isSvmAddress = isSolanaAddress(address)\n\n let url = `${\n providerOptions?.duneConfig?.apiBaseUrl ?? 'https://api.sim.dune.com'\n }/v1/evm/balances/${address.toLowerCase()}?chain_ids=${evmChainIds}&exclude_spam_tokens=true`\n\n if (isSvmAddress) {\n url = `${\n providerOptions?.duneConfig?.apiBaseUrl ?? 'https://api.sim.dune.com'\n }/beta/svm/balances/${address}?chain_ids=all&exclude_spam_tokens=true`\n }\n\n return {\n queryKey: ['useDuneBalances', address],\n queryFn: async (): Promise<DuneBalanceResponse> => {\n if (!isSvmAddress && !isEvmAddress) {\n return null\n }\n\n const response = await fetch(url, {\n headers: providerOptions?.duneConfig?.apiKey\n ? {\n 'X-Sim-Api-Key': providerOptions.duneConfig.apiKey\n }\n : {}\n })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch balance for ${address}`)\n }\n\n const data = await response.json()\n\n if (data?.balances) {\n // Filter out invalid amounts like useDuneBalances does\n const validBalances = data.balances.filter((balance: any) => {\n try {\n BigInt(balance.amount)\n return true\n } catch (e) {\n return false\n }\n })\n\n return {\n ...data,\n balances: validBalances\n } as DuneBalanceResponse\n }\n\n return data as DuneBalanceResponse\n },\n enabled: Boolean(\n address && address.trim() !== '' && (isEvmAddress || isSvmAddress)\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, mergedDuneTokens, isLoadingBalances } =\n useMemo(() => {\n const mergedMap: BalanceMap = {}\n const allBalances: NonNullable<DuneBalanceResponse>['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 mergedDuneTokens:\n allBalances.length > 0 ? { balances: allBalances } : undefined,\n isLoadingBalances: anyLoading\n }\n }, [balanceQueries])\n\n return {\n balanceMap: mergedBalanceMap,\n data: mergedDuneTokens,\n isLoading: isLoadingBalances\n }\n}\n"]}
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,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_query_1 = require("@tanstack/react-query");
4
+ const SOLANA_NATIVE_ADDRESS = '11111111111111111111111111111111';
5
+ exports.default = (address, currency, rpcUrl, queryOptions) => {
6
+ const queryKey = ['useSolanaBalance', address, currency, rpcUrl];
7
+ const response = react_query_1.useQuery({
8
+ queryKey,
9
+ queryFn: async () => {
10
+ if (!rpcUrl || !address || !currency) {
11
+ throw new Error('Missing address, currency or rpcUrl');
12
+ }
13
+ const isNative = currency === SOLANA_NATIVE_ADDRESS;
14
+ const payload = isNative
15
+ ? {
16
+ jsonrpc: '2.0',
17
+ id: 1,
18
+ method: 'getBalance',
19
+ params: [address]
20
+ }
21
+ : {
22
+ jsonrpc: '2.0',
23
+ id: 1,
24
+ method: 'getTokenAccountsByOwner',
25
+ params: [address, { mint: currency }, { encoding: 'jsonParsed' }]
26
+ };
27
+ const response = await fetch(rpcUrl, {
28
+ method: 'POST',
29
+ headers: {
30
+ 'Content-Type': 'application/json'
31
+ },
32
+ body: JSON.stringify(payload)
33
+ });
34
+ const data = await response.json();
35
+ if (data.error) {
36
+ throw new Error(data.error.message);
37
+ }
38
+ if (isNative) {
39
+ return {
40
+ balance: BigInt(data.result?.value ?? 0)
41
+ };
42
+ }
43
+ const accounts = (data.result?.value ?? []);
44
+ const balance = accounts.reduce((total, account) => total +
45
+ BigInt(account?.account?.data?.parsed?.info?.tokenAmount?.amount ?? 0), BigInt(0));
46
+ return { balance };
47
+ },
48
+ ...queryOptions,
49
+ enabled: address !== undefined &&
50
+ currency !== undefined &&
51
+ rpcUrl !== undefined &&
52
+ (queryOptions?.enabled ?? true)
53
+ });
54
+ return {
55
+ ...response,
56
+ balance: response.data?.balance,
57
+ queryKey
58
+ };
59
+ };
60
+ //# sourceMappingURL=useSolanaBalance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSolanaBalance.js","sourceRoot":"","sources":["../../../src/hooks/useSolanaBalance.ts"],"names":[],"mappings":";;AAAA,uDAI8B;AAE9B,MAAM,qBAAqB,GAAG,kCAAkC,CAAA;AA4BhE,kBAAe,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,sBAAsB,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"]}
@@ -125,7 +125,7 @@ const RelayKitProvider = function ({ children, options, theme }) {
125
125
  const providerOptions = (0, react_1.useMemo)(() => ({
126
126
  appName: options.appName,
127
127
  appFees: options.appFees,
128
- duneConfig: options.duneConfig,
128
+ codexConfig: options.codexConfig,
129
129
  vmConnectorKeyOverrides: options.vmConnectorKeyOverrides,
130
130
  privateChainIds: options.privateChainIds,
131
131
  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"]}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UI_VERSION = void 0;
4
- exports.UI_VERSION = '10.0.1';
4
+ exports.UI_VERSION = '11.0.0';
5
5
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["export const UI_VERSION = '10.0.1';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["export const UI_VERSION = '11.0.0';\n"]}