@thru/passkey 0.2.21 → 0.2.23
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/auth/add-device.cjs +139 -0
- package/dist/auth/add-device.cjs.map +1 -0
- package/dist/auth/add-device.d.cts +69 -0
- package/dist/auth/add-device.d.ts +69 -0
- package/dist/auth/add-device.js +7 -0
- package/dist/auth/add-device.js.map +1 -0
- package/dist/auth.cjs +121 -6
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +2 -0
- package/dist/auth.d.ts +2 -0
- package/dist/auth.js +10 -4
- package/dist/auth.js.map +1 -1
- package/dist/chunk-KASTJBBY.js +128 -0
- package/dist/chunk-KASTJBBY.js.map +1 -0
- package/dist/{chunk-75G2FPYW.js → chunk-OULTQZT7.js} +4 -3
- package/dist/chunk-OULTQZT7.js.map +1 -0
- package/dist/{chunk-B5SN7AS7.js → chunk-TW7HANJM.js} +99 -49
- package/dist/chunk-TW7HANJM.js.map +1 -0
- package/dist/{chunk-2JHC7OOH.js → chunk-ZNBMADOM.js} +2 -2
- package/dist/chunk-ZNBMADOM.js.map +1 -0
- package/dist/index.cjs +102 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -2
- package/dist/mobile.cjs +2 -2
- package/dist/mobile.cjs.map +1 -1
- package/dist/mobile.d.cts +2 -2
- package/dist/mobile.d.ts +2 -2
- package/dist/mobile.js +2 -2
- package/dist/mobile.js.map +1 -1
- package/dist/popup.cjs +3 -2
- package/dist/popup.cjs.map +1 -1
- package/dist/popup.d.cts +3 -3
- package/dist/popup.d.ts +3 -3
- package/dist/popup.js +1 -1
- package/dist/server.cjs +54 -66
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +14 -6
- package/dist/server.d.ts +14 -6
- package/dist/server.js +58 -69
- package/dist/server.js.map +1 -1
- package/dist/{types-_HRzmn-j.d.cts → types-BTTlCVrw.d.cts} +25 -2
- package/dist/{types-_HRzmn-j.d.ts → types-BTTlCVrw.d.ts} +25 -2
- package/dist/web.cjs +99 -48
- package/dist/web.cjs.map +1 -1
- package/dist/web.d.cts +14 -7
- package/dist/web.d.ts +14 -7
- package/dist/web.js +3 -1
- package/package.json +11 -6
- package/src/auth/add-device.ts +236 -0
- package/src/auth/execute-tx.ts +1 -1
- package/src/auth/index.ts +11 -0
- package/src/auth/use-passkey-auth.ts +4 -2
- package/src/capabilities.ts +2 -1
- package/src/index.ts +4 -0
- package/src/label.test.ts +21 -0
- package/src/label.ts +14 -0
- package/src/mobile/index.ts +1 -1
- package/src/mobile/passkey.ts +1 -1
- package/src/mobile/storage.ts +1 -1
- package/src/mobile/types.ts +2 -2
- package/src/popup-service.ts +2 -1
- package/src/register.ts +23 -8
- package/src/server/challenge.ts +15 -4
- package/src/server/create-wallet.test.ts +2 -2
- package/src/server/create-wallet.ts +24 -16
- package/src/server/handlers.ts +6 -2
- package/src/server/submit.test.ts +24 -6
- package/src/server/submit.ts +41 -10
- package/src/server/types.ts +5 -3
- package/src/server/utils.ts +1 -1
- package/src/sign.ts +127 -37
- package/src/types.ts +27 -2
- package/src/web.ts +6 -2
- package/tsconfig.json +3 -2
- package/tsup.config.ts +1 -0
- package/dist/chunk-2JHC7OOH.js.map +0 -1
- package/dist/chunk-75G2FPYW.js.map +0 -1
- package/dist/chunk-B5SN7AS7.js.map +0 -1
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AccountContext } from '@thru/passkey-manager';
|
|
2
|
-
import { TransactionHeaderConfig } from '@thru/
|
|
1
|
+
import { AccountContext } from '@thru/programs/passkey-manager';
|
|
2
|
+
import { TransactionHeaderConfig } from '@thru/sdk';
|
|
3
3
|
|
|
4
4
|
type PasskeyTransactionHeaderOverrides = TransactionHeaderConfig;
|
|
5
5
|
interface BuiltPasskeyTransaction {
|
|
@@ -81,7 +81,9 @@ interface PasskeyChallengeResult {
|
|
|
81
81
|
}
|
|
82
82
|
interface PasskeyContextResult {
|
|
83
83
|
accountCtx: AccountContext;
|
|
84
|
-
|
|
84
|
+
targetProgramAddress: string;
|
|
85
|
+
instructionData: Uint8Array;
|
|
86
|
+
authIdx?: number;
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
declare function createPasskeyWallet(opts: {
|
|
@@ -102,7 +104,9 @@ declare function createPasskeyChallenge(opts: {
|
|
|
102
104
|
client: ThruClient;
|
|
103
105
|
walletAddress: string;
|
|
104
106
|
accountCtx: AccountContext;
|
|
105
|
-
|
|
107
|
+
targetProgramAddress: string;
|
|
108
|
+
instructionData: Uint8Array;
|
|
109
|
+
authIdx?: number;
|
|
106
110
|
}): Promise<PasskeyChallengeResult>;
|
|
107
111
|
|
|
108
112
|
/**
|
|
@@ -118,7 +122,9 @@ declare function buildPasskeyTransaction(opts: {
|
|
|
118
122
|
adminPrivateKey: Uint8Array;
|
|
119
123
|
walletAddress: string;
|
|
120
124
|
accountCtx: AccountContext;
|
|
121
|
-
|
|
125
|
+
targetProgramAddress: string;
|
|
126
|
+
instructionData: Uint8Array;
|
|
127
|
+
authIdx?: number;
|
|
122
128
|
header?: PasskeyTransactionHeaderOverrides;
|
|
123
129
|
} & PasskeySignaturePayload): Promise<BuiltPasskeyTransaction>;
|
|
124
130
|
declare function submitPasskeyTransaction(opts: {
|
|
@@ -127,7 +133,9 @@ declare function submitPasskeyTransaction(opts: {
|
|
|
127
133
|
adminPrivateKey: Uint8Array;
|
|
128
134
|
walletAddress: string;
|
|
129
135
|
accountCtx: AccountContext;
|
|
130
|
-
|
|
136
|
+
targetProgramAddress: string;
|
|
137
|
+
instructionData: Uint8Array;
|
|
138
|
+
authIdx?: number;
|
|
131
139
|
header?: PasskeyTransactionHeaderOverrides;
|
|
132
140
|
} & PasskeySignaturePayload): Promise<TransactionResult>;
|
|
133
141
|
|
package/dist/server.js
CHANGED
|
@@ -9,59 +9,10 @@ import {
|
|
|
9
9
|
deriveWalletAddress,
|
|
10
10
|
encodeCreateInstruction,
|
|
11
11
|
encodeRegisterCredentialInstruction
|
|
12
|
-
} from "@thru/passkey-manager";
|
|
13
|
-
|
|
14
|
-
// ../helpers/src/constants.ts
|
|
15
|
-
var BASE64_URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
16
|
-
var tempMap = new Int16Array(256).fill(-1);
|
|
17
|
-
for (let i = 0; i < BASE64_URL_ALPHABET.length; i++) {
|
|
18
|
-
tempMap[BASE64_URL_ALPHABET.charCodeAt(i)] = i;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// ../helpers/src/address.ts
|
|
22
|
-
function encodeAddress(bytes) {
|
|
23
|
-
if (bytes.length !== 32) {
|
|
24
|
-
throw new Error("Expected 32-byte address");
|
|
25
|
-
}
|
|
26
|
-
let checksum = 0;
|
|
27
|
-
let accumulator = 0;
|
|
28
|
-
let bitsCollected = 0;
|
|
29
|
-
const output = ["t", "a"];
|
|
30
|
-
for (let i = 0; i < 30; i++) {
|
|
31
|
-
const byte = bytes[i];
|
|
32
|
-
checksum += byte;
|
|
33
|
-
accumulator = (accumulator << 8 | byte) >>> 0;
|
|
34
|
-
bitsCollected += 8;
|
|
35
|
-
while (bitsCollected >= 6) {
|
|
36
|
-
const index = accumulator >> bitsCollected - 6 & 63;
|
|
37
|
-
output.push(BASE64_URL_ALPHABET[index]);
|
|
38
|
-
bitsCollected -= 6;
|
|
39
|
-
accumulator &= maskForBits(bitsCollected);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
const secondLast = bytes[30];
|
|
43
|
-
checksum += secondLast;
|
|
44
|
-
accumulator = (accumulator << 8 | secondLast) >>> 0;
|
|
45
|
-
bitsCollected += 8;
|
|
46
|
-
const last = bytes[31];
|
|
47
|
-
checksum += last;
|
|
48
|
-
accumulator = (accumulator << 8 | last) >>> 0;
|
|
49
|
-
bitsCollected += 8;
|
|
50
|
-
accumulator = (accumulator << 8 | checksum & 255) >>> 0;
|
|
51
|
-
bitsCollected += 8;
|
|
52
|
-
while (bitsCollected >= 6) {
|
|
53
|
-
const index = accumulator >> bitsCollected - 6 & 63;
|
|
54
|
-
output.push(BASE64_URL_ALPHABET[index]);
|
|
55
|
-
bitsCollected -= 6;
|
|
56
|
-
accumulator &= maskForBits(bitsCollected);
|
|
57
|
-
}
|
|
58
|
-
return output.join("");
|
|
59
|
-
}
|
|
60
|
-
function maskForBits(bits) {
|
|
61
|
-
return bits === 0 ? 0 : (1 << bits) - 1;
|
|
62
|
-
}
|
|
12
|
+
} from "@thru/programs/passkey-manager";
|
|
63
13
|
|
|
64
14
|
// src/server/utils.ts
|
|
15
|
+
import { encodeAddress } from "@thru/sdk/helpers";
|
|
65
16
|
var feePayerQueueSymbol = /* @__PURE__ */ Symbol.for("thru.sharedFeePayerQueues");
|
|
66
17
|
function getFeePayerQueues() {
|
|
67
18
|
const globalQueues = globalThis;
|
|
@@ -154,7 +105,10 @@ async function withSerializedFeePayer(feePayerPublicKey, work) {
|
|
|
154
105
|
async function createPasskeyWallet(opts) {
|
|
155
106
|
const walletName = opts.walletName ?? "default";
|
|
156
107
|
const seed = await createWalletSeed(walletName, opts.pubkeyX, opts.pubkeyY);
|
|
157
|
-
const walletBytes = await deriveWalletAddress(
|
|
108
|
+
const walletBytes = await deriveWalletAddress(
|
|
109
|
+
seed,
|
|
110
|
+
PASSKEY_MANAGER_PROGRAM_ADDRESS
|
|
111
|
+
);
|
|
158
112
|
const walletAddress = toThruAddress(walletBytes);
|
|
159
113
|
await withSerializedFeePayer(opts.adminPublicKey, async () => {
|
|
160
114
|
let walletExists = false;
|
|
@@ -207,7 +161,6 @@ async function createPasskeyWallet(opts) {
|
|
|
207
161
|
const credentialIdBytes = base64UrlToBytes(opts.credentialId);
|
|
208
162
|
const lookupAddressBytes = await deriveCredentialLookupAddress(
|
|
209
163
|
credentialIdBytes,
|
|
210
|
-
walletName,
|
|
211
164
|
PASSKEY_MANAGER_PROGRAM_ADDRESS
|
|
212
165
|
);
|
|
213
166
|
const lookupAddress = toThruAddress(lookupAddressBytes);
|
|
@@ -222,7 +175,7 @@ async function createPasskeyWallet(opts) {
|
|
|
222
175
|
lookupExists = false;
|
|
223
176
|
}
|
|
224
177
|
if (lookupExists) return;
|
|
225
|
-
const credSeed = await createCredentialLookupSeed(credentialIdBytes
|
|
178
|
+
const credSeed = await createCredentialLookupSeed(credentialIdBytes);
|
|
226
179
|
const stateProof = await getStateProof(opts.client, lookupAddress);
|
|
227
180
|
const accountCtx = buildAccountContext({
|
|
228
181
|
walletAddress,
|
|
@@ -248,7 +201,9 @@ async function createPasskeyWallet(opts) {
|
|
|
248
201
|
header: { fee: 0n }
|
|
249
202
|
});
|
|
250
203
|
await transaction.sign(opts.adminPrivateKey);
|
|
251
|
-
const signature = await opts.client.transactions.send(
|
|
204
|
+
const signature = await opts.client.transactions.send(
|
|
205
|
+
transaction.toWire()
|
|
206
|
+
);
|
|
252
207
|
const result = await trackTransaction(opts.client, signature, 6e4);
|
|
253
208
|
if (result.status !== "finalized") {
|
|
254
209
|
throw new Error(
|
|
@@ -270,14 +225,23 @@ async function createPasskeyWallet(opts) {
|
|
|
270
225
|
import {
|
|
271
226
|
bytesToBase64Url,
|
|
272
227
|
createValidateChallenge,
|
|
228
|
+
decodeAddress,
|
|
273
229
|
fetchWalletNonce
|
|
274
|
-
} from "@thru/passkey-manager";
|
|
230
|
+
} from "@thru/programs/passkey-manager";
|
|
275
231
|
async function createPasskeyChallenge(opts) {
|
|
276
232
|
const nonce = await fetchWalletNonce(opts.client, opts.walletAddress);
|
|
233
|
+
const targetProgramIdx = opts.accountCtx.getAccountIndex(
|
|
234
|
+
decodeAddress(opts.targetProgramAddress)
|
|
235
|
+
);
|
|
277
236
|
const challenge = await createValidateChallenge(
|
|
278
237
|
nonce,
|
|
279
238
|
opts.accountCtx.accountAddresses,
|
|
280
|
-
opts.
|
|
239
|
+
opts.accountCtx.walletAccountIdx,
|
|
240
|
+
opts.authIdx ?? 0,
|
|
241
|
+
{
|
|
242
|
+
programIdx: targetProgramIdx,
|
|
243
|
+
instructionData: opts.instructionData
|
|
244
|
+
}
|
|
281
245
|
);
|
|
282
246
|
return {
|
|
283
247
|
challenge: bytesToBase64Url(challenge),
|
|
@@ -288,24 +252,45 @@ async function createPasskeyChallenge(opts) {
|
|
|
288
252
|
// src/server/submit.ts
|
|
289
253
|
import {
|
|
290
254
|
PASSKEY_MANAGER_PROGRAM_ADDRESS as PASSKEY_MANAGER_PROGRAM_ADDRESS2,
|
|
291
|
-
|
|
255
|
+
decodeAddress as decodeAddress2,
|
|
292
256
|
encodeValidateInstruction,
|
|
293
|
-
hexToBytes
|
|
294
|
-
} from "@thru/passkey-manager";
|
|
257
|
+
hexToBytes
|
|
258
|
+
} from "@thru/programs/passkey-manager";
|
|
259
|
+
function base64ToBytes(base64) {
|
|
260
|
+
const globalBuffer = globalThis.Buffer;
|
|
261
|
+
if (globalBuffer) {
|
|
262
|
+
return globalBuffer.from(base64, "base64");
|
|
263
|
+
}
|
|
264
|
+
if (typeof atob === "function") {
|
|
265
|
+
const binary = atob(base64);
|
|
266
|
+
const bytes = new Uint8Array(binary.length);
|
|
267
|
+
for (let i = 0; i < binary.length; i++) {
|
|
268
|
+
bytes[i] = binary.charCodeAt(i);
|
|
269
|
+
}
|
|
270
|
+
return bytes;
|
|
271
|
+
}
|
|
272
|
+
throw new Error("Base64 decoding is not supported in this environment");
|
|
273
|
+
}
|
|
295
274
|
async function buildPasskeyTransaction(opts) {
|
|
275
|
+
const targetProgramIdx = opts.accountCtx.getAccountIndex(
|
|
276
|
+
decodeAddress2(opts.targetProgramAddress)
|
|
277
|
+
);
|
|
296
278
|
const validateIx = encodeValidateInstruction({
|
|
297
279
|
walletAccountIdx: opts.accountCtx.walletAccountIdx,
|
|
298
|
-
authIdx: 0,
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
280
|
+
authIdx: opts.authIdx ?? 0,
|
|
281
|
+
targetInstruction: {
|
|
282
|
+
programIdx: targetProgramIdx,
|
|
283
|
+
instructionData: opts.instructionData
|
|
284
|
+
},
|
|
285
|
+
signatureR: hexToBytes(opts.signatureR),
|
|
286
|
+
signatureS: hexToBytes(opts.signatureS),
|
|
287
|
+
authenticatorData: base64ToBytes(opts.authenticatorData),
|
|
288
|
+
clientDataJSON: base64ToBytes(opts.clientDataJSON)
|
|
303
289
|
});
|
|
304
|
-
const instructionData = concatenateInstructions([validateIx, opts.invokeIx]);
|
|
305
290
|
const transaction = await opts.client.transactions.build({
|
|
306
291
|
feePayer: { publicKey: opts.adminPublicKey },
|
|
307
292
|
program: PASSKEY_MANAGER_PROGRAM_ADDRESS2,
|
|
308
|
-
instructionData,
|
|
293
|
+
instructionData: validateIx,
|
|
309
294
|
accounts: {
|
|
310
295
|
readWrite: opts.accountCtx.readWriteAddresses,
|
|
311
296
|
readOnly: opts.accountCtx.readOnlyAddresses
|
|
@@ -351,7 +336,9 @@ function createPasskeyHandlers(opts) {
|
|
|
351
336
|
client: opts.client,
|
|
352
337
|
walletAddress,
|
|
353
338
|
accountCtx: context.accountCtx,
|
|
354
|
-
|
|
339
|
+
targetProgramAddress: context.targetProgramAddress,
|
|
340
|
+
instructionData: context.instructionData,
|
|
341
|
+
authIdx: context.authIdx
|
|
355
342
|
});
|
|
356
343
|
pendingContexts.set(
|
|
357
344
|
createPendingContextKey(walletAddress, challenge.nonce, challenge.challenge),
|
|
@@ -382,7 +369,9 @@ function createPasskeyHandlers(opts) {
|
|
|
382
369
|
adminPrivateKey: opts.adminPrivateKey,
|
|
383
370
|
walletAddress,
|
|
384
371
|
accountCtx: pending.context.accountCtx,
|
|
385
|
-
|
|
372
|
+
targetProgramAddress: pending.context.targetProgramAddress,
|
|
373
|
+
instructionData: pending.context.instructionData,
|
|
374
|
+
authIdx: pending.context.authIdx,
|
|
386
375
|
...signaturePayload
|
|
387
376
|
});
|
|
388
377
|
}
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/create-wallet.ts","../../helpers/src/constants.ts","../../helpers/src/address.ts","../src/server/utils.ts","../src/server/challenge.ts","../src/server/submit.ts","../src/server/handlers.ts"],"sourcesContent":["import {\n PASSKEY_MANAGER_PROGRAM_ADDRESS,\n base64UrlToBytes,\n buildAccountContext,\n createCredentialLookupSeed,\n createWalletSeed,\n deriveCredentialLookupAddress,\n deriveWalletAddress,\n encodeCreateInstruction,\n encodeRegisterCredentialInstruction,\n} from '@thru/passkey-manager';\nimport {\n toThruAddress,\n getStateProof,\n trackTransaction,\n withSerializedFeePayer,\n} from './utils';\nimport type { ThruClient } from './types';\n\nexport async function createPasskeyWallet(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n adminAddress: string;\n pubkeyX: Uint8Array;\n pubkeyY: Uint8Array;\n credentialId?: string;\n walletName?: string;\n}): Promise<{ walletAddress: string; credentialLookupAddress?: string }> {\n const walletName = opts.walletName ?? 'default';\n const seed = await createWalletSeed(walletName, opts.pubkeyX, opts.pubkeyY);\n const walletBytes = await deriveWalletAddress(seed, PASSKEY_MANAGER_PROGRAM_ADDRESS);\n const walletAddress = toThruAddress(walletBytes);\n\n await withSerializedFeePayer(opts.adminPublicKey, async () => {\n let walletExists = false;\n try {\n await opts.client.accounts.get(walletAddress);\n walletExists = true;\n } catch {\n walletExists = false;\n }\n\n if (walletExists) return;\n\n const stateProof = await getStateProof(opts.client, walletAddress);\n const accountCtx = buildAccountContext({\n walletAddress,\n readWriteAccounts: [],\n readOnlyAccounts: [],\n feePayerAddress: opts.adminAddress,\n programAddress: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n });\n\n const createIx = encodeCreateInstruction({\n walletAccountIdx: accountCtx.walletAccountIdx,\n authority: {\n tag: 1,\n pubkeyX: opts.pubkeyX,\n pubkeyY: opts.pubkeyY,\n },\n seed,\n stateProof,\n });\n\n const transaction = await opts.client.transactions.build({\n feePayer: { publicKey: opts.adminPublicKey },\n program: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n instructionData: createIx,\n accounts: {\n readWrite: accountCtx.readWriteAddresses,\n readOnly: accountCtx.readOnlyAddresses,\n },\n header: { fee: 0n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n const signature = await opts.client.transactions.send(transaction.toWire());\n const result = await trackTransaction(opts.client, signature, 60000);\n if (result.status !== 'finalized') {\n throw new Error(\n `Wallet creation failed with status: ${result.status}${\n result.errorCode !== undefined ? ` (error code: ${result.errorCode})` : ''\n }`\n );\n }\n });\n\n let credentialLookupAddress: string | undefined;\n if (opts.credentialId) {\n const credentialIdBytes = base64UrlToBytes(opts.credentialId);\n const lookupAddressBytes = await deriveCredentialLookupAddress(\n credentialIdBytes,\n walletName,\n PASSKEY_MANAGER_PROGRAM_ADDRESS\n );\n const lookupAddress = toThruAddress(lookupAddressBytes);\n\n credentialLookupAddress = lookupAddress;\n\n try {\n await withSerializedFeePayer(opts.adminPublicKey, async () => {\n let lookupExists = false;\n try {\n await opts.client.accounts.get(lookupAddress);\n lookupExists = true;\n } catch {\n lookupExists = false;\n }\n\n if (lookupExists) return;\n\n const credSeed = await createCredentialLookupSeed(credentialIdBytes, walletName);\n const stateProof = await getStateProof(opts.client, lookupAddress);\n const accountCtx = buildAccountContext({\n walletAddress,\n readWriteAccounts: [lookupAddressBytes],\n readOnlyAccounts: [],\n feePayerAddress: opts.adminAddress,\n programAddress: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n });\n\n const registerIx = encodeRegisterCredentialInstruction({\n walletAccountIdx: accountCtx.walletAccountIdx,\n lookupAccountIdx: accountCtx.getAccountIndex(lookupAddressBytes),\n seed: credSeed,\n stateProof,\n });\n\n const transaction = await opts.client.transactions.build({\n feePayer: { publicKey: opts.adminPublicKey },\n program: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n instructionData: registerIx,\n accounts: {\n readWrite: accountCtx.readWriteAddresses,\n readOnly: accountCtx.readOnlyAddresses,\n },\n header: { fee: 0n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n const signature = await opts.client.transactions.send(transaction.toWire());\n const result = await trackTransaction(opts.client, signature, 60000);\n if (result.status !== 'finalized') {\n throw new Error(\n `Credential registration failed with status: ${result.status}${\n result.errorCode !== undefined ? ` (error code: ${result.errorCode})` : ''\n }`\n );\n }\n });\n } catch (error) {\n console.warn('Credential registration failed (non-fatal):', error);\n }\n }\n\n return {\n walletAddress,\n credentialLookupAddress,\n };\n}\n","export const BASE64_URL_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\nconst tempMap = new Int16Array(256).fill(-1);\nfor (let i = 0; i < BASE64_URL_ALPHABET.length; i++) {\n tempMap[BASE64_URL_ALPHABET.charCodeAt(i)] = i;\n}\nexport const BASE64_URL_MAP = tempMap\n\n","import { BASE64_URL_ALPHABET, BASE64_URL_MAP } from \"./constants\";\n\nexport function encodeAddress(bytes: Uint8Array): string {\n if (bytes.length !== 32) {\n throw new Error('Expected 32-byte address');\n }\n\n let checksum = 0;\n let accumulator = 0;\n let bitsCollected = 0;\n const output: string[] = ['t', 'a'];\n\n for (let i = 0; i < 30; i++) {\n const byte = bytes[i];\n checksum += byte;\n accumulator = ((accumulator << 8) | byte) >>> 0;\n bitsCollected += 8;\n while (bitsCollected >= 6) {\n const index = (accumulator >> (bitsCollected - 6)) & 0x3f;\n output.push(BASE64_URL_ALPHABET[index]);\n bitsCollected -= 6;\n accumulator &= maskForBits(bitsCollected);\n }\n }\n\n const secondLast = bytes[30];\n checksum += secondLast;\n accumulator = ((accumulator << 8) | secondLast) >>> 0;\n bitsCollected += 8;\n\n const last = bytes[31];\n checksum += last;\n accumulator = ((accumulator << 8) | last) >>> 0;\n bitsCollected += 8;\n\n accumulator = ((accumulator << 8) | (checksum & 0xff)) >>> 0;\n bitsCollected += 8;\n\n while (bitsCollected >= 6) {\n const index = (accumulator >> (bitsCollected - 6)) & 0x3f;\n output.push(BASE64_URL_ALPHABET[index]);\n bitsCollected -= 6;\n accumulator &= maskForBits(bitsCollected);\n }\n\n return output.join('');\n}\n\nexport function decodeAddress(value: string): Uint8Array {\n if (value.length !== 46) {\n throw new Error('Invalid address length');\n }\n if (!value.startsWith('ta')) {\n throw new Error('Address must start with \"ta\"');\n }\n\n const output = new Uint8Array(32);\n let checksum = 0;\n let inIdx = 2;\n let remaining = 40;\n let outIdx = 0;\n\n while (remaining >= 4) {\n const a = BASE64_URL_MAP[value.charCodeAt(inIdx)];\n const b = BASE64_URL_MAP[value.charCodeAt(inIdx + 1)];\n const c = BASE64_URL_MAP[value.charCodeAt(inIdx + 2)];\n const d = BASE64_URL_MAP[value.charCodeAt(inIdx + 3)];\n if (a < 0 || b < 0 || c < 0 || d < 0) {\n throw new Error('Invalid address encoding');\n }\n const triple = (a << 18) | (b << 12) | (c << 6) | d;\n const byte1 = (triple >> 16) & 0xff;\n const byte2 = (triple >> 8) & 0xff;\n const byte3 = triple & 0xff;\n checksum += byte1;\n checksum += byte2;\n checksum += byte3;\n output[outIdx++] = byte1;\n output[outIdx++] = byte2;\n output[outIdx++] = byte3;\n inIdx += 4;\n remaining -= 4;\n }\n\n const a = BASE64_URL_MAP[value.charCodeAt(inIdx)];\n const b = BASE64_URL_MAP[value.charCodeAt(inIdx + 1)];\n const c = BASE64_URL_MAP[value.charCodeAt(inIdx + 2)];\n const d = BASE64_URL_MAP[value.charCodeAt(inIdx + 3)];\n if (a < 0 || b < 0 || c < 0 || d < 0) {\n throw new Error('Invalid address encoding');\n }\n const triple = (a << 18) | (b << 12) | (c << 6) | d;\n const byte1 = (triple >> 16) & 0xff;\n const byte2 = (triple >> 8) & 0xff;\n const incomingChecksum = triple & 0xff;\n\n checksum += byte1;\n checksum += byte2;\n output[outIdx++] = byte1;\n output[outIdx++] = byte2;\n\n checksum &= 0xff;\n if (checksum !== incomingChecksum) {\n throw new Error('Address checksum mismatch');\n }\n\n return output;\n}\n\nfunction maskForBits(bits: number): number {\n return bits === 0 ? 0 : (1 << bits) - 1;\n}\n","import { encodeAddress } from '@thru/helpers';\nimport type { ThruClient, TransactionResult } from './types';\n\nconst feePayerQueueSymbol = Symbol.for('thru.sharedFeePayerQueues');\n\nfunction getFeePayerQueues(): Map<string, Promise<void>> {\n const globalQueues = globalThis as typeof globalThis & {\n [feePayerQueueSymbol]?: Map<string, Promise<void>>;\n };\n\n if (!globalQueues[feePayerQueueSymbol]) {\n globalQueues[feePayerQueueSymbol] = new Map<string, Promise<void>>();\n }\n\n return globalQueues[feePayerQueueSymbol];\n}\n\nexport async function getStateProof(\n client: ThruClient,\n address: string,\n proofType: number = 1,\n targetSlot?: bigint\n): Promise<Uint8Array> {\n const proofRequest: {\n address: string;\n proofType: number;\n targetSlot?: bigint;\n } = {\n address,\n proofType,\n };\n\n if (targetSlot !== undefined) {\n proofRequest.targetSlot = targetSlot;\n }\n\n const proof = await client.proofs.generate(proofRequest);\n\n if (!proof.proof || proof.proof.length === 0) {\n throw new Error(`No state proof returned for ${address}`);\n }\n\n return proof.proof;\n}\n\nexport async function trackTransaction(\n client: ThruClient,\n signature: string,\n timeoutMs: number = 5000\n): Promise<TransactionResult> {\n let finalizedSeen = false;\n\n try {\n for await (const update of client.transactions.track(signature, { timeoutMs })) {\n if (update.executionResult) {\n const vmError =\n update.executionResult.vmError !== undefined && update.executionResult.vmError !== null\n ? BigInt(update.executionResult.vmError)\n : 0n;\n const userErrorCode = update.executionResult.userErrorCode;\n const executionError =\n update.executionResult.executionResult !== undefined &&\n update.executionResult.executionResult !== null\n ? BigInt(update.executionResult.executionResult)\n : 0n;\n const success = vmError === 0n && executionError === 0n && userErrorCode === 0n;\n\n return {\n signature,\n status: success ? 'finalized' : 'failed',\n errorCode: vmError !== 0n ? vmError : executionError !== 0n ? executionError : userErrorCode,\n };\n }\n\n if (update.statusCode === 3) {\n finalizedSeen = true;\n }\n }\n\n if (finalizedSeen) {\n return {\n signature,\n status: 'finalized_without_execution',\n };\n }\n } catch {\n if (finalizedSeen) {\n return {\n signature,\n status: 'finalized_without_execution',\n };\n }\n\n return {\n signature,\n status: 'timeout',\n };\n }\n\n return {\n signature,\n status: 'timeout',\n };\n}\n\nexport function toThruAddress(bytes: Uint8Array): string {\n return encodeAddress(bytes);\n}\n\nexport async function withSerializedFeePayer<T>(\n feePayerPublicKey: Uint8Array,\n work: () => Promise<T>\n): Promise<T> {\n const queueKey = toThruAddress(feePayerPublicKey);\n const feePayerQueues = getFeePayerQueues();\n const previous = feePayerQueues.get(queueKey) ?? Promise.resolve();\n let release!: () => void;\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const tail = previous.then(() => current);\n feePayerQueues.set(queueKey, tail);\n\n await previous;\n\n try {\n return await work();\n } finally {\n release();\n if (feePayerQueues.get(queueKey) === tail) {\n feePayerQueues.delete(queueKey);\n }\n }\n}\n","import {\n bytesToBase64Url,\n createValidateChallenge,\n fetchWalletNonce,\n} from '@thru/passkey-manager';\nimport type { AccountContext } from '@thru/passkey-manager';\nimport type { PasskeyChallengeResult, ThruClient } from './types';\n\nexport async function createPasskeyChallenge(opts: {\n client: ThruClient;\n walletAddress: string;\n accountCtx: AccountContext;\n invokeIx: Uint8Array;\n}): Promise<PasskeyChallengeResult> {\n const nonce = await fetchWalletNonce(opts.client, opts.walletAddress);\n const challenge = await createValidateChallenge(\n nonce,\n opts.accountCtx.accountAddresses,\n opts.invokeIx\n );\n\n return {\n challenge: bytesToBase64Url(challenge),\n nonce: nonce.toString(),\n };\n}\n","import {\n PASSKEY_MANAGER_PROGRAM_ADDRESS,\n concatenateInstructions,\n encodeValidateInstruction,\n hexToBytes,\n} from '@thru/passkey-manager';\nimport type { AccountContext } from '@thru/passkey-manager';\nimport { trackTransaction, withSerializedFeePayer } from './utils';\nimport type {\n BuiltPasskeyTransaction,\n PasskeySignaturePayload,\n PasskeyTransactionHeaderOverrides,\n ThruClient,\n TransactionResult,\n} from './types';\n\n/**\n * Builds and signs a passkey-manager transaction without submitting it.\n *\n * Callers that override the transaction nonce are responsible for coordinating\n * fee-payer nonce allocation before calling this helper. Use\n * `submitPasskeyTransaction` for the serialized one-off submit path.\n */\nexport async function buildPasskeyTransaction(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n walletAddress: string;\n accountCtx: AccountContext;\n invokeIx: Uint8Array;\n header?: PasskeyTransactionHeaderOverrides;\n} & PasskeySignaturePayload): Promise<BuiltPasskeyTransaction> {\n const validateIx = encodeValidateInstruction({\n walletAccountIdx: opts.accountCtx.walletAccountIdx,\n authIdx: 0,\n signatureR: hexToBytes(opts.signatureR),\n signatureS: hexToBytes(opts.signatureS),\n authenticatorData: Buffer.from(opts.authenticatorData, 'base64'),\n clientDataJSON: Buffer.from(opts.clientDataJSON, 'base64'),\n });\n\n const instructionData = concatenateInstructions([validateIx, opts.invokeIx]);\n const transaction = await opts.client.transactions.build({\n feePayer: { publicKey: opts.adminPublicKey },\n program: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n instructionData,\n accounts: {\n readWrite: opts.accountCtx.readWriteAddresses,\n readOnly: opts.accountCtx.readOnlyAddresses,\n },\n header: {\n fee: 0n,\n ...opts.header,\n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n return {\n transaction,\n rawTransaction: transaction.toWire(),\n };\n}\n\nexport async function submitPasskeyTransaction(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n walletAddress: string;\n accountCtx: AccountContext;\n invokeIx: Uint8Array;\n header?: PasskeyTransactionHeaderOverrides;\n} & PasskeySignaturePayload): Promise<TransactionResult> {\n return withSerializedFeePayer(opts.adminPublicKey, async () => {\n const { rawTransaction } = await buildPasskeyTransaction(opts);\n const signature = await opts.client.transactions.send(rawTransaction);\n return trackTransaction(opts.client, signature);\n });\n}\n","import type { PasskeyContextResult } from './types';\nimport { createPasskeyChallenge } from './challenge';\nimport { submitPasskeyTransaction } from './submit';\nimport type {\n PasskeyChallengeSubmitPayload,\n ThruClient,\n TransactionResult,\n} from './types';\n\nexport function createPasskeyHandlers<P>(opts: {\n buildContext: (params: P) => Promise<PasskeyContextResult>;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n client: ThruClient;\n challengeTtlMs?: number;\n}) {\n const pendingContexts = new Map<\n string,\n { context: PasskeyContextResult; createdAt: number }\n >();\n const challengeTtlMs = opts.challengeTtlMs ?? 5 * 60_000;\n\n function createPendingContextKey(\n walletAddress: string,\n nonce: string,\n challenge: string\n ): string {\n return `${walletAddress}:${nonce}:${challenge}`;\n }\n\n function prunePendingContexts(now = Date.now()): void {\n for (const [nonce, entry] of pendingContexts.entries()) {\n if (now - entry.createdAt > challengeTtlMs) {\n pendingContexts.delete(nonce);\n }\n }\n }\n\n return {\n challenge: async (walletAddress: string, params: P) => {\n prunePendingContexts();\n\n const context = await opts.buildContext(params);\n const challenge = await createPasskeyChallenge({\n client: opts.client,\n walletAddress,\n accountCtx: context.accountCtx,\n invokeIx: context.invokeIx,\n });\n\n pendingContexts.set(\n createPendingContextKey(walletAddress, challenge.nonce, challenge.challenge),\n {\n context,\n createdAt: Date.now(),\n }\n );\n\n return challenge;\n },\n submit: async (\n walletAddress: string,\n params: P,\n payload: PasskeyChallengeSubmitPayload\n ): Promise<TransactionResult> => {\n void params;\n prunePendingContexts();\n\n const pendingKey = createPendingContextKey(\n walletAddress,\n payload.nonce,\n payload.challenge\n );\n const pending = pendingContexts.get(pendingKey);\n if (!pending) {\n throw new Error('Missing or expired challenge nonce');\n }\n\n pendingContexts.delete(pendingKey);\n const { nonce: _nonce, challenge: _challenge, ...signaturePayload } = payload;\n\n return submitPasskeyTransaction({\n client: opts.client,\n adminPublicKey: opts.adminPublicKey,\n adminPrivateKey: opts.adminPrivateKey,\n walletAddress,\n accountCtx: pending.context.accountCtx,\n invokeIx: pending.context.invokeIx,\n ...signaturePayload,\n });\n },\n };\n}\n"],"mappings":"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","names":["PASSKEY_MANAGER_PROGRAM_ADDRESS","hexToBytes","hexToBytes","PASSKEY_MANAGER_PROGRAM_ADDRESS"]}
|
|
1
|
+
{"version":3,"sources":["../src/server/create-wallet.ts","../src/server/utils.ts","../src/server/challenge.ts","../src/server/submit.ts","../src/server/handlers.ts"],"sourcesContent":["import {\n PASSKEY_MANAGER_PROGRAM_ADDRESS,\n base64UrlToBytes,\n buildAccountContext,\n createCredentialLookupSeed,\n createWalletSeed,\n deriveCredentialLookupAddress,\n deriveWalletAddress,\n encodeCreateInstruction,\n encodeRegisterCredentialInstruction,\n} from '@thru/programs/passkey-manager';\nimport {\n toThruAddress,\n getStateProof,\n trackTransaction,\n withSerializedFeePayer,\n} from \"./utils\";\nimport type { ThruClient } from \"./types\";\n\nexport async function createPasskeyWallet(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n adminAddress: string;\n pubkeyX: Uint8Array;\n pubkeyY: Uint8Array;\n credentialId?: string;\n walletName?: string;\n}): Promise<{ walletAddress: string; credentialLookupAddress?: string }> {\n const walletName = opts.walletName ?? \"default\";\n const seed = await createWalletSeed(walletName, opts.pubkeyX, opts.pubkeyY);\n const walletBytes = await deriveWalletAddress(\n seed,\n PASSKEY_MANAGER_PROGRAM_ADDRESS,\n );\n const walletAddress = toThruAddress(walletBytes);\n\n await withSerializedFeePayer(opts.adminPublicKey, async () => {\n let walletExists = false;\n try {\n await opts.client.accounts.get(walletAddress);\n walletExists = true;\n } catch {\n walletExists = false;\n }\n\n if (walletExists) return;\n\n const stateProof = await getStateProof(opts.client, walletAddress);\n const accountCtx = buildAccountContext({\n walletAddress,\n readWriteAccounts: [],\n readOnlyAccounts: [],\n feePayerAddress: opts.adminAddress,\n programAddress: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n });\n\n const createIx = encodeCreateInstruction({\n walletAccountIdx: accountCtx.walletAccountIdx,\n authority: {\n tag: 1,\n pubkeyX: opts.pubkeyX,\n pubkeyY: opts.pubkeyY,\n },\n seed,\n stateProof,\n });\n\n const transaction = await opts.client.transactions.build({\n feePayer: { publicKey: opts.adminPublicKey },\n program: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n instructionData: createIx,\n accounts: {\n readWrite: accountCtx.readWriteAddresses,\n readOnly: accountCtx.readOnlyAddresses,\n },\n header: { fee: 0n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n const signature = await opts.client.transactions.send(transaction.toWire());\n const result = await trackTransaction(opts.client, signature, 60000);\n if (result.status !== \"finalized\") {\n throw new Error(\n `Wallet creation failed with status: ${result.status}${\n result.errorCode !== undefined\n ? ` (error code: ${result.errorCode})`\n : \"\"\n }`,\n );\n }\n });\n\n let credentialLookupAddress: string | undefined;\n if (opts.credentialId) {\n const credentialIdBytes = base64UrlToBytes(opts.credentialId);\n const lookupAddressBytes = await deriveCredentialLookupAddress(\n credentialIdBytes,\n PASSKEY_MANAGER_PROGRAM_ADDRESS,\n );\n const lookupAddress = toThruAddress(lookupAddressBytes);\n\n credentialLookupAddress = lookupAddress;\n\n try {\n await withSerializedFeePayer(opts.adminPublicKey, async () => {\n let lookupExists = false;\n try {\n await opts.client.accounts.get(lookupAddress);\n lookupExists = true;\n } catch {\n lookupExists = false;\n }\n\n if (lookupExists) return;\n\n const credSeed = await createCredentialLookupSeed(credentialIdBytes);\n const stateProof = await getStateProof(opts.client, lookupAddress);\n const accountCtx = buildAccountContext({\n walletAddress,\n readWriteAccounts: [lookupAddressBytes],\n readOnlyAccounts: [],\n feePayerAddress: opts.adminAddress,\n programAddress: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n });\n\n const registerIx = encodeRegisterCredentialInstruction({\n walletAccountIdx: accountCtx.walletAccountIdx,\n lookupAccountIdx: accountCtx.getAccountIndex(lookupAddressBytes),\n seed: credSeed,\n stateProof,\n });\n\n const transaction = await opts.client.transactions.build({\n feePayer: { publicKey: opts.adminPublicKey },\n program: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n instructionData: registerIx,\n accounts: {\n readWrite: accountCtx.readWriteAddresses,\n readOnly: accountCtx.readOnlyAddresses,\n },\n header: { fee: 0n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n const signature = await opts.client.transactions.send(\n transaction.toWire(),\n );\n const result = await trackTransaction(opts.client, signature, 60000);\n if (result.status !== \"finalized\") {\n throw new Error(\n `Credential registration failed with status: ${result.status}${\n result.errorCode !== undefined\n ? ` (error code: ${result.errorCode})`\n : \"\"\n }`,\n );\n }\n });\n } catch (error) {\n console.warn(\"Credential registration failed (non-fatal):\", error);\n }\n }\n\n return {\n walletAddress,\n credentialLookupAddress,\n };\n}\n","import { encodeAddress } from '@thru/sdk/helpers';\nimport type { ThruClient, TransactionResult } from './types';\n\nconst feePayerQueueSymbol = Symbol.for('thru.sharedFeePayerQueues');\n\nfunction getFeePayerQueues(): Map<string, Promise<void>> {\n const globalQueues = globalThis as typeof globalThis & {\n [feePayerQueueSymbol]?: Map<string, Promise<void>>;\n };\n\n if (!globalQueues[feePayerQueueSymbol]) {\n globalQueues[feePayerQueueSymbol] = new Map<string, Promise<void>>();\n }\n\n return globalQueues[feePayerQueueSymbol];\n}\n\nexport async function getStateProof(\n client: ThruClient,\n address: string,\n proofType: number = 1,\n targetSlot?: bigint\n): Promise<Uint8Array> {\n const proofRequest: {\n address: string;\n proofType: number;\n targetSlot?: bigint;\n } = {\n address,\n proofType,\n };\n\n if (targetSlot !== undefined) {\n proofRequest.targetSlot = targetSlot;\n }\n\n const proof = await client.proofs.generate(proofRequest);\n\n if (!proof.proof || proof.proof.length === 0) {\n throw new Error(`No state proof returned for ${address}`);\n }\n\n return proof.proof;\n}\n\nexport async function trackTransaction(\n client: ThruClient,\n signature: string,\n timeoutMs: number = 5000\n): Promise<TransactionResult> {\n let finalizedSeen = false;\n\n try {\n for await (const update of client.transactions.track(signature, { timeoutMs })) {\n if (update.executionResult) {\n const vmError =\n update.executionResult.vmError !== undefined && update.executionResult.vmError !== null\n ? BigInt(update.executionResult.vmError)\n : 0n;\n const userErrorCode = update.executionResult.userErrorCode;\n const executionError =\n update.executionResult.executionResult !== undefined &&\n update.executionResult.executionResult !== null\n ? BigInt(update.executionResult.executionResult)\n : 0n;\n const success = vmError === 0n && executionError === 0n && userErrorCode === 0n;\n\n return {\n signature,\n status: success ? 'finalized' : 'failed',\n errorCode: vmError !== 0n ? vmError : executionError !== 0n ? executionError : userErrorCode,\n };\n }\n\n if (update.statusCode === 3) {\n finalizedSeen = true;\n }\n }\n\n if (finalizedSeen) {\n return {\n signature,\n status: 'finalized_without_execution',\n };\n }\n } catch {\n if (finalizedSeen) {\n return {\n signature,\n status: 'finalized_without_execution',\n };\n }\n\n return {\n signature,\n status: 'timeout',\n };\n }\n\n return {\n signature,\n status: 'timeout',\n };\n}\n\nexport function toThruAddress(bytes: Uint8Array): string {\n return encodeAddress(bytes);\n}\n\nexport async function withSerializedFeePayer<T>(\n feePayerPublicKey: Uint8Array,\n work: () => Promise<T>\n): Promise<T> {\n const queueKey = toThruAddress(feePayerPublicKey);\n const feePayerQueues = getFeePayerQueues();\n const previous = feePayerQueues.get(queueKey) ?? Promise.resolve();\n let release!: () => void;\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const tail = previous.then(() => current);\n feePayerQueues.set(queueKey, tail);\n\n await previous;\n\n try {\n return await work();\n } finally {\n release();\n if (feePayerQueues.get(queueKey) === tail) {\n feePayerQueues.delete(queueKey);\n }\n }\n}\n","import {\n bytesToBase64Url,\n createValidateChallenge,\n decodeAddress,\n fetchWalletNonce,\n} from '@thru/programs/passkey-manager';\nimport type { AccountContext } from '@thru/programs/passkey-manager';\nimport type { PasskeyChallengeResult, ThruClient } from './types';\n\nexport async function createPasskeyChallenge(opts: {\n client: ThruClient;\n walletAddress: string;\n accountCtx: AccountContext;\n targetProgramAddress: string;\n instructionData: Uint8Array;\n authIdx?: number;\n}): Promise<PasskeyChallengeResult> {\n const nonce = await fetchWalletNonce(opts.client, opts.walletAddress);\n const targetProgramIdx = opts.accountCtx.getAccountIndex(\n decodeAddress(opts.targetProgramAddress)\n );\n const challenge = await createValidateChallenge(\n nonce,\n opts.accountCtx.accountAddresses,\n opts.accountCtx.walletAccountIdx,\n opts.authIdx ?? 0,\n {\n programIdx: targetProgramIdx,\n instructionData: opts.instructionData,\n }\n );\n\n return {\n challenge: bytesToBase64Url(challenge),\n nonce: nonce.toString(),\n };\n}\n","import {\n PASSKEY_MANAGER_PROGRAM_ADDRESS,\n decodeAddress,\n encodeValidateInstruction,\n hexToBytes,\n} from '@thru/programs/passkey-manager';\nimport type { AccountContext } from '@thru/programs/passkey-manager';\nimport { trackTransaction, withSerializedFeePayer } from './utils';\nimport type {\n BuiltPasskeyTransaction,\n PasskeySignaturePayload,\n PasskeyTransactionHeaderOverrides,\n ThruClient,\n TransactionResult,\n} from './types';\n\nfunction base64ToBytes(base64: string): Uint8Array {\n type BufferLike = {\n from(value: string, encoding: 'base64'): Uint8Array;\n };\n const globalBuffer = (globalThis as { Buffer?: BufferLike }).Buffer;\n if (globalBuffer) {\n return globalBuffer.from(base64, 'base64');\n }\n\n if (typeof atob === 'function') {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n throw new Error('Base64 decoding is not supported in this environment');\n}\n\n/**\n * Builds and signs a passkey-manager transaction without submitting it.\n *\n * Callers that override the transaction nonce are responsible for coordinating\n * fee-payer nonce allocation before calling this helper. Use\n * `submitPasskeyTransaction` for the serialized one-off submit path.\n */\nexport async function buildPasskeyTransaction(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n walletAddress: string;\n accountCtx: AccountContext;\n targetProgramAddress: string;\n instructionData: Uint8Array;\n authIdx?: number;\n header?: PasskeyTransactionHeaderOverrides;\n} & PasskeySignaturePayload): Promise<BuiltPasskeyTransaction> {\n const targetProgramIdx = opts.accountCtx.getAccountIndex(\n decodeAddress(opts.targetProgramAddress)\n );\n const validateIx = encodeValidateInstruction({\n walletAccountIdx: opts.accountCtx.walletAccountIdx,\n authIdx: opts.authIdx ?? 0,\n targetInstruction: {\n programIdx: targetProgramIdx,\n instructionData: opts.instructionData,\n },\n signatureR: hexToBytes(opts.signatureR),\n signatureS: hexToBytes(opts.signatureS),\n authenticatorData: base64ToBytes(opts.authenticatorData),\n clientDataJSON: base64ToBytes(opts.clientDataJSON),\n });\n\n const transaction = await opts.client.transactions.build({\n feePayer: { publicKey: opts.adminPublicKey },\n program: PASSKEY_MANAGER_PROGRAM_ADDRESS,\n instructionData: validateIx,\n accounts: {\n readWrite: opts.accountCtx.readWriteAddresses,\n readOnly: opts.accountCtx.readOnlyAddresses,\n },\n header: {\n fee: 0n,\n ...opts.header,\n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n return {\n transaction,\n rawTransaction: transaction.toWire(),\n };\n}\n\nexport async function submitPasskeyTransaction(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n walletAddress: string;\n accountCtx: AccountContext;\n targetProgramAddress: string;\n instructionData: Uint8Array;\n authIdx?: number;\n header?: PasskeyTransactionHeaderOverrides;\n} & PasskeySignaturePayload): Promise<TransactionResult> {\n return withSerializedFeePayer(opts.adminPublicKey, async () => {\n const { rawTransaction } = await buildPasskeyTransaction(opts);\n const signature = await opts.client.transactions.send(rawTransaction);\n return trackTransaction(opts.client, signature);\n });\n}\n","import type { PasskeyContextResult } from './types';\nimport { createPasskeyChallenge } from './challenge';\nimport { submitPasskeyTransaction } from './submit';\nimport type {\n PasskeyChallengeSubmitPayload,\n ThruClient,\n TransactionResult,\n} from './types';\n\nexport function createPasskeyHandlers<P>(opts: {\n buildContext: (params: P) => Promise<PasskeyContextResult>;\n adminPublicKey: Uint8Array;\n adminPrivateKey: Uint8Array;\n client: ThruClient;\n challengeTtlMs?: number;\n}) {\n const pendingContexts = new Map<\n string,\n { context: PasskeyContextResult; createdAt: number }\n >();\n const challengeTtlMs = opts.challengeTtlMs ?? 5 * 60_000;\n\n function createPendingContextKey(\n walletAddress: string,\n nonce: string,\n challenge: string\n ): string {\n return `${walletAddress}:${nonce}:${challenge}`;\n }\n\n function prunePendingContexts(now = Date.now()): void {\n for (const [nonce, entry] of pendingContexts.entries()) {\n if (now - entry.createdAt > challengeTtlMs) {\n pendingContexts.delete(nonce);\n }\n }\n }\n\n return {\n challenge: async (walletAddress: string, params: P) => {\n prunePendingContexts();\n\n const context = await opts.buildContext(params);\n const challenge = await createPasskeyChallenge({\n client: opts.client,\n walletAddress,\n accountCtx: context.accountCtx,\n targetProgramAddress: context.targetProgramAddress,\n instructionData: context.instructionData,\n authIdx: context.authIdx,\n });\n\n pendingContexts.set(\n createPendingContextKey(walletAddress, challenge.nonce, challenge.challenge),\n {\n context,\n createdAt: Date.now(),\n }\n );\n\n return challenge;\n },\n submit: async (\n walletAddress: string,\n params: P,\n payload: PasskeyChallengeSubmitPayload\n ): Promise<TransactionResult> => {\n void params;\n prunePendingContexts();\n\n const pendingKey = createPendingContextKey(\n walletAddress,\n payload.nonce,\n payload.challenge\n );\n const pending = pendingContexts.get(pendingKey);\n if (!pending) {\n throw new Error('Missing or expired challenge nonce');\n }\n\n pendingContexts.delete(pendingKey);\n const { nonce: _nonce, challenge: _challenge, ...signaturePayload } = payload;\n\n return submitPasskeyTransaction({\n client: opts.client,\n adminPublicKey: opts.adminPublicKey,\n adminPrivateKey: opts.adminPrivateKey,\n walletAddress,\n accountCtx: pending.context.accountCtx,\n targetProgramAddress: pending.context.targetProgramAddress,\n instructionData: pending.context.instructionData,\n authIdx: pending.context.authIdx,\n ...signaturePayload,\n });\n },\n };\n}\n"],"mappings":"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","names":["PASSKEY_MANAGER_PROGRAM_ADDRESS","decodeAddress","decodeAddress","PASSKEY_MANAGER_PROGRAM_ADDRESS"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PasskeySigningResult, PasskeyMetadata } from '@thru/passkey-manager';
|
|
1
|
+
import { PasskeySigningResult, PasskeyMetadata } from '@thru/programs/passkey-manager';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Signing result with stored passkey metadata attached.
|
|
@@ -33,6 +33,23 @@ interface PasskeyPopupContext {
|
|
|
33
33
|
origin?: string;
|
|
34
34
|
imageUrl?: string;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for stored passkey signing in embedded contexts.
|
|
38
|
+
*/
|
|
39
|
+
interface PasskeyStoredSigningOptions {
|
|
40
|
+
allowPopupFallback?: boolean;
|
|
41
|
+
/** Prefer an RP-scoped discoverable credential prompt over a stored
|
|
42
|
+
* credential-id lookup. Native WebViews can show misleading
|
|
43
|
+
* app-level "no passkey" UI when allowCredentials is stale, while a
|
|
44
|
+
* discoverable prompt correctly lets the wallet/RP choose the passkey. */
|
|
45
|
+
preferDiscoverable?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Options for passkey registration in embedded contexts.
|
|
49
|
+
*/
|
|
50
|
+
interface PasskeyRegistrationOptions {
|
|
51
|
+
allowPopupFallback?: boolean;
|
|
52
|
+
}
|
|
36
53
|
/**
|
|
37
54
|
* Account info passed through popup bridge.
|
|
38
55
|
*/
|
|
@@ -73,6 +90,7 @@ interface PasskeyPopupSigningResult {
|
|
|
73
90
|
clientDataJSONBase64Url: string;
|
|
74
91
|
signatureRBase64Url: string;
|
|
75
92
|
signatureSBase64Url: string;
|
|
93
|
+
authenticatorAttachment?: 'platform' | 'cross-platform' | null;
|
|
76
94
|
}
|
|
77
95
|
interface PasskeyPopupStoredPasskey {
|
|
78
96
|
credentialId: string;
|
|
@@ -80,6 +98,10 @@ interface PasskeyPopupStoredPasskey {
|
|
|
80
98
|
publicKeyY: string;
|
|
81
99
|
rpId: string;
|
|
82
100
|
label?: string;
|
|
101
|
+
deviceName?: string;
|
|
102
|
+
devicePlatform?: string;
|
|
103
|
+
browserName?: string;
|
|
104
|
+
authenticatorAttachment?: 'platform' | 'cross-platform' | null;
|
|
83
105
|
createdAt: string;
|
|
84
106
|
lastUsedAt: string;
|
|
85
107
|
}
|
|
@@ -92,6 +114,7 @@ interface PasskeyPopupRegistrationResult {
|
|
|
92
114
|
publicKeyX: string;
|
|
93
115
|
publicKeyY: string;
|
|
94
116
|
rpId: string;
|
|
117
|
+
authenticatorAttachment?: 'platform' | 'cross-platform' | null;
|
|
95
118
|
}
|
|
96
119
|
type PasskeyPopupResponse = {
|
|
97
120
|
type: string;
|
|
@@ -122,4 +145,4 @@ type PasskeyPopupResponse = {
|
|
|
122
145
|
};
|
|
123
146
|
};
|
|
124
147
|
|
|
125
|
-
export type {
|
|
148
|
+
export type { PasskeyClientCapabilities as P, PasskeyPopupAccount as a, PasskeyPopupAction as b, PasskeyPopupContext as c, PasskeyPopupCreateRequestPayload as d, PasskeyPopupGetRequestPayload as e, PasskeyPopupGetStoredRequestPayload as f, PasskeyPopupRegistrationResult as g, PasskeyPopupRequest as h, PasskeyPopupRequestPayload as i, PasskeyPopupResponse as j, PasskeyPopupSigningResult as k, PasskeyPopupStoredPasskey as l, PasskeyPopupStoredSigningResult as m, PasskeyRegistrationOptions as n, PasskeyStoredSigningOptions as o, PasskeyStoredSigningResult as p };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PasskeySigningResult, PasskeyMetadata } from '@thru/passkey-manager';
|
|
1
|
+
import { PasskeySigningResult, PasskeyMetadata } from '@thru/programs/passkey-manager';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Signing result with stored passkey metadata attached.
|
|
@@ -33,6 +33,23 @@ interface PasskeyPopupContext {
|
|
|
33
33
|
origin?: string;
|
|
34
34
|
imageUrl?: string;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for stored passkey signing in embedded contexts.
|
|
38
|
+
*/
|
|
39
|
+
interface PasskeyStoredSigningOptions {
|
|
40
|
+
allowPopupFallback?: boolean;
|
|
41
|
+
/** Prefer an RP-scoped discoverable credential prompt over a stored
|
|
42
|
+
* credential-id lookup. Native WebViews can show misleading
|
|
43
|
+
* app-level "no passkey" UI when allowCredentials is stale, while a
|
|
44
|
+
* discoverable prompt correctly lets the wallet/RP choose the passkey. */
|
|
45
|
+
preferDiscoverable?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Options for passkey registration in embedded contexts.
|
|
49
|
+
*/
|
|
50
|
+
interface PasskeyRegistrationOptions {
|
|
51
|
+
allowPopupFallback?: boolean;
|
|
52
|
+
}
|
|
36
53
|
/**
|
|
37
54
|
* Account info passed through popup bridge.
|
|
38
55
|
*/
|
|
@@ -73,6 +90,7 @@ interface PasskeyPopupSigningResult {
|
|
|
73
90
|
clientDataJSONBase64Url: string;
|
|
74
91
|
signatureRBase64Url: string;
|
|
75
92
|
signatureSBase64Url: string;
|
|
93
|
+
authenticatorAttachment?: 'platform' | 'cross-platform' | null;
|
|
76
94
|
}
|
|
77
95
|
interface PasskeyPopupStoredPasskey {
|
|
78
96
|
credentialId: string;
|
|
@@ -80,6 +98,10 @@ interface PasskeyPopupStoredPasskey {
|
|
|
80
98
|
publicKeyY: string;
|
|
81
99
|
rpId: string;
|
|
82
100
|
label?: string;
|
|
101
|
+
deviceName?: string;
|
|
102
|
+
devicePlatform?: string;
|
|
103
|
+
browserName?: string;
|
|
104
|
+
authenticatorAttachment?: 'platform' | 'cross-platform' | null;
|
|
83
105
|
createdAt: string;
|
|
84
106
|
lastUsedAt: string;
|
|
85
107
|
}
|
|
@@ -92,6 +114,7 @@ interface PasskeyPopupRegistrationResult {
|
|
|
92
114
|
publicKeyX: string;
|
|
93
115
|
publicKeyY: string;
|
|
94
116
|
rpId: string;
|
|
117
|
+
authenticatorAttachment?: 'platform' | 'cross-platform' | null;
|
|
95
118
|
}
|
|
96
119
|
type PasskeyPopupResponse = {
|
|
97
120
|
type: string;
|
|
@@ -122,4 +145,4 @@ type PasskeyPopupResponse = {
|
|
|
122
145
|
};
|
|
123
146
|
};
|
|
124
147
|
|
|
125
|
-
export type {
|
|
148
|
+
export type { PasskeyClientCapabilities as P, PasskeyPopupAccount as a, PasskeyPopupAction as b, PasskeyPopupContext as c, PasskeyPopupCreateRequestPayload as d, PasskeyPopupGetRequestPayload as e, PasskeyPopupGetStoredRequestPayload as f, PasskeyPopupRegistrationResult as g, PasskeyPopupRequest as h, PasskeyPopupRequestPayload as i, PasskeyPopupResponse as j, PasskeyPopupSigningResult as k, PasskeyPopupStoredPasskey as l, PasskeyPopupStoredSigningResult as m, PasskeyRegistrationOptions as n, PasskeyStoredSigningOptions as o, PasskeyStoredSigningResult as p };
|