@thru/passkey 0.2.13 → 0.2.15

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.
Files changed (71) hide show
  1. package/README.md +73 -90
  2. package/dist/auth.cjs +672 -0
  3. package/dist/auth.cjs.map +1 -0
  4. package/dist/auth.d.cts +60 -0
  5. package/dist/auth.d.ts +60 -0
  6. package/dist/auth.js +422 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/chunk-2JHC7OOH.js +250 -0
  9. package/dist/chunk-2JHC7OOH.js.map +1 -0
  10. package/dist/chunk-75G2FPYW.js +54 -0
  11. package/dist/chunk-75G2FPYW.js.map +1 -0
  12. package/dist/chunk-B5SN7AS7.js +586 -0
  13. package/dist/chunk-B5SN7AS7.js.map +1 -0
  14. package/dist/chunk-LNDWK3FA.js +163 -0
  15. package/dist/chunk-LNDWK3FA.js.map +1 -0
  16. package/dist/index.cjs +27 -94
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +4 -187
  19. package/dist/index.d.ts +4 -187
  20. package/dist/index.js +47 -810
  21. package/dist/index.js.map +1 -1
  22. package/dist/mobile.cjs +301 -0
  23. package/dist/mobile.cjs.map +1 -0
  24. package/dist/mobile.d.cts +49 -0
  25. package/dist/mobile.d.ts +49 -0
  26. package/dist/mobile.js +41 -0
  27. package/dist/mobile.js.map +1 -0
  28. package/dist/popup.cjs +247 -0
  29. package/dist/popup.cjs.map +1 -0
  30. package/dist/popup.d.cts +22 -0
  31. package/dist/popup.d.ts +22 -0
  32. package/dist/popup.js +31 -0
  33. package/dist/popup.js.map +1 -0
  34. package/dist/server.cjs +351 -0
  35. package/dist/server.cjs.map +1 -0
  36. package/dist/server.d.cts +119 -0
  37. package/dist/server.d.ts +119 -0
  38. package/dist/server.js +340 -0
  39. package/dist/server.js.map +1 -0
  40. package/dist/types-_HRzmn-j.d.cts +125 -0
  41. package/dist/types-_HRzmn-j.d.ts +125 -0
  42. package/dist/web.cjs +758 -0
  43. package/dist/web.cjs.map +1 -0
  44. package/dist/web.d.cts +32 -0
  45. package/dist/web.d.ts +32 -0
  46. package/dist/web.js +60 -0
  47. package/dist/web.js.map +1 -0
  48. package/package.json +47 -2
  49. package/src/auth/execute-tx.ts +87 -0
  50. package/src/auth/index.ts +18 -0
  51. package/src/auth/types.ts +56 -0
  52. package/src/auth/use-passkey-auth.ts +428 -0
  53. package/src/index.ts +37 -39
  54. package/src/mobile/errors.ts +31 -0
  55. package/src/mobile/index.ts +33 -0
  56. package/src/mobile/passkey.ts +154 -0
  57. package/src/mobile/storage.ts +115 -0
  58. package/src/mobile/types.ts +24 -0
  59. package/src/popup-entry.ts +33 -0
  60. package/src/popup-service.ts +0 -103
  61. package/src/server/challenge.ts +26 -0
  62. package/src/server/create-wallet.ts +149 -0
  63. package/src/server/handlers.ts +93 -0
  64. package/src/server/index.ts +13 -0
  65. package/src/server/submit.ts +47 -0
  66. package/src/server/types.ts +70 -0
  67. package/src/server/utils.ts +69 -0
  68. package/src/types.ts +1 -0
  69. package/src/web.ts +51 -0
  70. package/tsconfig.json +6 -1
  71. package/tsup.config.ts +9 -1
package/dist/server.js ADDED
@@ -0,0 +1,340 @@
1
+ // src/server/create-wallet.ts
2
+ import {
3
+ PASSKEY_MANAGER_PROGRAM_ADDRESS,
4
+ base64UrlToBytes,
5
+ buildAccountContext,
6
+ createCredentialLookupSeed,
7
+ createWalletSeed,
8
+ deriveCredentialLookupAddress,
9
+ deriveWalletAddress,
10
+ encodeCreateInstruction,
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
+ }
63
+
64
+ // src/server/utils.ts
65
+ async function getStateProof(client, address, proofType = 1, targetSlot) {
66
+ const proofRequest = {
67
+ address,
68
+ proofType
69
+ };
70
+ if (targetSlot !== void 0) {
71
+ proofRequest.targetSlot = targetSlot;
72
+ }
73
+ const proof = await client.proofs.generate(proofRequest);
74
+ if (!proof.proof || proof.proof.length === 0) {
75
+ throw new Error(`No state proof returned for ${address}`);
76
+ }
77
+ return proof.proof;
78
+ }
79
+ async function trackTransaction(client, signature, timeoutMs = 5e3) {
80
+ try {
81
+ for await (const update of client.transactions.track(signature, { timeoutMs })) {
82
+ if (update.executionResult) {
83
+ return {
84
+ signature,
85
+ status: update.executionResult.userErrorCode === 0n ? "finalized" : "failed",
86
+ errorCode: update.executionResult.userErrorCode
87
+ };
88
+ }
89
+ if (update.statusCode === 3) {
90
+ return {
91
+ signature,
92
+ status: "finalized"
93
+ };
94
+ }
95
+ }
96
+ } catch {
97
+ return {
98
+ signature,
99
+ status: "timeout"
100
+ };
101
+ }
102
+ return {
103
+ signature,
104
+ status: "timeout"
105
+ };
106
+ }
107
+ function toThruAddress(bytes) {
108
+ return encodeAddress(bytes);
109
+ }
110
+
111
+ // src/server/create-wallet.ts
112
+ async function createPasskeyWallet(opts) {
113
+ const walletName = opts.walletName ?? "default";
114
+ const seed = await createWalletSeed(walletName, opts.pubkeyX, opts.pubkeyY);
115
+ const walletBytes = await deriveWalletAddress(seed, PASSKEY_MANAGER_PROGRAM_ADDRESS);
116
+ const walletAddress = toThruAddress(walletBytes);
117
+ let walletExists = false;
118
+ try {
119
+ await opts.client.accounts.get(walletAddress);
120
+ walletExists = true;
121
+ } catch {
122
+ walletExists = false;
123
+ }
124
+ if (!walletExists) {
125
+ const stateProof = await getStateProof(opts.client, walletAddress);
126
+ const accountCtx = buildAccountContext({
127
+ walletAddress,
128
+ readWriteAccounts: [],
129
+ readOnlyAccounts: [],
130
+ feePayerAddress: opts.adminAddress,
131
+ programAddress: PASSKEY_MANAGER_PROGRAM_ADDRESS
132
+ });
133
+ const createIx = encodeCreateInstruction({
134
+ walletAccountIdx: accountCtx.walletAccountIdx,
135
+ authority: {
136
+ tag: 1,
137
+ pubkeyX: opts.pubkeyX,
138
+ pubkeyY: opts.pubkeyY
139
+ },
140
+ seed,
141
+ stateProof
142
+ });
143
+ const transaction = await opts.client.transactions.build({
144
+ feePayer: { publicKey: opts.adminPublicKey },
145
+ program: PASSKEY_MANAGER_PROGRAM_ADDRESS,
146
+ instructionData: createIx,
147
+ accounts: {
148
+ readWrite: [walletAddress],
149
+ readOnly: []
150
+ },
151
+ header: { fee: 0n }
152
+ });
153
+ await transaction.sign(opts.adminPrivateKey);
154
+ const signature = await opts.client.transactions.send(transaction.toWire());
155
+ const result = await trackTransaction(opts.client, signature, 6e4);
156
+ if (result.status !== "finalized") {
157
+ throw new Error(
158
+ `Wallet creation failed with error code: ${result.errorCode ?? "unknown"}`
159
+ );
160
+ }
161
+ }
162
+ let credentialLookupAddress;
163
+ if (opts.credentialId) {
164
+ const credentialIdBytes = base64UrlToBytes(opts.credentialId);
165
+ const lookupAddressBytes = await deriveCredentialLookupAddress(
166
+ credentialIdBytes,
167
+ walletName,
168
+ PASSKEY_MANAGER_PROGRAM_ADDRESS
169
+ );
170
+ credentialLookupAddress = toThruAddress(lookupAddressBytes);
171
+ let lookupExists = false;
172
+ try {
173
+ await opts.client.accounts.get(credentialLookupAddress);
174
+ lookupExists = true;
175
+ } catch {
176
+ lookupExists = false;
177
+ }
178
+ if (!lookupExists) {
179
+ try {
180
+ const credSeed = await createCredentialLookupSeed(credentialIdBytes, walletName);
181
+ const stateProof = await getStateProof(opts.client, credentialLookupAddress);
182
+ const accountCtx = buildAccountContext({
183
+ walletAddress,
184
+ readWriteAccounts: [lookupAddressBytes],
185
+ readOnlyAccounts: [],
186
+ feePayerAddress: opts.adminAddress,
187
+ programAddress: PASSKEY_MANAGER_PROGRAM_ADDRESS
188
+ });
189
+ const registerIx = encodeRegisterCredentialInstruction({
190
+ walletAccountIdx: accountCtx.walletAccountIdx,
191
+ lookupAccountIdx: accountCtx.getAccountIndex(lookupAddressBytes),
192
+ seed: credSeed,
193
+ stateProof
194
+ });
195
+ const transaction = await opts.client.transactions.build({
196
+ feePayer: { publicKey: opts.adminPublicKey },
197
+ program: PASSKEY_MANAGER_PROGRAM_ADDRESS,
198
+ instructionData: registerIx,
199
+ accounts: {
200
+ readWrite: [walletAddress, credentialLookupAddress],
201
+ readOnly: []
202
+ },
203
+ header: { fee: 0n }
204
+ });
205
+ await transaction.sign(opts.adminPrivateKey);
206
+ const signature = await opts.client.transactions.send(transaction.toWire());
207
+ const result = await trackTransaction(opts.client, signature, 6e4);
208
+ if (result.status !== "finalized") {
209
+ throw new Error(
210
+ `Credential registration failed with status: ${result.status}${result.errorCode !== void 0 ? ` (error code: ${result.errorCode})` : ""}`
211
+ );
212
+ }
213
+ } catch (error) {
214
+ console.warn("Credential registration failed (non-fatal):", error);
215
+ }
216
+ }
217
+ }
218
+ return {
219
+ walletAddress,
220
+ credentialLookupAddress
221
+ };
222
+ }
223
+
224
+ // src/server/challenge.ts
225
+ import {
226
+ bytesToBase64Url,
227
+ createValidateChallenge,
228
+ fetchWalletNonce
229
+ } from "@thru/passkey-manager";
230
+ async function createPasskeyChallenge(opts) {
231
+ const nonce = await fetchWalletNonce(opts.client, opts.walletAddress);
232
+ const challenge = await createValidateChallenge(
233
+ nonce,
234
+ opts.accountCtx.accountAddresses,
235
+ opts.invokeIx
236
+ );
237
+ return {
238
+ challenge: bytesToBase64Url(challenge),
239
+ nonce: nonce.toString()
240
+ };
241
+ }
242
+
243
+ // src/server/submit.ts
244
+ import {
245
+ PASSKEY_MANAGER_PROGRAM_ADDRESS as PASSKEY_MANAGER_PROGRAM_ADDRESS2,
246
+ concatenateInstructions,
247
+ encodeValidateInstruction,
248
+ hexToBytes as hexToBytes2
249
+ } from "@thru/passkey-manager";
250
+ async function submitPasskeyTransaction(opts) {
251
+ const validateIx = encodeValidateInstruction({
252
+ walletAccountIdx: opts.accountCtx.walletAccountIdx,
253
+ authIdx: 0,
254
+ signatureR: hexToBytes2(opts.signatureR),
255
+ signatureS: hexToBytes2(opts.signatureS),
256
+ authenticatorData: Buffer.from(opts.authenticatorData, "base64"),
257
+ clientDataJSON: Buffer.from(opts.clientDataJSON, "base64")
258
+ });
259
+ const instructionData = concatenateInstructions([validateIx, opts.invokeIx]);
260
+ const transaction = await opts.client.transactions.build({
261
+ feePayer: { publicKey: opts.adminPublicKey },
262
+ program: PASSKEY_MANAGER_PROGRAM_ADDRESS2,
263
+ instructionData,
264
+ accounts: {
265
+ readWrite: opts.accountCtx.readWriteAddresses,
266
+ readOnly: opts.accountCtx.readOnlyAddresses
267
+ },
268
+ header: { fee: 0n }
269
+ });
270
+ await transaction.sign(opts.adminPrivateKey);
271
+ const signature = await opts.client.transactions.send(transaction.toWire());
272
+ return trackTransaction(opts.client, signature);
273
+ }
274
+
275
+ // src/server/handlers.ts
276
+ function createPasskeyHandlers(opts) {
277
+ const pendingContexts = /* @__PURE__ */ new Map();
278
+ const challengeTtlMs = opts.challengeTtlMs ?? 5 * 6e4;
279
+ function createPendingContextKey(walletAddress, nonce, challenge) {
280
+ return `${walletAddress}:${nonce}:${challenge}`;
281
+ }
282
+ function prunePendingContexts(now = Date.now()) {
283
+ for (const [nonce, entry] of pendingContexts.entries()) {
284
+ if (now - entry.createdAt > challengeTtlMs) {
285
+ pendingContexts.delete(nonce);
286
+ }
287
+ }
288
+ }
289
+ return {
290
+ challenge: async (walletAddress, params) => {
291
+ prunePendingContexts();
292
+ const context = await opts.buildContext(params);
293
+ const challenge = await createPasskeyChallenge({
294
+ client: opts.client,
295
+ walletAddress,
296
+ accountCtx: context.accountCtx,
297
+ invokeIx: context.invokeIx
298
+ });
299
+ pendingContexts.set(
300
+ createPendingContextKey(walletAddress, challenge.nonce, challenge.challenge),
301
+ {
302
+ context,
303
+ createdAt: Date.now()
304
+ }
305
+ );
306
+ return challenge;
307
+ },
308
+ submit: async (walletAddress, params, payload) => {
309
+ void params;
310
+ prunePendingContexts();
311
+ const pendingKey = createPendingContextKey(
312
+ walletAddress,
313
+ payload.nonce,
314
+ payload.challenge
315
+ );
316
+ const pending = pendingContexts.get(pendingKey);
317
+ if (!pending) {
318
+ throw new Error("Missing or expired challenge nonce");
319
+ }
320
+ pendingContexts.delete(pendingKey);
321
+ const { nonce: _nonce, challenge: _challenge, ...signaturePayload } = payload;
322
+ return submitPasskeyTransaction({
323
+ client: opts.client,
324
+ adminPublicKey: opts.adminPublicKey,
325
+ adminPrivateKey: opts.adminPrivateKey,
326
+ walletAddress,
327
+ accountCtx: pending.context.accountCtx,
328
+ invokeIx: pending.context.invokeIx,
329
+ ...signaturePayload
330
+ });
331
+ }
332
+ };
333
+ }
334
+ export {
335
+ createPasskeyChallenge,
336
+ createPasskeyHandlers,
337
+ createPasskeyWallet,
338
+ submitPasskeyTransaction
339
+ };
340
+ //# sourceMappingURL=server.js.map
@@ -0,0 +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 { toThruAddress, getStateProof, trackTransaction } from './utils';\nimport type { ThruClient } from './types';\n\nexport async function createPasskeyWallet(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: string;\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 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) {\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: [walletAddress],\n readOnly: [],\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 error code: ${result.errorCode ?? 'unknown'}`\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\n credentialLookupAddress = toThruAddress(lookupAddressBytes);\n\n let lookupExists = false;\n try {\n await opts.client.accounts.get(credentialLookupAddress);\n lookupExists = true;\n } catch {\n lookupExists = false;\n }\n\n if (!lookupExists) {\n try {\n const credSeed = await createCredentialLookupSeed(credentialIdBytes, walletName);\n const stateProof = await getStateProof(opts.client, credentialLookupAddress);\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: [walletAddress, credentialLookupAddress],\n readOnly: [],\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 } catch (error) {\n console.warn('Credential registration failed (non-fatal):', error);\n }\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\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 try {\n for await (const update of client.transactions.track(signature, { timeoutMs })) {\n if (update.executionResult) {\n return {\n signature,\n status: update.executionResult.userErrorCode === 0n ? 'finalized' : 'failed',\n errorCode: update.executionResult.userErrorCode,\n };\n }\n\n if (update.statusCode === 3) {\n return {\n signature,\n status: 'finalized',\n };\n }\n }\n } catch {\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","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 } from './utils';\nimport type {\n PasskeySignaturePayload,\n ThruClient,\n TransactionResult,\n} from './types';\n\nexport async function submitPasskeyTransaction(opts: {\n client: ThruClient;\n adminPublicKey: Uint8Array;\n adminPrivateKey: string;\n walletAddress: string;\n accountCtx: AccountContext;\n invokeIx: Uint8Array;\n} & PasskeySignaturePayload): Promise<TransactionResult> {\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: { fee: 0n },\n });\n\n await transaction.sign(opts.adminPrivateKey);\n const signature = await opts.client.transactions.send(transaction.toWire());\n return trackTransaction(opts.client, signature);\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: string;\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"]}
@@ -0,0 +1,125 @@
1
+ import { PasskeySigningResult, PasskeyMetadata } from '@thru/passkey-manager';
2
+
3
+ /**
4
+ * Signing result with stored passkey metadata attached.
5
+ */
6
+ interface PasskeyStoredSigningResult extends PasskeySigningResult {
7
+ passkey: PasskeyMetadata;
8
+ accounts?: PasskeyPopupAccount[];
9
+ }
10
+ /**
11
+ * WebAuthn client capabilities map.
12
+ */
13
+ interface PasskeyClientCapabilities {
14
+ conditionalCreate?: boolean;
15
+ conditionalGet?: boolean;
16
+ credentialProtectionPolicy?: boolean;
17
+ credProps?: boolean;
18
+ minPinLength?: boolean;
19
+ multiFactor?: boolean;
20
+ passkeyPlatformAuthenticator?: boolean;
21
+ largeBlob?: boolean;
22
+ rpId?: boolean;
23
+ userVerifyingPlatformAuthenticator?: boolean;
24
+ relatedOrigins?: boolean;
25
+ }
26
+ /**
27
+ * Context sent to popup for display purposes.
28
+ */
29
+ interface PasskeyPopupContext {
30
+ appId?: string;
31
+ appName?: string;
32
+ appUrl?: string;
33
+ origin?: string;
34
+ imageUrl?: string;
35
+ }
36
+ /**
37
+ * Account info passed through popup bridge.
38
+ */
39
+ interface PasskeyPopupAccount {
40
+ index: number;
41
+ label?: string;
42
+ publicKey: string;
43
+ path?: string;
44
+ createdAt?: string;
45
+ addressType?: string;
46
+ publicKeyRawBase64?: string;
47
+ }
48
+ type PasskeyPopupAction = 'get' | 'create' | 'getStored';
49
+ interface PasskeyPopupGetRequestPayload {
50
+ credentialId: string;
51
+ challengeBase64Url: string;
52
+ rpId: string;
53
+ }
54
+ interface PasskeyPopupCreateRequestPayload {
55
+ alias: string;
56
+ userId: string;
57
+ rpId: string;
58
+ }
59
+ interface PasskeyPopupGetStoredRequestPayload {
60
+ challengeBase64Url: string;
61
+ context?: PasskeyPopupContext;
62
+ }
63
+ type PasskeyPopupRequestPayload = PasskeyPopupGetRequestPayload | PasskeyPopupCreateRequestPayload | PasskeyPopupGetStoredRequestPayload;
64
+ interface PasskeyPopupRequest {
65
+ type: string;
66
+ requestId: string;
67
+ action: PasskeyPopupAction;
68
+ payload: PasskeyPopupRequestPayload;
69
+ }
70
+ interface PasskeyPopupSigningResult {
71
+ signatureBase64Url: string;
72
+ authenticatorDataBase64Url: string;
73
+ clientDataJSONBase64Url: string;
74
+ signatureRBase64Url: string;
75
+ signatureSBase64Url: string;
76
+ }
77
+ interface PasskeyPopupStoredPasskey {
78
+ credentialId: string;
79
+ publicKeyX: string;
80
+ publicKeyY: string;
81
+ rpId: string;
82
+ label?: string;
83
+ createdAt: string;
84
+ lastUsedAt: string;
85
+ }
86
+ interface PasskeyPopupStoredSigningResult extends PasskeyPopupSigningResult {
87
+ passkey: PasskeyPopupStoredPasskey;
88
+ accounts?: PasskeyPopupAccount[];
89
+ }
90
+ interface PasskeyPopupRegistrationResult {
91
+ credentialId: string;
92
+ publicKeyX: string;
93
+ publicKeyY: string;
94
+ rpId: string;
95
+ }
96
+ type PasskeyPopupResponse = {
97
+ type: string;
98
+ requestId: string;
99
+ action: 'get';
100
+ success: true;
101
+ result: PasskeyPopupSigningResult;
102
+ } | {
103
+ type: string;
104
+ requestId: string;
105
+ action: 'create';
106
+ success: true;
107
+ result: PasskeyPopupRegistrationResult;
108
+ } | {
109
+ type: string;
110
+ requestId: string;
111
+ action: 'getStored';
112
+ success: true;
113
+ result: PasskeyPopupStoredSigningResult;
114
+ } | {
115
+ type: string;
116
+ requestId: string;
117
+ action: PasskeyPopupAction;
118
+ success: false;
119
+ error: {
120
+ name?: string;
121
+ message: string;
122
+ };
123
+ };
124
+
125
+ export type { PasskeyStoredSigningResult as P, PasskeyClientCapabilities as a, PasskeyPopupContext as b, PasskeyPopupAccount as c, PasskeyPopupAction as d, PasskeyPopupGetRequestPayload as e, PasskeyPopupCreateRequestPayload as f, PasskeyPopupGetStoredRequestPayload as g, PasskeyPopupRequestPayload as h, PasskeyPopupRequest as i, PasskeyPopupSigningResult as j, PasskeyPopupStoredPasskey as k, PasskeyPopupStoredSigningResult as l, PasskeyPopupRegistrationResult as m, PasskeyPopupResponse as n };
@@ -0,0 +1,125 @@
1
+ import { PasskeySigningResult, PasskeyMetadata } from '@thru/passkey-manager';
2
+
3
+ /**
4
+ * Signing result with stored passkey metadata attached.
5
+ */
6
+ interface PasskeyStoredSigningResult extends PasskeySigningResult {
7
+ passkey: PasskeyMetadata;
8
+ accounts?: PasskeyPopupAccount[];
9
+ }
10
+ /**
11
+ * WebAuthn client capabilities map.
12
+ */
13
+ interface PasskeyClientCapabilities {
14
+ conditionalCreate?: boolean;
15
+ conditionalGet?: boolean;
16
+ credentialProtectionPolicy?: boolean;
17
+ credProps?: boolean;
18
+ minPinLength?: boolean;
19
+ multiFactor?: boolean;
20
+ passkeyPlatformAuthenticator?: boolean;
21
+ largeBlob?: boolean;
22
+ rpId?: boolean;
23
+ userVerifyingPlatformAuthenticator?: boolean;
24
+ relatedOrigins?: boolean;
25
+ }
26
+ /**
27
+ * Context sent to popup for display purposes.
28
+ */
29
+ interface PasskeyPopupContext {
30
+ appId?: string;
31
+ appName?: string;
32
+ appUrl?: string;
33
+ origin?: string;
34
+ imageUrl?: string;
35
+ }
36
+ /**
37
+ * Account info passed through popup bridge.
38
+ */
39
+ interface PasskeyPopupAccount {
40
+ index: number;
41
+ label?: string;
42
+ publicKey: string;
43
+ path?: string;
44
+ createdAt?: string;
45
+ addressType?: string;
46
+ publicKeyRawBase64?: string;
47
+ }
48
+ type PasskeyPopupAction = 'get' | 'create' | 'getStored';
49
+ interface PasskeyPopupGetRequestPayload {
50
+ credentialId: string;
51
+ challengeBase64Url: string;
52
+ rpId: string;
53
+ }
54
+ interface PasskeyPopupCreateRequestPayload {
55
+ alias: string;
56
+ userId: string;
57
+ rpId: string;
58
+ }
59
+ interface PasskeyPopupGetStoredRequestPayload {
60
+ challengeBase64Url: string;
61
+ context?: PasskeyPopupContext;
62
+ }
63
+ type PasskeyPopupRequestPayload = PasskeyPopupGetRequestPayload | PasskeyPopupCreateRequestPayload | PasskeyPopupGetStoredRequestPayload;
64
+ interface PasskeyPopupRequest {
65
+ type: string;
66
+ requestId: string;
67
+ action: PasskeyPopupAction;
68
+ payload: PasskeyPopupRequestPayload;
69
+ }
70
+ interface PasskeyPopupSigningResult {
71
+ signatureBase64Url: string;
72
+ authenticatorDataBase64Url: string;
73
+ clientDataJSONBase64Url: string;
74
+ signatureRBase64Url: string;
75
+ signatureSBase64Url: string;
76
+ }
77
+ interface PasskeyPopupStoredPasskey {
78
+ credentialId: string;
79
+ publicKeyX: string;
80
+ publicKeyY: string;
81
+ rpId: string;
82
+ label?: string;
83
+ createdAt: string;
84
+ lastUsedAt: string;
85
+ }
86
+ interface PasskeyPopupStoredSigningResult extends PasskeyPopupSigningResult {
87
+ passkey: PasskeyPopupStoredPasskey;
88
+ accounts?: PasskeyPopupAccount[];
89
+ }
90
+ interface PasskeyPopupRegistrationResult {
91
+ credentialId: string;
92
+ publicKeyX: string;
93
+ publicKeyY: string;
94
+ rpId: string;
95
+ }
96
+ type PasskeyPopupResponse = {
97
+ type: string;
98
+ requestId: string;
99
+ action: 'get';
100
+ success: true;
101
+ result: PasskeyPopupSigningResult;
102
+ } | {
103
+ type: string;
104
+ requestId: string;
105
+ action: 'create';
106
+ success: true;
107
+ result: PasskeyPopupRegistrationResult;
108
+ } | {
109
+ type: string;
110
+ requestId: string;
111
+ action: 'getStored';
112
+ success: true;
113
+ result: PasskeyPopupStoredSigningResult;
114
+ } | {
115
+ type: string;
116
+ requestId: string;
117
+ action: PasskeyPopupAction;
118
+ success: false;
119
+ error: {
120
+ name?: string;
121
+ message: string;
122
+ };
123
+ };
124
+
125
+ export type { PasskeyStoredSigningResult as P, PasskeyClientCapabilities as a, PasskeyPopupContext as b, PasskeyPopupAccount as c, PasskeyPopupAction as d, PasskeyPopupGetRequestPayload as e, PasskeyPopupCreateRequestPayload as f, PasskeyPopupGetStoredRequestPayload as g, PasskeyPopupRequestPayload as h, PasskeyPopupRequest as i, PasskeyPopupSigningResult as j, PasskeyPopupStoredPasskey as k, PasskeyPopupStoredSigningResult as l, PasskeyPopupRegistrationResult as m, PasskeyPopupResponse as n };