@account-kit/signer 4.54.1 → 4.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,3 +10,4 @@ export type * from "./solanaSigner.js";
10
10
  export type * from "./types.js";
11
11
  export { AlchemySignerStatus } from "./types.js";
12
12
  export { SolanaSigner } from "./solanaSigner.js";
13
+ export { createSolanaSponsoredTransaction, createSolanaTransaction, } from "./utils/solana.js";
package/dist/esm/index.js CHANGED
@@ -6,4 +6,5 @@ export { DEFAULT_SESSION_MS, SessionManagerParamsSchema, } from "./session/manag
6
6
  export { AlchemyWebSigner } from "./signer.js";
7
7
  export { AlchemySignerStatus } from "./types.js";
8
8
  export { SolanaSigner } from "./solanaSigner.js";
9
+ export { createSolanaSponsoredTransaction, createSolanaTransaction, } from "./utils/solana.js";
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["export { BaseAlchemySigner } from \"./base.js\";\nexport { BaseSignerClient } from \"./client/base.js\";\nexport {\n AlchemySignerWebClient,\n OauthCancelledError,\n OauthFailedError,\n} from \"./client/index.js\";\nexport type * from \"./client/types.js\";\nexport {\n NotAuthenticatedError,\n OAuthProvidersError,\n MfaRequiredError,\n} from \"./errors.js\";\nexport {\n DEFAULT_SESSION_MS,\n SessionManagerParamsSchema,\n} from \"./session/manager.js\";\nexport type * from \"./signer.js\";\nexport { AlchemyWebSigner } from \"./signer.js\";\nexport type * from \"./solanaSigner.js\";\nexport type * from \"./types.js\";\nexport { AlchemySignerStatus } from \"./types.js\";\nexport { SolanaSigner } from \"./solanaSigner.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,mBAAmB,CAAC","sourcesContent":["export { BaseAlchemySigner } from \"./base.js\";\nexport { BaseSignerClient } from \"./client/base.js\";\nexport {\n AlchemySignerWebClient,\n OauthCancelledError,\n OauthFailedError,\n} from \"./client/index.js\";\nexport type * from \"./client/types.js\";\nexport {\n NotAuthenticatedError,\n OAuthProvidersError,\n MfaRequiredError,\n} from \"./errors.js\";\nexport {\n DEFAULT_SESSION_MS,\n SessionManagerParamsSchema,\n} from \"./session/manager.js\";\nexport type * from \"./signer.js\";\nexport { AlchemyWebSigner } from \"./signer.js\";\nexport type * from \"./solanaSigner.js\";\nexport type * from \"./types.js\";\nexport { AlchemySignerStatus } from \"./types.js\";\nexport { SolanaSigner } from \"./solanaSigner.js\";\nexport {\n createSolanaSponsoredTransaction,\n createSolanaTransaction,\n} from \"./utils/solana.js\";\n"]}
@@ -1,6 +1,7 @@
1
1
  import { Connection, PublicKey, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction, } from "@solana/web3.js";
2
2
  import { size, slice, toBytes, toHex } from "viem";
3
3
  import { NotAuthenticatedError } from "./errors.js";
4
+ import { createSolanaSponsoredTransaction } from "./utils/solana.js";
4
5
  /**
5
6
  * The SolanaSigner class is used to sign transactions and messages for the Solana blockchain.
6
7
  * It provides methods to add signatures to transactions and sign messages.
@@ -108,43 +109,7 @@ export class SolanaSigner {
108
109
  * @returns {Promise<VersionedTransaction>} The transaction with sponsorship added
109
110
  */
110
111
  async addSponsorship(instructions, connection, policyId) {
111
- const { blockhash } = await connection.getLatestBlockhash({
112
- commitment: "finalized",
113
- });
114
- const message = new TransactionMessage({
115
- // Right now the backend will rewrite this payer Key to the server's address
116
- payerKey: new PublicKey(this.address),
117
- recentBlockhash: blockhash,
118
- instructions,
119
- }).compileToV0Message();
120
- const versionedTransaction = new VersionedTransaction(message);
121
- const serializedTransaction = Buffer.from(versionedTransaction.serialize()).toString("base64");
122
- const body = JSON.stringify({
123
- id: crypto?.randomUUID() ?? Math.floor(Math.random() * 1000000),
124
- jsonrpc: "2.0",
125
- method: "alchemy_requestFeePayer",
126
- params: [
127
- {
128
- policyId,
129
- serializedTransaction,
130
- },
131
- ],
132
- });
133
- const options = {
134
- method: "POST",
135
- headers: {
136
- accept: "application/json",
137
- "content-type": "application/json",
138
- },
139
- body,
140
- };
141
- const response = await fetch(
142
- // TODO: Use the connection??
143
- connection.rpcEndpoint, options);
144
- const jsonResponse = await response.json();
145
- if (!jsonResponse?.result?.serializedTransaction)
146
- throw new Error(`Response doesn't include the serializedTransaction ${JSON.stringify(jsonResponse)}`);
147
- return VersionedTransaction.deserialize(decodeBase64(jsonResponse.result.serializedTransaction));
112
+ return createSolanaSponsoredTransaction(instructions, connection, policyId, this.address);
148
113
  }
149
114
  formatSignatureForSolana(signature) {
150
115
  if (size(signature) === 64)
@@ -162,7 +127,4 @@ export class SolanaSigner {
162
127
  return toHex(messageToSign);
163
128
  }
164
129
  }
165
- function decodeBase64(serializedTransaction) {
166
- return Buffer.from(serializedTransaction, "base64");
167
- }
168
130
  //# sourceMappingURL=solanaSigner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"solanaSigner.js","sourceRoot":"","sources":["../../src/solanaSigner.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Connection,\n PublicKey,\n Transaction,\n TransactionInstruction,\n TransactionMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport { size, slice, toBytes, toHex, type ByteArray, type Hex } from \"viem\";\nimport type { BaseSignerClient } from \"./client/base\";\nimport { NotAuthenticatedError } from \"./errors.js\";\n\n/**\n * The SolanaSigner class is used to sign transactions and messages for the Solana blockchain.\n * It provides methods to add signatures to transactions and sign messages.\n */\nexport class SolanaSigner {\n readonly alchemyClient: BaseSignerClient;\n public readonly address: string;\n\n /**\n * Constructor for the SolanaSigner class which is a wrapper around the alchemy client, and is more focused on the solana web3\n *\n * @param {object} client This is the client that will be used to sign the transaction, and we are just having functions on top of it.\n */\n constructor(client: BaseSignerClient) {\n this.alchemyClient = client;\n if (!client.getUser()) throw new Error(\"Must be authenticated!\");\n\n // TODO: also throw here\n this.address = client.getUser()!.solanaAddress!;\n }\n\n /**\n * Adds a signature of the client user to a transaction\n *\n * @param {Transaction | VersionedTransaction} transaction - The transaction to add the signature to\n * @returns {Promise<Transaction | VersionedTransaction >} The transaction with the signature added\n */\n async addSignature(\n transaction: Transaction | VersionedTransaction,\n ): Promise<Transaction | VersionedTransaction> {\n const user = this.alchemyClient.getUser();\n if (!user) {\n throw new NotAuthenticatedError();\n }\n\n if (!user.solanaAddress) {\n throw new Error(\"no solana address\");\n }\n\n const fromKey = new PublicKey(user.solanaAddress);\n const messageToSign = this.getMessageToSign(transaction);\n const signature = await this.alchemyClient.signRawMessage(\n messageToSign,\n \"SOLANA\",\n );\n\n transaction.addSignature(\n fromKey,\n Buffer.from(toBytes(this.formatSignatureForSolana(signature))),\n );\n return transaction;\n }\n\n /**\n * Signs a message\n *\n * @param {Uint8Array} message - The message to sign\n * @returns {Promise<ByteArray>} The signature of the message\n */\n async signMessage(message: Uint8Array): Promise<ByteArray> {\n const user = this.alchemyClient.getUser();\n if (!user) {\n throw new NotAuthenticatedError();\n }\n\n if (!user.solanaAddress) {\n throw new Error(\"no solana address\");\n }\n\n const messageToSign = toHex(message);\n const signature = await this.alchemyClient.signRawMessage(\n messageToSign,\n \"SOLANA\",\n );\n\n return toBytes(this.formatSignatureForSolana(signature));\n }\n\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n version?: \"versioned\",\n ): Promise<VersionedTransaction>;\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n version?: \"legacy\",\n ): Promise<Transaction>;\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n ): Promise<VersionedTransaction>;\n\n /**\n * Creates a transfer transaction. Used for the SolanaCard example.\n *\n * @param {TransactionInstruction[]} instructions - The instructions to add to the transaction\n * @param {Connection} connection - The connection to use for the transaction\n * @param {\"versioned\" | \"legacy\"} [version] - The version of the transaction\n * @returns {Promise<Transaction | VersionedTransaction>} The transfer transaction\n */\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n version?: string,\n ): Promise<Transaction | VersionedTransaction> {\n const blockhash = (await connection.getLatestBlockhash()).blockhash;\n\n let transferTransaction;\n\n if (version === \"legacy\") {\n // Legacy transaction\n transferTransaction = instructions.reduce(\n (tx, instruction) => tx.add(instruction),\n new Transaction(),\n );\n\n // Get a recent block hash\n transferTransaction.recentBlockhash = blockhash;\n // Set the signer\n transferTransaction.feePayer = new PublicKey(this.address);\n } else {\n // VersionedTransaction\n const txMessage = new TransactionMessage({\n payerKey: new PublicKey(this.address),\n recentBlockhash: blockhash,\n instructions,\n });\n\n const versionedTxMessage = txMessage.compileToV0Message();\n transferTransaction = new VersionedTransaction(versionedTxMessage);\n }\n\n return transferTransaction;\n }\n\n /**\n * Adds sponsorship to a transaction. Used to have a party like Alchemy pay for the transaction.\n *\n * @param {TransactionInstruction[]} instructions - The instructions to add to the transaction\n * @param {Connection} connection - The connection to use for the transaction\n * @param {string} [policyId] - The policy ID to add sponsorship to\n * @returns {Promise<VersionedTransaction>} The transaction with sponsorship added\n */\n async addSponsorship(\n instructions: TransactionInstruction[],\n connection: Connection,\n policyId: string,\n ): Promise<VersionedTransaction> {\n const { blockhash } = await connection.getLatestBlockhash({\n commitment: \"finalized\",\n });\n const message = new TransactionMessage({\n // Right now the backend will rewrite this payer Key to the server's address\n payerKey: new PublicKey(this.address),\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n const versionedTransaction = new VersionedTransaction(message);\n const serializedTransaction = Buffer.from(\n versionedTransaction.serialize(),\n ).toString(\"base64\");\n const body = JSON.stringify({\n id: crypto?.randomUUID() ?? Math.floor(Math.random() * 1000000),\n jsonrpc: \"2.0\",\n method: \"alchemy_requestFeePayer\",\n params: [\n {\n policyId,\n serializedTransaction,\n },\n ],\n });\n const options = {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n },\n body,\n };\n\n const response = await fetch(\n // TODO: Use the connection??\n connection.rpcEndpoint,\n options,\n );\n const jsonResponse = await response.json();\n if (!jsonResponse?.result?.serializedTransaction)\n throw new Error(\n `Response doesn't include the serializedTransaction ${JSON.stringify(\n jsonResponse,\n )}`,\n );\n return VersionedTransaction.deserialize(\n decodeBase64(jsonResponse.result.serializedTransaction),\n );\n }\n\n private formatSignatureForSolana(signature: Hex): Hex {\n if (size(signature) === 64) return signature;\n\n return slice(signature, 0, 64);\n }\n\n private getMessageToSign(tx: Transaction | VersionedTransaction): Hex {\n let messageToSign;\n if (tx instanceof Transaction) {\n messageToSign = tx.serializeMessage();\n } else {\n messageToSign = Buffer.from(tx.message.serialize());\n }\n return toHex(messageToSign);\n }\n}\nfunction decodeBase64(serializedTransaction: string): Uint8Array {\n return Buffer.from(serializedTransaction, \"base64\");\n}\n"]}
1
+ {"version":3,"file":"solanaSigner.js","sourceRoot":"","sources":["../../src/solanaSigner.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Connection,\n PublicKey,\n Transaction,\n TransactionInstruction,\n TransactionMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport { size, slice, toBytes, toHex, type ByteArray, type Hex } from \"viem\";\nimport type { BaseSignerClient } from \"./client/base\";\nimport { NotAuthenticatedError } from \"./errors.js\";\nimport { createSolanaSponsoredTransaction } from \"./utils/solana.js\";\n\n/**\n * The SolanaSigner class is used to sign transactions and messages for the Solana blockchain.\n * It provides methods to add signatures to transactions and sign messages.\n */\nexport class SolanaSigner {\n readonly alchemyClient: BaseSignerClient;\n public readonly address: string;\n\n /**\n * Constructor for the SolanaSigner class which is a wrapper around the alchemy client, and is more focused on the solana web3\n *\n * @param {object} client This is the client that will be used to sign the transaction, and we are just having functions on top of it.\n */\n constructor(client: BaseSignerClient) {\n this.alchemyClient = client;\n if (!client.getUser()) throw new Error(\"Must be authenticated!\");\n\n // TODO: also throw here\n this.address = client.getUser()!.solanaAddress!;\n }\n\n /**\n * Adds a signature of the client user to a transaction\n *\n * @param {Transaction | VersionedTransaction} transaction - The transaction to add the signature to\n * @returns {Promise<Transaction | VersionedTransaction >} The transaction with the signature added\n */\n async addSignature(\n transaction: Transaction | VersionedTransaction,\n ): Promise<Transaction | VersionedTransaction> {\n const user = this.alchemyClient.getUser();\n if (!user) {\n throw new NotAuthenticatedError();\n }\n\n if (!user.solanaAddress) {\n throw new Error(\"no solana address\");\n }\n\n const fromKey = new PublicKey(user.solanaAddress);\n const messageToSign = this.getMessageToSign(transaction);\n const signature = await this.alchemyClient.signRawMessage(\n messageToSign,\n \"SOLANA\",\n );\n\n transaction.addSignature(\n fromKey,\n Buffer.from(toBytes(this.formatSignatureForSolana(signature))),\n );\n return transaction;\n }\n\n /**\n * Signs a message\n *\n * @param {Uint8Array} message - The message to sign\n * @returns {Promise<ByteArray>} The signature of the message\n */\n async signMessage(message: Uint8Array): Promise<ByteArray> {\n const user = this.alchemyClient.getUser();\n if (!user) {\n throw new NotAuthenticatedError();\n }\n\n if (!user.solanaAddress) {\n throw new Error(\"no solana address\");\n }\n\n const messageToSign = toHex(message);\n const signature = await this.alchemyClient.signRawMessage(\n messageToSign,\n \"SOLANA\",\n );\n\n return toBytes(this.formatSignatureForSolana(signature));\n }\n\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n version?: \"versioned\",\n ): Promise<VersionedTransaction>;\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n version?: \"legacy\",\n ): Promise<Transaction>;\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n ): Promise<VersionedTransaction>;\n\n /**\n * Creates a transfer transaction. Used for the SolanaCard example.\n *\n * @param {TransactionInstruction[]} instructions - The instructions to add to the transaction\n * @param {Connection} connection - The connection to use for the transaction\n * @param {\"versioned\" | \"legacy\"} [version] - The version of the transaction\n * @returns {Promise<Transaction | VersionedTransaction>} The transfer transaction\n */\n async createTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n version?: string,\n ): Promise<Transaction | VersionedTransaction> {\n const blockhash = (await connection.getLatestBlockhash()).blockhash;\n\n let transferTransaction;\n\n if (version === \"legacy\") {\n // Legacy transaction\n transferTransaction = instructions.reduce(\n (tx, instruction) => tx.add(instruction),\n new Transaction(),\n );\n\n // Get a recent block hash\n transferTransaction.recentBlockhash = blockhash;\n // Set the signer\n transferTransaction.feePayer = new PublicKey(this.address);\n } else {\n // VersionedTransaction\n const txMessage = new TransactionMessage({\n payerKey: new PublicKey(this.address),\n recentBlockhash: blockhash,\n instructions,\n });\n\n const versionedTxMessage = txMessage.compileToV0Message();\n transferTransaction = new VersionedTransaction(versionedTxMessage);\n }\n\n return transferTransaction;\n }\n\n /**\n * Adds sponsorship to a transaction. Used to have a party like Alchemy pay for the transaction.\n *\n * @param {TransactionInstruction[]} instructions - The instructions to add to the transaction\n * @param {Connection} connection - The connection to use for the transaction\n * @param {string} [policyId] - The policy ID to add sponsorship to\n * @returns {Promise<VersionedTransaction>} The transaction with sponsorship added\n */\n async addSponsorship(\n instructions: TransactionInstruction[],\n connection: Connection,\n policyId: string,\n ): Promise<VersionedTransaction> {\n return createSolanaSponsoredTransaction(\n instructions,\n connection,\n policyId,\n this.address,\n );\n }\n\n private formatSignatureForSolana(signature: Hex): Hex {\n if (size(signature) === 64) return signature;\n\n return slice(signature, 0, 64);\n }\n\n private getMessageToSign(tx: Transaction | VersionedTransaction): Hex {\n let messageToSign;\n if (tx instanceof Transaction) {\n messageToSign = tx.serializeMessage();\n } else {\n messageToSign = Buffer.from(tx.message.serialize());\n }\n return toHex(messageToSign);\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { TransactionInstruction } from "@solana/web3.js";
2
+ import { Connection, VersionedTransaction } from "@solana/web3.js";
3
+ /**
4
+ * This function wraps instructions in a sponsored transaction using Alchemy's fee payer service
5
+ *
6
+ * @param {TransactionInstruction[]} instructions - The instructions to add sponsorship to
7
+ * @param {Connection} connection - The connection to use
8
+ * @param {string} policyId - The policy id to use
9
+ * @param {string} address - The address to use
10
+ * @returns {Promise<VersionedTransaction>} - The sponsored transaction
11
+ */
12
+ export declare function createSolanaSponsoredTransaction(instructions: TransactionInstruction[], connection: Connection, policyId: string, address: string): Promise<VersionedTransaction>;
13
+ /**
14
+ * Creates a regular (non-sponsored) Solana transaction from instructions
15
+ *
16
+ * @param {TransactionInstruction[]} instructions - The instructions to create transaction from
17
+ * @param {Connection} connection - The connection to use
18
+ * @param {string} address - The payer address
19
+ * @returns {Promise<VersionedTransaction>} - The transaction
20
+ */
21
+ export declare function createSolanaTransaction(instructions: TransactionInstruction[], connection: Connection, address: string): Promise<VersionedTransaction>;
@@ -0,0 +1,72 @@
1
+ import { Connection, PublicKey, TransactionMessage, VersionedTransaction, } from "@solana/web3.js";
2
+ /**
3
+ * This function wraps instructions in a sponsored transaction using Alchemy's fee payer service
4
+ *
5
+ * @param {TransactionInstruction[]} instructions - The instructions to add sponsorship to
6
+ * @param {Connection} connection - The connection to use
7
+ * @param {string} policyId - The policy id to use
8
+ * @param {string} address - The address to use
9
+ * @returns {Promise<VersionedTransaction>} - The sponsored transaction
10
+ */
11
+ export async function createSolanaSponsoredTransaction(instructions, connection, policyId, address) {
12
+ const { blockhash } = await connection.getLatestBlockhash({
13
+ commitment: "finalized",
14
+ });
15
+ const message = new TransactionMessage({
16
+ // Right now the backend will rewrite this payer Key to the server's address
17
+ payerKey: new PublicKey(address),
18
+ recentBlockhash: blockhash,
19
+ instructions,
20
+ }).compileToV0Message();
21
+ const versionedTransaction = new VersionedTransaction(message);
22
+ const serializedTransaction = Buffer.from(versionedTransaction.serialize()).toString("base64");
23
+ const body = JSON.stringify({
24
+ id: crypto?.randomUUID() ?? Math.floor(Math.random() * 1000000),
25
+ jsonrpc: "2.0",
26
+ method: "alchemy_requestFeePayer",
27
+ params: [
28
+ {
29
+ policyId,
30
+ serializedTransaction,
31
+ },
32
+ ],
33
+ });
34
+ const options = {
35
+ method: "POST",
36
+ headers: {
37
+ accept: "application/json",
38
+ "content-type": "application/json",
39
+ },
40
+ body,
41
+ };
42
+ const response = await fetch(
43
+ // TODO: Use the connection??
44
+ connection.rpcEndpoint, options);
45
+ const jsonResponse = await response.json();
46
+ if (!jsonResponse?.result?.serializedTransaction)
47
+ throw new Error(`Response doesn't include the serializedTransaction ${JSON.stringify(jsonResponse)}`);
48
+ return VersionedTransaction.deserialize(decodeBase64(jsonResponse.result.serializedTransaction));
49
+ }
50
+ /**
51
+ * Creates a regular (non-sponsored) Solana transaction from instructions
52
+ *
53
+ * @param {TransactionInstruction[]} instructions - The instructions to create transaction from
54
+ * @param {Connection} connection - The connection to use
55
+ * @param {string} address - The payer address
56
+ * @returns {Promise<VersionedTransaction>} - The transaction
57
+ */
58
+ export async function createSolanaTransaction(instructions, connection, address) {
59
+ const { blockhash } = await connection.getLatestBlockhash({
60
+ commitment: "finalized",
61
+ });
62
+ const message = new TransactionMessage({
63
+ payerKey: new PublicKey(address),
64
+ recentBlockhash: blockhash,
65
+ instructions,
66
+ }).compileToV0Message();
67
+ return new VersionedTransaction(message);
68
+ }
69
+ function decodeBase64(serializedTransaction) {
70
+ return Buffer.from(serializedTransaction, "base64");
71
+ }
72
+ //# sourceMappingURL=solana.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solana.js","sourceRoot":"","sources":["../../../src/utils/solana.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,YAAsC,EACtC,UAAsB,EACtB,QAAgB,EAChB,OAAe;IAEf,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,UAAU,CAAC,kBAAkB,CAAC;QACxD,UAAU,EAAE,WAAW;KACxB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC;QACrC,4EAA4E;QAC5E,QAAQ,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC;QAChC,eAAe,EAAE,SAAS;QAC1B,YAAY;KACb,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACxB,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,qBAAqB,GAAG,MAAM,CAAC,IAAI,CACvC,oBAAoB,CAAC,SAAS,EAAE,CACjC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC;QAC/D,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,yBAAyB;QACjC,MAAM,EAAE;YACN;gBACE,QAAQ;gBACR,qBAAqB;aACtB;SACF;KACF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG;QACd,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI;KACL,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,KAAK;IAC1B,6BAA6B;IAC7B,UAAU,CAAC,WAAW,EACtB,OAAO,CACR,CAAC;IACF,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,qBAAqB;QAC9C,MAAM,IAAI,KAAK,CACb,sDAAsD,IAAI,CAAC,SAAS,CAClE,YAAY,CACb,EAAE,CACJ,CAAC;IACJ,OAAO,oBAAoB,CAAC,WAAW,CACrC,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,qBAAqB,CAAC,CACxD,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAAsC,EACtC,UAAsB,EACtB,OAAe;IAEf,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,UAAU,CAAC,kBAAkB,CAAC;QACxD,UAAU,EAAE,WAAW;KACxB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC;QACrC,QAAQ,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC;QAChC,eAAe,EAAE,SAAS;QAC1B,YAAY;KACb,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACxB,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,YAAY,CAAC,qBAA6B;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC","sourcesContent":["import type { TransactionInstruction } from \"@solana/web3.js\";\nimport {\n Connection,\n PublicKey,\n TransactionMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\n\n/**\n * This function wraps instructions in a sponsored transaction using Alchemy's fee payer service\n *\n * @param {TransactionInstruction[]} instructions - The instructions to add sponsorship to\n * @param {Connection} connection - The connection to use\n * @param {string} policyId - The policy id to use\n * @param {string} address - The address to use\n * @returns {Promise<VersionedTransaction>} - The sponsored transaction\n */\nexport async function createSolanaSponsoredTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n policyId: string,\n address: string,\n): Promise<VersionedTransaction> {\n const { blockhash } = await connection.getLatestBlockhash({\n commitment: \"finalized\",\n });\n const message = new TransactionMessage({\n // Right now the backend will rewrite this payer Key to the server's address\n payerKey: new PublicKey(address),\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n const versionedTransaction = new VersionedTransaction(message);\n const serializedTransaction = Buffer.from(\n versionedTransaction.serialize(),\n ).toString(\"base64\");\n const body = JSON.stringify({\n id: crypto?.randomUUID() ?? Math.floor(Math.random() * 1000000),\n jsonrpc: \"2.0\",\n method: \"alchemy_requestFeePayer\",\n params: [\n {\n policyId,\n serializedTransaction,\n },\n ],\n });\n const options = {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n },\n body,\n };\n\n const response = await fetch(\n // TODO: Use the connection??\n connection.rpcEndpoint,\n options,\n );\n const jsonResponse = await response.json();\n if (!jsonResponse?.result?.serializedTransaction)\n throw new Error(\n `Response doesn't include the serializedTransaction ${JSON.stringify(\n jsonResponse,\n )}`,\n );\n return VersionedTransaction.deserialize(\n decodeBase64(jsonResponse.result.serializedTransaction),\n );\n}\n\n/**\n * Creates a regular (non-sponsored) Solana transaction from instructions\n *\n * @param {TransactionInstruction[]} instructions - The instructions to create transaction from\n * @param {Connection} connection - The connection to use\n * @param {string} address - The payer address\n * @returns {Promise<VersionedTransaction>} - The transaction\n */\nexport async function createSolanaTransaction(\n instructions: TransactionInstruction[],\n connection: Connection,\n address: string,\n): Promise<VersionedTransaction> {\n const { blockhash } = await connection.getLatestBlockhash({\n commitment: \"finalized\",\n });\n const message = new TransactionMessage({\n payerKey: new PublicKey(address),\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n return new VersionedTransaction(message);\n}\n\nfunction decodeBase64(serializedTransaction: string): Uint8Array {\n return Buffer.from(serializedTransaction, \"base64\");\n}\n"]}
@@ -1 +1 @@
1
- export declare const VERSION = "4.54.1";
1
+ export declare const VERSION = "4.55.0";
@@ -1,4 +1,4 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "4.54.1";
3
+ export const VERSION = "4.55.0";
4
4
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"4.54.1\";\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"4.55.0\";\n"]}
@@ -10,4 +10,5 @@ export type * from "./solanaSigner.js";
10
10
  export type * from "./types.js";
11
11
  export { AlchemySignerStatus } from "./types.js";
12
12
  export { SolanaSigner } from "./solanaSigner.js";
13
+ export { createSolanaSponsoredTransaction, createSolanaTransaction, } from "./utils/solana.js";
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,mBAAmB,mBAAmB,CAAC;AACvC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,mBAAmB,aAAa,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,YAAY,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,mBAAmB,mBAAmB,CAAC;AACvC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,mBAAmB,aAAa,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,YAAY,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"solanaSigner.d.ts","sourceRoot":"","sources":["../../src/solanaSigner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,WAAW,EACX,sBAAsB,EAEtB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA+B,KAAK,SAAS,EAAY,MAAM,MAAM,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD;;;GAGG;AACH,qBAAa,YAAY;IACvB,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;gBACS,MAAM,EAAE,gBAAgB;IAQpC;;;;;OAKG;IACG,YAAY,CAChB,WAAW,EAAE,WAAW,GAAG,oBAAoB,GAC9C,OAAO,CAAC,WAAW,GAAG,oBAAoB,CAAC;IAwB9C;;;;;OAKG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAmBpD,iBAAiB,CACrB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,oBAAoB,CAAC;IAC1B,iBAAiB,CACrB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,WAAW,CAAC;IACjB,iBAAiB,CACrB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,oBAAoB,CAAC;IA6ChC;;;;;;;OAOG;IACG,cAAc,CAClB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAmDhC,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,gBAAgB;CASzB"}
1
+ {"version":3,"file":"solanaSigner.d.ts","sourceRoot":"","sources":["../../src/solanaSigner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,WAAW,EACX,sBAAsB,EAEtB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA+B,KAAK,SAAS,EAAY,MAAM,MAAM,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD;;;GAGG;AACH,qBAAa,YAAY;IACvB,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;gBACS,MAAM,EAAE,gBAAgB;IAQpC;;;;;OAKG;IACG,YAAY,CAChB,WAAW,EAAE,WAAW,GAAG,oBAAoB,GAC9C,OAAO,CAAC,WAAW,GAAG,oBAAoB,CAAC;IAwB9C;;;;;OAKG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAmBpD,iBAAiB,CACrB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,oBAAoB,CAAC;IAC1B,iBAAiB,CACrB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,WAAW,CAAC;IACjB,iBAAiB,CACrB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,oBAAoB,CAAC;IA6ChC;;;;;;;OAOG;IACG,cAAc,CAClB,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAShC,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,gBAAgB;CASzB"}
@@ -0,0 +1,22 @@
1
+ import type { TransactionInstruction } from "@solana/web3.js";
2
+ import { Connection, VersionedTransaction } from "@solana/web3.js";
3
+ /**
4
+ * This function wraps instructions in a sponsored transaction using Alchemy's fee payer service
5
+ *
6
+ * @param {TransactionInstruction[]} instructions - The instructions to add sponsorship to
7
+ * @param {Connection} connection - The connection to use
8
+ * @param {string} policyId - The policy id to use
9
+ * @param {string} address - The address to use
10
+ * @returns {Promise<VersionedTransaction>} - The sponsored transaction
11
+ */
12
+ export declare function createSolanaSponsoredTransaction(instructions: TransactionInstruction[], connection: Connection, policyId: string, address: string): Promise<VersionedTransaction>;
13
+ /**
14
+ * Creates a regular (non-sponsored) Solana transaction from instructions
15
+ *
16
+ * @param {TransactionInstruction[]} instructions - The instructions to create transaction from
17
+ * @param {Connection} connection - The connection to use
18
+ * @param {string} address - The payer address
19
+ * @returns {Promise<VersionedTransaction>} - The transaction
20
+ */
21
+ export declare function createSolanaTransaction(instructions: TransactionInstruction[], connection: Connection, address: string): Promise<VersionedTransaction>;
22
+ //# sourceMappingURL=solana.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../src/utils/solana.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EACL,UAAU,EAGV,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;GAQG;AACH,wBAAsB,gCAAgC,CACpD,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CAiD/B;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,sBAAsB,EAAE,EACtC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CAU/B"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "4.54.1";
1
+ export declare const VERSION = "4.55.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@account-kit/signer",
3
- "version": "4.54.1",
3
+ "version": "4.55.0",
4
4
  "description": "Core interfaces and clients for interfacing with the Alchemy Signer API",
5
5
  "author": "Alchemy",
6
6
  "license": "MIT",
@@ -48,8 +48,8 @@
48
48
  "typescript-template": "*"
49
49
  },
50
50
  "dependencies": {
51
- "@aa-sdk/core": "^4.54.1",
52
- "@account-kit/logging": "^4.54.1",
51
+ "@aa-sdk/core": "^4.55.0",
52
+ "@account-kit/logging": "^4.55.0",
53
53
  "@noble/curves": "^1.9.2",
54
54
  "@noble/hashes": "1.7.1",
55
55
  "@noble/secp256k1": "^2.3.0",
@@ -78,5 +78,5 @@
78
78
  "url": "https://github.com/alchemyplatform/aa-sdk/issues"
79
79
  },
80
80
  "homepage": "https://github.com/alchemyplatform/aa-sdk#readme",
81
- "gitHead": "44a337cbf1375398d92a74ea527fcf4d9bccdde7"
81
+ "gitHead": "0fd8daecdf3e978afc6dc795579f5222ec7e0ebf"
82
82
  }
package/src/index.ts CHANGED
@@ -21,3 +21,7 @@ export type * from "./solanaSigner.js";
21
21
  export type * from "./types.js";
22
22
  export { AlchemySignerStatus } from "./types.js";
23
23
  export { SolanaSigner } from "./solanaSigner.js";
24
+ export {
25
+ createSolanaSponsoredTransaction,
26
+ createSolanaTransaction,
27
+ } from "./utils/solana.js";
@@ -9,6 +9,7 @@ import {
9
9
  import { size, slice, toBytes, toHex, type ByteArray, type Hex } from "viem";
10
10
  import type { BaseSignerClient } from "./client/base";
11
11
  import { NotAuthenticatedError } from "./errors.js";
12
+ import { createSolanaSponsoredTransaction } from "./utils/solana.js";
12
13
 
13
14
  /**
14
15
  * The SolanaSigner class is used to sign transactions and messages for the Solana blockchain.
@@ -159,53 +160,11 @@ export class SolanaSigner {
159
160
  connection: Connection,
160
161
  policyId: string,
161
162
  ): Promise<VersionedTransaction> {
162
- const { blockhash } = await connection.getLatestBlockhash({
163
- commitment: "finalized",
164
- });
165
- const message = new TransactionMessage({
166
- // Right now the backend will rewrite this payer Key to the server's address
167
- payerKey: new PublicKey(this.address),
168
- recentBlockhash: blockhash,
163
+ return createSolanaSponsoredTransaction(
169
164
  instructions,
170
- }).compileToV0Message();
171
- const versionedTransaction = new VersionedTransaction(message);
172
- const serializedTransaction = Buffer.from(
173
- versionedTransaction.serialize(),
174
- ).toString("base64");
175
- const body = JSON.stringify({
176
- id: crypto?.randomUUID() ?? Math.floor(Math.random() * 1000000),
177
- jsonrpc: "2.0",
178
- method: "alchemy_requestFeePayer",
179
- params: [
180
- {
181
- policyId,
182
- serializedTransaction,
183
- },
184
- ],
185
- });
186
- const options = {
187
- method: "POST",
188
- headers: {
189
- accept: "application/json",
190
- "content-type": "application/json",
191
- },
192
- body,
193
- };
194
-
195
- const response = await fetch(
196
- // TODO: Use the connection??
197
- connection.rpcEndpoint,
198
- options,
199
- );
200
- const jsonResponse = await response.json();
201
- if (!jsonResponse?.result?.serializedTransaction)
202
- throw new Error(
203
- `Response doesn't include the serializedTransaction ${JSON.stringify(
204
- jsonResponse,
205
- )}`,
206
- );
207
- return VersionedTransaction.deserialize(
208
- decodeBase64(jsonResponse.result.serializedTransaction),
165
+ connection,
166
+ policyId,
167
+ this.address,
209
168
  );
210
169
  }
211
170
 
@@ -225,6 +184,3 @@ export class SolanaSigner {
225
184
  return toHex(messageToSign);
226
185
  }
227
186
  }
228
- function decodeBase64(serializedTransaction: string): Uint8Array {
229
- return Buffer.from(serializedTransaction, "base64");
230
- }
@@ -0,0 +1,100 @@
1
+ import type { TransactionInstruction } from "@solana/web3.js";
2
+ import {
3
+ Connection,
4
+ PublicKey,
5
+ TransactionMessage,
6
+ VersionedTransaction,
7
+ } from "@solana/web3.js";
8
+
9
+ /**
10
+ * This function wraps instructions in a sponsored transaction using Alchemy's fee payer service
11
+ *
12
+ * @param {TransactionInstruction[]} instructions - The instructions to add sponsorship to
13
+ * @param {Connection} connection - The connection to use
14
+ * @param {string} policyId - The policy id to use
15
+ * @param {string} address - The address to use
16
+ * @returns {Promise<VersionedTransaction>} - The sponsored transaction
17
+ */
18
+ export async function createSolanaSponsoredTransaction(
19
+ instructions: TransactionInstruction[],
20
+ connection: Connection,
21
+ policyId: string,
22
+ address: string,
23
+ ): Promise<VersionedTransaction> {
24
+ const { blockhash } = await connection.getLatestBlockhash({
25
+ commitment: "finalized",
26
+ });
27
+ const message = new TransactionMessage({
28
+ // Right now the backend will rewrite this payer Key to the server's address
29
+ payerKey: new PublicKey(address),
30
+ recentBlockhash: blockhash,
31
+ instructions,
32
+ }).compileToV0Message();
33
+ const versionedTransaction = new VersionedTransaction(message);
34
+ const serializedTransaction = Buffer.from(
35
+ versionedTransaction.serialize(),
36
+ ).toString("base64");
37
+ const body = JSON.stringify({
38
+ id: crypto?.randomUUID() ?? Math.floor(Math.random() * 1000000),
39
+ jsonrpc: "2.0",
40
+ method: "alchemy_requestFeePayer",
41
+ params: [
42
+ {
43
+ policyId,
44
+ serializedTransaction,
45
+ },
46
+ ],
47
+ });
48
+ const options = {
49
+ method: "POST",
50
+ headers: {
51
+ accept: "application/json",
52
+ "content-type": "application/json",
53
+ },
54
+ body,
55
+ };
56
+
57
+ const response = await fetch(
58
+ // TODO: Use the connection??
59
+ connection.rpcEndpoint,
60
+ options,
61
+ );
62
+ const jsonResponse = await response.json();
63
+ if (!jsonResponse?.result?.serializedTransaction)
64
+ throw new Error(
65
+ `Response doesn't include the serializedTransaction ${JSON.stringify(
66
+ jsonResponse,
67
+ )}`,
68
+ );
69
+ return VersionedTransaction.deserialize(
70
+ decodeBase64(jsonResponse.result.serializedTransaction),
71
+ );
72
+ }
73
+
74
+ /**
75
+ * Creates a regular (non-sponsored) Solana transaction from instructions
76
+ *
77
+ * @param {TransactionInstruction[]} instructions - The instructions to create transaction from
78
+ * @param {Connection} connection - The connection to use
79
+ * @param {string} address - The payer address
80
+ * @returns {Promise<VersionedTransaction>} - The transaction
81
+ */
82
+ export async function createSolanaTransaction(
83
+ instructions: TransactionInstruction[],
84
+ connection: Connection,
85
+ address: string,
86
+ ): Promise<VersionedTransaction> {
87
+ const { blockhash } = await connection.getLatestBlockhash({
88
+ commitment: "finalized",
89
+ });
90
+ const message = new TransactionMessage({
91
+ payerKey: new PublicKey(address),
92
+ recentBlockhash: blockhash,
93
+ instructions,
94
+ }).compileToV0Message();
95
+ return new VersionedTransaction(message);
96
+ }
97
+
98
+ function decodeBase64(serializedTransaction: string): Uint8Array {
99
+ return Buffer.from(serializedTransaction, "base64");
100
+ }
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "4.54.1";
3
+ export const VERSION = "4.55.0";