@fogo/sessions-sdk 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/connection.d.ts +9 -6
- package/cjs/connection.js +40 -34
- package/cjs/context.d.ts +7 -2
- package/cjs/context.js +10 -5
- package/cjs/index.d.ts +5 -5
- package/cjs/index.js +21 -18
- package/esm/connection.d.ts +9 -6
- package/esm/connection.js +40 -34
- package/esm/context.d.ts +7 -2
- package/esm/context.js +9 -4
- package/esm/index.d.ts +5 -5
- package/esm/index.js +21 -18
- package/package.json +1 -1
package/cjs/connection.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Transaction, Instruction, TransactionWithLifetime } from "@solana/kit";
|
|
1
|
+
import type { Transaction, Instruction, TransactionWithLifetime, Rpc, GetLatestBlockhashApi } from "@solana/kit";
|
|
2
2
|
import type { TransactionError } from "@solana/web3.js";
|
|
3
3
|
import { Keypair, Connection as Web3Connection, TransactionInstruction, VersionedTransaction, PublicKey } from "@solana/web3.js";
|
|
4
4
|
export declare enum Network {
|
|
@@ -33,15 +33,18 @@ export declare const createSessionConnection: (options: {
|
|
|
33
33
|
sendToPaymaster: (transaction: Transaction) => Promise<TransactionResult>;
|
|
34
34
|
sponsor: PublicKey;
|
|
35
35
|
})) => {
|
|
36
|
-
rpc:
|
|
36
|
+
rpc: Rpc<import("@solana/kit").RequestAirdropApi & import("@solana/kit").GetAccountInfoApi & import("@solana/kit").GetBalanceApi & import("@solana/kit").GetBlockApi & import("@solana/kit").GetBlockCommitmentApi & import("@solana/kit").GetBlockHeightApi & import("@solana/kit").GetBlockProductionApi & import("@solana/kit").GetBlocksApi & import("@solana/kit").GetBlocksWithLimitApi & import("@solana/kit").GetBlockTimeApi & import("@solana/kit").GetClusterNodesApi & import("@solana/kit").GetEpochInfoApi & import("@solana/kit").GetEpochScheduleApi & import("@solana/kit").GetFeeForMessageApi & import("@solana/kit").GetFirstAvailableBlockApi & import("@solana/kit").GetGenesisHashApi & import("@solana/kit").GetHealthApi & import("@solana/kit").GetHighestSnapshotSlotApi & import("@solana/kit").GetIdentityApi & import("@solana/kit").GetInflationGovernorApi & import("@solana/kit").GetInflationRateApi & import("@solana/kit").GetInflationRewardApi & import("@solana/kit").GetLargestAccountsApi & GetLatestBlockhashApi & import("@solana/kit").GetLeaderScheduleApi & import("@solana/kit").GetMaxRetransmitSlotApi & import("@solana/kit").GetMaxShredInsertSlotApi & import("@solana/kit").GetMinimumBalanceForRentExemptionApi & import("@solana/kit").GetMultipleAccountsApi & import("@solana/kit").GetProgramAccountsApi & import("@solana/kit").GetRecentPerformanceSamplesApi & import("@solana/kit").GetRecentPrioritizationFeesApi & import("@solana/kit").GetSignaturesForAddressApi & import("@solana/kit").GetSignatureStatusesApi & import("@solana/kit").GetSlotApi & import("@solana/kit").GetSlotLeaderApi & import("@solana/kit").GetSlotLeadersApi & import("@solana/kit").GetStakeMinimumDelegationApi & import("@solana/kit").GetSupplyApi & import("@solana/kit").GetTokenAccountBalanceApi & import("@solana/kit").GetTokenAccountsByDelegateApi & import("@solana/kit").GetTokenAccountsByOwnerApi & import("@solana/kit").GetTokenLargestAccountsApi & import("@solana/kit").GetTokenSupplyApi & import("@solana/kit").GetTransactionApi & import("@solana/kit").GetTransactionCountApi & import("@solana/kit").GetVersionApi & import("@solana/kit").GetVoteAccountsApi & import("@solana/kit").IsBlockhashValidApi & import("@solana/kit").MinimumLedgerSlotApi & import("@solana/kit").SendTransactionApi & import("@solana/kit").SimulateTransactionApi>;
|
|
37
37
|
connection: Web3Connection;
|
|
38
38
|
network: Network;
|
|
39
39
|
getSolanaConnection: () => Promise<Web3Connection>;
|
|
40
|
-
sendToPaymaster: (domain: string,
|
|
41
|
-
addressLookupTable?: string | undefined;
|
|
42
|
-
extraSigners?: (CryptoKeyPair | Keypair)[] | undefined;
|
|
43
|
-
}) => Promise<TransactionResult>;
|
|
40
|
+
sendToPaymaster: (domain: string, sessionKey: CryptoKeyPair | undefined, instructions: TransactionOrInstructions, extraConfig?: SendTransactionOptions) => Promise<TransactionResult>;
|
|
44
41
|
getSponsor: (domain: string) => Promise<PublicKey>;
|
|
45
42
|
};
|
|
43
|
+
export type TransactionOrInstructions = (TransactionInstruction | Instruction)[] | VersionedTransaction | (Transaction & TransactionWithLifetime);
|
|
44
|
+
export type SendTransactionOptions = {
|
|
45
|
+
variation?: string | undefined;
|
|
46
|
+
addressLookupTable?: string | undefined;
|
|
47
|
+
extraSigners?: (CryptoKeyPair | Keypair)[] | undefined;
|
|
48
|
+
};
|
|
46
49
|
export type Connection = ReturnType<typeof createSessionConnection>;
|
|
47
50
|
export {};
|
package/cjs/connection.js
CHANGED
|
@@ -39,17 +39,14 @@ const createSessionConnection = (options) => {
|
|
|
39
39
|
const rpc = (0, kit_1.createSolanaRpc)(rpcUrl);
|
|
40
40
|
const connection = new web3_js_1.Connection(rpcUrl, "confirmed");
|
|
41
41
|
const addressLookupTableCache = new Map();
|
|
42
|
+
const sponsorCache = new Map();
|
|
42
43
|
return {
|
|
43
44
|
rpc,
|
|
44
45
|
connection,
|
|
45
46
|
network: options.network,
|
|
46
47
|
getSolanaConnection: createSolanaConnectionGetter(options.network),
|
|
47
|
-
sendToPaymaster: async (domain,
|
|
48
|
-
|
|
49
|
-
const transaction = await buildTransaction(connection, latestBlockhash, sessionKey, sponsor, instructions, addressLookupTableCache, extraConfig);
|
|
50
|
-
return sendToPaymaster(options, domain, transaction);
|
|
51
|
-
},
|
|
52
|
-
getSponsor: (domain) => getSponsor(options, domain),
|
|
48
|
+
sendToPaymaster: async (domain, sessionKey, instructions, extraConfig) => sendToPaymaster({ ...options, rpc, connection, addressLookupTableCache, sponsorCache }, domain, sessionKey, instructions, extraConfig),
|
|
49
|
+
getSponsor: (domain) => getSponsor(options, sponsorCache, domain),
|
|
53
50
|
};
|
|
54
51
|
};
|
|
55
52
|
exports.createSessionConnection = createSessionConnection;
|
|
@@ -75,10 +72,17 @@ const NETWORK_TO_QUERY_PARAM = {
|
|
|
75
72
|
[Network.Mainnet]: "mainnet",
|
|
76
73
|
[Network.Testnet]: "testnet",
|
|
77
74
|
};
|
|
78
|
-
const sendToPaymaster = async (
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
const sendToPaymaster = async (connection, domain, sessionKey, instructions, extraConfig) => {
|
|
76
|
+
const signerKeys = await getSignerKeys(sessionKey, extraConfig?.extraSigners);
|
|
77
|
+
const transaction = Array.isArray(instructions)
|
|
78
|
+
? await buildTransaction(connection, domain, signerKeys, instructions, extraConfig)
|
|
79
|
+
: await addSignaturesToExistingTransaction(instructions, signerKeys);
|
|
80
|
+
if (connection.sendToPaymaster === undefined) {
|
|
81
|
+
const url = new URL("/api/sponsor_and_send", connection.paymaster ?? DEFAULT_PAYMASTER[connection.network]);
|
|
81
82
|
url.searchParams.set("domain", domain);
|
|
83
|
+
if (extraConfig?.variation !== undefined) {
|
|
84
|
+
url.searchParams.set("variation", extraConfig.variation);
|
|
85
|
+
}
|
|
82
86
|
const response = await fetch(url, {
|
|
83
87
|
method: "POST",
|
|
84
88
|
headers: {
|
|
@@ -96,33 +100,31 @@ const sendToPaymaster = async (options, domain, transaction) => {
|
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
else {
|
|
99
|
-
return
|
|
103
|
+
return connection.sendToPaymaster(transaction);
|
|
100
104
|
}
|
|
101
105
|
};
|
|
102
|
-
const buildTransaction = async (connection,
|
|
103
|
-
const [
|
|
104
|
-
|
|
106
|
+
const buildTransaction = async (connection, domain, signerKeys, instructions, extraConfig) => {
|
|
107
|
+
const [{ value: latestBlockhash }, sponsor, addressLookupTable, signers] = await Promise.all([
|
|
108
|
+
connection.rpc.getLatestBlockhash().send(),
|
|
109
|
+
connection.sponsor === undefined
|
|
110
|
+
? getSponsor(connection, connection.sponsorCache, domain)
|
|
111
|
+
: Promise.resolve(connection.sponsor),
|
|
105
112
|
extraConfig?.addressLookupTable === undefined
|
|
106
113
|
? Promise.resolve(undefined)
|
|
107
|
-
: getAddressLookupTable(connection, addressLookupTableCache, extraConfig.addressLookupTable),
|
|
114
|
+
: getAddressLookupTable(connection.connection, connection.addressLookupTableCache, extraConfig.addressLookupTable),
|
|
115
|
+
Promise.all(signerKeys.map((signer) => (0, kit_1.createSignerFromKeyPair)(signer))),
|
|
108
116
|
]);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
[(0, compat_1.fromLegacyPublicKey)(addressLookupTable.key)]: addressLookupTable.state.addresses.map((address) => (0, compat_1.fromLegacyPublicKey)(address)),
|
|
117
|
-
}), (tx) => (0, kit_1.addSignersToTransactionMessage)(signers, tx)));
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
const tx = instructions instanceof web3_js_1.VersionedTransaction
|
|
121
|
-
? (0, compat_1.fromVersionedTransaction)(instructions) // VersionedTransaction has a lifetime so it's fine to cast it so we can call partiallySignTransaction
|
|
122
|
-
: instructions;
|
|
123
|
-
return (0, kit_1.partiallySignTransaction)(signerKeys, tx);
|
|
124
|
-
}
|
|
117
|
+
return (0, kit_1.partiallySignTransactionMessageWithSigners)((0, kit_1.pipe)((0, kit_1.createTransactionMessage)({ version: 0 }), (tx) => (0, kit_1.setTransactionMessageFeePayer)((0, compat_1.fromLegacyPublicKey)(sponsor), tx), (tx) => (0, kit_1.setTransactionMessageLifetimeUsingBlockhash)(latestBlockhash, tx), (tx) => (0, kit_1.appendTransactionMessageInstructions)(instructions.map((instruction) => instruction instanceof web3_js_1.TransactionInstruction
|
|
118
|
+
? (0, compat_1.fromLegacyTransactionInstruction)(instruction)
|
|
119
|
+
: instruction), tx), (tx) => addressLookupTable === undefined
|
|
120
|
+
? tx
|
|
121
|
+
: (0, kit_1.compressTransactionMessageUsingAddressLookupTables)(tx, {
|
|
122
|
+
[(0, compat_1.fromLegacyPublicKey)(addressLookupTable.key)]: addressLookupTable.state.addresses.map((address) => (0, compat_1.fromLegacyPublicKey)(address)),
|
|
123
|
+
}), (tx) => (0, kit_1.addSignersToTransactionMessage)(signers, tx)));
|
|
125
124
|
};
|
|
125
|
+
const addSignaturesToExistingTransaction = (transaction, signerKeys) => (0, kit_1.partiallySignTransaction)(signerKeys, transaction instanceof web3_js_1.VersionedTransaction
|
|
126
|
+
? (0, compat_1.fromVersionedTransaction)(transaction) // VersionedTransaction has a lifetime so it's fine to cast it so we can call partiallySignTransaction
|
|
127
|
+
: transaction);
|
|
126
128
|
const getSignerKeys = async (sessionKey, extraSigners) => {
|
|
127
129
|
const extraSignerKeys = extraSigners === undefined
|
|
128
130
|
? []
|
|
@@ -151,20 +153,24 @@ const sponsorAndSendResponseSchema = zod_1.z
|
|
|
151
153
|
? TransactionResult.Success(data.signature)
|
|
152
154
|
: TransactionResult.Failed(data.signature, data.error);
|
|
153
155
|
});
|
|
154
|
-
const getSponsor = async (options, domain) => {
|
|
155
|
-
|
|
156
|
+
const getSponsor = async (options, sponsorCache, domain) => {
|
|
157
|
+
const value = sponsorCache.get(domain);
|
|
158
|
+
if (value === undefined) {
|
|
156
159
|
const url = new URL("/api/sponsor_pubkey", options.paymaster ?? DEFAULT_PAYMASTER[options.network]);
|
|
157
160
|
url.searchParams.set("domain", domain);
|
|
161
|
+
url.searchParams.set("index", "autoassign");
|
|
158
162
|
const response = await fetch(url);
|
|
159
163
|
if (response.status === 200) {
|
|
160
|
-
|
|
164
|
+
const sponsor = new web3_js_1.PublicKey(zod_1.z.string().parse(await response.text()));
|
|
165
|
+
sponsorCache.set(domain, sponsor);
|
|
166
|
+
return sponsor;
|
|
161
167
|
}
|
|
162
168
|
else {
|
|
163
169
|
throw new PaymasterResponseError(response.status, await response.text());
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
172
|
else {
|
|
167
|
-
return
|
|
173
|
+
return value;
|
|
168
174
|
}
|
|
169
175
|
};
|
|
170
176
|
const getAddressLookupTable = async (connection, addressLookupTableCache, addressLookupTableAddress) => {
|
package/cjs/context.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Connection as Web3Connection } from "@solana/web3.js";
|
|
2
|
-
import type { Connection } from "./connection.js";
|
|
2
|
+
import type { Connection, SendTransactionOptions as SendTransactionBaseOptions, TransactionOrInstructions } from "./connection.js";
|
|
3
|
+
export declare const SESSIONS_INTERNAL_PAYMASTER_DOMAIN = "sessions";
|
|
3
4
|
export declare const createSessionContext: (options: {
|
|
4
5
|
connection: Connection;
|
|
5
6
|
defaultAddressLookupTableAddress?: string | undefined;
|
|
@@ -8,10 +9,14 @@ export declare const createSessionContext: (options: {
|
|
|
8
9
|
chainId: string;
|
|
9
10
|
domain: string;
|
|
10
11
|
payer: import("@solana/web3.js").PublicKey;
|
|
12
|
+
internalPayer: import("@solana/web3.js").PublicKey;
|
|
11
13
|
getSolanaConnection: () => Promise<Web3Connection>;
|
|
12
14
|
connection: Web3Connection;
|
|
13
15
|
rpc: import("@solana/kit").Rpc<import("@solana/kit").RequestAirdropApi & import("@solana/kit").GetAccountInfoApi & import("@solana/kit").GetBalanceApi & import("@solana/kit").GetBlockApi & import("@solana/kit").GetBlockCommitmentApi & import("@solana/kit").GetBlockHeightApi & import("@solana/kit").GetBlockProductionApi & import("@solana/kit").GetBlocksApi & import("@solana/kit").GetBlocksWithLimitApi & import("@solana/kit").GetBlockTimeApi & import("@solana/kit").GetClusterNodesApi & import("@solana/kit").GetEpochInfoApi & import("@solana/kit").GetEpochScheduleApi & import("@solana/kit").GetFeeForMessageApi & import("@solana/kit").GetFirstAvailableBlockApi & import("@solana/kit").GetGenesisHashApi & import("@solana/kit").GetHealthApi & import("@solana/kit").GetHighestSnapshotSlotApi & import("@solana/kit").GetIdentityApi & import("@solana/kit").GetInflationGovernorApi & import("@solana/kit").GetInflationRateApi & import("@solana/kit").GetInflationRewardApi & import("@solana/kit").GetLargestAccountsApi & import("@solana/kit").GetLatestBlockhashApi & import("@solana/kit").GetLeaderScheduleApi & import("@solana/kit").GetMaxRetransmitSlotApi & import("@solana/kit").GetMaxShredInsertSlotApi & import("@solana/kit").GetMinimumBalanceForRentExemptionApi & import("@solana/kit").GetMultipleAccountsApi & import("@solana/kit").GetProgramAccountsApi & import("@solana/kit").GetRecentPerformanceSamplesApi & import("@solana/kit").GetRecentPrioritizationFeesApi & import("@solana/kit").GetSignaturesForAddressApi & import("@solana/kit").GetSignatureStatusesApi & import("@solana/kit").GetSlotApi & import("@solana/kit").GetSlotLeaderApi & import("@solana/kit").GetSlotLeadersApi & import("@solana/kit").GetStakeMinimumDelegationApi & import("@solana/kit").GetSupplyApi & import("@solana/kit").GetTokenAccountBalanceApi & import("@solana/kit").GetTokenAccountsByDelegateApi & import("@solana/kit").GetTokenAccountsByOwnerApi & import("@solana/kit").GetTokenLargestAccountsApi & import("@solana/kit").GetTokenSupplyApi & import("@solana/kit").GetTransactionApi & import("@solana/kit").GetTransactionCountApi & import("@solana/kit").GetVersionApi & import("@solana/kit").GetVoteAccountsApi & import("@solana/kit").IsBlockhashValidApi & import("@solana/kit").MinimumLedgerSlotApi & import("@solana/kit").SendTransactionApi & import("@solana/kit").SimulateTransactionApi>;
|
|
14
16
|
network: import("./connection.js").Network;
|
|
15
|
-
sendTransaction: (sessionKey: CryptoKeyPair | undefined, instructions:
|
|
17
|
+
sendTransaction: (sessionKey: CryptoKeyPair | undefined, instructions: TransactionOrInstructions, sendTxOptions?: SendTransactionOptions) => Promise<import("./connection.js").TransactionResult>;
|
|
16
18
|
}>;
|
|
19
|
+
export type SendTransactionOptions = SendTransactionBaseOptions & {
|
|
20
|
+
paymasterDomain?: string | undefined;
|
|
21
|
+
};
|
|
17
22
|
export type SessionContext = Awaited<ReturnType<typeof createSessionContext>>;
|
package/cjs/context.js
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createSessionContext = void 0;
|
|
3
|
+
exports.createSessionContext = exports.SESSIONS_INTERNAL_PAYMASTER_DOMAIN = void 0;
|
|
4
4
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
5
|
const sessions_idls_1 = require("@fogo/sessions-idls");
|
|
6
6
|
const web3_js_1 = require("@solana/web3.js");
|
|
7
7
|
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
8
8
|
const IS_BROWSER = typeof globalThis.window !== "undefined";
|
|
9
|
+
exports.SESSIONS_INTERNAL_PAYMASTER_DOMAIN = "sessions";
|
|
9
10
|
const createSessionContext = async (options) => {
|
|
10
11
|
const domain = getDomain(options.domain);
|
|
11
|
-
const sponsor = await
|
|
12
|
+
const [sponsor, internalSponsor] = await Promise.all([
|
|
13
|
+
options.connection.getSponsor(domain),
|
|
14
|
+
options.connection.getSponsor(exports.SESSIONS_INTERNAL_PAYMASTER_DOMAIN),
|
|
15
|
+
]);
|
|
12
16
|
return {
|
|
13
17
|
chainId: await fetchChainId(options.connection.connection),
|
|
14
18
|
domain: getDomain(options.domain),
|
|
15
19
|
payer: sponsor,
|
|
20
|
+
internalPayer: internalSponsor,
|
|
16
21
|
getSolanaConnection: options.connection.getSolanaConnection,
|
|
17
22
|
connection: options.connection.connection,
|
|
18
23
|
rpc: options.connection.rpc,
|
|
19
24
|
network: options.connection.network,
|
|
20
|
-
sendTransaction: (sessionKey, instructions,
|
|
21
|
-
|
|
25
|
+
sendTransaction: (sessionKey, instructions, sendTxOptions) => options.connection.sendToPaymaster(sendTxOptions?.paymasterDomain ?? domain, sessionKey, instructions, {
|
|
26
|
+
...sendTxOptions,
|
|
27
|
+
addressLookupTable: sendTxOptions?.addressLookupTable ??
|
|
22
28
|
options.defaultAddressLookupTableAddress,
|
|
23
|
-
extraSigners: extraConfig?.extraSigners,
|
|
24
29
|
}),
|
|
25
30
|
};
|
|
26
31
|
};
|
package/cjs/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { Connection, PublicKey } from "@solana/web3.js";
|
|
|
4
4
|
import type { Chain } from "@wormhole-foundation/sdk";
|
|
5
5
|
import BN from "bn.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import type { TransactionResult } from "./connection.js";
|
|
8
|
-
import type { SessionContext } from "./context.js";
|
|
9
|
-
export { type SessionContext, createSessionContext } from "./context.js";
|
|
10
|
-
export { type TransactionResult, type Connection, Network, TransactionResultType, createSessionConnection, } from "./connection.js";
|
|
7
|
+
import type { TransactionOrInstructions, TransactionResult } from "./connection.js";
|
|
8
|
+
import type { SendTransactionOptions, SessionContext } from "./context.js";
|
|
9
|
+
export { type SessionContext, type SendTransactionOptions, createSessionContext, } from "./context.js";
|
|
10
|
+
export { type TransactionResult, type Connection, type TransactionOrInstructions, Network, TransactionResultType, createSessionConnection, } from "./connection.js";
|
|
11
11
|
type EstablishSessionOptions = {
|
|
12
12
|
context: SessionContext;
|
|
13
13
|
walletPublicKey: PublicKey;
|
|
@@ -1307,7 +1307,7 @@ export type Session = {
|
|
|
1307
1307
|
sessionKey: CryptoKeyPair;
|
|
1308
1308
|
walletPublicKey: PublicKey;
|
|
1309
1309
|
payer: PublicKey;
|
|
1310
|
-
sendTransaction: (instructions:
|
|
1310
|
+
sendTransaction: (instructions: TransactionOrInstructions, extraConfig?: SendTransactionOptions) => Promise<TransactionResult>;
|
|
1311
1311
|
sessionInfo: NonNullable<z.infer<typeof sessionInfoSchema>>;
|
|
1312
1312
|
};
|
|
1313
1313
|
export declare const getTransferFee: (context: SessionContext) => Promise<{
|
package/cjs/index.js
CHANGED
|
@@ -24,9 +24,10 @@ const bn_js_1 = __importDefault(require("bn.js"));
|
|
|
24
24
|
const bs58_1 = __importDefault(require("bs58"));
|
|
25
25
|
const zod_1 = require("zod");
|
|
26
26
|
const connection_js_1 = require("./connection.js");
|
|
27
|
+
const context_js_1 = require("./context.js");
|
|
27
28
|
const crypto_js_1 = require("./crypto.js");
|
|
28
|
-
var
|
|
29
|
-
Object.defineProperty(exports, "createSessionContext", { enumerable: true, get: function () { return
|
|
29
|
+
var context_js_2 = require("./context.js");
|
|
30
|
+
Object.defineProperty(exports, "createSessionContext", { enumerable: true, get: function () { return context_js_2.createSessionContext; } });
|
|
30
31
|
var connection_js_2 = require("./connection.js");
|
|
31
32
|
Object.defineProperty(exports, "Network", { enumerable: true, get: function () { return connection_js_2.Network; } });
|
|
32
33
|
Object.defineProperty(exports, "TransactionResultType", { enumerable: true, get: function () { return connection_js_2.TransactionResultType; } });
|
|
@@ -65,16 +66,13 @@ const establishSession = async (options) => {
|
|
|
65
66
|
buildIntentInstruction(options, sessionKey, tokenInfo),
|
|
66
67
|
buildStartSessionInstruction(options, sessionKey, tokenInfo),
|
|
67
68
|
]);
|
|
68
|
-
return sendSessionEstablishTransaction(options, sessionKey, [
|
|
69
|
-
...buildCreateAssociatedTokenAccountInstructions(options, tokenInfo),
|
|
70
|
-
intentInstruction,
|
|
71
|
-
startSessionInstruction,
|
|
72
|
-
], options.sessionEstablishmentLookupTable);
|
|
69
|
+
return sendSessionEstablishTransaction(options, sessionKey, [intentInstruction, startSessionInstruction], options.sessionEstablishmentLookupTable);
|
|
73
70
|
}
|
|
74
71
|
};
|
|
75
72
|
exports.establishSession = establishSession;
|
|
76
73
|
const sendSessionEstablishTransaction = async (options, sessionKey, instructions, sessionEstablishmentLookupTable) => {
|
|
77
74
|
const result = await options.context.sendTransaction(sessionKey, instructions, {
|
|
75
|
+
variation: "Session Establishment",
|
|
78
76
|
addressLookupTable: sessionEstablishmentLookupTable ??
|
|
79
77
|
SESSION_ESTABLISHMENT_LOOKUP_TABLE_ADDRESS[options.context.network],
|
|
80
78
|
});
|
|
@@ -104,9 +102,9 @@ const revokeSession = async (options) => {
|
|
|
104
102
|
session: options.session.sessionPublicKey,
|
|
105
103
|
})
|
|
106
104
|
.instruction();
|
|
107
|
-
return options.context.sendTransaction(options.session.sessionKey, [
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
return options.context.sendTransaction(options.session.sessionKey, [instruction], {
|
|
106
|
+
variation: "Session Revocation",
|
|
107
|
+
});
|
|
110
108
|
}
|
|
111
109
|
else {
|
|
112
110
|
return;
|
|
@@ -132,7 +130,7 @@ const createSession = async (context, walletPublicKey, sessionKey) => {
|
|
|
132
130
|
walletPublicKey,
|
|
133
131
|
sessionKey,
|
|
134
132
|
payer: context.payer,
|
|
135
|
-
sendTransaction: (instructions) => context.sendTransaction(sessionKey, instructions),
|
|
133
|
+
sendTransaction: (instructions, extraConfig) => context.sendTransaction(sessionKey, instructions, extraConfig),
|
|
136
134
|
sessionInfo,
|
|
137
135
|
};
|
|
138
136
|
};
|
|
@@ -435,7 +433,6 @@ const amountToString = (amount, decimals) => {
|
|
|
435
433
|
...(decimalTruncated === "" ? [] : [".", decimalTruncated]),
|
|
436
434
|
].join("");
|
|
437
435
|
};
|
|
438
|
-
const buildCreateAssociatedTokenAccountInstructions = (options, tokens) => tokens.map(({ mint }) => (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(options.context.payer, (0, spl_token_1.getAssociatedTokenAddressSync)(mint, options.walletPublicKey), options.walletPublicKey, mint));
|
|
439
436
|
const getDomainRecordAddress = (domain) => {
|
|
440
437
|
const hash = (0, sha2_1.sha256)(domain);
|
|
441
438
|
return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("domain-record"), hash], new web3_js_1.PublicKey(sessions_idls_1.DomainRegistryIdl.address))[0];
|
|
@@ -535,7 +532,7 @@ const getFee = async (context) => {
|
|
|
535
532
|
mint: (0, umi_1.publicKey)(usdcMintAddress),
|
|
536
533
|
})[0],
|
|
537
534
|
mint: usdcMint,
|
|
538
|
-
symbolOrMint:
|
|
535
|
+
symbolOrMint: "USDC.s",
|
|
539
536
|
decimals: USDC_DECIMALS,
|
|
540
537
|
fee: {
|
|
541
538
|
intrachainTransfer: BigInt(feeConfig.intrachainTransferFee.toString()),
|
|
@@ -565,12 +562,16 @@ const sendTransfer = async (options) => {
|
|
|
565
562
|
feeSource: (0, spl_token_1.getAssociatedTokenAddressSync)(options.feeConfig.mint, options.walletPublicKey),
|
|
566
563
|
mint: options.mint,
|
|
567
564
|
source: sourceAta,
|
|
568
|
-
sponsor: options.context.
|
|
565
|
+
sponsor: options.context.internalPayer,
|
|
566
|
+
metadata:
|
|
569
567
|
// eslint-disable-next-line unicorn/no-null
|
|
570
|
-
|
|
568
|
+
symbol === undefined ? null : new web3_js_1.PublicKey(metadataAddress),
|
|
571
569
|
})
|
|
572
570
|
.instruction(),
|
|
573
|
-
]
|
|
571
|
+
], {
|
|
572
|
+
variation: "Intent Transfer",
|
|
573
|
+
paymasterDomain: context_js_1.SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
|
|
574
|
+
});
|
|
574
575
|
};
|
|
575
576
|
exports.sendTransfer = sendTransfer;
|
|
576
577
|
const buildTransferIntentInstruction = async (program, options, symbol, feeToken, feeAmount) => {
|
|
@@ -622,10 +623,10 @@ const bridgeOut = async (options) => {
|
|
|
622
623
|
program.methods
|
|
623
624
|
.bridgeNttTokens({
|
|
624
625
|
payDestinationAtaRent: !destinationAtaExists,
|
|
625
|
-
signedQuoteBytes:
|
|
626
|
+
signedQuoteBytes: [...quote.signedQuote],
|
|
626
627
|
})
|
|
627
628
|
.accounts({
|
|
628
|
-
sponsor: options.context.
|
|
629
|
+
sponsor: options.context.internalPayer,
|
|
629
630
|
mint: options.fromToken.mint,
|
|
630
631
|
metadata: metadata?.symbol === undefined
|
|
631
632
|
? // eslint-disable-next-line unicorn/no-null
|
|
@@ -643,6 +644,8 @@ const bridgeOut = async (options) => {
|
|
|
643
644
|
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: BRIDGE_OUT_CUS }),
|
|
644
645
|
...instructions,
|
|
645
646
|
], {
|
|
647
|
+
variation: "Intent NTT Bridge",
|
|
648
|
+
paymasterDomain: context_js_1.SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
|
|
646
649
|
extraSigners: [outboxItem],
|
|
647
650
|
addressLookupTable: BRIDGING_ADDRESS_LOOKUP_TABLE[options.context.network]?.[options.fromToken.mint.toBase58()],
|
|
648
651
|
});
|
package/esm/connection.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Transaction, Instruction, TransactionWithLifetime } from "@solana/kit";
|
|
1
|
+
import type { Transaction, Instruction, TransactionWithLifetime, Rpc, GetLatestBlockhashApi } from "@solana/kit";
|
|
2
2
|
import type { TransactionError } from "@solana/web3.js";
|
|
3
3
|
import { Keypair, Connection as Web3Connection, TransactionInstruction, VersionedTransaction, PublicKey } from "@solana/web3.js";
|
|
4
4
|
export declare enum Network {
|
|
@@ -33,15 +33,18 @@ export declare const createSessionConnection: (options: {
|
|
|
33
33
|
sendToPaymaster: (transaction: Transaction) => Promise<TransactionResult>;
|
|
34
34
|
sponsor: PublicKey;
|
|
35
35
|
})) => {
|
|
36
|
-
rpc:
|
|
36
|
+
rpc: Rpc<import("@solana/kit").RequestAirdropApi & import("@solana/kit").GetAccountInfoApi & import("@solana/kit").GetBalanceApi & import("@solana/kit").GetBlockApi & import("@solana/kit").GetBlockCommitmentApi & import("@solana/kit").GetBlockHeightApi & import("@solana/kit").GetBlockProductionApi & import("@solana/kit").GetBlocksApi & import("@solana/kit").GetBlocksWithLimitApi & import("@solana/kit").GetBlockTimeApi & import("@solana/kit").GetClusterNodesApi & import("@solana/kit").GetEpochInfoApi & import("@solana/kit").GetEpochScheduleApi & import("@solana/kit").GetFeeForMessageApi & import("@solana/kit").GetFirstAvailableBlockApi & import("@solana/kit").GetGenesisHashApi & import("@solana/kit").GetHealthApi & import("@solana/kit").GetHighestSnapshotSlotApi & import("@solana/kit").GetIdentityApi & import("@solana/kit").GetInflationGovernorApi & import("@solana/kit").GetInflationRateApi & import("@solana/kit").GetInflationRewardApi & import("@solana/kit").GetLargestAccountsApi & GetLatestBlockhashApi & import("@solana/kit").GetLeaderScheduleApi & import("@solana/kit").GetMaxRetransmitSlotApi & import("@solana/kit").GetMaxShredInsertSlotApi & import("@solana/kit").GetMinimumBalanceForRentExemptionApi & import("@solana/kit").GetMultipleAccountsApi & import("@solana/kit").GetProgramAccountsApi & import("@solana/kit").GetRecentPerformanceSamplesApi & import("@solana/kit").GetRecentPrioritizationFeesApi & import("@solana/kit").GetSignaturesForAddressApi & import("@solana/kit").GetSignatureStatusesApi & import("@solana/kit").GetSlotApi & import("@solana/kit").GetSlotLeaderApi & import("@solana/kit").GetSlotLeadersApi & import("@solana/kit").GetStakeMinimumDelegationApi & import("@solana/kit").GetSupplyApi & import("@solana/kit").GetTokenAccountBalanceApi & import("@solana/kit").GetTokenAccountsByDelegateApi & import("@solana/kit").GetTokenAccountsByOwnerApi & import("@solana/kit").GetTokenLargestAccountsApi & import("@solana/kit").GetTokenSupplyApi & import("@solana/kit").GetTransactionApi & import("@solana/kit").GetTransactionCountApi & import("@solana/kit").GetVersionApi & import("@solana/kit").GetVoteAccountsApi & import("@solana/kit").IsBlockhashValidApi & import("@solana/kit").MinimumLedgerSlotApi & import("@solana/kit").SendTransactionApi & import("@solana/kit").SimulateTransactionApi>;
|
|
37
37
|
connection: Web3Connection;
|
|
38
38
|
network: Network;
|
|
39
39
|
getSolanaConnection: () => Promise<Web3Connection>;
|
|
40
|
-
sendToPaymaster: (domain: string,
|
|
41
|
-
addressLookupTable?: string | undefined;
|
|
42
|
-
extraSigners?: (CryptoKeyPair | Keypair)[] | undefined;
|
|
43
|
-
}) => Promise<TransactionResult>;
|
|
40
|
+
sendToPaymaster: (domain: string, sessionKey: CryptoKeyPair | undefined, instructions: TransactionOrInstructions, extraConfig?: SendTransactionOptions) => Promise<TransactionResult>;
|
|
44
41
|
getSponsor: (domain: string) => Promise<PublicKey>;
|
|
45
42
|
};
|
|
43
|
+
export type TransactionOrInstructions = (TransactionInstruction | Instruction)[] | VersionedTransaction | (Transaction & TransactionWithLifetime);
|
|
44
|
+
export type SendTransactionOptions = {
|
|
45
|
+
variation?: string | undefined;
|
|
46
|
+
addressLookupTable?: string | undefined;
|
|
47
|
+
extraSigners?: (CryptoKeyPair | Keypair)[] | undefined;
|
|
48
|
+
};
|
|
46
49
|
export type Connection = ReturnType<typeof createSessionConnection>;
|
|
47
50
|
export {};
|
package/esm/connection.js
CHANGED
|
@@ -36,17 +36,14 @@ export const createSessionConnection = (options) => {
|
|
|
36
36
|
const rpc = createSolanaRpc(rpcUrl);
|
|
37
37
|
const connection = new Web3Connection(rpcUrl, "confirmed");
|
|
38
38
|
const addressLookupTableCache = new Map();
|
|
39
|
+
const sponsorCache = new Map();
|
|
39
40
|
return {
|
|
40
41
|
rpc,
|
|
41
42
|
connection,
|
|
42
43
|
network: options.network,
|
|
43
44
|
getSolanaConnection: createSolanaConnectionGetter(options.network),
|
|
44
|
-
sendToPaymaster: async (domain,
|
|
45
|
-
|
|
46
|
-
const transaction = await buildTransaction(connection, latestBlockhash, sessionKey, sponsor, instructions, addressLookupTableCache, extraConfig);
|
|
47
|
-
return sendToPaymaster(options, domain, transaction);
|
|
48
|
-
},
|
|
49
|
-
getSponsor: (domain) => getSponsor(options, domain),
|
|
45
|
+
sendToPaymaster: async (domain, sessionKey, instructions, extraConfig) => sendToPaymaster({ ...options, rpc, connection, addressLookupTableCache, sponsorCache }, domain, sessionKey, instructions, extraConfig),
|
|
46
|
+
getSponsor: (domain) => getSponsor(options, sponsorCache, domain),
|
|
50
47
|
};
|
|
51
48
|
};
|
|
52
49
|
const createSolanaConnectionGetter = (network) => {
|
|
@@ -71,10 +68,17 @@ const NETWORK_TO_QUERY_PARAM = {
|
|
|
71
68
|
[Network.Mainnet]: "mainnet",
|
|
72
69
|
[Network.Testnet]: "testnet",
|
|
73
70
|
};
|
|
74
|
-
const sendToPaymaster = async (
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
const sendToPaymaster = async (connection, domain, sessionKey, instructions, extraConfig) => {
|
|
72
|
+
const signerKeys = await getSignerKeys(sessionKey, extraConfig?.extraSigners);
|
|
73
|
+
const transaction = Array.isArray(instructions)
|
|
74
|
+
? await buildTransaction(connection, domain, signerKeys, instructions, extraConfig)
|
|
75
|
+
: await addSignaturesToExistingTransaction(instructions, signerKeys);
|
|
76
|
+
if (connection.sendToPaymaster === undefined) {
|
|
77
|
+
const url = new URL("/api/sponsor_and_send", connection.paymaster ?? DEFAULT_PAYMASTER[connection.network]);
|
|
77
78
|
url.searchParams.set("domain", domain);
|
|
79
|
+
if (extraConfig?.variation !== undefined) {
|
|
80
|
+
url.searchParams.set("variation", extraConfig.variation);
|
|
81
|
+
}
|
|
78
82
|
const response = await fetch(url, {
|
|
79
83
|
method: "POST",
|
|
80
84
|
headers: {
|
|
@@ -92,33 +96,31 @@ const sendToPaymaster = async (options, domain, transaction) => {
|
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
else {
|
|
95
|
-
return
|
|
99
|
+
return connection.sendToPaymaster(transaction);
|
|
96
100
|
}
|
|
97
101
|
};
|
|
98
|
-
const buildTransaction = async (connection,
|
|
99
|
-
const [
|
|
100
|
-
|
|
102
|
+
const buildTransaction = async (connection, domain, signerKeys, instructions, extraConfig) => {
|
|
103
|
+
const [{ value: latestBlockhash }, sponsor, addressLookupTable, signers] = await Promise.all([
|
|
104
|
+
connection.rpc.getLatestBlockhash().send(),
|
|
105
|
+
connection.sponsor === undefined
|
|
106
|
+
? getSponsor(connection, connection.sponsorCache, domain)
|
|
107
|
+
: Promise.resolve(connection.sponsor),
|
|
101
108
|
extraConfig?.addressLookupTable === undefined
|
|
102
109
|
? Promise.resolve(undefined)
|
|
103
|
-
: getAddressLookupTable(connection, addressLookupTableCache, extraConfig.addressLookupTable),
|
|
110
|
+
: getAddressLookupTable(connection.connection, connection.addressLookupTableCache, extraConfig.addressLookupTable),
|
|
111
|
+
Promise.all(signerKeys.map((signer) => createSignerFromKeyPair(signer))),
|
|
104
112
|
]);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
[fromLegacyPublicKey(addressLookupTable.key)]: addressLookupTable.state.addresses.map((address) => fromLegacyPublicKey(address)),
|
|
113
|
-
}), (tx) => addSignersToTransactionMessage(signers, tx)));
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
const tx = instructions instanceof VersionedTransaction
|
|
117
|
-
? fromVersionedTransaction(instructions) // VersionedTransaction has a lifetime so it's fine to cast it so we can call partiallySignTransaction
|
|
118
|
-
: instructions;
|
|
119
|
-
return partiallySignTransaction(signerKeys, tx);
|
|
120
|
-
}
|
|
113
|
+
return partiallySignTransactionMessageWithSigners(pipe(createTransactionMessage({ version: 0 }), (tx) => setTransactionMessageFeePayer(fromLegacyPublicKey(sponsor), tx), (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions(instructions.map((instruction) => instruction instanceof TransactionInstruction
|
|
114
|
+
? fromLegacyTransactionInstruction(instruction)
|
|
115
|
+
: instruction), tx), (tx) => addressLookupTable === undefined
|
|
116
|
+
? tx
|
|
117
|
+
: compressTransactionMessageUsingAddressLookupTables(tx, {
|
|
118
|
+
[fromLegacyPublicKey(addressLookupTable.key)]: addressLookupTable.state.addresses.map((address) => fromLegacyPublicKey(address)),
|
|
119
|
+
}), (tx) => addSignersToTransactionMessage(signers, tx)));
|
|
121
120
|
};
|
|
121
|
+
const addSignaturesToExistingTransaction = (transaction, signerKeys) => partiallySignTransaction(signerKeys, transaction instanceof VersionedTransaction
|
|
122
|
+
? fromVersionedTransaction(transaction) // VersionedTransaction has a lifetime so it's fine to cast it so we can call partiallySignTransaction
|
|
123
|
+
: transaction);
|
|
122
124
|
const getSignerKeys = async (sessionKey, extraSigners) => {
|
|
123
125
|
const extraSignerKeys = extraSigners === undefined
|
|
124
126
|
? []
|
|
@@ -147,20 +149,24 @@ const sponsorAndSendResponseSchema = z
|
|
|
147
149
|
? TransactionResult.Success(data.signature)
|
|
148
150
|
: TransactionResult.Failed(data.signature, data.error);
|
|
149
151
|
});
|
|
150
|
-
const getSponsor = async (options, domain) => {
|
|
151
|
-
|
|
152
|
+
const getSponsor = async (options, sponsorCache, domain) => {
|
|
153
|
+
const value = sponsorCache.get(domain);
|
|
154
|
+
if (value === undefined) {
|
|
152
155
|
const url = new URL("/api/sponsor_pubkey", options.paymaster ?? DEFAULT_PAYMASTER[options.network]);
|
|
153
156
|
url.searchParams.set("domain", domain);
|
|
157
|
+
url.searchParams.set("index", "autoassign");
|
|
154
158
|
const response = await fetch(url);
|
|
155
159
|
if (response.status === 200) {
|
|
156
|
-
|
|
160
|
+
const sponsor = new PublicKey(z.string().parse(await response.text()));
|
|
161
|
+
sponsorCache.set(domain, sponsor);
|
|
162
|
+
return sponsor;
|
|
157
163
|
}
|
|
158
164
|
else {
|
|
159
165
|
throw new PaymasterResponseError(response.status, await response.text());
|
|
160
166
|
}
|
|
161
167
|
}
|
|
162
168
|
else {
|
|
163
|
-
return
|
|
169
|
+
return value;
|
|
164
170
|
}
|
|
165
171
|
};
|
|
166
172
|
const getAddressLookupTable = async (connection, addressLookupTableCache, addressLookupTableAddress) => {
|
package/esm/context.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Connection as Web3Connection } from "@solana/web3.js";
|
|
2
|
-
import type { Connection } from "./connection.js";
|
|
2
|
+
import type { Connection, SendTransactionOptions as SendTransactionBaseOptions, TransactionOrInstructions } from "./connection.js";
|
|
3
|
+
export declare const SESSIONS_INTERNAL_PAYMASTER_DOMAIN = "sessions";
|
|
3
4
|
export declare const createSessionContext: (options: {
|
|
4
5
|
connection: Connection;
|
|
5
6
|
defaultAddressLookupTableAddress?: string | undefined;
|
|
@@ -8,10 +9,14 @@ export declare const createSessionContext: (options: {
|
|
|
8
9
|
chainId: string;
|
|
9
10
|
domain: string;
|
|
10
11
|
payer: import("@solana/web3.js").PublicKey;
|
|
12
|
+
internalPayer: import("@solana/web3.js").PublicKey;
|
|
11
13
|
getSolanaConnection: () => Promise<Web3Connection>;
|
|
12
14
|
connection: Web3Connection;
|
|
13
15
|
rpc: import("@solana/kit").Rpc<import("@solana/kit").RequestAirdropApi & import("@solana/kit").GetAccountInfoApi & import("@solana/kit").GetBalanceApi & import("@solana/kit").GetBlockApi & import("@solana/kit").GetBlockCommitmentApi & import("@solana/kit").GetBlockHeightApi & import("@solana/kit").GetBlockProductionApi & import("@solana/kit").GetBlocksApi & import("@solana/kit").GetBlocksWithLimitApi & import("@solana/kit").GetBlockTimeApi & import("@solana/kit").GetClusterNodesApi & import("@solana/kit").GetEpochInfoApi & import("@solana/kit").GetEpochScheduleApi & import("@solana/kit").GetFeeForMessageApi & import("@solana/kit").GetFirstAvailableBlockApi & import("@solana/kit").GetGenesisHashApi & import("@solana/kit").GetHealthApi & import("@solana/kit").GetHighestSnapshotSlotApi & import("@solana/kit").GetIdentityApi & import("@solana/kit").GetInflationGovernorApi & import("@solana/kit").GetInflationRateApi & import("@solana/kit").GetInflationRewardApi & import("@solana/kit").GetLargestAccountsApi & import("@solana/kit").GetLatestBlockhashApi & import("@solana/kit").GetLeaderScheduleApi & import("@solana/kit").GetMaxRetransmitSlotApi & import("@solana/kit").GetMaxShredInsertSlotApi & import("@solana/kit").GetMinimumBalanceForRentExemptionApi & import("@solana/kit").GetMultipleAccountsApi & import("@solana/kit").GetProgramAccountsApi & import("@solana/kit").GetRecentPerformanceSamplesApi & import("@solana/kit").GetRecentPrioritizationFeesApi & import("@solana/kit").GetSignaturesForAddressApi & import("@solana/kit").GetSignatureStatusesApi & import("@solana/kit").GetSlotApi & import("@solana/kit").GetSlotLeaderApi & import("@solana/kit").GetSlotLeadersApi & import("@solana/kit").GetStakeMinimumDelegationApi & import("@solana/kit").GetSupplyApi & import("@solana/kit").GetTokenAccountBalanceApi & import("@solana/kit").GetTokenAccountsByDelegateApi & import("@solana/kit").GetTokenAccountsByOwnerApi & import("@solana/kit").GetTokenLargestAccountsApi & import("@solana/kit").GetTokenSupplyApi & import("@solana/kit").GetTransactionApi & import("@solana/kit").GetTransactionCountApi & import("@solana/kit").GetVersionApi & import("@solana/kit").GetVoteAccountsApi & import("@solana/kit").IsBlockhashValidApi & import("@solana/kit").MinimumLedgerSlotApi & import("@solana/kit").SendTransactionApi & import("@solana/kit").SimulateTransactionApi>;
|
|
14
16
|
network: import("./connection.js").Network;
|
|
15
|
-
sendTransaction: (sessionKey: CryptoKeyPair | undefined, instructions:
|
|
17
|
+
sendTransaction: (sessionKey: CryptoKeyPair | undefined, instructions: TransactionOrInstructions, sendTxOptions?: SendTransactionOptions) => Promise<import("./connection.js").TransactionResult>;
|
|
16
18
|
}>;
|
|
19
|
+
export type SendTransactionOptions = SendTransactionBaseOptions & {
|
|
20
|
+
paymasterDomain?: string | undefined;
|
|
21
|
+
};
|
|
17
22
|
export type SessionContext = Awaited<ReturnType<typeof createSessionContext>>;
|
package/esm/context.js
CHANGED
|
@@ -3,21 +3,26 @@ import { ChainIdProgram } from "@fogo/sessions-idls";
|
|
|
3
3
|
import { Connection as Web3Connection, Keypair } from "@solana/web3.js";
|
|
4
4
|
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
5
5
|
const IS_BROWSER = typeof globalThis.window !== "undefined";
|
|
6
|
+
export const SESSIONS_INTERNAL_PAYMASTER_DOMAIN = "sessions";
|
|
6
7
|
export const createSessionContext = async (options) => {
|
|
7
8
|
const domain = getDomain(options.domain);
|
|
8
|
-
const sponsor = await
|
|
9
|
+
const [sponsor, internalSponsor] = await Promise.all([
|
|
10
|
+
options.connection.getSponsor(domain),
|
|
11
|
+
options.connection.getSponsor(SESSIONS_INTERNAL_PAYMASTER_DOMAIN),
|
|
12
|
+
]);
|
|
9
13
|
return {
|
|
10
14
|
chainId: await fetchChainId(options.connection.connection),
|
|
11
15
|
domain: getDomain(options.domain),
|
|
12
16
|
payer: sponsor,
|
|
17
|
+
internalPayer: internalSponsor,
|
|
13
18
|
getSolanaConnection: options.connection.getSolanaConnection,
|
|
14
19
|
connection: options.connection.connection,
|
|
15
20
|
rpc: options.connection.rpc,
|
|
16
21
|
network: options.connection.network,
|
|
17
|
-
sendTransaction: (sessionKey, instructions,
|
|
18
|
-
|
|
22
|
+
sendTransaction: (sessionKey, instructions, sendTxOptions) => options.connection.sendToPaymaster(sendTxOptions?.paymasterDomain ?? domain, sessionKey, instructions, {
|
|
23
|
+
...sendTxOptions,
|
|
24
|
+
addressLookupTable: sendTxOptions?.addressLookupTable ??
|
|
19
25
|
options.defaultAddressLookupTableAddress,
|
|
20
|
-
extraSigners: extraConfig?.extraSigners,
|
|
21
26
|
}),
|
|
22
27
|
};
|
|
23
28
|
};
|
package/esm/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { Connection, PublicKey } from "@solana/web3.js";
|
|
|
4
4
|
import type { Chain } from "@wormhole-foundation/sdk";
|
|
5
5
|
import BN from "bn.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import type { TransactionResult } from "./connection.js";
|
|
8
|
-
import type { SessionContext } from "./context.js";
|
|
9
|
-
export { type SessionContext, createSessionContext } from "./context.js";
|
|
10
|
-
export { type TransactionResult, type Connection, Network, TransactionResultType, createSessionConnection, } from "./connection.js";
|
|
7
|
+
import type { TransactionOrInstructions, TransactionResult } from "./connection.js";
|
|
8
|
+
import type { SendTransactionOptions, SessionContext } from "./context.js";
|
|
9
|
+
export { type SessionContext, type SendTransactionOptions, createSessionContext, } from "./context.js";
|
|
10
|
+
export { type TransactionResult, type Connection, type TransactionOrInstructions, Network, TransactionResultType, createSessionConnection, } from "./connection.js";
|
|
11
11
|
type EstablishSessionOptions = {
|
|
12
12
|
context: SessionContext;
|
|
13
13
|
walletPublicKey: PublicKey;
|
|
@@ -1307,7 +1307,7 @@ export type Session = {
|
|
|
1307
1307
|
sessionKey: CryptoKeyPair;
|
|
1308
1308
|
walletPublicKey: PublicKey;
|
|
1309
1309
|
payer: PublicKey;
|
|
1310
|
-
sendTransaction: (instructions:
|
|
1310
|
+
sendTransaction: (instructions: TransactionOrInstructions, extraConfig?: SendTransactionOptions) => Promise<TransactionResult>;
|
|
1311
1311
|
sessionInfo: NonNullable<z.infer<typeof sessionInfoSchema>>;
|
|
1312
1312
|
};
|
|
1313
1313
|
export declare const getTransferFee: (context: SessionContext) => Promise<{
|
package/esm/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
|
|
6
6
|
import { sha256 } from "@noble/hashes/sha2";
|
|
7
7
|
import { fromLegacyPublicKey } from "@solana/compat";
|
|
8
8
|
import { generateKeyPair, getAddressFromPublicKey, getProgramDerivedAddress, signatureBytes, verifySignature, } from "@solana/kit";
|
|
9
|
-
import {
|
|
9
|
+
import { getAssociatedTokenAddressSync, getMint } from "@solana/spl-token";
|
|
10
10
|
import { ComputeBudgetProgram, Connection, Ed25519Program, Keypair, PublicKey, } from "@solana/web3.js";
|
|
11
11
|
import { Wormhole, wormhole, routes } from "@wormhole-foundation/sdk";
|
|
12
12
|
import solanaSdk from "@wormhole-foundation/sdk/solana";
|
|
@@ -18,8 +18,9 @@ import BN from "bn.js";
|
|
|
18
18
|
import bs58 from "bs58";
|
|
19
19
|
import { z } from "zod";
|
|
20
20
|
import { Network, TransactionResultType } from "./connection.js";
|
|
21
|
+
import { SESSIONS_INTERNAL_PAYMASTER_DOMAIN } from "./context.js";
|
|
21
22
|
import { importKey, signMessageWithKey, verifyMessageWithKey, } from "./crypto.js";
|
|
22
|
-
export { createSessionContext } from "./context.js";
|
|
23
|
+
export { createSessionContext, } from "./context.js";
|
|
23
24
|
export { Network, TransactionResultType, createSessionConnection, } from "./connection.js";
|
|
24
25
|
const MESSAGE_HEADER = `Fogo Sessions:
|
|
25
26
|
Signing this intent will allow this app to interact with your on-chain balances. Please make sure you trust this app and the domain in the message matches the domain of the current web application.
|
|
@@ -55,15 +56,12 @@ export const establishSession = async (options) => {
|
|
|
55
56
|
buildIntentInstruction(options, sessionKey, tokenInfo),
|
|
56
57
|
buildStartSessionInstruction(options, sessionKey, tokenInfo),
|
|
57
58
|
]);
|
|
58
|
-
return sendSessionEstablishTransaction(options, sessionKey, [
|
|
59
|
-
...buildCreateAssociatedTokenAccountInstructions(options, tokenInfo),
|
|
60
|
-
intentInstruction,
|
|
61
|
-
startSessionInstruction,
|
|
62
|
-
], options.sessionEstablishmentLookupTable);
|
|
59
|
+
return sendSessionEstablishTransaction(options, sessionKey, [intentInstruction, startSessionInstruction], options.sessionEstablishmentLookupTable);
|
|
63
60
|
}
|
|
64
61
|
};
|
|
65
62
|
const sendSessionEstablishTransaction = async (options, sessionKey, instructions, sessionEstablishmentLookupTable) => {
|
|
66
63
|
const result = await options.context.sendTransaction(sessionKey, instructions, {
|
|
64
|
+
variation: "Session Establishment",
|
|
67
65
|
addressLookupTable: sessionEstablishmentLookupTable ??
|
|
68
66
|
SESSION_ESTABLISHMENT_LOOKUP_TABLE_ADDRESS[options.context.network],
|
|
69
67
|
});
|
|
@@ -92,9 +90,9 @@ export const revokeSession = async (options) => {
|
|
|
92
90
|
session: options.session.sessionPublicKey,
|
|
93
91
|
})
|
|
94
92
|
.instruction();
|
|
95
|
-
return options.context.sendTransaction(options.session.sessionKey, [
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
return options.context.sendTransaction(options.session.sessionKey, [instruction], {
|
|
94
|
+
variation: "Session Revocation",
|
|
95
|
+
});
|
|
98
96
|
}
|
|
99
97
|
else {
|
|
100
98
|
return;
|
|
@@ -117,7 +115,7 @@ const createSession = async (context, walletPublicKey, sessionKey) => {
|
|
|
117
115
|
walletPublicKey,
|
|
118
116
|
sessionKey,
|
|
119
117
|
payer: context.payer,
|
|
120
|
-
sendTransaction: (instructions) => context.sendTransaction(sessionKey, instructions),
|
|
118
|
+
sendTransaction: (instructions, extraConfig) => context.sendTransaction(sessionKey, instructions, extraConfig),
|
|
121
119
|
sessionInfo,
|
|
122
120
|
};
|
|
123
121
|
};
|
|
@@ -420,7 +418,6 @@ const amountToString = (amount, decimals) => {
|
|
|
420
418
|
...(decimalTruncated === "" ? [] : [".", decimalTruncated]),
|
|
421
419
|
].join("");
|
|
422
420
|
};
|
|
423
|
-
const buildCreateAssociatedTokenAccountInstructions = (options, tokens) => tokens.map(({ mint }) => createAssociatedTokenAccountIdempotentInstruction(options.context.payer, getAssociatedTokenAddressSync(mint, options.walletPublicKey), options.walletPublicKey, mint));
|
|
424
421
|
export const getDomainRecordAddress = (domain) => {
|
|
425
422
|
const hash = sha256(domain);
|
|
426
423
|
return PublicKey.findProgramAddressSync([Buffer.from("domain-record"), hash], new PublicKey(DomainRegistryIdl.address))[0];
|
|
@@ -517,7 +514,7 @@ const getFee = async (context) => {
|
|
|
517
514
|
mint: metaplexPublicKey(usdcMintAddress),
|
|
518
515
|
})[0],
|
|
519
516
|
mint: usdcMint,
|
|
520
|
-
symbolOrMint:
|
|
517
|
+
symbolOrMint: "USDC.s",
|
|
521
518
|
decimals: USDC_DECIMALS,
|
|
522
519
|
fee: {
|
|
523
520
|
intrachainTransfer: BigInt(feeConfig.intrachainTransferFee.toString()),
|
|
@@ -547,12 +544,16 @@ export const sendTransfer = async (options) => {
|
|
|
547
544
|
feeSource: getAssociatedTokenAddressSync(options.feeConfig.mint, options.walletPublicKey),
|
|
548
545
|
mint: options.mint,
|
|
549
546
|
source: sourceAta,
|
|
550
|
-
sponsor: options.context.
|
|
547
|
+
sponsor: options.context.internalPayer,
|
|
548
|
+
metadata:
|
|
551
549
|
// eslint-disable-next-line unicorn/no-null
|
|
552
|
-
|
|
550
|
+
symbol === undefined ? null : new PublicKey(metadataAddress),
|
|
553
551
|
})
|
|
554
552
|
.instruction(),
|
|
555
|
-
]
|
|
553
|
+
], {
|
|
554
|
+
variation: "Intent Transfer",
|
|
555
|
+
paymasterDomain: SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
|
|
556
|
+
});
|
|
556
557
|
};
|
|
557
558
|
const buildTransferIntentInstruction = async (program, options, symbol, feeToken, feeAmount) => {
|
|
558
559
|
const [nonce, { decimals }] = await Promise.all([
|
|
@@ -603,10 +604,10 @@ export const bridgeOut = async (options) => {
|
|
|
603
604
|
program.methods
|
|
604
605
|
.bridgeNttTokens({
|
|
605
606
|
payDestinationAtaRent: !destinationAtaExists,
|
|
606
|
-
signedQuoteBytes:
|
|
607
|
+
signedQuoteBytes: [...quote.signedQuote],
|
|
607
608
|
})
|
|
608
609
|
.accounts({
|
|
609
|
-
sponsor: options.context.
|
|
610
|
+
sponsor: options.context.internalPayer,
|
|
610
611
|
mint: options.fromToken.mint,
|
|
611
612
|
metadata: metadata?.symbol === undefined
|
|
612
613
|
? // eslint-disable-next-line unicorn/no-null
|
|
@@ -624,6 +625,8 @@ export const bridgeOut = async (options) => {
|
|
|
624
625
|
ComputeBudgetProgram.setComputeUnitLimit({ units: BRIDGE_OUT_CUS }),
|
|
625
626
|
...instructions,
|
|
626
627
|
], {
|
|
628
|
+
variation: "Intent NTT Bridge",
|
|
629
|
+
paymasterDomain: SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
|
|
627
630
|
extraSigners: [outboxItem],
|
|
628
631
|
addressLookupTable: BRIDGING_ADDRESS_LOOKUP_TABLE[options.context.network]?.[options.fromToken.mint.toBase58()],
|
|
629
632
|
});
|