@account-kit/signer 4.53.2-alpha.0 → 4.53.3-alpha.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.
- package/dist/esm/base.d.ts +0 -1
- package/dist/esm/base.js +0 -34
- package/dist/esm/base.js.map +1 -1
- package/dist/esm/client/base.d.ts +1 -2
- package/dist/esm/client/base.js.map +1 -1
- package/dist/esm/client/index.d.ts +1 -27
- package/dist/esm/client/index.js +0 -35
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/types.d.ts +1 -18
- package/dist/esm/client/types.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/metrics.d.ts +0 -3
- package/dist/esm/metrics.js.map +1 -1
- package/dist/esm/session/manager.js +0 -6
- package/dist/esm/session/manager.js.map +1 -1
- package/dist/esm/session/types.d.ts +1 -1
- package/dist/esm/session/types.js.map +1 -1
- package/dist/esm/signer.d.ts +1 -4
- package/dist/esm/signer.js.map +1 -1
- package/dist/esm/solanaSigner.js +2 -40
- package/dist/esm/solanaSigner.js.map +1 -1
- package/dist/esm/types.d.ts +0 -1
- package/dist/esm/types.js +0 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/solana.d.ts +21 -0
- package/dist/esm/utils/solana.js +72 -0
- package/dist/esm/utils/solana.js.map +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/base.d.ts +0 -1
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/client/base.d.ts +1 -2
- package/dist/types/client/base.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +1 -27
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/client/types.d.ts +1 -18
- package/dist/types/client/types.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/metrics.d.ts +0 -3
- package/dist/types/metrics.d.ts.map +1 -1
- package/dist/types/session/manager.d.ts.map +1 -1
- package/dist/types/session/types.d.ts +1 -1
- package/dist/types/session/types.d.ts.map +1 -1
- package/dist/types/signer.d.ts +1 -4
- package/dist/types/signer.d.ts.map +1 -1
- package/dist/types/solanaSigner.d.ts.map +1 -1
- package/dist/types/types.d.ts +0 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/solana.d.ts +22 -0
- package/dist/types/utils/solana.d.ts.map +1 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +4 -4
- package/src/base.ts +0 -34
- package/src/client/base.ts +0 -6
- package/src/client/index.ts +0 -40
- package/src/client/types.ts +1 -27
- package/src/index.ts +4 -0
- package/src/metrics.ts +1 -2
- package/src/session/manager.ts +2 -8
- package/src/session/types.ts +1 -1
- package/src/signer.ts +0 -4
- package/src/solanaSigner.ts +5 -49
- package/src/types.ts +0 -1
- package/src/utils/solana.ts +100 -0
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@account-kit/signer",
|
|
3
|
-
"version": "4.53.
|
|
3
|
+
"version": "4.53.3-alpha.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.53.
|
|
52
|
-
"@account-kit/logging": "^4.53.
|
|
51
|
+
"@aa-sdk/core": "^4.53.3-alpha.0",
|
|
52
|
+
"@account-kit/logging": "^4.53.3-alpha.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": "
|
|
81
|
+
"gitHead": "ee82ab2d79bf9cc21edd1f588a0d4d1b4710a29c"
|
|
82
82
|
}
|
package/src/base.ts
CHANGED
|
@@ -330,8 +330,6 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
|
|
|
330
330
|
return this.handleOauthReturn(params);
|
|
331
331
|
case "otp":
|
|
332
332
|
return this.authenticateWithOtp(params);
|
|
333
|
-
case "custom-jwt":
|
|
334
|
-
return this.authenticateWithJwt(params);
|
|
335
333
|
default:
|
|
336
334
|
assertNever(type, `Unknown auth type: ${type}`);
|
|
337
335
|
}
|
|
@@ -387,16 +385,6 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
|
|
|
387
385
|
});
|
|
388
386
|
return;
|
|
389
387
|
}
|
|
390
|
-
case "custom-jwt": {
|
|
391
|
-
SignerLogger.trackEvent({
|
|
392
|
-
name: "signer_authnticate",
|
|
393
|
-
data: {
|
|
394
|
-
authType: "custom-jwt",
|
|
395
|
-
provider: params.authProviderId,
|
|
396
|
-
},
|
|
397
|
-
});
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
388
|
case "oauth":
|
|
401
389
|
SignerLogger.trackEvent({
|
|
402
390
|
name: "signer_authnticate",
|
|
@@ -1225,26 +1213,6 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
|
|
|
1225
1213
|
return this.inner.listAuthMethods();
|
|
1226
1214
|
};
|
|
1227
1215
|
|
|
1228
|
-
private authenticateWithJwt = async (
|
|
1229
|
-
args: Extract<AuthParams, { type: "custom-jwt" }>,
|
|
1230
|
-
): Promise<User> => {
|
|
1231
|
-
const { credentialBundle, orgId, isSignUp } = await this.inner.submitJwt({
|
|
1232
|
-
jwt: args.jwt,
|
|
1233
|
-
authProvider: args.authProviderId,
|
|
1234
|
-
expirationSeconds: this.getExpirationSeconds(),
|
|
1235
|
-
});
|
|
1236
|
-
|
|
1237
|
-
const user = await this.inner.completeAuthWithBundle({
|
|
1238
|
-
bundle: credentialBundle,
|
|
1239
|
-
orgId: orgId,
|
|
1240
|
-
connectedEventName: "connectedJwt",
|
|
1241
|
-
authenticatingType: "custom-jwt",
|
|
1242
|
-
});
|
|
1243
|
-
|
|
1244
|
-
this.emitNewUserEvent(isSignUp);
|
|
1245
|
-
return user;
|
|
1246
|
-
};
|
|
1247
|
-
|
|
1248
1216
|
private authenticateWithOtp = async (
|
|
1249
1217
|
args: Extract<AuthParams, { type: "otp" }>,
|
|
1250
1218
|
): Promise<User> => {
|
|
@@ -1431,8 +1399,6 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
|
|
|
1431
1399
|
return AlchemySignerStatus.AWAITING_OTP_AUTH;
|
|
1432
1400
|
case "sms":
|
|
1433
1401
|
return AlchemySignerStatus.AWAITING_SMS_AUTH;
|
|
1434
|
-
case "custom-jwt":
|
|
1435
|
-
return AlchemySignerStatus.AUTHENTICATING_JWT;
|
|
1436
1402
|
default:
|
|
1437
1403
|
assertNever(type, "unhandled authenticating type");
|
|
1438
1404
|
}
|
package/src/client/base.ts
CHANGED
|
@@ -29,8 +29,6 @@ import type {
|
|
|
29
29
|
GetOauthProviderUrlArgs,
|
|
30
30
|
GetWebAuthnAttestationResult,
|
|
31
31
|
MfaFactor,
|
|
32
|
-
JwtParams,
|
|
33
|
-
JwtResponse,
|
|
34
32
|
OauthConfig,
|
|
35
33
|
OauthParams,
|
|
36
34
|
OauthState,
|
|
@@ -257,10 +255,6 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
|
|
|
257
255
|
args: Omit<OtpParams, "targetPublicKey">,
|
|
258
256
|
): Promise<SubmitOtpCodeResponse>;
|
|
259
257
|
|
|
260
|
-
public abstract submitJwt(
|
|
261
|
-
args: Omit<JwtParams, "targetPublicKey">,
|
|
262
|
-
): Promise<JwtResponse>;
|
|
263
|
-
|
|
264
258
|
public abstract disconnect(): Promise<void>;
|
|
265
259
|
|
|
266
260
|
public abstract exportWallet(params: TExportWalletParams): Promise<boolean>;
|
package/src/client/index.ts
CHANGED
|
@@ -14,8 +14,6 @@ import type {
|
|
|
14
14
|
ExportWalletParams,
|
|
15
15
|
OauthConfig,
|
|
16
16
|
OtpParams,
|
|
17
|
-
JwtParams,
|
|
18
|
-
JwtResponse,
|
|
19
17
|
User,
|
|
20
18
|
SubmitOtpCodeResponse,
|
|
21
19
|
AuthLinkingPrompt,
|
|
@@ -261,44 +259,6 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
|
|
|
261
259
|
);
|
|
262
260
|
}
|
|
263
261
|
|
|
264
|
-
/**
|
|
265
|
-
* Authenticates using a custom issued JWT
|
|
266
|
-
*
|
|
267
|
-
* @example
|
|
268
|
-
* ```ts
|
|
269
|
-
* import { AlchemySignerWebClient } from "@account-kit/signer";
|
|
270
|
-
*
|
|
271
|
-
* const client = new AlchemySignerWebClient({
|
|
272
|
-
* connection: {
|
|
273
|
-
* apiKey: "your-api-key",
|
|
274
|
-
* },
|
|
275
|
-
* iframeConfig: {
|
|
276
|
-
* iframeContainerId: "signer-iframe-container",
|
|
277
|
-
* },
|
|
278
|
-
* });
|
|
279
|
-
*
|
|
280
|
-
* const account = await client.submitJwt({
|
|
281
|
-
* jwt: "custom-issued-jwt",
|
|
282
|
-
* authProvider: "auth-provider-name",
|
|
283
|
-
* });
|
|
284
|
-
* ```
|
|
285
|
-
*
|
|
286
|
-
* @param {Omit<JwtParams, "targetPublicKey">} args The parameters for the JWT request, excluding the target public key.
|
|
287
|
-
* @returns {Promise<{ bundle: string }>} A promise that resolves to an object containing the credential bundle.
|
|
288
|
-
*/
|
|
289
|
-
public override async submitJwt(
|
|
290
|
-
args: Omit<JwtParams, "targetPublicKey">,
|
|
291
|
-
): Promise<JwtResponse> {
|
|
292
|
-
this.eventEmitter.emit("authenticating", { type: "custom-jwt" });
|
|
293
|
-
const targetPublicKey = await this.initSessionStamper();
|
|
294
|
-
return this.request("/v1/auth-jwt", {
|
|
295
|
-
jwt: args.jwt,
|
|
296
|
-
targetPublicKey,
|
|
297
|
-
authProvider: args.authProvider,
|
|
298
|
-
expirationSeconds: args?.expirationSeconds,
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
|
|
302
262
|
/**
|
|
303
263
|
* Completes auth for the user by injecting a credential bundle and retrieving
|
|
304
264
|
* the user information based on the provided organization ID. Emits events
|
package/src/client/types.ts
CHANGED
|
@@ -95,19 +95,6 @@ export type OtpResponse =
|
|
|
95
95
|
multiFactors: MfaFactor[];
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
export type JwtParams = {
|
|
99
|
-
jwt: string;
|
|
100
|
-
targetPublicKey: string;
|
|
101
|
-
authProvider: string;
|
|
102
|
-
expirationSeconds?: number;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export type JwtResponse = {
|
|
106
|
-
isSignUp: boolean;
|
|
107
|
-
orgId: string;
|
|
108
|
-
credentialBundle: string;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
98
|
export type SignupResponse = {
|
|
112
99
|
orgId: string;
|
|
113
100
|
userId?: string;
|
|
@@ -276,11 +263,6 @@ export type SignerEndpoints = [
|
|
|
276
263
|
multiFactors: MfaFactor[];
|
|
277
264
|
};
|
|
278
265
|
},
|
|
279
|
-
{
|
|
280
|
-
Route: "/v1/auth-jwt";
|
|
281
|
-
Body: JwtParams;
|
|
282
|
-
Response: JwtResponse;
|
|
283
|
-
},
|
|
284
266
|
{
|
|
285
267
|
Route: "/v1/signer-config";
|
|
286
268
|
Body: {};
|
|
@@ -365,14 +347,7 @@ export type SignerEndpoints = [
|
|
|
365
347
|
];
|
|
366
348
|
|
|
367
349
|
export type AuthenticatingEventMetadata = {
|
|
368
|
-
type:
|
|
369
|
-
| "email"
|
|
370
|
-
| "passkey"
|
|
371
|
-
| "oauth"
|
|
372
|
-
| "otp"
|
|
373
|
-
| "otpVerify"
|
|
374
|
-
| "custom-jwt"
|
|
375
|
-
| "sms";
|
|
350
|
+
type: "email" | "passkey" | "oauth" | "otp" | "otpVerify" | "sms";
|
|
376
351
|
};
|
|
377
352
|
|
|
378
353
|
export type AlchemySignerClientEvents = {
|
|
@@ -383,7 +358,6 @@ export type AlchemySignerClientEvents = {
|
|
|
383
358
|
connectedPasskey(user: User): void;
|
|
384
359
|
connectedOauth(user: User, bundle: string): void;
|
|
385
360
|
connectedOtp(user: User, bundle: string): void;
|
|
386
|
-
connectedJwt(user: User, bundle: string): void;
|
|
387
361
|
disconnected(): void;
|
|
388
362
|
};
|
|
389
363
|
|
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";
|
package/src/metrics.ts
CHANGED
|
@@ -15,8 +15,7 @@ export type SignerEventsSchema = [
|
|
|
15
15
|
| "oauthReturn";
|
|
16
16
|
provider?: never;
|
|
17
17
|
}
|
|
18
|
-
| { authType: "oauth"; provider: string }
|
|
19
|
-
| { authType: "custom-jwt"; provider: string };
|
|
18
|
+
| { authType: "oauth"; provider: string };
|
|
20
19
|
},
|
|
21
20
|
{
|
|
22
21
|
EventName: "signer_sign_message";
|
package/src/session/manager.ts
CHANGED
|
@@ -97,7 +97,6 @@ export class SessionManager {
|
|
|
97
97
|
switch (existingSession.type) {
|
|
98
98
|
case "email":
|
|
99
99
|
case "oauth":
|
|
100
|
-
case "custom-jwt":
|
|
101
100
|
case "otp": {
|
|
102
101
|
const connectedEventName = (() => {
|
|
103
102
|
switch (existingSession.type) {
|
|
@@ -107,8 +106,6 @@ export class SessionManager {
|
|
|
107
106
|
return "connectedOauth";
|
|
108
107
|
case "otp":
|
|
109
108
|
return "connectedOtp";
|
|
110
|
-
case "custom-jwt":
|
|
111
|
-
return "connectedJwt";
|
|
112
109
|
}
|
|
113
110
|
})();
|
|
114
111
|
const result = await this.client
|
|
@@ -211,7 +208,7 @@ export class SessionManager {
|
|
|
211
208
|
private setSession = (
|
|
212
209
|
session_:
|
|
213
210
|
| Omit<
|
|
214
|
-
Extract<Session, { type: "email" | "oauth" | "otp"
|
|
211
|
+
Extract<Session, { type: "email" | "oauth" | "otp" }>,
|
|
215
212
|
"expirationDateMs"
|
|
216
213
|
>
|
|
217
214
|
| Omit<Extract<Session, { type: "passkey" }>, "expirationDateMs">,
|
|
@@ -287,9 +284,6 @@ export class SessionManager {
|
|
|
287
284
|
connectedOtp: (user, bundle) => {
|
|
288
285
|
this.setSessionWithUserAndBundle({ type: "otp", user, bundle });
|
|
289
286
|
},
|
|
290
|
-
connectedJwt: (user, bundle) => {
|
|
291
|
-
this.setSessionWithUserAndBundle({ type: "custom-jwt", user, bundle });
|
|
292
|
-
},
|
|
293
287
|
disconnected: () => this.clearSession(),
|
|
294
288
|
};
|
|
295
289
|
|
|
@@ -345,7 +339,7 @@ export class SessionManager {
|
|
|
345
339
|
user,
|
|
346
340
|
bundle,
|
|
347
341
|
}: {
|
|
348
|
-
type: "email" | "oauth" | "otp"
|
|
342
|
+
type: "email" | "oauth" | "otp";
|
|
349
343
|
user: User;
|
|
350
344
|
bundle: string;
|
|
351
345
|
}) => {
|
package/src/session/types.ts
CHANGED
package/src/signer.ts
CHANGED
package/src/solanaSigner.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
}
|
package/src/types.ts
CHANGED
|
@@ -23,7 +23,6 @@ export enum AlchemySignerStatus {
|
|
|
23
23
|
AUTHENTICATING_PASSKEY = "AUTHENTICATING_PASSKEY",
|
|
24
24
|
AUTHENTICATING_EMAIL = "AUTHENTICATING_EMAIL",
|
|
25
25
|
AUTHENTICATING_OAUTH = "AUTHENTICATING_OAUTH",
|
|
26
|
-
AUTHENTICATING_JWT = "AUTHENTICATING_JWT",
|
|
27
26
|
AWAITING_EMAIL_AUTH = "AWAITING_EMAIL_AUTH",
|
|
28
27
|
AWAITING_SMS_AUTH = "AWAITING_SMS_AUTH",
|
|
29
28
|
AWAITING_OTP_AUTH = "AWAITING_OTP_AUTH",
|
|
@@ -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