@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.
- package/build/assets/logos.d.ts +3 -0
- package/build/assets/logos.js +2 -0
- package/build/assets/logos.js.map +1 -1
- package/build/components/Common/SolanaChain/index.d.ts +8 -0
- package/build/components/Common/SolanaChain/index.js +40 -0
- package/build/components/Common/SolanaChain/index.js.map +1 -0
- package/build/components/ConnectModal/index.js +2 -0
- package/build/components/ConnectModal/index.js.map +1 -1
- package/build/components/Openfort/types.d.ts +17 -11
- package/build/components/Openfort/types.js +1 -0
- package/build/components/Openfort/types.js.map +1 -1
- package/build/components/Pages/Buy/coinbaseApi.d.ts +1 -1
- package/build/components/Pages/Buy/coinbaseApi.js +2 -13
- package/build/components/Pages/Buy/coinbaseApi.js.map +1 -1
- package/build/components/Pages/Buy/evmCurrencies.d.ts +11 -0
- package/build/components/Pages/Buy/evmCurrencies.js +27 -0
- package/build/components/Pages/Buy/evmCurrencies.js.map +1 -0
- package/build/components/Pages/Buy/index.js +8 -1
- package/build/components/Pages/Buy/index.js.map +1 -1
- package/build/components/Pages/Buy/onrampApi.d.ts +8 -1
- package/build/components/Pages/Buy/onrampApi.js +24 -14
- package/build/components/Pages/Buy/onrampApi.js.map +1 -1
- package/build/components/Pages/Buy/solanaCurrencies.d.ts +9 -0
- package/build/components/Pages/Buy/solanaCurrencies.js +25 -0
- package/build/components/Pages/Buy/solanaCurrencies.js.map +1 -0
- package/build/components/Pages/Buy/stripeApi.d.ts +1 -1
- package/build/components/Pages/Buy/stripeApi.js +2 -13
- package/build/components/Pages/Buy/stripeApi.js.map +1 -1
- package/build/components/Pages/BuyComplete/index.js +7 -1
- package/build/components/Pages/BuyComplete/index.js.map +1 -1
- package/build/components/Pages/BuyProcessing/index.js +9 -5
- package/build/components/Pages/BuyProcessing/index.js.map +1 -1
- package/build/components/Pages/BuySelectProvider/index.js +10 -5
- package/build/components/Pages/BuySelectProvider/index.js.map +1 -1
- package/build/components/Pages/Connected/SolanaConnected.js +3 -2
- package/build/components/Pages/Connected/SolanaConnected.js.map +1 -1
- package/build/components/Pages/Deposit/DepositProgress.js +3 -2
- package/build/components/Pages/Deposit/DepositProgress.js.map +1 -1
- package/build/components/Pages/Deposit/DepositSuccess.js +2 -1
- package/build/components/Pages/Deposit/DepositSuccess.js.map +1 -1
- package/build/components/Pages/Deposit/index.js +16 -2
- package/build/components/Pages/Deposit/index.js.map +1 -1
- package/build/components/Pages/Deposit/paymentOptions.js +3 -3
- package/build/components/Pages/Deposit/useDepositRoute.d.ts +0 -1
- package/build/components/Pages/Deposit/useDepositRoute.js +10 -11
- package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -1
- package/build/components/Pages/Deposit/useFundingTarget.d.ts +2 -4
- package/build/components/Pages/Deposit/useFundingTarget.js +3 -5
- package/build/components/Pages/Deposit/useFundingTarget.js.map +1 -1
- package/build/components/Pages/DepositCex/index.js +7 -8
- package/build/components/Pages/DepositCex/index.js.map +1 -1
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.d.ts +4 -1
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +11 -20
- package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -1
- package/build/components/Pages/DepositWallet/index.d.ts +5 -5
- package/build/components/Pages/DepositWallet/index.js +36 -31
- package/build/components/Pages/DepositWallet/index.js.map +1 -1
- package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +6 -4
- package/build/components/Pages/DepositWallet/walletDeeplinks.js +3 -1
- package/build/components/Pages/DepositWallet/walletDeeplinks.js.map +1 -1
- package/build/components/Pages/SelectToken/SolanaSelectToken.d.ts +1 -0
- package/build/components/Pages/SelectToken/SolanaSelectToken.js +50 -0
- package/build/components/Pages/SelectToken/SolanaSelectToken.js.map +1 -0
- package/build/components/Pages/SelectToken/index.js +13 -2
- package/build/components/Pages/SelectToken/index.js.map +1 -1
- package/build/components/Pages/Send/SolanaSend.js +32 -31
- package/build/components/Pages/Send/SolanaSend.js.map +1 -1
- package/build/components/Pages/Send/utils.js +4 -1
- package/build/components/Pages/Send/utils.js.map +1 -1
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +57 -13
- package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -1
- package/build/components/Pages/SendConfirmation/styles.d.ts +0 -5
- package/build/components/Pages/SendConfirmation/styles.js +1 -39
- package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
- package/build/hooks/openfort/useFunding.js +7 -7
- package/build/hooks/openfort/useFundingChains.js +4 -6
- package/build/hooks/openfort/useFundingChains.js.map +1 -1
- package/build/shared/hooks/useAsyncData.js +15 -2
- package/build/shared/hooks/useAsyncData.js.map +1 -1
- package/build/solana/transfer.d.ts +35 -6
- package/build/solana/transfer.js +112 -18
- package/build/solana/transfer.js.map +1 -1
- package/build/solana/types.d.ts +8 -0
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- 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
|
|
56
|
+
var _a, _b;
|
|
57
57
|
const { uiConfig, publishableKey } = useOpenfort();
|
|
58
58
|
const { client: coreClient } = useOpenfortCore();
|
|
59
|
-
// The
|
|
60
|
-
// the
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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: (
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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 {};
|
package/build/solana/transfer.js
CHANGED
|
@@ -20,17 +20,11 @@ function deriveWssUrl(rpcUrl) {
|
|
|
20
20
|
return rpcUrl.replace(/^https?:\/\//, 'wss://');
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
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
|
-
|
|
28
|
-
|
|
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
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
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
|
|
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
|
|
152
|
+
// 2. A sponsored transfer (native or SPL), with Kora as the fee payer.
|
|
83
153
|
const { instructions } = await client.transferTransaction({
|
|
84
|
-
amount: Number(
|
|
85
|
-
token:
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/solana/types.d.ts
CHANGED
|
@@ -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
|
};
|
package/build/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const OPENFORT_VERSION = "1.
|
|
1
|
+
export declare const OPENFORT_VERSION = "1.3.0";
|
package/build/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfort/react",
|
|
3
|
-
"version": "1.
|
|
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
|
},
|