@fogo/sessions-sdk 0.0.25 → 0.0.29
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.js +2 -2
- package/cjs/index.d.ts +1026 -99
- package/cjs/index.js +102 -123
- package/esm/connection.js +2 -2
- package/esm/index.d.ts +1026 -99
- package/esm/index.js +103 -124
- package/package.json +8 -3
package/esm/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { publicKey as metaplexPublicKey } from "@metaplex-foundation/umi";
|
|
|
5
5
|
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
|
6
6
|
import { sha256 } from "@noble/hashes/sha2";
|
|
7
7
|
import { fromLegacyPublicKey } from "@solana/compat";
|
|
8
|
-
import { generateKeyPair, getAddressFromPublicKey, getProgramDerivedAddress,
|
|
8
|
+
import { generateKeyPair, getAddressFromPublicKey, getProgramDerivedAddress, } from "@solana/kit";
|
|
9
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";
|
|
@@ -43,7 +43,7 @@ export const establishSession = async (options) => {
|
|
|
43
43
|
: await generateKeyPair();
|
|
44
44
|
if (options.unlimited) {
|
|
45
45
|
return sendSessionEstablishTransaction(options, sessionKey, await Promise.all([
|
|
46
|
-
|
|
46
|
+
buildStartSessionIntentInstruction(options, sessionKey),
|
|
47
47
|
buildStartSessionInstruction(options, sessionKey),
|
|
48
48
|
]), options.sessionEstablishmentLookupTable);
|
|
49
49
|
}
|
|
@@ -53,7 +53,7 @@ export const establishSession = async (options) => {
|
|
|
53
53
|
? await getTokenInfo(options.context, filteredLimits)
|
|
54
54
|
: [];
|
|
55
55
|
const [intentInstruction, startSessionInstruction] = await Promise.all([
|
|
56
|
-
|
|
56
|
+
buildStartSessionIntentInstruction(options, sessionKey, tokenInfo),
|
|
57
57
|
buildStartSessionInstruction(options, sessionKey, tokenInfo),
|
|
58
58
|
]);
|
|
59
59
|
return sendSessionEstablishTransaction(options, sessionKey, [intentInstruction, startSessionInstruction], options.sessionEstablishmentLookupTable);
|
|
@@ -119,6 +119,47 @@ const createSession = async (context, walletPublicKey, sessionKey) => {
|
|
|
119
119
|
sessionInfo,
|
|
120
120
|
};
|
|
121
121
|
};
|
|
122
|
+
const authorizedTokensSchema = z.union([
|
|
123
|
+
z.object({
|
|
124
|
+
Specific: z.object({
|
|
125
|
+
"0": z.array(z.instanceof(PublicKey)),
|
|
126
|
+
}),
|
|
127
|
+
}),
|
|
128
|
+
z.object({ All: z.object({}) }),
|
|
129
|
+
]);
|
|
130
|
+
const revokedSessionInfoSchema = z.object({
|
|
131
|
+
user: z.instanceof(PublicKey),
|
|
132
|
+
expiration: z.instanceof(BN),
|
|
133
|
+
authorized_tokens_with_mints: authorizedTokensSchema,
|
|
134
|
+
});
|
|
135
|
+
const activeSessionInfoSchema = z.object({
|
|
136
|
+
authorized_programs: z.union([
|
|
137
|
+
z.object({
|
|
138
|
+
Specific: z.object({
|
|
139
|
+
0: z.array(z.object({
|
|
140
|
+
program_id: z.instanceof(PublicKey),
|
|
141
|
+
signer_pda: z.instanceof(PublicKey),
|
|
142
|
+
})),
|
|
143
|
+
}),
|
|
144
|
+
}),
|
|
145
|
+
z.object({
|
|
146
|
+
All: z.object({}),
|
|
147
|
+
}),
|
|
148
|
+
]),
|
|
149
|
+
authorized_tokens: z.union([
|
|
150
|
+
z.object({
|
|
151
|
+
Specific: z.object({
|
|
152
|
+
"0": z.array(z.instanceof(PublicKey)),
|
|
153
|
+
}),
|
|
154
|
+
}),
|
|
155
|
+
z.object({ All: z.object({}) }),
|
|
156
|
+
]),
|
|
157
|
+
expiration: z.instanceof(BN),
|
|
158
|
+
extra: z.object({
|
|
159
|
+
0: z.unknown(),
|
|
160
|
+
}),
|
|
161
|
+
user: z.instanceof(PublicKey),
|
|
162
|
+
});
|
|
122
163
|
const sessionInfoSchema = z
|
|
123
164
|
.object({
|
|
124
165
|
session_info: z.union([
|
|
@@ -191,37 +232,31 @@ const sessionInfoSchema = z
|
|
|
191
232
|
V3: z.object({
|
|
192
233
|
"0": z.union([
|
|
193
234
|
z.object({
|
|
194
|
-
Revoked: z.
|
|
235
|
+
Revoked: z.object({
|
|
236
|
+
"0": revokedSessionInfoSchema,
|
|
237
|
+
}),
|
|
238
|
+
}),
|
|
239
|
+
z.object({
|
|
240
|
+
Active: z.object({
|
|
241
|
+
"0": activeSessionInfoSchema,
|
|
242
|
+
}),
|
|
243
|
+
}),
|
|
244
|
+
]),
|
|
245
|
+
}),
|
|
246
|
+
}),
|
|
247
|
+
z.object({
|
|
248
|
+
V4: z.object({
|
|
249
|
+
"0": z.union([
|
|
250
|
+
z.object({
|
|
251
|
+
Revoked: z.object({
|
|
252
|
+
"0": revokedSessionInfoSchema,
|
|
253
|
+
}),
|
|
195
254
|
}),
|
|
196
255
|
z.object({
|
|
197
256
|
Active: z.object({
|
|
198
257
|
"0": z.object({
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Specific: z.object({
|
|
202
|
-
0: z.array(z.object({
|
|
203
|
-
program_id: z.instanceof(PublicKey),
|
|
204
|
-
signer_pda: z.instanceof(PublicKey),
|
|
205
|
-
})),
|
|
206
|
-
}),
|
|
207
|
-
}),
|
|
208
|
-
z.object({
|
|
209
|
-
All: z.object({}),
|
|
210
|
-
}),
|
|
211
|
-
]),
|
|
212
|
-
authorized_tokens: z.union([
|
|
213
|
-
z.object({
|
|
214
|
-
Specific: z.object({
|
|
215
|
-
"0": z.array(z.instanceof(PublicKey)),
|
|
216
|
-
}),
|
|
217
|
-
}),
|
|
218
|
-
z.object({ All: z.object({}) }),
|
|
219
|
-
]),
|
|
220
|
-
expiration: z.instanceof(BN),
|
|
221
|
-
extra: z.object({
|
|
222
|
-
0: z.unknown(),
|
|
223
|
-
}),
|
|
224
|
-
user: z.instanceof(PublicKey),
|
|
258
|
+
domain_hash: z.array(z.number()).length(32),
|
|
259
|
+
active_session_info: activeSessionInfoSchema,
|
|
225
260
|
}),
|
|
226
261
|
}),
|
|
227
262
|
}),
|
|
@@ -247,6 +282,10 @@ const sessionInfoSchema = z
|
|
|
247
282
|
activeSessionInfo = session_info.V3["0"].Active["0"];
|
|
248
283
|
minor = 3;
|
|
249
284
|
}
|
|
285
|
+
else if ("V4" in session_info && "Active" in session_info.V4["0"]) {
|
|
286
|
+
activeSessionInfo = session_info.V4["0"].Active["0"].active_session_info;
|
|
287
|
+
minor = 4;
|
|
288
|
+
}
|
|
250
289
|
else {
|
|
251
290
|
return;
|
|
252
291
|
}
|
|
@@ -320,64 +359,23 @@ const getTokenInfo = async (context, limits) => {
|
|
|
320
359
|
};
|
|
321
360
|
}));
|
|
322
361
|
};
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
// Source: https://github.com/anza-xyz/solana-sdk/blob/master/offchain-message/src/lib.rs#L162
|
|
336
|
-
const messageWithOffchainMessagePrefix = Uint8Array.from([
|
|
337
|
-
// eslint-disable-next-line unicorn/number-literal-case
|
|
338
|
-
0xff,
|
|
339
|
-
...new TextEncoder().encode("solana offchain"),
|
|
340
|
-
0,
|
|
341
|
-
1,
|
|
342
|
-
...serializeU16LE(message.length),
|
|
343
|
-
...message,
|
|
344
|
-
]);
|
|
345
|
-
if (await verifySignature(publicKey, signature, messageWithOffchainMessagePrefix)) {
|
|
346
|
-
return messageWithOffchainMessagePrefix;
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
throw new Error("The signature provided by the browser wallet is not valid");
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
const buildIntentInstruction = async (options, sessionKey, tokens) => {
|
|
354
|
-
const message = await buildMessage({
|
|
355
|
-
chainId: options.context.chainId,
|
|
356
|
-
domain: options.context.domain,
|
|
357
|
-
sessionKey,
|
|
358
|
-
expires: options.expires,
|
|
359
|
-
tokens,
|
|
360
|
-
extra: options.extra,
|
|
361
|
-
});
|
|
362
|
-
const intentSignature = signatureBytes(await options.signMessage(message));
|
|
362
|
+
const buildStartSessionIntentInstruction = async (options, sessionKey, tokens) => buildIntentInstruction(options, MESSAGE_HEADER, {
|
|
363
|
+
version: `${CURRENT_MAJOR}.${CURRENT_MINOR}`,
|
|
364
|
+
chain_id: options.context.chainId,
|
|
365
|
+
domain: options.context.domain,
|
|
366
|
+
expires: options.expires.toISOString(),
|
|
367
|
+
session_key: await getAddressFromPublicKey(sessionKey.publicKey),
|
|
368
|
+
tokens: serializeTokenList(tokens),
|
|
369
|
+
});
|
|
370
|
+
const buildIntentInstruction = async (options, header, body, extra) => {
|
|
371
|
+
const message = new TextEncoder().encode([header, serializeKV(body), extra && serializeExtra(extra)].join("\n"));
|
|
372
|
+
const { signature, signedMessage } = await options.signMessage(message);
|
|
363
373
|
return Ed25519Program.createInstructionWithPublicKey({
|
|
364
374
|
publicKey: options.walletPublicKey.toBytes(),
|
|
365
|
-
signature
|
|
366
|
-
message:
|
|
375
|
+
signature,
|
|
376
|
+
message: signedMessage,
|
|
367
377
|
});
|
|
368
378
|
};
|
|
369
|
-
const buildMessage = async (body) => new TextEncoder().encode([
|
|
370
|
-
MESSAGE_HEADER,
|
|
371
|
-
serializeKV({
|
|
372
|
-
version: `${CURRENT_MAJOR}.${CURRENT_MINOR}`,
|
|
373
|
-
chain_id: body.chainId,
|
|
374
|
-
domain: body.domain,
|
|
375
|
-
expires: body.expires.toISOString(),
|
|
376
|
-
session_key: await getAddressFromPublicKey(body.sessionKey.publicKey),
|
|
377
|
-
tokens: serializeTokenList(body.tokens),
|
|
378
|
-
}),
|
|
379
|
-
body.extra && serializeExtra(body.extra),
|
|
380
|
-
].join("\n"));
|
|
381
379
|
const serializeExtra = (extra) => {
|
|
382
380
|
for (const [key, value] of Object.entries(extra)) {
|
|
383
381
|
if (!/^[a-z]+(_[a-z0-9]+)*$/.test(key)) {
|
|
@@ -560,24 +558,15 @@ const buildTransferIntentInstruction = async (program, options, symbol, feeToken
|
|
|
560
558
|
getNonce(program, options.walletPublicKey, NonceType.Transfer),
|
|
561
559
|
getMint(options.context.connection, options.mint),
|
|
562
560
|
]);
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
fee_amount: feeAmount,
|
|
573
|
-
nonce: nonce === null ? "1" : nonce.nonce.add(new BN(1)).toString(),
|
|
574
|
-
}),
|
|
575
|
-
].join("\n"));
|
|
576
|
-
const intentSignature = signatureBytes(await options.signMessage(message));
|
|
577
|
-
return Ed25519Program.createInstructionWithPublicKey({
|
|
578
|
-
publicKey: options.walletPublicKey.toBytes(),
|
|
579
|
-
signature: intentSignature,
|
|
580
|
-
message: await addOffchainMessagePrefixToMessageIfNeeded(options.walletPublicKey, intentSignature, message),
|
|
561
|
+
return buildIntentInstruction(options, TRANSFER_MESSAGE_HEADER, {
|
|
562
|
+
version: `${CURRENT_INTENT_TRANSFER_MAJOR}.${CURRENT_INTENT_TRANSFER_MINOR}`,
|
|
563
|
+
chain_id: options.context.chainId,
|
|
564
|
+
token: symbol ?? options.mint.toBase58(),
|
|
565
|
+
amount: amountToString(options.amount, decimals),
|
|
566
|
+
recipient: options.recipient.toBase58(),
|
|
567
|
+
fee_token: feeToken,
|
|
568
|
+
fee_amount: feeAmount,
|
|
569
|
+
nonce: nonce === null ? "1" : nonce.nonce.add(new BN(1)).toString(),
|
|
581
570
|
});
|
|
582
571
|
};
|
|
583
572
|
const BRIDGE_OUT_MESSAGE_HEADER = `Fogo Bridge Transfer:
|
|
@@ -679,25 +668,16 @@ const getNttPdas = async (options, wh, program, outboxItemPublicKey, quotePayeeA
|
|
|
679
668
|
};
|
|
680
669
|
const buildBridgeOutIntent = async (program, options, decimals, symbol, feeToken, feeAmount) => {
|
|
681
670
|
const nonce = await getNonce(program, options.walletPublicKey, NonceType.Bridge);
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
fee_amount: feeAmount,
|
|
693
|
-
nonce: nonce === null ? "1" : nonce.nonce.add(new BN(1)).toString(),
|
|
694
|
-
}),
|
|
695
|
-
].join("\n"));
|
|
696
|
-
const intentSignature = signatureBytes(await options.solanaWallet.signMessage(message));
|
|
697
|
-
return Ed25519Program.createInstructionWithPublicKey({
|
|
698
|
-
publicKey: options.walletPublicKey.toBytes(),
|
|
699
|
-
signature: intentSignature,
|
|
700
|
-
message: await addOffchainMessagePrefixToMessageIfNeeded(options.walletPublicKey, intentSignature, message),
|
|
671
|
+
return buildIntentInstruction(options, BRIDGE_OUT_MESSAGE_HEADER, {
|
|
672
|
+
version: `${CURRENT_BRIDGE_OUT_MAJOR}.${CURRENT_BRIDGE_OUT_MINOR}`,
|
|
673
|
+
from_chain_id: options.context.chainId,
|
|
674
|
+
to_chain_id: "solana",
|
|
675
|
+
token: symbol ?? options.fromToken.mint.toBase58(),
|
|
676
|
+
amount: amountToString(options.amount, decimals),
|
|
677
|
+
recipient_address: options.walletPublicKey.toBase58(),
|
|
678
|
+
fee_token: feeToken,
|
|
679
|
+
fee_amount: feeAmount,
|
|
680
|
+
nonce: nonce === null ? "1" : nonce.nonce.add(new BN(1)).toString(),
|
|
701
681
|
});
|
|
702
682
|
};
|
|
703
683
|
export const bridgeIn = async (options) => {
|
|
@@ -711,10 +691,9 @@ export const bridgeIn = async (options) => {
|
|
|
711
691
|
address: () => options.walletPublicKey.toBase58(),
|
|
712
692
|
chain: () => "Solana",
|
|
713
693
|
sign: (transactions) => Promise.all(transactions.map(async ({ transaction }) => {
|
|
714
|
-
|
|
715
|
-
const signedTx = await options.solanaWallet.signTransaction(
|
|
694
|
+
const signedTx = await options.signTransaction(
|
|
716
695
|
// Hooray for Wormhole's incomplete typing eh?
|
|
717
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
696
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
|
718
697
|
transaction.transaction);
|
|
719
698
|
// Hooray for Wormhole's incomplete typing eh?
|
|
720
699
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fogo/sessions-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "A set of utilities for integrating with Fogo sessions",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/fogo-foundation/fogo-sessions",
|
|
8
|
+
"directory": "packages/sessions-sdk-ts"
|
|
9
|
+
},
|
|
5
10
|
"keywords": [
|
|
6
11
|
"fogo",
|
|
7
12
|
"sessions",
|
|
@@ -43,7 +48,7 @@
|
|
|
43
48
|
"@wormhole-foundation/sdk-solana-ntt": "^4.0.1",
|
|
44
49
|
"bn.js": "^5.1.2",
|
|
45
50
|
"bs58": "^6.0.0",
|
|
46
|
-
"zod": "
|
|
47
|
-
"@fogo/sessions-idls": "^0.0.
|
|
51
|
+
"zod": "3.25.67",
|
|
52
|
+
"@fogo/sessions-idls": "^0.0.12"
|
|
48
53
|
}
|
|
49
54
|
}
|