@openfort/react 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/build/assets/logos.d.ts +3 -0
  2. package/build/assets/logos.js +2 -0
  3. package/build/assets/logos.js.map +1 -1
  4. package/build/components/Common/SolanaChain/index.d.ts +8 -0
  5. package/build/components/Common/SolanaChain/index.js +40 -0
  6. package/build/components/Common/SolanaChain/index.js.map +1 -0
  7. package/build/components/ConnectModal/index.js +2 -0
  8. package/build/components/ConnectModal/index.js.map +1 -1
  9. package/build/components/Openfort/types.d.ts +17 -11
  10. package/build/components/Openfort/types.js +1 -0
  11. package/build/components/Openfort/types.js.map +1 -1
  12. package/build/components/Pages/Buy/coinbaseApi.d.ts +1 -1
  13. package/build/components/Pages/Buy/coinbaseApi.js +2 -13
  14. package/build/components/Pages/Buy/coinbaseApi.js.map +1 -1
  15. package/build/components/Pages/Buy/evmCurrencies.d.ts +11 -0
  16. package/build/components/Pages/Buy/evmCurrencies.js +27 -0
  17. package/build/components/Pages/Buy/evmCurrencies.js.map +1 -0
  18. package/build/components/Pages/Buy/index.js +8 -1
  19. package/build/components/Pages/Buy/index.js.map +1 -1
  20. package/build/components/Pages/Buy/onrampApi.d.ts +8 -1
  21. package/build/components/Pages/Buy/onrampApi.js +24 -14
  22. package/build/components/Pages/Buy/onrampApi.js.map +1 -1
  23. package/build/components/Pages/Buy/solanaCurrencies.d.ts +9 -0
  24. package/build/components/Pages/Buy/solanaCurrencies.js +25 -0
  25. package/build/components/Pages/Buy/solanaCurrencies.js.map +1 -0
  26. package/build/components/Pages/Buy/stripeApi.d.ts +1 -1
  27. package/build/components/Pages/Buy/stripeApi.js +2 -13
  28. package/build/components/Pages/Buy/stripeApi.js.map +1 -1
  29. package/build/components/Pages/BuyComplete/index.js +7 -1
  30. package/build/components/Pages/BuyComplete/index.js.map +1 -1
  31. package/build/components/Pages/BuyProcessing/index.js +9 -5
  32. package/build/components/Pages/BuyProcessing/index.js.map +1 -1
  33. package/build/components/Pages/BuySelectProvider/index.js +10 -5
  34. package/build/components/Pages/BuySelectProvider/index.js.map +1 -1
  35. package/build/components/Pages/Connected/SolanaConnected.js +3 -2
  36. package/build/components/Pages/Connected/SolanaConnected.js.map +1 -1
  37. package/build/components/Pages/Deposit/DepositProgress.js +3 -2
  38. package/build/components/Pages/Deposit/DepositProgress.js.map +1 -1
  39. package/build/components/Pages/Deposit/DepositSuccess.js +2 -1
  40. package/build/components/Pages/Deposit/DepositSuccess.js.map +1 -1
  41. package/build/components/Pages/Deposit/index.js +16 -2
  42. package/build/components/Pages/Deposit/index.js.map +1 -1
  43. package/build/components/Pages/Deposit/paymentOptions.js +3 -3
  44. package/build/components/Pages/Deposit/useDepositRoute.d.ts +0 -1
  45. package/build/components/Pages/Deposit/useDepositRoute.js +10 -11
  46. package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -1
  47. package/build/components/Pages/Deposit/useFundingTarget.d.ts +2 -4
  48. package/build/components/Pages/Deposit/useFundingTarget.js +3 -5
  49. package/build/components/Pages/Deposit/useFundingTarget.js.map +1 -1
  50. package/build/components/Pages/DepositCex/index.js +7 -8
  51. package/build/components/Pages/DepositCex/index.js.map +1 -1
  52. package/build/components/Pages/DepositWallet/DepositWalletDesktop.d.ts +4 -1
  53. package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +11 -20
  54. package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -1
  55. package/build/components/Pages/DepositWallet/index.d.ts +5 -5
  56. package/build/components/Pages/DepositWallet/index.js +36 -31
  57. package/build/components/Pages/DepositWallet/index.js.map +1 -1
  58. package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +6 -4
  59. package/build/components/Pages/DepositWallet/walletDeeplinks.js +3 -1
  60. package/build/components/Pages/DepositWallet/walletDeeplinks.js.map +1 -1
  61. package/build/components/Pages/SelectToken/SolanaSelectToken.d.ts +1 -0
  62. package/build/components/Pages/SelectToken/SolanaSelectToken.js +50 -0
  63. package/build/components/Pages/SelectToken/SolanaSelectToken.js.map +1 -0
  64. package/build/components/Pages/SelectToken/index.js +13 -2
  65. package/build/components/Pages/SelectToken/index.js.map +1 -1
  66. package/build/components/Pages/Send/SolanaSend.js +32 -31
  67. package/build/components/Pages/Send/SolanaSend.js.map +1 -1
  68. package/build/components/Pages/Send/utils.js +4 -1
  69. package/build/components/Pages/Send/utils.js.map +1 -1
  70. package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +57 -13
  71. package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -1
  72. package/build/components/Pages/SendConfirmation/styles.d.ts +0 -5
  73. package/build/components/Pages/SendConfirmation/styles.js +1 -39
  74. package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
  75. package/build/hooks/openfort/useFunding.js +7 -7
  76. package/build/hooks/openfort/useFundingChains.js +4 -6
  77. package/build/hooks/openfort/useFundingChains.js.map +1 -1
  78. package/build/shared/hooks/useAsyncData.js +15 -2
  79. package/build/shared/hooks/useAsyncData.js.map +1 -1
  80. package/build/solana/transfer.d.ts +35 -6
  81. package/build/solana/transfer.js +112 -18
  82. package/build/solana/transfer.js.map +1 -1
  83. package/build/solana/types.d.ts +8 -0
  84. package/build/version.d.ts +1 -1
  85. package/build/version.js +1 -1
  86. package/package.json +5 -1
@@ -53,14 +53,14 @@ async function pollUntilTerminal(client, onUpdate, start, isCurrent) {
53
53
  * @returns Session state plus `fund` (run the deposit flow) and `reset`.
54
54
  */
55
55
  function useFunding(options) {
56
- var _a, _b, _c;
56
+ var _a, _b;
57
57
  const { uiConfig, publishableKey } = useOpenfort();
58
58
  const { client: coreClient } = useOpenfortCore();
59
- // The CEX rail (DepositCex) is served by the Openfort API; everything else uses
60
- // the standalone funding service at uiConfig.fundingBaseUrl.
61
- const baseUrl = (options === null || options === void 0 ? void 0 : options.useBackendUrl)
62
- ? ((_a = SDKConfiguration.getInstance()) === null || _a === void 0 ? void 0 : _a.backendUrl) || 'https://api.openfort.io'
63
- : ((_b = uiConfig.fundingBaseUrl) !== null && _b !== void 0 ? _b : '');
59
+ // The funding JSON API defaults to the Openfort backend (api.openfort.io);
60
+ // integrators can point the crypto rails at a custom service via
61
+ // uiConfig.fundingBaseUrl. The CEX rail always uses the backend (Coinbase pay-link).
62
+ const backendUrl = ((_a = SDKConfiguration.getInstance()) === null || _a === void 0 ? void 0 : _a.backendUrl) || 'https://api.openfort.io';
63
+ const baseUrl = (options === null || options === void 0 ? void 0 : options.useBackendUrl) ? backendUrl : uiConfig.fundingBaseUrl || backendUrl;
64
64
  const injected = options === null || options === void 0 ? void 0 : options.client;
65
65
  // Resolve the client, in order of preference:
66
66
  // 1. an explicitly injected client (tests / custom backends),
@@ -188,7 +188,7 @@ function useFunding(options) {
188
188
  }, [client]);
189
189
  return {
190
190
  session,
191
- status: (_c = session === null || session === void 0 ? void 0 : session.status) !== null && _c !== void 0 ? _c : 'idle',
191
+ status: (_b = session === null || session === void 0 ? void 0 : session.status) !== null && _b !== void 0 ? _b : 'idle',
192
192
  error,
193
193
  loading,
194
194
  isAvailable,
@@ -1,3 +1,4 @@
1
+ import { SDKConfiguration } from '@openfort/openfort-js';
1
2
  import { useState, useEffect } from 'react';
2
3
  import { useOpenfort } from '../../components/Openfort/useOpenfort.js';
3
4
 
@@ -32,15 +33,12 @@ const DEFAULT_SOURCE_CURRENCIES = ['native', 'USDC', 'USDT'];
32
33
  function useFundingChains() {
33
34
  var _a, _b, _c, _d, _e;
34
35
  const { uiConfig } = useOpenfort();
35
- const baseUrl = (_a = uiConfig.fundingBaseUrl) !== null && _a !== void 0 ? _a : '';
36
+ // Defaults to the SDK backend (api.openfort.io); override for a custom funding service.
37
+ const baseUrl = uiConfig.fundingBaseUrl || ((_a = SDKConfiguration.getInstance()) === null || _a === void 0 ? void 0 : _a.backendUrl) || 'https://api.openfort.io';
36
38
  const sourceChains = (_c = (_b = uiConfig.funding) === null || _b === void 0 ? void 0 : _b.sourceChains) !== null && _c !== void 0 ? _c : DEFAULT_SOURCE_CHAINS;
37
39
  const sourceCurrencies = (_e = (_d = uiConfig.funding) === null || _d === void 0 ? void 0 : _d.sourceCurrencies) !== null && _e !== void 0 ? _e : DEFAULT_SOURCE_CURRENCIES;
38
- const [state, setState] = useState({ chains: [], loading: Boolean(baseUrl), error: null });
40
+ const [state, setState] = useState({ chains: [], loading: true, error: null });
39
41
  useEffect(() => {
40
- if (!baseUrl) {
41
- setState({ chains: [], loading: false, error: null });
42
- return;
43
- }
44
42
  let cancelled = false;
45
43
  setState((s) => ({ ...s, loading: true }));
46
44
  fetch(`${baseUrl}/v2/funding/chains`)
@@ -1 +1 @@
1
- {"version":3,"file":"useFundingChains.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useFundingChains.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,6 +2,19 @@ import { useState, useRef, useCallback, useEffect } from 'react';
2
2
 
3
3
  /** Module-level cache shared across hook instances, so revisiting a view paints instantly. */
4
4
  const dataCache = new Map();
5
+ /**
6
+ * Serialize a queryKey to a stable cache string.
7
+ *
8
+ * `JSON.stringify` throws `TypeError: Do not know how to serialize a BigInt`,
9
+ * and queryKeys legitimately carry bigints (token amounts, balances, gas
10
+ * values — e.g. a native ETH send keys its gas estimate on the bigint amount).
11
+ * Without this replacer such a key crashes the whole modal render. A bigint is
12
+ * encoded as its decimal digits with an `n` suffix so distinct values stay
13
+ * distinct keys.
14
+ */
15
+ function serializeQueryKey(queryKey) {
16
+ return JSON.stringify(queryKey, (_key, value) => (typeof value === 'bigint' ? `${value}n` : value));
17
+ }
5
18
  /**
6
19
  * Drop cached entries so the next mount (or refetch) hits the network instead of
7
20
  * painting stale data. Pass a substring matched against the serialized queryKey
@@ -40,8 +53,8 @@ function isEmptyResult(result) {
40
53
  */
41
54
  function useAsyncData({ queryFn, queryKey, enabled = true, refetchInterval, staleTime = 0, }) {
42
55
  // Serialize queryKey to a stable string so the effect only re-runs when values change,
43
- // not when array/object references change.
44
- const queryKeyStr = JSON.stringify(queryKey);
56
+ // not when array/object references change. Bigint-safe (see serializeQueryKey).
57
+ const queryKeyStr = serializeQueryKey(queryKey);
45
58
  const [data, setData] = useState(() => { var _a; return (_a = dataCache.get(queryKeyStr)) === null || _a === void 0 ? void 0 : _a.data; });
46
59
  const [error, setError] = useState(null);
47
60
  const [isLoading, setIsLoading] = useState(false);
@@ -1 +1 @@
1
- {"version":3,"file":"useAsyncData.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useAsyncData.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -13,6 +13,26 @@ type SendSolParams = {
13
13
  * to sponsor it.
14
14
  */
15
15
  export declare function sendSol({ from, to, amountSol, provider, rpcUrl, commitment, }: SendSolParams): Promise<string>;
16
+ type SendSplTokenParams = {
17
+ from: string;
18
+ to: string;
19
+ /** SPL mint address (base58). */
20
+ mint: string;
21
+ /** Amount in token base units (already scaled by `decimals`). */
22
+ amount: bigint;
23
+ decimals: number;
24
+ provider: OpenfortEmbeddedSolanaWalletProvider;
25
+ rpcUrl: string;
26
+ commitment?: 'processed' | 'confirmed' | 'finalized';
27
+ };
28
+ /**
29
+ * Build, sign, and broadcast an SPL token transfer. Creates the recipient's
30
+ * associated token account if it doesn't exist yet (idempotent — a no-op when it
31
+ * already holds the token; the sender pays the small rent). The wallet pays the
32
+ * network fee — use {@link sendSplTokenGasless} to sponsor it. Returns the
33
+ * transaction signature (base58).
34
+ */
35
+ export declare function sendSplToken({ from, to, mint, amount, decimals, provider, rpcUrl, commitment, }: SendSplTokenParams): Promise<string>;
16
36
  type SendSolGaslessParams = {
17
37
  from: string;
18
38
  to: string;
@@ -22,11 +42,20 @@ type SendSolGaslessParams = {
22
42
  /** Project publishable key; sent to the Openfort Solana paymaster (Kora) as a Bearer token. */
23
43
  publishableKey: string;
24
44
  };
25
- /**
26
- * Send a native SOL transfer with fees sponsored by the Openfort Solana paymaster
27
- * (Kora): Kora is the fee payer, the user signs their part with the embedded wallet,
28
- * and Kora co-signs + broadcasts. Requires a `sponsorSolTransaction` policy on the
29
- * project. Returns the transaction signature (base58).
30
- */
45
+ /** Send a native SOL transfer with fees sponsored by the Openfort paymaster (Kora). */
31
46
  export declare function sendSolGasless({ from, to, amountSol, provider, cluster, publishableKey, }: SendSolGaslessParams): Promise<string>;
47
+ type SendSplTokenGaslessParams = {
48
+ from: string;
49
+ to: string;
50
+ /** SPL mint address (base58). */
51
+ mint: string;
52
+ /** Amount in token base units (already scaled by `decimals`). */
53
+ amount: bigint;
54
+ provider: OpenfortEmbeddedSolanaWalletProvider;
55
+ cluster: SolanaCluster;
56
+ /** Project publishable key; sent to the Openfort Solana paymaster (Kora) as a Bearer token. */
57
+ publishableKey: string;
58
+ };
59
+ /** Send an SPL token transfer with fees sponsored by the Openfort paymaster (Kora). */
60
+ export declare function sendSplTokenGasless({ from, to, mint, amount, provider, cluster, publishableKey, }: SendSplTokenGaslessParams): Promise<string>;
32
61
  export {};
@@ -20,17 +20,11 @@ function deriveWssUrl(rpcUrl) {
20
20
  return rpcUrl.replace(/^https?:\/\//, 'wss://');
21
21
  }
22
22
  /**
23
- * Build, sign, and broadcast a native SOL transfer. Returns the transaction
24
- * signature (base58). The wallet pays the network fee use {@link sendSolGasless}
25
- * to sponsor it.
23
+ * A `TransactionSigner` that signs message bytes through the embedded wallet
24
+ * provider (Ed25519). Shared by the native and SPL non-sponsored paths.
26
25
  */
27
- async function sendSol({ from, to, amountSol, provider, rpcUrl, commitment = 'confirmed', }) {
28
- const kit = await import('@solana/kit');
29
- const { getTransferSolInstruction } = await import('@solana-program/system');
30
- const fromAddress = kit.address(from);
31
- const rpc = kit.createSolanaRpc(rpcUrl);
32
- const rpcSubscriptions = kit.createSolanaRpcSubscriptions(deriveWssUrl(rpcUrl));
33
- const signer = {
26
+ function createEmbeddedSigner(kit, provider, fromAddress) {
27
+ return {
34
28
  address: fromAddress,
35
29
  signTransactions: async (transactions) => Promise.all(transactions.map(async (transaction) => {
36
30
  const { signature } = await provider.signTransaction({
@@ -40,6 +34,19 @@ async function sendSol({ from, to, amountSol, provider, rpcUrl, commitment = 'co
40
34
  return Object.freeze({ [fromAddress]: bytes });
41
35
  })),
42
36
  };
37
+ }
38
+ /**
39
+ * Build, sign, and broadcast a native SOL transfer. Returns the transaction
40
+ * signature (base58). The wallet pays the network fee — use {@link sendSolGasless}
41
+ * to sponsor it.
42
+ */
43
+ async function sendSol({ from, to, amountSol, provider, rpcUrl, commitment = 'confirmed', }) {
44
+ const kit = await import('@solana/kit');
45
+ const { getTransferSolInstruction } = await import('@solana-program/system');
46
+ const fromAddress = kit.address(from);
47
+ const rpc = kit.createSolanaRpc(rpcUrl);
48
+ const rpcSubscriptions = kit.createSolanaRpcSubscriptions(deriveWssUrl(rpcUrl));
49
+ const signer = createEmbeddedSigner(kit, provider, fromAddress);
43
50
  const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
44
51
  const message = kit.pipe(kit.createTransactionMessage({ version: 0 }), (tx) => kit.setTransactionMessageFeePayer(fromAddress, tx), (tx) => kit.setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => kit.appendTransactionMessageInstruction(getTransferSolInstruction({
45
52
  source: signer,
@@ -61,28 +68,91 @@ async function sendSol({ from, to, amountSol, provider, rpcUrl, commitment = 'co
61
68
  }
62
69
  return kit.getSignatureFromTransaction(signedTransaction);
63
70
  }
71
+ /**
72
+ * Build, sign, and broadcast an SPL token transfer. Creates the recipient's
73
+ * associated token account if it doesn't exist yet (idempotent — a no-op when it
74
+ * already holds the token; the sender pays the small rent). The wallet pays the
75
+ * network fee — use {@link sendSplTokenGasless} to sponsor it. Returns the
76
+ * transaction signature (base58).
77
+ */
78
+ async function sendSplToken({ from, to, mint, amount, decimals, provider, rpcUrl, commitment = 'confirmed', }) {
79
+ const kit = await import('@solana/kit');
80
+ const token = await import('@solana-program/token');
81
+ const fromAddress = kit.address(from);
82
+ const toAddress = kit.address(to);
83
+ const mintAddress = kit.address(mint);
84
+ const rpc = kit.createSolanaRpc(rpcUrl);
85
+ const rpcSubscriptions = kit.createSolanaRpcSubscriptions(deriveWssUrl(rpcUrl));
86
+ const signer = createEmbeddedSigner(kit, provider, fromAddress);
87
+ const [sourceAta] = await token.findAssociatedTokenPda({
88
+ owner: fromAddress,
89
+ tokenProgram: token.TOKEN_PROGRAM_ADDRESS,
90
+ mint: mintAddress,
91
+ });
92
+ const [destinationAta] = await token.findAssociatedTokenPda({
93
+ owner: toAddress,
94
+ tokenProgram: token.TOKEN_PROGRAM_ADDRESS,
95
+ mint: mintAddress,
96
+ });
97
+ const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
98
+ const message = kit.pipe(kit.createTransactionMessage({ version: 0 }), (tx) => kit.setTransactionMessageFeePayer(fromAddress, tx), (tx) => kit.setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => kit.appendTransactionMessageInstructions([
99
+ token.getCreateAssociatedTokenIdempotentInstruction({
100
+ payer: signer,
101
+ ata: destinationAta,
102
+ owner: toAddress,
103
+ mint: mintAddress,
104
+ }),
105
+ token.getTransferCheckedInstruction({
106
+ source: sourceAta,
107
+ mint: mintAddress,
108
+ destination: destinationAta,
109
+ authority: signer,
110
+ amount,
111
+ decimals,
112
+ }),
113
+ ], tx));
114
+ const signedTransaction = await kit.signTransactionMessageWithSigners(message);
115
+ const sendAndConfirm = kit.sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
116
+ const abortController = new AbortController();
117
+ const timeout = setTimeout(() => abortController.abort(), SEND_TIMEOUT_MS);
118
+ try {
119
+ await sendAndConfirm(signedTransaction, {
120
+ commitment,
121
+ abortSignal: abortController.signal,
122
+ });
123
+ }
124
+ finally {
125
+ clearTimeout(timeout);
126
+ }
127
+ return kit.getSignatureFromTransaction(signedTransaction);
128
+ }
64
129
  /** The Openfort Solana paymaster (Kora) endpoint for a cluster. */
65
130
  function koraRpcUrl(cluster) {
66
131
  const segment = cluster === 'mainnet-beta' ? 'mainnet' : cluster;
67
132
  return `https://api.openfort.io/rpc/solana/${segment}`;
68
133
  }
69
134
  /**
70
- * Send a native SOL transfer with fees sponsored by the Openfort Solana paymaster
71
- * (Kora): Kora is the fee payer, the user signs their part with the embedded wallet,
72
- * and Kora co-signs + broadcasts. Requires a `sponsorSolTransaction` policy on the
135
+ * Sponsor a transfer through the Openfort Solana paymaster (Kora): Kora is the
136
+ * fee payer, the user signs their part with the embedded wallet, and Kora
137
+ * co-signs + broadcasts. Requires a `sponsorSolTransaction` policy on the
73
138
  * project. Returns the transaction signature (base58).
74
139
  */
75
- async function sendSolGasless({ from, to, amountSol, provider, cluster, publishableKey, }) {
140
+ async function sendViaKora({ from, to, amountBaseUnits, tokenMint, provider, cluster, publishableKey, }) {
141
+ // Kora's request takes a JS number; fail loudly rather than silently corrupt
142
+ // an amount that can't be represented exactly.
143
+ if (amountBaseUnits > BigInt(Number.MAX_SAFE_INTEGER)) {
144
+ throw new Error('Amount is too large to sponsor through the paymaster.');
145
+ }
76
146
  const kit = await import('@solana/kit');
77
147
  const { KoraClient } = await import('@solana/kora');
78
148
  const client = new KoraClient({ rpcUrl: koraRpcUrl(cluster), apiKey: `Bearer ${publishableKey}` });
79
149
  // 1. Kora's fee-payer signer.
80
150
  const { signer_address } = await client.getPayerSigner();
81
151
  const feePayer = kit.createNoopSigner(signer_address);
82
- // 2. A sponsored native SOL transfer, with Kora as the fee payer.
152
+ // 2. A sponsored transfer (native or SPL), with Kora as the fee payer.
83
153
  const { instructions } = await client.transferTransaction({
84
- amount: Number(solToLamports(amountSol)),
85
- token: SYSTEM_PROGRAM_ID,
154
+ amount: Number(amountBaseUnits),
155
+ token: tokenMint,
86
156
  source: from,
87
157
  destination: to,
88
158
  signer_key: signer_address,
@@ -120,6 +190,30 @@ async function sendSolGasless({ from, to, amountSol, provider, cluster, publisha
120
190
  }
121
191
  throw new Error('Failed to extract transaction signature from the Kora response');
122
192
  }
193
+ /** Send a native SOL transfer with fees sponsored by the Openfort paymaster (Kora). */
194
+ async function sendSolGasless({ from, to, amountSol, provider, cluster, publishableKey, }) {
195
+ return sendViaKora({
196
+ from,
197
+ to,
198
+ amountBaseUnits: solToLamports(amountSol),
199
+ tokenMint: SYSTEM_PROGRAM_ID,
200
+ provider,
201
+ cluster,
202
+ publishableKey,
203
+ });
204
+ }
205
+ /** Send an SPL token transfer with fees sponsored by the Openfort paymaster (Kora). */
206
+ async function sendSplTokenGasless({ from, to, mint, amount, provider, cluster, publishableKey, }) {
207
+ return sendViaKora({
208
+ from,
209
+ to,
210
+ amountBaseUnits: amount,
211
+ tokenMint: mint,
212
+ provider,
213
+ cluster,
214
+ publishableKey,
215
+ });
216
+ }
123
217
 
124
- export { sendSol, sendSolGasless };
218
+ export { sendSol, sendSolGasless, sendSplToken, sendSplTokenGasless };
125
219
  //# sourceMappingURL=transfer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transfer.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"transfer.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -47,6 +47,14 @@ export type SolanaConfig = {
47
47
  rpcUrls?: Partial<Record<'mainnet-beta' | 'devnet' | 'testnet', string>>;
48
48
  /** Commitment level for transactions (default: 'confirmed') */
49
49
  commitment?: SolanaCommitment;
50
+ /**
51
+ * Sponsor network fees for Solana sends through the Openfort paymaster (Kora).
52
+ * The SVM counterpart of `ethereum.ethereumFeeSponsorshipId`: when `true`, sends
53
+ * are routed gaslessly and the confirm screen marks the network fee as sponsored.
54
+ * Requires a `sponsorSolTransaction` policy on the project (resolved server-side
55
+ * from the publishable key). Defaults to `false` (user pays the fee).
56
+ */
57
+ sponsorFees?: boolean;
50
58
  /** UI options for Solana-connected screens */
51
59
  ui?: SolanaUIOptions;
52
60
  };
@@ -1 +1 @@
1
- export declare const OPENFORT_VERSION = "1.2.0";
1
+ export declare const OPENFORT_VERSION = "1.3.0";
package/build/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const OPENFORT_VERSION = '1.2.0';
1
+ const OPENFORT_VERSION = '1.3.0';
2
2
 
3
3
  export { OPENFORT_VERSION };
4
4
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/react",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "author": "Openfort (https://www.openfort.io)",
5
5
  "license": "BSD-2-Clause license",
6
6
  "description": "The easiest way to integrate Openfort to your project.",
@@ -84,6 +84,7 @@
84
84
  "@safe-global/safe-apps-provider": "~0.18.6",
85
85
  "@safe-global/safe-apps-sdk": "^9.1.0",
86
86
  "@solana-program/system": "^0.10.0",
87
+ "@solana-program/token": "^0.9.0",
87
88
  "@solana/kit": "^2.0.0 || ^5.0.0",
88
89
  "@solana/kora": "^0.1.1",
89
90
  "@walletconnect/ethereum-provider": "^2.21.1",
@@ -121,6 +122,9 @@
121
122
  "@solana-program/system": {
122
123
  "optional": true
123
124
  },
125
+ "@solana-program/token": {
126
+ "optional": true
127
+ },
124
128
  "@solana/kit": {
125
129
  "optional": true
126
130
  },