@fogo/sessions-sdk 0.0.7 → 0.0.9

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/adapter.d.ts CHANGED
@@ -26,12 +26,12 @@ declare const TransactionResult: {
26
26
  export type TransactionResult = ReturnType<(typeof TransactionResult)[keyof typeof TransactionResult]>;
27
27
  export declare const createSolanaWalletAdapter: (options: {
28
28
  connection: Connection;
29
- sponsor: PublicKey;
30
29
  addressLookupTableAddress?: string | undefined;
31
30
  domain?: string | undefined;
32
31
  } & ({
33
- paymasterUrl: string;
32
+ paymaster?: string | URL | undefined;
34
33
  } | {
35
34
  sendToPaymaster: (transaction: Transaction) => Promise<string>;
35
+ sponsor: PublicKey;
36
36
  })) => Promise<SessionAdapter>;
37
37
  export {};
package/cjs/adapter.js CHANGED
@@ -6,8 +6,11 @@ const sessions_idls_1 = require("@fogo/sessions-idls");
6
6
  const compat_1 = require("@solana/compat");
7
7
  const kit_1 = require("@solana/kit");
8
8
  const web3_js_1 = require("@solana/web3.js");
9
+ const zod_1 = require("zod");
9
10
  // eslint-disable-next-line unicorn/no-typeof-undefined
10
11
  const IS_BROWSER = typeof globalThis.window !== "undefined";
12
+ const DEFAULT_PAYMASTER = "https://paymaster.fogo.io";
13
+ const DEFAULT_ADDRESS_LOOKUP_TABLE_ADDRESS = "B8cUjJMqaWWTNNSTXBmeptjWswwCH1gTSCRYv4nu7kJW";
11
14
  var TransactionResultType;
12
15
  (function (TransactionResultType) {
13
16
  TransactionResultType[TransactionResultType["Success"] = 0] = "Success";
@@ -26,9 +29,10 @@ const TransactionResult = {
26
29
  };
27
30
  const createSolanaWalletAdapter = async (options) => {
28
31
  const addressLookupTables = await getAddressLookupTables(options.connection, options.addressLookupTableAddress);
32
+ const sponsor = await getSponsor(options);
29
33
  return {
30
34
  connection: options.connection,
31
- payer: options.sponsor,
35
+ payer: sponsor,
32
36
  chainId: await fetchChainId(options.connection),
33
37
  domain: getDomain(options.domain),
34
38
  sendTransaction: async (sessionKey, instructions) => {
@@ -36,7 +40,7 @@ const createSolanaWalletAdapter = async (options) => {
36
40
  const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
37
41
  const sessionKeySigner = await (0, kit_1.createSignerFromKeyPair)(sessionKey);
38
42
  const transaction = Array.isArray(instructions)
39
- ? await (0, kit_1.partiallySignTransactionMessageWithSigners)((0, kit_1.pipe)((0, kit_1.createTransactionMessage)({ version: 0 }), (tx) => (0, kit_1.setTransactionMessageFeePayer)((0, compat_1.fromLegacyPublicKey)(options.sponsor), tx), (tx) => (0, kit_1.setTransactionMessageLifetimeUsingBlockhash)(latestBlockhash, tx), (tx) => (0, kit_1.appendTransactionMessageInstructions)(instructions.map((instruction) => instruction instanceof web3_js_1.TransactionInstruction
43
+ ? await (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
40
44
  ? (0, compat_1.fromLegacyTransactionInstruction)(instruction)
41
45
  : instruction), tx), (tx) => (0, kit_1.compressTransactionMessageUsingAddressLookupTables)(tx, Object.fromEntries(addressLookupTables?.map((table) => [
42
46
  (0, compat_1.fromLegacyPublicKey)(table.key),
@@ -45,9 +49,7 @@ const createSolanaWalletAdapter = async (options) => {
45
49
  : await (0, kit_1.partiallySignTransaction)([sessionKey], instructions instanceof web3_js_1.VersionedTransaction
46
50
  ? (0, compat_1.fromVersionedTransaction)(instructions)
47
51
  : instructions);
48
- const signature = "sendToPaymaster" in options
49
- ? await options.sendToPaymaster(transaction)
50
- : await sendToPaymaster(options.paymasterUrl, transaction);
52
+ const signature = await sendToPaymaster(options, transaction);
51
53
  const lastValidBlockHeight = await rpc.getSlot().send();
52
54
  const confirmationResult = await options.connection.confirmTransaction({
53
55
  signature,
@@ -61,34 +63,43 @@ const createSolanaWalletAdapter = async (options) => {
61
63
  };
62
64
  };
63
65
  exports.createSolanaWalletAdapter = createSolanaWalletAdapter;
64
- const sendToPaymaster = async (paymasterUrl, transaction) => {
65
- const response = await fetch(paymasterUrl, {
66
- method: "POST",
67
- headers: {
68
- "Content-Type": "application/json",
69
- },
70
- body: JSON.stringify({
71
- transaction: (0, kit_1.getBase64EncodedWireTransaction)(transaction),
72
- }),
73
- });
74
- if (response.status === 200) {
75
- return response.text();
66
+ const getSponsor = async (options) => {
67
+ if ("sponsor" in options) {
68
+ return options.sponsor;
76
69
  }
77
70
  else {
78
- throw new PaymasterResponseError(response.status, await response.text());
71
+ const response = await fetch(new URL("/api/sponsor_pubkey", options.paymaster ?? DEFAULT_PAYMASTER));
72
+ return new web3_js_1.PublicKey(zod_1.z.string().parse(await response.text()));
79
73
  }
80
74
  };
81
- const getAddressLookupTables = async (connection, addressLookupTableAddress) => {
82
- if (addressLookupTableAddress === undefined) {
83
- return [];
75
+ const sendToPaymaster = async (options, transaction) => {
76
+ if ("sendToPaymaster" in options) {
77
+ return options.sendToPaymaster(transaction);
84
78
  }
85
79
  else {
86
- const addressLookupTableResult = await connection.getAddressLookupTable(new web3_js_1.PublicKey(addressLookupTableAddress));
87
- return addressLookupTableResult.value
88
- ? [addressLookupTableResult.value]
89
- : undefined;
80
+ const response = await fetch(new URL("/api/sponsor_and_send", options.paymaster ?? DEFAULT_PAYMASTER), {
81
+ method: "POST",
82
+ headers: {
83
+ "Content-Type": "application/json",
84
+ },
85
+ body: JSON.stringify({
86
+ transaction: (0, kit_1.getBase64EncodedWireTransaction)(transaction),
87
+ }),
88
+ });
89
+ if (response.status === 200) {
90
+ return response.text();
91
+ }
92
+ else {
93
+ throw new PaymasterResponseError(response.status, await response.text());
94
+ }
90
95
  }
91
96
  };
97
+ const getAddressLookupTables = async (connection, addressLookupTableAddress = DEFAULT_ADDRESS_LOOKUP_TABLE_ADDRESS) => {
98
+ const addressLookupTableResult = await connection.getAddressLookupTable(new web3_js_1.PublicKey(addressLookupTableAddress));
99
+ return addressLookupTableResult.value
100
+ ? [addressLookupTableResult.value]
101
+ : undefined;
102
+ };
92
103
  const fetchChainId = async (connection) => {
93
104
  const chainIdProgram = new sessions_idls_1.ChainIdProgram(new anchor_1.AnchorProvider(connection, { publicKey: new web3_js_1.Keypair().publicKey }, {})); // We mock the wallet because we don't need to sign anything
94
105
  const { chainIdAccount: chainIdAddress } = await chainIdProgram.methods
@@ -111,15 +122,7 @@ const getDomain = (requestedDomain) => {
111
122
  }
112
123
  }
113
124
  else {
114
- if (detectedDomain === undefined ||
115
- detectedDomain === requestedDomain ||
116
- process.env.NODE_ENV !== "production" // eslint-disable-line n/no-process-env
117
- ) {
118
- return requestedDomain;
119
- }
120
- else {
121
- throw new DomainOverrideNotAllowedError();
122
- }
125
+ return requestedDomain;
123
126
  }
124
127
  };
125
128
  class PaymasterResponseError extends Error {
@@ -140,9 +143,3 @@ class DomainRequiredError extends Error {
140
143
  this.name = "DomainRequiredError";
141
144
  }
142
145
  }
143
- class DomainOverrideNotAllowedError extends Error {
144
- constructor() {
145
- super("You cannot create a session for a different domain.");
146
- this.name = "DomainOverrideNotAllowedError";
147
- }
148
- }
package/esm/adapter.d.ts CHANGED
@@ -26,12 +26,12 @@ declare const TransactionResult: {
26
26
  export type TransactionResult = ReturnType<(typeof TransactionResult)[keyof typeof TransactionResult]>;
27
27
  export declare const createSolanaWalletAdapter: (options: {
28
28
  connection: Connection;
29
- sponsor: PublicKey;
30
29
  addressLookupTableAddress?: string | undefined;
31
30
  domain?: string | undefined;
32
31
  } & ({
33
- paymasterUrl: string;
32
+ paymaster?: string | URL | undefined;
34
33
  } | {
35
34
  sendToPaymaster: (transaction: Transaction) => Promise<string>;
35
+ sponsor: PublicKey;
36
36
  })) => Promise<SessionAdapter>;
37
37
  export {};
package/esm/adapter.js CHANGED
@@ -3,8 +3,11 @@ import { ChainIdProgram } from "@fogo/sessions-idls";
3
3
  import { fromLegacyPublicKey, fromLegacyTransactionInstruction, fromVersionedTransaction, } from "@solana/compat";
4
4
  import { createTransactionMessage, setTransactionMessageFeePayer, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, getBase64EncodedWireTransaction, partiallySignTransactionMessageWithSigners, pipe, createSolanaRpc, addSignersToTransactionMessage, compressTransactionMessageUsingAddressLookupTables, createSignerFromKeyPair, partiallySignTransaction, } from "@solana/kit";
5
5
  import { PublicKey, Keypair, TransactionInstruction, VersionedTransaction, } from "@solana/web3.js";
6
+ import { z } from "zod";
6
7
  // eslint-disable-next-line unicorn/no-typeof-undefined
7
8
  const IS_BROWSER = typeof globalThis.window !== "undefined";
9
+ const DEFAULT_PAYMASTER = "https://paymaster.fogo.io";
10
+ const DEFAULT_ADDRESS_LOOKUP_TABLE_ADDRESS = "B8cUjJMqaWWTNNSTXBmeptjWswwCH1gTSCRYv4nu7kJW";
8
11
  export var TransactionResultType;
9
12
  (function (TransactionResultType) {
10
13
  TransactionResultType[TransactionResultType["Success"] = 0] = "Success";
@@ -23,9 +26,10 @@ const TransactionResult = {
23
26
  };
24
27
  export const createSolanaWalletAdapter = async (options) => {
25
28
  const addressLookupTables = await getAddressLookupTables(options.connection, options.addressLookupTableAddress);
29
+ const sponsor = await getSponsor(options);
26
30
  return {
27
31
  connection: options.connection,
28
- payer: options.sponsor,
32
+ payer: sponsor,
29
33
  chainId: await fetchChainId(options.connection),
30
34
  domain: getDomain(options.domain),
31
35
  sendTransaction: async (sessionKey, instructions) => {
@@ -33,7 +37,7 @@ export const createSolanaWalletAdapter = async (options) => {
33
37
  const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
34
38
  const sessionKeySigner = await createSignerFromKeyPair(sessionKey);
35
39
  const transaction = Array.isArray(instructions)
36
- ? await partiallySignTransactionMessageWithSigners(pipe(createTransactionMessage({ version: 0 }), (tx) => setTransactionMessageFeePayer(fromLegacyPublicKey(options.sponsor), tx), (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions(instructions.map((instruction) => instruction instanceof TransactionInstruction
40
+ ? await partiallySignTransactionMessageWithSigners(pipe(createTransactionMessage({ version: 0 }), (tx) => setTransactionMessageFeePayer(fromLegacyPublicKey(sponsor), tx), (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions(instructions.map((instruction) => instruction instanceof TransactionInstruction
37
41
  ? fromLegacyTransactionInstruction(instruction)
38
42
  : instruction), tx), (tx) => compressTransactionMessageUsingAddressLookupTables(tx, Object.fromEntries(addressLookupTables?.map((table) => [
39
43
  fromLegacyPublicKey(table.key),
@@ -42,9 +46,7 @@ export const createSolanaWalletAdapter = async (options) => {
42
46
  : await partiallySignTransaction([sessionKey], instructions instanceof VersionedTransaction
43
47
  ? fromVersionedTransaction(instructions)
44
48
  : instructions);
45
- const signature = "sendToPaymaster" in options
46
- ? await options.sendToPaymaster(transaction)
47
- : await sendToPaymaster(options.paymasterUrl, transaction);
49
+ const signature = await sendToPaymaster(options, transaction);
48
50
  const lastValidBlockHeight = await rpc.getSlot().send();
49
51
  const confirmationResult = await options.connection.confirmTransaction({
50
52
  signature,
@@ -57,34 +59,43 @@ export const createSolanaWalletAdapter = async (options) => {
57
59
  },
58
60
  };
59
61
  };
60
- const sendToPaymaster = async (paymasterUrl, transaction) => {
61
- const response = await fetch(paymasterUrl, {
62
- method: "POST",
63
- headers: {
64
- "Content-Type": "application/json",
65
- },
66
- body: JSON.stringify({
67
- transaction: getBase64EncodedWireTransaction(transaction),
68
- }),
69
- });
70
- if (response.status === 200) {
71
- return response.text();
62
+ const getSponsor = async (options) => {
63
+ if ("sponsor" in options) {
64
+ return options.sponsor;
72
65
  }
73
66
  else {
74
- throw new PaymasterResponseError(response.status, await response.text());
67
+ const response = await fetch(new URL("/api/sponsor_pubkey", options.paymaster ?? DEFAULT_PAYMASTER));
68
+ return new PublicKey(z.string().parse(await response.text()));
75
69
  }
76
70
  };
77
- const getAddressLookupTables = async (connection, addressLookupTableAddress) => {
78
- if (addressLookupTableAddress === undefined) {
79
- return [];
71
+ const sendToPaymaster = async (options, transaction) => {
72
+ if ("sendToPaymaster" in options) {
73
+ return options.sendToPaymaster(transaction);
80
74
  }
81
75
  else {
82
- const addressLookupTableResult = await connection.getAddressLookupTable(new PublicKey(addressLookupTableAddress));
83
- return addressLookupTableResult.value
84
- ? [addressLookupTableResult.value]
85
- : undefined;
76
+ const response = await fetch(new URL("/api/sponsor_and_send", options.paymaster ?? DEFAULT_PAYMASTER), {
77
+ method: "POST",
78
+ headers: {
79
+ "Content-Type": "application/json",
80
+ },
81
+ body: JSON.stringify({
82
+ transaction: getBase64EncodedWireTransaction(transaction),
83
+ }),
84
+ });
85
+ if (response.status === 200) {
86
+ return response.text();
87
+ }
88
+ else {
89
+ throw new PaymasterResponseError(response.status, await response.text());
90
+ }
86
91
  }
87
92
  };
93
+ const getAddressLookupTables = async (connection, addressLookupTableAddress = DEFAULT_ADDRESS_LOOKUP_TABLE_ADDRESS) => {
94
+ const addressLookupTableResult = await connection.getAddressLookupTable(new PublicKey(addressLookupTableAddress));
95
+ return addressLookupTableResult.value
96
+ ? [addressLookupTableResult.value]
97
+ : undefined;
98
+ };
88
99
  const fetchChainId = async (connection) => {
89
100
  const chainIdProgram = new ChainIdProgram(new AnchorProvider(connection, { publicKey: new Keypair().publicKey }, {})); // We mock the wallet because we don't need to sign anything
90
101
  const { chainIdAccount: chainIdAddress } = await chainIdProgram.methods
@@ -107,15 +118,7 @@ const getDomain = (requestedDomain) => {
107
118
  }
108
119
  }
109
120
  else {
110
- if (detectedDomain === undefined ||
111
- detectedDomain === requestedDomain ||
112
- process.env.NODE_ENV !== "production" // eslint-disable-line n/no-process-env
113
- ) {
114
- return requestedDomain;
115
- }
116
- else {
117
- throw new DomainOverrideNotAllowedError();
118
- }
121
+ return requestedDomain;
119
122
  }
120
123
  };
121
124
  class PaymasterResponseError extends Error {
@@ -136,9 +139,3 @@ class DomainRequiredError extends Error {
136
139
  this.name = "DomainRequiredError";
137
140
  }
138
141
  }
139
- class DomainOverrideNotAllowedError extends Error {
140
- constructor() {
141
- super("You cannot create a session for a different domain.");
142
- this.name = "DomainOverrideNotAllowedError";
143
- }
144
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fogo/sessions-sdk",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "A set of utilities for integrating with Fogo sessions",
5
5
  "keywords": [
6
6
  "fogo",