@fogo/sessions-sdk 0.0.12 → 0.0.14
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.js +6 -2
- package/cjs/crypto.d.ts +21 -0
- package/cjs/crypto.js +39 -0
- package/cjs/index.d.ts +1203 -158
- package/cjs/index.js +262 -46
- package/esm/adapter.js +6 -2
- package/esm/crypto.d.ts +21 -0
- package/esm/crypto.js +30 -0
- package/esm/index.d.ts +1203 -158
- package/esm/index.js +260 -47
- package/package.json +3 -12
- package/cjs/paymaster.d.ts +0 -7
- package/cjs/paymaster.js +0 -51
- package/esm/paymaster.d.ts +0 -7
- package/esm/paymaster.js +0 -47
package/cjs/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.sendTransfer = exports.SessionResultType = exports.getDomainRecordAddress = exports.AuthorizedTokens = exports.AuthorizedProgramsType = exports.getSessionAccount = exports.reestablishSession = exports.replaceSession = exports.establishSession = exports.
|
|
6
|
+
exports.verifyLogInToken = exports.createLogInToken = exports.sendTransfer = exports.SessionResultType = exports.getDomainRecordAddress = exports.AuthorizedTokens = exports.AuthorizedProgramsType = exports.getSessionAccount = exports.reestablishSession = exports.revokeSession = exports.replaceSession = exports.establishSession = exports.TransactionResultType = exports.createSolanaWalletAdapter = void 0;
|
|
7
7
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
8
8
|
const sessions_idls_1 = require("@fogo/sessions-idls");
|
|
9
9
|
const mpl_token_metadata_1 = require("@metaplex-foundation/mpl-token-metadata");
|
|
@@ -15,22 +15,26 @@ const kit_1 = require("@solana/kit");
|
|
|
15
15
|
const spl_token_1 = require("@solana/spl-token");
|
|
16
16
|
const web3_js_1 = require("@solana/web3.js");
|
|
17
17
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
18
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
18
19
|
const zod_1 = require("zod");
|
|
19
20
|
const adapter_js_1 = require("./adapter.js");
|
|
21
|
+
const crypto_js_1 = require("./crypto.js");
|
|
20
22
|
var adapter_js_2 = require("./adapter.js");
|
|
21
|
-
Object.defineProperty(exports, "TransactionResultType", { enumerable: true, get: function () { return adapter_js_2.TransactionResultType; } });
|
|
22
23
|
Object.defineProperty(exports, "createSolanaWalletAdapter", { enumerable: true, get: function () { return adapter_js_2.createSolanaWalletAdapter; } });
|
|
24
|
+
Object.defineProperty(exports, "TransactionResultType", { enumerable: true, get: function () { return adapter_js_2.TransactionResultType; } });
|
|
23
25
|
const MESSAGE_HEADER = `Fogo Sessions:
|
|
24
26
|
Signing this intent will allow this app to interact with your on-chain balances. Please make sure you trust this app and the domain in the message matches the domain of the current web application.
|
|
25
27
|
`;
|
|
26
28
|
const UNLIMITED_TOKEN_PERMISSIONS_VALUE = "this app may spend any amount of any token";
|
|
27
29
|
const TOKENLESS_PERMISSIONS_VALUE = "this app may not spend any tokens";
|
|
28
30
|
const CURRENT_MAJOR = "0";
|
|
29
|
-
const CURRENT_MINOR = "
|
|
31
|
+
const CURRENT_MINOR = "3";
|
|
30
32
|
const CURRENT_INTENT_TRANSFER_MAJOR = "0";
|
|
31
33
|
const CURRENT_INTENT_TRANSFER_MINOR = "1";
|
|
32
34
|
const establishSession = async (options) => {
|
|
33
|
-
const sessionKey =
|
|
35
|
+
const sessionKey = options.createUnsafeExtractableSessionKey
|
|
36
|
+
? await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"])
|
|
37
|
+
: await (0, kit_1.generateKeyPair)();
|
|
34
38
|
if (options.unlimited) {
|
|
35
39
|
return sendSessionEstablishTransaction(options, sessionKey, await Promise.all([
|
|
36
40
|
buildIntentInstruction(options, sessionKey),
|
|
@@ -73,10 +77,28 @@ const replaceSession = async (options) => (0, exports.establishSession)({
|
|
|
73
77
|
walletPublicKey: options.session.walletPublicKey,
|
|
74
78
|
});
|
|
75
79
|
exports.replaceSession = replaceSession;
|
|
80
|
+
const revokeSession = async (options) => {
|
|
81
|
+
if (options.session.sessionInfo.minor >= 2) {
|
|
82
|
+
const instruction = await new sessions_idls_1.SessionManagerProgram(new anchor_1.AnchorProvider(options.adapter.connection, {}, {})).methods
|
|
83
|
+
.revokeSession()
|
|
84
|
+
.accounts({
|
|
85
|
+
sponsor: options.session.sessionInfo.sponsor,
|
|
86
|
+
session: options.session.sessionPublicKey,
|
|
87
|
+
})
|
|
88
|
+
.instruction();
|
|
89
|
+
return options.adapter.sendTransaction(options.session.sessionKey, [
|
|
90
|
+
instruction,
|
|
91
|
+
]);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
exports.revokeSession = revokeSession;
|
|
76
98
|
const reestablishSession = async (adapter, walletPublicKey, sessionKey) => createSession(adapter, walletPublicKey, sessionKey);
|
|
77
99
|
exports.reestablishSession = reestablishSession;
|
|
78
100
|
const getSessionAccount = async (connection, sessionPublicKey) => {
|
|
79
|
-
const result = await connection.getAccountInfo(sessionPublicKey);
|
|
101
|
+
const result = await connection.getAccountInfo(sessionPublicKey, "confirmed");
|
|
80
102
|
return result === null
|
|
81
103
|
? undefined
|
|
82
104
|
: sessionInfoSchema.parse(new anchor_1.BorshAccountsCoder(sessions_idls_1.SessionManagerIdl).decode("Session", result.data));
|
|
@@ -98,49 +120,153 @@ const createSession = async (adapter, walletPublicKey, sessionKey) => {
|
|
|
98
120
|
};
|
|
99
121
|
const sessionInfoSchema = zod_1.z
|
|
100
122
|
.object({
|
|
101
|
-
session_info: zod_1.z.
|
|
102
|
-
|
|
103
|
-
zod_1.z.object({
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
123
|
+
session_info: zod_1.z.union([
|
|
124
|
+
zod_1.z.object({
|
|
125
|
+
V1: zod_1.z.object({
|
|
126
|
+
"0": zod_1.z.object({
|
|
127
|
+
authorized_programs: zod_1.z.union([
|
|
128
|
+
zod_1.z.object({
|
|
129
|
+
Specific: zod_1.z.object({
|
|
130
|
+
0: zod_1.z.array(zod_1.z.object({
|
|
131
|
+
program_id: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
132
|
+
signer_pda: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
133
|
+
})),
|
|
134
|
+
}),
|
|
135
|
+
}),
|
|
136
|
+
zod_1.z.object({
|
|
137
|
+
All: zod_1.z.object({}),
|
|
138
|
+
}),
|
|
139
|
+
]),
|
|
140
|
+
authorized_tokens: zod_1.z.union([
|
|
141
|
+
zod_1.z.object({ Specific: zod_1.z.object({}) }),
|
|
142
|
+
zod_1.z.object({ All: zod_1.z.object({}) }),
|
|
143
|
+
]),
|
|
144
|
+
expiration: zod_1.z.instanceof(bn_js_1.default),
|
|
145
|
+
extra: zod_1.z.object({
|
|
146
|
+
0: zod_1.z.unknown(),
|
|
147
|
+
}),
|
|
148
|
+
user: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
109
149
|
}),
|
|
110
150
|
}),
|
|
111
|
-
|
|
112
|
-
|
|
151
|
+
}),
|
|
152
|
+
zod_1.z.object({
|
|
153
|
+
V2: zod_1.z.object({
|
|
154
|
+
"0": zod_1.z.union([
|
|
155
|
+
zod_1.z.object({
|
|
156
|
+
Revoked: zod_1.z.instanceof(bn_js_1.default),
|
|
157
|
+
}),
|
|
158
|
+
zod_1.z.object({
|
|
159
|
+
Active: zod_1.z.object({
|
|
160
|
+
"0": zod_1.z.object({
|
|
161
|
+
authorized_programs: zod_1.z.union([
|
|
162
|
+
zod_1.z.object({
|
|
163
|
+
Specific: zod_1.z.object({
|
|
164
|
+
0: zod_1.z.array(zod_1.z.object({
|
|
165
|
+
program_id: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
166
|
+
signer_pda: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
167
|
+
})),
|
|
168
|
+
}),
|
|
169
|
+
}),
|
|
170
|
+
zod_1.z.object({
|
|
171
|
+
All: zod_1.z.object({}),
|
|
172
|
+
}),
|
|
173
|
+
]),
|
|
174
|
+
authorized_tokens: zod_1.z.union([
|
|
175
|
+
zod_1.z.object({ Specific: zod_1.z.object({}) }),
|
|
176
|
+
zod_1.z.object({ All: zod_1.z.object({}) }),
|
|
177
|
+
]),
|
|
178
|
+
expiration: zod_1.z.instanceof(bn_js_1.default),
|
|
179
|
+
extra: zod_1.z.object({
|
|
180
|
+
0: zod_1.z.unknown(),
|
|
181
|
+
}),
|
|
182
|
+
user: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
183
|
+
}),
|
|
184
|
+
}),
|
|
185
|
+
}),
|
|
186
|
+
]),
|
|
113
187
|
}),
|
|
114
|
-
]),
|
|
115
|
-
authorized_tokens: zod_1.z.union([
|
|
116
|
-
zod_1.z.object({ Specific: zod_1.z.object({}) }),
|
|
117
|
-
zod_1.z.object({ All: zod_1.z.object({}) }),
|
|
118
|
-
]),
|
|
119
|
-
expiration: zod_1.z.instanceof(bn_js_1.default),
|
|
120
|
-
extra: zod_1.z.object({
|
|
121
|
-
0: zod_1.z.unknown(),
|
|
122
188
|
}),
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
189
|
+
zod_1.z.object({
|
|
190
|
+
V3: zod_1.z.object({
|
|
191
|
+
"0": zod_1.z.union([
|
|
192
|
+
zod_1.z.object({
|
|
193
|
+
Revoked: zod_1.z.instanceof(bn_js_1.default),
|
|
194
|
+
}),
|
|
195
|
+
zod_1.z.object({
|
|
196
|
+
Active: zod_1.z.object({
|
|
197
|
+
"0": zod_1.z.object({
|
|
198
|
+
authorized_programs: zod_1.z.union([
|
|
199
|
+
zod_1.z.object({
|
|
200
|
+
Specific: zod_1.z.object({
|
|
201
|
+
0: zod_1.z.array(zod_1.z.object({
|
|
202
|
+
program_id: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
203
|
+
signer_pda: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
204
|
+
})),
|
|
205
|
+
}),
|
|
206
|
+
}),
|
|
207
|
+
zod_1.z.object({
|
|
208
|
+
All: zod_1.z.object({}),
|
|
209
|
+
}),
|
|
210
|
+
]),
|
|
211
|
+
authorized_tokens: zod_1.z.union([
|
|
212
|
+
zod_1.z.object({
|
|
213
|
+
Specific: zod_1.z.object({
|
|
214
|
+
"0": zod_1.z.array(zod_1.z.instanceof(web3_js_1.PublicKey)),
|
|
215
|
+
}),
|
|
216
|
+
}),
|
|
217
|
+
zod_1.z.object({ All: zod_1.z.object({}) }),
|
|
218
|
+
]),
|
|
219
|
+
expiration: zod_1.z.instanceof(bn_js_1.default),
|
|
220
|
+
extra: zod_1.z.object({
|
|
221
|
+
0: zod_1.z.unknown(),
|
|
222
|
+
}),
|
|
223
|
+
user: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
224
|
+
}),
|
|
225
|
+
}),
|
|
226
|
+
}),
|
|
227
|
+
]),
|
|
228
|
+
}),
|
|
229
|
+
}),
|
|
230
|
+
]),
|
|
231
|
+
major: zod_1.z.number(),
|
|
232
|
+
sponsor: zod_1.z.instanceof(web3_js_1.PublicKey),
|
|
127
233
|
})
|
|
128
|
-
.transform(({ session_info }) =>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
234
|
+
.transform(({ session_info, major, sponsor }) => {
|
|
235
|
+
let activeSessionInfo;
|
|
236
|
+
let minor;
|
|
237
|
+
if ("V1" in session_info) {
|
|
238
|
+
activeSessionInfo = session_info.V1["0"];
|
|
239
|
+
minor = 1;
|
|
240
|
+
}
|
|
241
|
+
else if ("V2" in session_info && "Active" in session_info.V2["0"]) {
|
|
242
|
+
activeSessionInfo = session_info.V2["0"].Active["0"];
|
|
243
|
+
minor = 2;
|
|
244
|
+
}
|
|
245
|
+
else if ("V3" in session_info && "Active" in session_info.V3["0"]) {
|
|
246
|
+
activeSessionInfo = session_info.V3["0"].Active["0"];
|
|
247
|
+
minor = 3;
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
authorizedPrograms: "All" in activeSessionInfo.authorized_programs
|
|
254
|
+
? AuthorizedPrograms.All()
|
|
255
|
+
: AuthorizedPrograms.Specific(activeSessionInfo.authorized_programs.Specific[0].map(({ program_id, signer_pda }) => ({
|
|
256
|
+
programId: program_id,
|
|
257
|
+
signerPda: signer_pda,
|
|
258
|
+
}))),
|
|
259
|
+
authorizedTokens: "All" in activeSessionInfo.authorized_tokens
|
|
260
|
+
? AuthorizedTokens.All
|
|
261
|
+
: AuthorizedTokens.Specific,
|
|
262
|
+
expiration: new Date(Number(activeSessionInfo.expiration) * 1000),
|
|
263
|
+
extra: activeSessionInfo.extra[0],
|
|
264
|
+
major: major,
|
|
265
|
+
minor: minor,
|
|
266
|
+
user: activeSessionInfo.user,
|
|
267
|
+
sponsor,
|
|
268
|
+
};
|
|
269
|
+
});
|
|
144
270
|
var AuthorizedProgramsType;
|
|
145
271
|
(function (AuthorizedProgramsType) {
|
|
146
272
|
AuthorizedProgramsType[AuthorizedProgramsType["All"] = 0] = "All";
|
|
@@ -193,6 +319,36 @@ const getTokenInfo = async (adapter, limits) => {
|
|
|
193
319
|
};
|
|
194
320
|
}));
|
|
195
321
|
};
|
|
322
|
+
const serializeU16LE = (value) => {
|
|
323
|
+
const result = new ArrayBuffer(2);
|
|
324
|
+
new DataView(result).setUint16(0, value, true); // littleEndian = true
|
|
325
|
+
return new Uint8Array(result);
|
|
326
|
+
};
|
|
327
|
+
// Some wallets add a prefix to the messag before signing, for example Ledger through Phantom
|
|
328
|
+
const addOffchainMessagePrefixToMessageIfNeeded = async (walletPublicKey, signature, message) => {
|
|
329
|
+
const publicKey = await crypto.subtle.importKey("raw", walletPublicKey.toBytes(), { name: "Ed25519" }, true, ["verify"]);
|
|
330
|
+
if (await (0, kit_1.verifySignature)(publicKey, signature, message)) {
|
|
331
|
+
return message;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
// Source: https://github.com/anza-xyz/solana-sdk/blob/master/offchain-message/src/lib.rs#L162
|
|
335
|
+
const messageWithOffchainMessagePrefix = Uint8Array.from([
|
|
336
|
+
// eslint-disable-next-line unicorn/number-literal-case
|
|
337
|
+
0xff,
|
|
338
|
+
...new TextEncoder().encode("solana offchain"),
|
|
339
|
+
0,
|
|
340
|
+
1,
|
|
341
|
+
...serializeU16LE(message.length),
|
|
342
|
+
...message,
|
|
343
|
+
]);
|
|
344
|
+
if (await (0, kit_1.verifySignature)(publicKey, signature, messageWithOffchainMessagePrefix)) {
|
|
345
|
+
return messageWithOffchainMessagePrefix;
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
throw new Error("The signature provided by the browser wallet is not valid");
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
};
|
|
196
352
|
const buildIntentInstruction = async (options, sessionKey, tokens) => {
|
|
197
353
|
const message = await buildMessage({
|
|
198
354
|
chainId: options.adapter.chainId,
|
|
@@ -206,7 +362,7 @@ const buildIntentInstruction = async (options, sessionKey, tokens) => {
|
|
|
206
362
|
return web3_js_1.Ed25519Program.createInstructionWithPublicKey({
|
|
207
363
|
publicKey: options.walletPublicKey.toBytes(),
|
|
208
364
|
signature: intentSignature,
|
|
209
|
-
message: message,
|
|
365
|
+
message: await addOffchainMessagePrefixToMessageIfNeeded(options.walletPublicKey, intentSignature, message),
|
|
210
366
|
});
|
|
211
367
|
};
|
|
212
368
|
const buildMessage = async (body) => new TextEncoder().encode([
|
|
@@ -218,9 +374,20 @@ const buildMessage = async (body) => new TextEncoder().encode([
|
|
|
218
374
|
expires: body.expires.toISOString(),
|
|
219
375
|
session_key: await (0, kit_1.getAddressFromPublicKey)(body.sessionKey.publicKey),
|
|
220
376
|
tokens: serializeTokenList(body.tokens),
|
|
221
|
-
...(body.extra && { extra: body.extra }),
|
|
222
377
|
}),
|
|
378
|
+
body.extra && serializeExtra(body.extra),
|
|
223
379
|
].join("\n"));
|
|
380
|
+
const serializeExtra = (extra) => {
|
|
381
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
382
|
+
if (!/^[a-z]+(_[a-z0-9]+)*$/.test(key)) {
|
|
383
|
+
throw new Error(`Extra key must be a snake_case string: ${key}`);
|
|
384
|
+
}
|
|
385
|
+
if (value.includes("\n")) {
|
|
386
|
+
throw new Error(`Extra value must not contain a line break: ${value}`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return serializeKV(extra);
|
|
390
|
+
};
|
|
224
391
|
const serializeKV = (data) => Object.entries(data)
|
|
225
392
|
.map(([key, value]) => [key, ":", value.startsWith("\n") ? "" : " ", value].join(""))
|
|
226
393
|
.join("\n");
|
|
@@ -356,7 +523,7 @@ const buildTransferIntentInstruction = async (program, options, symbol) => {
|
|
|
356
523
|
return web3_js_1.Ed25519Program.createInstructionWithPublicKey({
|
|
357
524
|
publicKey: options.walletPublicKey.toBytes(),
|
|
358
525
|
signature: intentSignature,
|
|
359
|
-
message: message,
|
|
526
|
+
message: await addOffchainMessagePrefixToMessageIfNeeded(options.walletPublicKey, intentSignature, message),
|
|
360
527
|
});
|
|
361
528
|
};
|
|
362
529
|
const getNonce = async (program, walletPublicKey) => {
|
|
@@ -366,3 +533,52 @@ const getNonce = async (program, walletPublicKey) => {
|
|
|
366
533
|
});
|
|
367
534
|
return program.account.nonce.fetchNullable(noncePda);
|
|
368
535
|
};
|
|
536
|
+
const loginTokenPayloadSchema = zod_1.z.object({
|
|
537
|
+
iat: zod_1.z.number(),
|
|
538
|
+
sessionPublicKey: zod_1.z.string(),
|
|
539
|
+
});
|
|
540
|
+
/**
|
|
541
|
+
* Create a login token signed with the session key
|
|
542
|
+
* @param session - The session to create a login token for
|
|
543
|
+
* @returns The login token
|
|
544
|
+
*/
|
|
545
|
+
const createLogInToken = async (session) => {
|
|
546
|
+
const payload = {
|
|
547
|
+
// ...we can pass any arbitrary data we want to sign here...
|
|
548
|
+
iat: Date.now(),
|
|
549
|
+
sessionPublicKey: session.sessionPublicKey.toBase58(),
|
|
550
|
+
};
|
|
551
|
+
const message = JSON.stringify(payload);
|
|
552
|
+
// Sign the payload with the session private key
|
|
553
|
+
const signature = await (0, crypto_js_1.signMessageWithKey)(session.sessionKey, message);
|
|
554
|
+
// Return base58(message) + base58(signature)
|
|
555
|
+
return `${bs58_1.default.encode(new TextEncoder().encode(message))}.${signature}`;
|
|
556
|
+
};
|
|
557
|
+
exports.createLogInToken = createLogInToken;
|
|
558
|
+
/**
|
|
559
|
+
* Verify a login token
|
|
560
|
+
* @param token - The login token to verify against the session public key
|
|
561
|
+
* @param connection - The connection to use to get the session account
|
|
562
|
+
* @returns The session account if the token is valid, otherwise undefined
|
|
563
|
+
*/
|
|
564
|
+
const verifyLogInToken = async (token, connection) => {
|
|
565
|
+
const [rawMessage, signature] = token.split(".");
|
|
566
|
+
if (!rawMessage || !signature)
|
|
567
|
+
return;
|
|
568
|
+
// Decode + parse payload
|
|
569
|
+
const messageStr = new TextDecoder().decode(bs58_1.default.decode(rawMessage));
|
|
570
|
+
const payload = loginTokenPayloadSchema.parse(JSON.parse(messageStr));
|
|
571
|
+
// Verify signature with sessionPublicKey
|
|
572
|
+
const sessionCryptoKey = await (0, crypto_js_1.importKey)(payload.sessionPublicKey);
|
|
573
|
+
const isValid = await (0, crypto_js_1.verifyMessageWithKey)(sessionCryptoKey, messageStr, signature);
|
|
574
|
+
if (!isValid)
|
|
575
|
+
return;
|
|
576
|
+
const sessionAccount = await (0, exports.getSessionAccount)(connection, new web3_js_1.PublicKey(payload.sessionPublicKey));
|
|
577
|
+
if (!sessionAccount)
|
|
578
|
+
return;
|
|
579
|
+
if (sessionAccount.expiration.getTime() < Date.now()) {
|
|
580
|
+
throw new Error("The session associated with this login token has expired");
|
|
581
|
+
}
|
|
582
|
+
return sessionAccount;
|
|
583
|
+
};
|
|
584
|
+
exports.verifyLogInToken = verifyLogInToken;
|
package/esm/adapter.js
CHANGED
|
@@ -71,7 +71,12 @@ const getSponsor = async (options, domain) => {
|
|
|
71
71
|
const url = new URL("/api/sponsor_pubkey", options.paymaster ?? DEFAULT_PAYMASTER);
|
|
72
72
|
url.searchParams.set("domain", domain);
|
|
73
73
|
const response = await fetch(url);
|
|
74
|
-
|
|
74
|
+
if (response.status === 200) {
|
|
75
|
+
return new PublicKey(z.string().parse(await response.text()));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
throw new PaymasterResponseError(response.status, await response.text());
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
81
|
};
|
|
77
82
|
const sponsorAndSendResponseSchema = z
|
|
@@ -99,7 +104,6 @@ const sendToPaymaster = async (options, transaction, domain) => {
|
|
|
99
104
|
}
|
|
100
105
|
else {
|
|
101
106
|
const url = new URL("/api/sponsor_and_send", options.paymaster ?? DEFAULT_PAYMASTER);
|
|
102
|
-
url.searchParams.set("confirm", "true");
|
|
103
107
|
url.searchParams.set("domain", domain);
|
|
104
108
|
const response = await fetch(url, {
|
|
105
109
|
method: "POST",
|
package/esm/crypto.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sign a message using a CryptoKeyPair session key
|
|
3
|
+
* @param publicPrivateKeyPair - The public private key pair to sign the message with
|
|
4
|
+
* @param message - The message to sign
|
|
5
|
+
* @returns The signature of the message
|
|
6
|
+
*/
|
|
7
|
+
export declare const signMessageWithKey: (publicPrivateKeyPair: CryptoKeyPair, message: string) => Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Verify a message with a CryptoKey public key
|
|
10
|
+
* @param publicKey - The public key of the session key
|
|
11
|
+
* @param message - The message to verify
|
|
12
|
+
* @param signature - The signature to verify
|
|
13
|
+
* @returns True if the message and signature are valid, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
export declare const verifyMessageWithKey: (publicKey: CryptoKey, message: string, signature: string) => Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Import a public key into a CryptoKey
|
|
18
|
+
* @param publicKey - The public key to import
|
|
19
|
+
* @returns The imported CryptoKey
|
|
20
|
+
*/
|
|
21
|
+
export declare const importKey: (publicKey: string) => Promise<CryptoKey>;
|
package/esm/crypto.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import bs58 from "bs58";
|
|
2
|
+
/**
|
|
3
|
+
* Sign a message using a CryptoKeyPair session key
|
|
4
|
+
* @param publicPrivateKeyPair - The public private key pair to sign the message with
|
|
5
|
+
* @param message - The message to sign
|
|
6
|
+
* @returns The signature of the message
|
|
7
|
+
*/
|
|
8
|
+
export const signMessageWithKey = async (publicPrivateKeyPair, message) => {
|
|
9
|
+
const signature = await crypto.subtle.sign({ name: "Ed25519" }, publicPrivateKeyPair.privateKey, new TextEncoder().encode(message));
|
|
10
|
+
return bs58.encode(new Uint8Array(signature));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Verify a message with a CryptoKey public key
|
|
14
|
+
* @param publicKey - The public key of the session key
|
|
15
|
+
* @param message - The message to verify
|
|
16
|
+
* @param signature - The signature to verify
|
|
17
|
+
* @returns True if the message and signature are valid, false otherwise
|
|
18
|
+
*/
|
|
19
|
+
export const verifyMessageWithKey = async (publicKey, message, signature) => {
|
|
20
|
+
const isValid = await crypto.subtle.verify({ name: "Ed25519" }, publicKey, bs58.decode(signature), new TextEncoder().encode(message));
|
|
21
|
+
return isValid;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Import a public key into a CryptoKey
|
|
25
|
+
* @param publicKey - The public key to import
|
|
26
|
+
* @returns The imported CryptoKey
|
|
27
|
+
*/
|
|
28
|
+
export const importKey = async (publicKey) => {
|
|
29
|
+
return await crypto.subtle.importKey("raw", new Uint8Array(bs58.decode(publicKey)), { name: "Ed25519" }, false, ["verify"]);
|
|
30
|
+
};
|