@fogo/sessions-sdk 0.1.8 → 0.1.10

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/esm/index.js CHANGED
@@ -3,17 +3,18 @@ import { DomainRegistryIdl, IntentTransferIdl, IntentTransferProgram, SessionMan
3
3
  import { findMetadataPda, safeFetchMetadata, } from "@metaplex-foundation/mpl-token-metadata";
4
4
  import { publicKey as metaplexPublicKey } from "@metaplex-foundation/umi";
5
5
  import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
6
- import { sha256 } from "@noble/hashes/sha2";
6
+ import { sha256 } from "@noble/hashes/sha2.js";
7
7
  import { fromLegacyPublicKey } from "@solana/compat";
8
- import { generateKeyPair, getAddressFromPublicKey, getProgramDerivedAddress, } from "@solana/kit";
8
+ import { generateKeyPair, getAddressFromPublicKey, getOffchainMessageDecoder, getProgramDerivedAddress, } from "@solana/kit";
9
9
  import { getAssociatedTokenAddressSync, getMint } from "@solana/spl-token";
10
- import { ComputeBudgetProgram, Ed25519Program, Keypair, PublicKey, } from "@solana/web3.js";
11
- import { routes, Wormhole, wormhole } from "@wormhole-foundation/sdk";
10
+ import { ComputeBudgetProgram, Ed25519Program, Keypair, PublicKey, TransactionInstruction, } from "@solana/web3.js";
11
+ import { Wormhole, wormhole } from "@wormhole-foundation/sdk";
12
12
  import solanaSdk from "@wormhole-foundation/sdk/solana";
13
13
  import { contracts } from "@wormhole-foundation/sdk-base";
14
+ import * as routes from "@wormhole-foundation/sdk-connect/routes";
14
15
  import { nttExecutorRoute } from "@wormhole-foundation/sdk-route-ntt";
15
16
  import { utils } from "@wormhole-foundation/sdk-solana-core";
16
- import { NTT } from "@wormhole-foundation/sdk-solana-ntt";
17
+ import { NTT, register as registerNtt, } from "@wormhole-foundation/sdk-solana-ntt";
17
18
  import BN from "bn.js";
18
19
  import bs58 from "bs58";
19
20
  import { z } from "zod";
@@ -23,6 +24,7 @@ import { importKey, signMessageWithKey, verifyMessageWithKey, } from "./crypto.j
23
24
  import { createSessionUnwrapInstruction, createSessionWrapInstructions, createSystemProgramSessionWrapInstruction, } from "./instructions.js";
24
25
  import { USDC_DECIMALS, USDC_MINT } from "./mints.js";
25
26
  import { Network } from "./network.js";
27
+ registerNtt();
26
28
  export { createSessionConnection, TransactionResultType, } from "./connection.js";
27
29
  export { createSessionContext, } from "./context.js";
28
30
  export { createPaymasterFeeInstruction, createSessionUnwrapInstruction, createSessionWrapInstructions, createSystemProgramSessionWrapInstruction, } from "./instructions.js";
@@ -67,9 +69,9 @@ export const establishSession = async (options) => {
67
69
  };
68
70
  const sendSessionEstablishTransaction = async (options, sessionKey, instructions, sessionEstablishmentLookupTable) => {
69
71
  const result = await options.context.sendTransaction(sessionKey, instructions, options.walletPublicKey, {
70
- variation: "Session Establishment",
71
72
  addressLookupTable: sessionEstablishmentLookupTable ??
72
73
  SESSION_ESTABLISHMENT_LOOKUP_TABLE_ADDRESS[options.context.network],
74
+ variation: "Session Establishment",
73
75
  });
74
76
  switch (result.type) {
75
77
  case TransactionResultType.Success: {
@@ -92,8 +94,8 @@ export const revokeSession = async (options) => {
92
94
  const instruction = await new SessionManagerProgram(new AnchorProvider(options.context.connection, {}, {})).methods
93
95
  .revokeSession()
94
96
  .accounts({
95
- sponsor: options.session.sessionInfo.sponsor,
96
97
  session: options.session.sessionPublicKey,
98
+ sponsor: options.session.sessionInfo.sponsor,
97
99
  })
98
100
  .instruction();
99
101
  return options.context.sendTransaction(options.session.sessionKey, [instruction], options.session.walletPublicKey, {
@@ -143,17 +145,17 @@ const createSession = async (context, walletPublicKey, sessionKey) => {
143
145
  !authorizedProgramsMatchDomainRegistry(sessionInfo.authorizedPrograms, domainRegistryAuthorizedPrograms)
144
146
  ? undefined
145
147
  : {
146
- sessionPublicKey,
147
- walletPublicKey,
148
- sessionKey,
149
- payer: context.payer,
150
- getSystemProgramSessionWrapInstruction: (amount) => createSystemProgramSessionWrapInstruction(sessionPublicKey, walletPublicKey, amount),
151
- getSessionWrapInstructions: (amount) => createSessionWrapInstructions(sessionPublicKey, walletPublicKey, amount),
152
148
  getSessionUnwrapInstructions: () => [
153
149
  createSessionUnwrapInstruction(sessionPublicKey, walletPublicKey),
154
150
  ],
151
+ getSessionWrapInstructions: (amount) => createSessionWrapInstructions(sessionPublicKey, walletPublicKey, amount),
152
+ getSystemProgramSessionWrapInstruction: (amount) => createSystemProgramSessionWrapInstruction(sessionPublicKey, walletPublicKey, amount),
153
+ payer: context.payer,
155
154
  sendTransaction: (instructions, extraConfig) => context.sendTransaction(sessionKey, instructions, walletPublicKey, extraConfig),
156
155
  sessionInfo,
156
+ sessionKey,
157
+ sessionPublicKey,
158
+ walletPublicKey,
157
159
  };
158
160
  };
159
161
  const authorizedTokensSchema = z.union([
@@ -165,9 +167,9 @@ const authorizedTokensSchema = z.union([
165
167
  z.object({ All: z.object({}) }),
166
168
  ]);
167
169
  const revokedSessionInfoSchema = z.object({
168
- user: z.instanceof(PublicKey),
169
- expiration: z.instanceof(BN),
170
170
  authorized_tokens_with_mints: authorizedTokensSchema,
171
+ expiration: z.instanceof(BN),
172
+ user: z.instanceof(PublicKey),
171
173
  });
172
174
  const activeSessionInfoSchema = z.object({
173
175
  authorized_programs: z.union([
@@ -199,6 +201,7 @@ const activeSessionInfoSchema = z.object({
199
201
  });
200
202
  const sessionInfoSchema = z
201
203
  .object({
204
+ major: z.number(),
202
205
  session_info: z.union([
203
206
  z.object({
204
207
  V1: z.object({
@@ -292,8 +295,8 @@ const sessionInfoSchema = z
292
295
  z.object({
293
296
  Active: z.object({
294
297
  "0": z.object({
295
- domain_hash: z.array(z.number()).length(32),
296
298
  active_session_info: activeSessionInfoSchema,
299
+ domain_hash: z.array(z.number()).length(32),
297
300
  }),
298
301
  }),
299
302
  }),
@@ -301,7 +304,6 @@ const sessionInfoSchema = z
301
304
  }),
302
305
  }),
303
306
  ]),
304
- major: z.number(),
305
307
  sponsor: z.instanceof(PublicKey),
306
308
  })
307
309
  .transform(({ session_info, major, sponsor }) => {
@@ -340,8 +342,8 @@ const sessionInfoSchema = z
340
342
  extra: activeSessionInfo.extra[0],
341
343
  major: major,
342
344
  minor: minor,
343
- user: activeSessionInfo.user,
344
345
  sponsor,
346
+ user: activeSessionInfo.user,
345
347
  };
346
348
  });
347
349
  export var AuthorizedProgramsType;
@@ -352,8 +354,8 @@ export var AuthorizedProgramsType;
352
354
  const AuthorizedPrograms = {
353
355
  All: () => ({ type: AuthorizedProgramsType.All }),
354
356
  Specific: (programs) => ({
355
- type: AuthorizedProgramsType.Specific,
356
357
  programs,
358
+ type: AuthorizedProgramsType.Specific,
357
359
  }),
358
360
  };
359
361
  export var AuthorizedTokens;
@@ -367,13 +369,13 @@ var SymbolOrMintType;
367
369
  SymbolOrMintType[SymbolOrMintType["Mint"] = 1] = "Mint";
368
370
  })(SymbolOrMintType || (SymbolOrMintType = {}));
369
371
  const SymbolOrMint = {
370
- Symbol: (symbol) => ({
371
- type: SymbolOrMintType.Symbol,
372
- symbol,
373
- }),
374
372
  Mint: (mint) => ({
375
- type: SymbolOrMintType.Mint,
376
373
  mint,
374
+ type: SymbolOrMintType.Mint,
375
+ }),
376
+ Symbol: (symbol) => ({
377
+ symbol,
378
+ type: SymbolOrMintType.Symbol,
377
379
  }),
378
380
  };
379
381
  const getTokenInfo = (context, limits) => {
@@ -386,17 +388,19 @@ const getTokenInfo = (context, limits) => {
386
388
  safeFetchMetadata(umi, metadataAddress),
387
389
  ]);
388
390
  return {
391
+ amount,
392
+ decimals: mintInfo.decimals,
393
+ metadataAddress: new PublicKey(metadataAddress),
394
+ mint,
389
395
  symbolOrMint: metadata?.symbol
390
396
  ? SymbolOrMint.Symbol(metadata.symbol)
391
397
  : SymbolOrMint.Mint(mint),
392
- metadataAddress: new PublicKey(metadataAddress),
393
- amount,
394
- mint,
395
- decimals: mintInfo.decimals,
396
398
  };
397
399
  }));
398
400
  };
399
- const buildStartSessionIntentInstruction = async (options, sessionKey, tokens) => buildIntentInstruction(options, MESSAGE_HEADER, {
401
+ const buildStartSessionIntentInstruction = async (options, sessionKey, tokens) => buildIntentInstruction(options, MESSAGE_HEADER,
402
+ // biome-ignore assist/source/useSortedKeys: The sort order is important here
403
+ {
400
404
  version: `${CURRENT_MAJOR}.${CURRENT_MINOR}`,
401
405
  chain_id: options.context.chainId,
402
406
  domain: options.context.domain,
@@ -407,12 +411,80 @@ const buildStartSessionIntentInstruction = async (options, sessionKey, tokens) =
407
411
  const buildIntentInstruction = async (options, header, body, extra) => {
408
412
  const message = new TextEncoder().encode([header, serializeKV(body), extra && serializeExtra(extra)].join("\n"));
409
413
  const { signature, signedMessage } = await options.signMessage(message);
410
- return Ed25519Program.createInstructionWithPublicKey({
411
- publicKey: options.walletPublicKey.toBytes(),
412
- signature,
413
- message: signedMessage,
414
+ const publicKey = options.walletPublicKey.toBytes();
415
+ const publicKeyOffsetInMessage = getOffchainMessagePublicKeyOffset(signedMessage, options.walletPublicKey);
416
+ if (publicKeyOffsetInMessage !== undefined) {
417
+ return buildEd25519InstructionWithOffsets({
418
+ message: signedMessage,
419
+ publicKeyOffsetInMessage,
420
+ signature,
421
+ });
422
+ }
423
+ else {
424
+ return Ed25519Program.createInstructionWithPublicKey({
425
+ message: signedMessage,
426
+ publicKey,
427
+ signature,
428
+ });
429
+ }
430
+ };
431
+ const ED25519_HEADER_LEN = 16;
432
+ const ED25519_PUBLIC_KEY_LEN = 32;
433
+ const ED25519_SIGNATURE_LEN = 64;
434
+ const ED25519_CURRENT_INSTRUCTION_INDEX = 0xff_ff;
435
+ const buildEd25519InstructionWithOffsets = (params) => {
436
+ const { signature, message, publicKeyOffsetInMessage } = params;
437
+ if (signature.length !== ED25519_SIGNATURE_LEN) {
438
+ throw new Error(`Signature must be ${ED25519_SIGNATURE_LEN} bytes but received ${signature.length} bytes`);
439
+ }
440
+ if (publicKeyOffsetInMessage < 0 ||
441
+ publicKeyOffsetInMessage + ED25519_PUBLIC_KEY_LEN > message.length) {
442
+ throw new Error("Public key offset is out of bounds of signed message");
443
+ }
444
+ const signatureOffset = ED25519_HEADER_LEN;
445
+ const messageDataOffset = signatureOffset + signature.length;
446
+ const publicKeyOffsetInInstruction = messageDataOffset + publicKeyOffsetInMessage;
447
+ const instructionData = new Uint8Array(ED25519_HEADER_LEN + ED25519_SIGNATURE_LEN + message.length);
448
+ const view = new DataView(instructionData.buffer);
449
+ view.setUint8(0, 1); // num_signatures
450
+ view.setUint8(1, 0); // padding
451
+ view.setUint16(2, signatureOffset, true);
452
+ view.setUint16(4, ED25519_CURRENT_INSTRUCTION_INDEX, true);
453
+ view.setUint16(6, publicKeyOffsetInInstruction, true);
454
+ view.setUint16(8, ED25519_CURRENT_INSTRUCTION_INDEX, true);
455
+ view.setUint16(10, messageDataOffset, true);
456
+ view.setUint16(12, message.length, true);
457
+ view.setUint16(14, ED25519_CURRENT_INSTRUCTION_INDEX, true);
458
+ instructionData.set(signature, signatureOffset);
459
+ instructionData.set(message, messageDataOffset);
460
+ return new TransactionInstruction({
461
+ data: Buffer.from(instructionData),
462
+ keys: [],
463
+ programId: Ed25519Program.programId,
414
464
  });
415
465
  };
466
+ const OFFCHAIN_SIGNING_DOMAIN_LEN = 16;
467
+ const OFFCHAIN_V0_SIGNER_LIST_OFFSET = OFFCHAIN_SIGNING_DOMAIN_LEN + 1 + 32 + 1 + 1;
468
+ const OFFCHAIN_V1_SIGNER_LIST_OFFSET = OFFCHAIN_SIGNING_DOMAIN_LEN + 1 + 1;
469
+ const getOffchainMessagePublicKeyOffset = (signedMessage, publicKey) => {
470
+ const address = publicKey.toBase58();
471
+ try {
472
+ const message = getOffchainMessageDecoder().decode(signedMessage);
473
+ const index = message.requiredSignatories.findIndex((signer) => signer.address === address);
474
+ if (index !== -1) {
475
+ const baseOffset = message.version === 1
476
+ ? OFFCHAIN_V1_SIGNER_LIST_OFFSET
477
+ : OFFCHAIN_V0_SIGNER_LIST_OFFSET;
478
+ return baseOffset + index * ED25519_PUBLIC_KEY_LEN;
479
+ }
480
+ else {
481
+ return undefined;
482
+ }
483
+ }
484
+ catch {
485
+ return undefined;
486
+ }
487
+ };
416
488
  const serializeExtra = (extra) => {
417
489
  for (const [key, value] of Object.entries(extra)) {
418
490
  if (!/^[a-z]+(_[a-z0-9]+)*$/.test(key)) {
@@ -454,7 +526,7 @@ const amountToString = (amount, decimals) => {
454
526
  ].join("");
455
527
  };
456
528
  export const getDomainRecordAddress = (domain) => {
457
- const hash = sha256(domain);
529
+ const hash = sha256(new TextEncoder().encode(domain));
458
530
  return PublicKey.findProgramAddressSync([Buffer.from("domain-record"), hash], new PublicKey(DomainRegistryIdl.address))[0];
459
531
  };
460
532
  const BRIDGING_ADDRESS_LOOKUP_TABLE = {
@@ -471,30 +543,30 @@ const buildStartSessionInstruction = async (options, sessionKey, tokens) => {
471
543
  const instruction = new SessionManagerProgram(new AnchorProvider(options.context.connection, {}, {})).methods
472
544
  .startSession()
473
545
  .accounts({
474
- sponsor: options.context.payer,
475
- session: await getAddressFromPublicKey(sessionKey.publicKey),
476
546
  domainRegistry: getDomainRecordAddress(options.context.domain),
547
+ session: await getAddressFromPublicKey(sessionKey.publicKey),
548
+ sponsor: options.context.payer,
477
549
  });
478
550
  return tokens === undefined
479
551
  ? instruction.instruction()
480
552
  : instruction
481
553
  .remainingAccounts(tokens.flatMap(({ symbolOrMint, mint, metadataAddress }) => [
482
554
  {
483
- pubkey: getAssociatedTokenAddressSync(mint, options.walletPublicKey),
484
- isWritable: true,
485
555
  isSigner: false,
556
+ isWritable: true,
557
+ pubkey: getAssociatedTokenAddressSync(mint, options.walletPublicKey),
486
558
  },
487
559
  {
488
- pubkey: mint,
489
- isWritable: false,
490
560
  isSigner: false,
561
+ isWritable: false,
562
+ pubkey: mint,
491
563
  },
492
564
  ...(symbolOrMint.type === SymbolOrMintType.Symbol
493
565
  ? [
494
566
  {
495
- pubkey: metadataAddress,
496
- isWritable: false,
497
567
  isSigner: false,
568
+ isWritable: false,
569
+ pubkey: metadataAddress,
498
570
  },
499
571
  ]
500
572
  : []),
@@ -507,15 +579,15 @@ export var SessionResultType;
507
579
  SessionResultType[SessionResultType["Failed"] = 1] = "Failed";
508
580
  })(SessionResultType || (SessionResultType = {}));
509
581
  const EstablishSessionResult = {
510
- Success: (signature, session) => ({
511
- type: SessionResultType.Success,
512
- signature,
513
- session,
514
- }),
515
582
  Failed: (signature, error) => ({
583
+ error,
584
+ signature,
516
585
  type: SessionResultType.Failed,
586
+ }),
587
+ Success: (signature, session) => ({
588
+ session,
517
589
  signature,
518
- error,
590
+ type: SessionResultType.Success,
519
591
  }),
520
592
  };
521
593
  export const getTransferFee = async (context) => {
@@ -540,16 +612,16 @@ const getFee = async (context) => {
540
612
  const [feeConfigPda] = PublicKey.findProgramAddressSync([Buffer.from("fee_config"), usdcMint.toBytes()], program.programId);
541
613
  const feeConfig = await program.account.feeConfig.fetch(feeConfigPda);
542
614
  return {
615
+ decimals: USDC_DECIMALS,
616
+ fee: {
617
+ bridgeTransfer: BigInt(feeConfig.bridgeTransferFee.toString()),
618
+ intrachainTransfer: BigInt(feeConfig.intrachainTransferFee.toString()),
619
+ },
543
620
  metadata: findMetadataPda(umi, {
544
621
  mint: metaplexPublicKey(usdcMintAddress),
545
622
  })[0],
546
623
  mint: usdcMint,
547
624
  symbolOrMint: "USDC.s",
548
- decimals: USDC_DECIMALS,
549
- fee: {
550
- intrachainTransfer: BigInt(feeConfig.intrachainTransferFee.toString()),
551
- bridgeTransfer: BigInt(feeConfig.bridgeTransferFee.toString()),
552
- },
553
625
  };
554
626
  };
555
627
  const TRANSFER_MESSAGE_HEADER = `Fogo Transfer:
@@ -572,17 +644,17 @@ export const sendTransfer = async (options) => {
572
644
  feeMetadata: options.feeConfig.metadata,
573
645
  feeMint: options.feeConfig.mint,
574
646
  feeSource: getAssociatedTokenAddressSync(options.feeConfig.mint, options.walletPublicKey),
575
- mint: options.mint,
576
- source: sourceAta,
577
- sponsor: options.context.internalPayer,
578
647
  metadata:
579
648
  // eslint-disable-next-line unicorn/no-null
580
649
  symbol === undefined ? null : new PublicKey(metadataAddress),
650
+ mint: options.mint,
651
+ source: sourceAta,
652
+ sponsor: options.context.internalPayer,
581
653
  })
582
654
  .instruction(),
583
655
  ], options.walletPublicKey, {
584
- variation: "Intent Transfer",
585
656
  paymasterDomain: SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
657
+ variation: "Intent Transfer",
586
658
  });
587
659
  };
588
660
  const buildTransferIntentInstruction = async (program, options, symbol, feeToken, feeAmount) => {
@@ -590,7 +662,9 @@ const buildTransferIntentInstruction = async (program, options, symbol, feeToken
590
662
  getNonce(program, options.walletPublicKey, NonceType.Transfer),
591
663
  getMint(options.context.connection, options.mint),
592
664
  ]);
593
- return buildIntentInstruction(options, TRANSFER_MESSAGE_HEADER, {
665
+ return buildIntentInstruction(options, TRANSFER_MESSAGE_HEADER,
666
+ // biome-ignore assist/source/useSortedKeys: The sort order is important here
667
+ {
594
668
  version: `${CURRENT_INTENT_TRANSFER_MAJOR}.${CURRENT_INTENT_TRANSFER_MINOR}`,
595
669
  chain_id: options.context.chainId,
596
670
  token: symbol ?? options.mint.toBase58(),
@@ -608,24 +682,26 @@ export const sendNativeTransfer = async (options) => {
608
682
  await program.methods
609
683
  .sendNative()
610
684
  .accounts({
685
+ destination: options.recipient,
686
+ feeDestination: IntentTransferIdl.address,
611
687
  feeMetadata: options.feeConfig.metadata,
612
688
  feeMint: options.feeConfig.mint,
613
689
  feeSource: getAssociatedTokenAddressSync(options.feeConfig.mint, options.walletPublicKey),
614
- feeDestination: IntentTransferIdl.address,
615
690
  source: options.walletPublicKey,
616
- destination: options.recipient,
617
691
  sponsor: options.context.internalPayer,
618
692
  })
619
693
  .instruction(),
620
694
  ], options.walletPublicKey, {
621
- variation: "Intent Transfer",
622
695
  paymasterDomain: SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
696
+ variation: "Intent Transfer",
623
697
  });
624
698
  };
625
699
  const FOGO_DECIMALS = 9;
626
700
  const buildNativeTransferIntentInstruction = async (program, options, feeToken, feeAmount) => {
627
701
  const nonce = await getNonce(program, options.walletPublicKey, NonceType.Transfer);
628
- return buildIntentInstruction(options, TRANSFER_MESSAGE_HEADER, {
702
+ return buildIntentInstruction(options, TRANSFER_MESSAGE_HEADER,
703
+ // biome-ignore assist/source/useSortedKeys: The sort order is important here
704
+ {
629
705
  version: `${CURRENT_INTENT_TRANSFER_MAJOR}.${CURRENT_INTENT_TRANSFER_MINOR}`,
630
706
  chain_id: options.context.chainId,
631
707
  token: "FOGO",
@@ -663,17 +739,17 @@ export const bridgeOut = async (options) => {
663
739
  signedQuoteBytes: [...quote.signedQuote],
664
740
  })
665
741
  .accounts({
666
- sponsor: options.context.internalPayer,
667
- mint: options.fromToken.mint,
742
+ feeMetadata: options.feeConfig.metadata,
743
+ feeMint: options.feeConfig.mint,
744
+ feeSource: getAssociatedTokenAddressSync(options.feeConfig.mint, options.walletPublicKey),
668
745
  metadata: metadata?.symbol === undefined
669
746
  ? // eslint-disable-next-line unicorn/no-null
670
747
  null
671
748
  : new PublicKey(metadataAddress),
672
- source: getAssociatedTokenAddressSync(options.fromToken.mint, options.walletPublicKey),
749
+ mint: options.fromToken.mint,
673
750
  ntt: nttPdas,
674
- feeMetadata: options.feeConfig.metadata,
675
- feeMint: options.feeConfig.mint,
676
- feeSource: getAssociatedTokenAddressSync(options.feeConfig.mint, options.walletPublicKey),
751
+ source: getAssociatedTokenAddressSync(options.fromToken.mint, options.walletPublicKey),
752
+ sponsor: options.context.internalPayer,
677
753
  })
678
754
  .instruction(),
679
755
  ]);
@@ -681,10 +757,10 @@ export const bridgeOut = async (options) => {
681
757
  ComputeBudgetProgram.setComputeUnitLimit({ units: BRIDGE_OUT_CUS }),
682
758
  ...instructions,
683
759
  ], options.walletPublicKey, {
684
- variation: "Intent NTT Bridge",
685
- paymasterDomain: SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
686
- extraSigners: [outboxItem],
687
760
  addressLookupTable: BRIDGING_ADDRESS_LOOKUP_TABLE[options.context.network]?.[options.fromToken.mint.toBase58()],
761
+ extraSigners: [outboxItem],
762
+ paymasterDomain: SESSIONS_INTERNAL_PAYMASTER_DOMAIN,
763
+ variation: "Intent NTT Bridge",
688
764
  });
689
765
  };
690
766
  const getDestinationAtaExists = async (context, token, wallet) => {
@@ -726,16 +802,18 @@ const getNttPdas = async (options, wh, program, outboxItemPublicKey, quotePayeeA
726
802
  nttTokenAuthority: pdas.tokenAuthority(),
727
803
  payeeNttWithExecutor: quotePayeeAddress,
728
804
  transceiver: registeredTransceiverPda,
729
- wormholeProgram: coreBridgeContract,
730
805
  wormholeBridge: wormholePdas.wormholeBridge,
731
806
  wormholeFeeCollector: wormholePdas.wormholeFeeCollector,
732
807
  wormholeMessage: transceiverPdas.wormholeMessageAccount(outboxItemPublicKey),
808
+ wormholeProgram: coreBridgeContract,
733
809
  wormholeSequence: wormholePdas.wormholeSequence,
734
810
  };
735
811
  };
736
812
  const buildBridgeOutIntent = async (program, options, decimals, symbol, feeToken, feeAmount) => {
737
813
  const nonce = await getNonce(program, options.walletPublicKey, NonceType.Bridge);
738
- return buildIntentInstruction(options, BRIDGE_OUT_MESSAGE_HEADER, {
814
+ return buildIntentInstruction(options, BRIDGE_OUT_MESSAGE_HEADER,
815
+ // biome-ignore assist/source/useSortedKeys: The sort order is important here
816
+ {
739
817
  version: `${CURRENT_BRIDGE_OUT_MAJOR}.${CURRENT_BRIDGE_OUT_MINOR}`,
740
818
  from_chain_id: options.context.chainId,
741
819
  to_chain_id: "solana",
@@ -813,9 +891,9 @@ const buildWormholeTransfer = async (options, connection) => {
813
891
  });
814
892
  const route = new Route(wh);
815
893
  const transferRequest = await routes.RouteTransferRequest.create(wh, {
894
+ destination: Wormhole.tokenId(options.toToken.chain, options.toToken.mint.toBase58()),
816
895
  recipient: Wormhole.chainAddress(options.toToken.chain, options.walletPublicKey.toBase58()),
817
896
  source: Wormhole.tokenId(options.fromToken.chain, options.fromToken.mint.toBase58()),
818
- destination: Wormhole.tokenId(options.toToken.chain, options.toToken.mint.toBase58()),
819
897
  });
820
898
  const validated = await route.validate(transferRequest, {
821
899
  amount: amountToString(options.amount, decimals),
@@ -823,11 +901,11 @@ const buildWormholeTransfer = async (options, connection) => {
823
901
  });
824
902
  if (validated.valid) {
825
903
  return {
826
- wh,
904
+ decimals,
827
905
  route,
828
- transferRequest,
829
906
  transferParams: validated.params,
830
- decimals,
907
+ transferRequest,
908
+ wh,
831
909
  };
832
910
  }
833
911
  else {
@@ -1,6 +1,6 @@
1
1
  import { AnchorProvider } from "@coral-xyz/anchor";
2
2
  import { TollboothIdl, TollboothProgram } from "@fogo/sessions-idls";
3
- import { sha256 } from "@noble/hashes/sha2";
3
+ import { sha256 } from "@noble/hashes/sha2.js";
4
4
  import { createAssociatedTokenAccountIdempotentInstruction, createCloseAccountInstruction, createSyncNativeInstruction, getAssociatedTokenAddressSync, NATIVE_MINT, } from "@solana/spl-token";
5
5
  import { PublicKey, SystemProgram, TransactionInstruction, } from "@solana/web3.js";
6
6
  const SESSION_WRAP_DISCRIMINATOR = 4_000_000;
@@ -17,17 +17,17 @@ export function createSystemProgramSessionWrapInstruction(sessionKey, walletPubl
17
17
  view.setUint32(0, SESSION_WRAP_DISCRIMINATOR, true);
18
18
  view.setBigUint64(4, amount, true);
19
19
  return new TransactionInstruction({
20
- programId: SystemProgram.programId,
20
+ data: Buffer.from(data),
21
21
  keys: [
22
- { pubkey: walletPublicKey, isSigner: false, isWritable: true },
22
+ { isSigner: false, isWritable: true, pubkey: walletPublicKey },
23
23
  {
24
- pubkey: getNativeMintAssociatedTokenAddressSync(walletPublicKey),
25
24
  isSigner: false,
26
25
  isWritable: true,
26
+ pubkey: getNativeMintAssociatedTokenAddressSync(walletPublicKey),
27
27
  },
28
- { pubkey: sessionKey, isSigner: true, isWritable: false },
28
+ { isSigner: true, isWritable: false, pubkey: sessionKey },
29
29
  ],
30
- data: Buffer.from(data),
30
+ programId: SystemProgram.programId,
31
31
  });
32
32
  }
33
33
  /**
@@ -53,7 +53,7 @@ export function createSessionUnwrapInstruction(sessionKey, walletPublicKey) {
53
53
  return createCloseAccountInstruction(getNativeMintAssociatedTokenAddressSync(walletPublicKey), walletPublicKey, sessionKey);
54
54
  }
55
55
  const getDomainTollRecipientAddress = (domain) => {
56
- const hash = sha256(domain);
56
+ const hash = sha256(new TextEncoder().encode(domain));
57
57
  return PublicKey.findProgramAddressSync([Buffer.from("toll_recipient"), Buffer.from([0]), hash], new PublicKey(TollboothIdl.address))[0];
58
58
  };
59
59
  /**
@@ -66,10 +66,10 @@ export const createPaymasterFeeInstruction = ({ sessionKey, walletPublicKey, dom
66
66
  return new TollboothProgram(new AnchorProvider({}, {})).methods
67
67
  .payToll(feeAmount, 0)
68
68
  .accounts({
69
- session: sessionKey,
70
- source: getAssociatedTokenAddressSync(feeMint, walletPublicKey),
71
69
  destination: getAssociatedTokenAddressSync(feeMint, recipient, true),
72
70
  mint: feeMint,
71
+ session: sessionKey,
72
+ source: getAssociatedTokenAddressSync(feeMint, walletPublicKey),
73
73
  })
74
74
  .instruction();
75
75
  };
package/package.json CHANGED
@@ -1,54 +1,55 @@
1
1
  {
2
- "name": "@fogo/sessions-sdk",
3
- "version": "0.1.8",
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"
2
+ "dependencies": {
3
+ "@coral-xyz/anchor": "^0.32.1",
4
+ "@metaplex-foundation/mpl-token-metadata": "^3.4.0",
5
+ "@metaplex-foundation/umi": "^1.5.1",
6
+ "@metaplex-foundation/umi-bundle-defaults": "^1.5.1",
7
+ "@noble/hashes": "^2.2.0",
8
+ "@solana/compat": "^6.8.0",
9
+ "@solana/kit": "^6.8.0",
10
+ "@solana/spl-token": "^0.4.14",
11
+ "@solana/web3.js": "^1.98.4",
12
+ "@wormhole-foundation/sdk": "^4.17.0",
13
+ "@wormhole-foundation/sdk-base": "^4.17.0",
14
+ "@wormhole-foundation/sdk-connect": "^4.17.0",
15
+ "@wormhole-foundation/sdk-route-ntt": "^4.0.17",
16
+ "@wormhole-foundation/sdk-solana-core": "^4.17.0",
17
+ "@wormhole-foundation/sdk-solana-ntt": "^4.0.17",
18
+ "bn.js": "^5.2.3",
19
+ "bs58": "^6.0.0",
20
+ "zod": "4.3.6",
21
+ "@fogo/sessions-idls": "^0.1.4"
9
22
  },
10
- "keywords": [
11
- "fogo",
12
- "sessions",
13
- "crypto",
14
- "wallet"
15
- ],
16
- "type": "module",
17
- "main": "./cjs/index.js",
18
- "types": "./cjs/index.d.ts",
23
+ "description": "A set of utilities for integrating with Fogo sessions",
19
24
  "engines": {
20
25
  "node": ">=22"
21
26
  },
22
27
  "exports": {
23
28
  ".": {
24
29
  "import": {
25
- "types": "./esm/index.d.ts",
26
- "default": "./esm/index.js"
30
+ "default": "./esm/index.js",
31
+ "types": "./esm/index.d.ts"
27
32
  },
28
33
  "require": {
29
- "types": "./cjs/index.d.ts",
30
- "default": "./cjs/index.js"
34
+ "default": "./cjs/index.js",
35
+ "types": "./cjs/index.d.ts"
31
36
  }
32
37
  }
33
38
  },
34
- "dependencies": {
35
- "@coral-xyz/anchor": "^0.31.1",
36
- "@metaplex-foundation/mpl-token-metadata": "^3.4.0",
37
- "@metaplex-foundation/umi": "^1.2.0",
38
- "@metaplex-foundation/umi-bundle-defaults": "^1.2.0",
39
- "@noble/hashes": "^1.8.0",
40
- "@solana/compat": "^4.0.0",
41
- "@solana/kit": "^4.0.0",
42
- "@solana/spl-token": "^0.4.13",
43
- "@solana/web3.js": "^1.92.3",
44
- "@wormhole-foundation/sdk": "^3.10.0",
45
- "@wormhole-foundation/sdk-base": "^3.11.0",
46
- "@wormhole-foundation/sdk-route-ntt": "^4.0.1",
47
- "@wormhole-foundation/sdk-solana-core": "^3.10.0",
48
- "@wormhole-foundation/sdk-solana-ntt": "^4.0.1",
49
- "bn.js": "^5.1.2",
50
- "bs58": "^6.0.0",
51
- "zod": "3.25.67",
52
- "@fogo/sessions-idls": "^0.1.2"
53
- }
39
+ "keywords": [
40
+ "fogo",
41
+ "sessions",
42
+ "crypto",
43
+ "wallet"
44
+ ],
45
+ "main": "./cjs/index.js",
46
+ "name": "@fogo/sessions-sdk",
47
+ "repository": {
48
+ "directory": "packages/sessions-sdk-ts",
49
+ "type": "git",
50
+ "url": "https://github.com/fogo-foundation/fogo-sessions"
51
+ },
52
+ "type": "module",
53
+ "types": "./cjs/index.d.ts",
54
+ "version": "0.1.10"
54
55
  }