@thru/passkey 0.2.12 → 0.2.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/README.md +73 -90
- package/dist/auth.cjs +672 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +60 -0
- package/dist/auth.d.ts +60 -0
- package/dist/auth.js +422 -0
- package/dist/auth.js.map +1 -0
- package/dist/chunk-2JHC7OOH.js +250 -0
- package/dist/chunk-2JHC7OOH.js.map +1 -0
- package/dist/chunk-75G2FPYW.js +54 -0
- package/dist/chunk-75G2FPYW.js.map +1 -0
- package/dist/chunk-B5SN7AS7.js +586 -0
- package/dist/chunk-B5SN7AS7.js.map +1 -0
- package/dist/chunk-LNDWK3FA.js +163 -0
- package/dist/chunk-LNDWK3FA.js.map +1 -0
- package/dist/index.cjs +27 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -187
- package/dist/index.d.ts +4 -187
- package/dist/index.js +47 -810
- package/dist/index.js.map +1 -1
- package/dist/mobile.cjs +301 -0
- package/dist/mobile.cjs.map +1 -0
- package/dist/mobile.d.cts +49 -0
- package/dist/mobile.d.ts +49 -0
- package/dist/mobile.js +41 -0
- package/dist/mobile.js.map +1 -0
- package/dist/popup.cjs +247 -0
- package/dist/popup.cjs.map +1 -0
- package/dist/popup.d.cts +22 -0
- package/dist/popup.d.ts +22 -0
- package/dist/popup.js +31 -0
- package/dist/popup.js.map +1 -0
- package/dist/server.cjs +351 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +119 -0
- package/dist/server.d.ts +119 -0
- package/dist/server.js +340 -0
- package/dist/server.js.map +1 -0
- package/dist/types-_HRzmn-j.d.cts +125 -0
- package/dist/types-_HRzmn-j.d.ts +125 -0
- package/dist/web.cjs +758 -0
- package/dist/web.cjs.map +1 -0
- package/dist/web.d.cts +32 -0
- package/dist/web.d.ts +32 -0
- package/dist/web.js +60 -0
- package/dist/web.js.map +1 -0
- package/package.json +47 -2
- package/src/auth/execute-tx.ts +87 -0
- package/src/auth/index.ts +18 -0
- package/src/auth/types.ts +56 -0
- package/src/auth/use-passkey-auth.ts +428 -0
- package/src/index.ts +37 -39
- package/src/mobile/errors.ts +31 -0
- package/src/mobile/index.ts +33 -0
- package/src/mobile/passkey.ts +154 -0
- package/src/mobile/storage.ts +115 -0
- package/src/mobile/types.ts +24 -0
- package/src/popup-entry.ts +33 -0
- package/src/popup-service.ts +0 -103
- package/src/server/challenge.ts +26 -0
- package/src/server/create-wallet.ts +149 -0
- package/src/server/handlers.ts +93 -0
- package/src/server/index.ts +13 -0
- package/src/server/submit.ts +47 -0
- package/src/server/types.ts +70 -0
- package/src/server/utils.ts +69 -0
- package/src/types.ts +1 -0
- package/src/web.ts +51 -0
- package/tsconfig.json +6 -1
- package/tsup.config.ts +9 -1
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server/index.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
createPasskeyChallenge: () => createPasskeyChallenge,
|
|
24
|
+
createPasskeyHandlers: () => createPasskeyHandlers,
|
|
25
|
+
createPasskeyWallet: () => createPasskeyWallet,
|
|
26
|
+
submitPasskeyTransaction: () => submitPasskeyTransaction
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(server_exports);
|
|
29
|
+
|
|
30
|
+
// src/server/create-wallet.ts
|
|
31
|
+
var import_passkey_manager = require("@thru/passkey-manager");
|
|
32
|
+
|
|
33
|
+
// ../helpers/src/constants.ts
|
|
34
|
+
var BASE64_URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
35
|
+
var tempMap = new Int16Array(256).fill(-1);
|
|
36
|
+
for (let i = 0; i < BASE64_URL_ALPHABET.length; i++) {
|
|
37
|
+
tempMap[BASE64_URL_ALPHABET.charCodeAt(i)] = i;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ../helpers/src/address.ts
|
|
41
|
+
function encodeAddress(bytes) {
|
|
42
|
+
if (bytes.length !== 32) {
|
|
43
|
+
throw new Error("Expected 32-byte address");
|
|
44
|
+
}
|
|
45
|
+
let checksum = 0;
|
|
46
|
+
let accumulator = 0;
|
|
47
|
+
let bitsCollected = 0;
|
|
48
|
+
const output = ["t", "a"];
|
|
49
|
+
for (let i = 0; i < 30; i++) {
|
|
50
|
+
const byte = bytes[i];
|
|
51
|
+
checksum += byte;
|
|
52
|
+
accumulator = (accumulator << 8 | byte) >>> 0;
|
|
53
|
+
bitsCollected += 8;
|
|
54
|
+
while (bitsCollected >= 6) {
|
|
55
|
+
const index = accumulator >> bitsCollected - 6 & 63;
|
|
56
|
+
output.push(BASE64_URL_ALPHABET[index]);
|
|
57
|
+
bitsCollected -= 6;
|
|
58
|
+
accumulator &= maskForBits(bitsCollected);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const secondLast = bytes[30];
|
|
62
|
+
checksum += secondLast;
|
|
63
|
+
accumulator = (accumulator << 8 | secondLast) >>> 0;
|
|
64
|
+
bitsCollected += 8;
|
|
65
|
+
const last = bytes[31];
|
|
66
|
+
checksum += last;
|
|
67
|
+
accumulator = (accumulator << 8 | last) >>> 0;
|
|
68
|
+
bitsCollected += 8;
|
|
69
|
+
accumulator = (accumulator << 8 | checksum & 255) >>> 0;
|
|
70
|
+
bitsCollected += 8;
|
|
71
|
+
while (bitsCollected >= 6) {
|
|
72
|
+
const index = accumulator >> bitsCollected - 6 & 63;
|
|
73
|
+
output.push(BASE64_URL_ALPHABET[index]);
|
|
74
|
+
bitsCollected -= 6;
|
|
75
|
+
accumulator &= maskForBits(bitsCollected);
|
|
76
|
+
}
|
|
77
|
+
return output.join("");
|
|
78
|
+
}
|
|
79
|
+
function maskForBits(bits) {
|
|
80
|
+
return bits === 0 ? 0 : (1 << bits) - 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/server/utils.ts
|
|
84
|
+
async function getStateProof(client, address, proofType = 1, targetSlot) {
|
|
85
|
+
const proofRequest = {
|
|
86
|
+
address,
|
|
87
|
+
proofType
|
|
88
|
+
};
|
|
89
|
+
if (targetSlot !== void 0) {
|
|
90
|
+
proofRequest.targetSlot = targetSlot;
|
|
91
|
+
}
|
|
92
|
+
const proof = await client.proofs.generate(proofRequest);
|
|
93
|
+
if (!proof.proof || proof.proof.length === 0) {
|
|
94
|
+
throw new Error(`No state proof returned for ${address}`);
|
|
95
|
+
}
|
|
96
|
+
return proof.proof;
|
|
97
|
+
}
|
|
98
|
+
async function trackTransaction(client, signature, timeoutMs = 5e3) {
|
|
99
|
+
try {
|
|
100
|
+
for await (const update of client.transactions.track(signature, { timeoutMs })) {
|
|
101
|
+
if (update.executionResult) {
|
|
102
|
+
return {
|
|
103
|
+
signature,
|
|
104
|
+
status: update.executionResult.userErrorCode === 0n ? "finalized" : "failed",
|
|
105
|
+
errorCode: update.executionResult.userErrorCode
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (update.statusCode === 3) {
|
|
109
|
+
return {
|
|
110
|
+
signature,
|
|
111
|
+
status: "finalized"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch {
|
|
116
|
+
return {
|
|
117
|
+
signature,
|
|
118
|
+
status: "timeout"
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
signature,
|
|
123
|
+
status: "timeout"
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function toThruAddress(bytes) {
|
|
127
|
+
return encodeAddress(bytes);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/server/create-wallet.ts
|
|
131
|
+
async function createPasskeyWallet(opts) {
|
|
132
|
+
const walletName = opts.walletName ?? "default";
|
|
133
|
+
const seed = await (0, import_passkey_manager.createWalletSeed)(walletName, opts.pubkeyX, opts.pubkeyY);
|
|
134
|
+
const walletBytes = await (0, import_passkey_manager.deriveWalletAddress)(seed, import_passkey_manager.PASSKEY_MANAGER_PROGRAM_ADDRESS);
|
|
135
|
+
const walletAddress = toThruAddress(walletBytes);
|
|
136
|
+
let walletExists = false;
|
|
137
|
+
try {
|
|
138
|
+
await opts.client.accounts.get(walletAddress);
|
|
139
|
+
walletExists = true;
|
|
140
|
+
} catch {
|
|
141
|
+
walletExists = false;
|
|
142
|
+
}
|
|
143
|
+
if (!walletExists) {
|
|
144
|
+
const stateProof = await getStateProof(opts.client, walletAddress);
|
|
145
|
+
const accountCtx = (0, import_passkey_manager.buildAccountContext)({
|
|
146
|
+
walletAddress,
|
|
147
|
+
readWriteAccounts: [],
|
|
148
|
+
readOnlyAccounts: [],
|
|
149
|
+
feePayerAddress: opts.adminAddress,
|
|
150
|
+
programAddress: import_passkey_manager.PASSKEY_MANAGER_PROGRAM_ADDRESS
|
|
151
|
+
});
|
|
152
|
+
const createIx = (0, import_passkey_manager.encodeCreateInstruction)({
|
|
153
|
+
walletAccountIdx: accountCtx.walletAccountIdx,
|
|
154
|
+
authority: {
|
|
155
|
+
tag: 1,
|
|
156
|
+
pubkeyX: opts.pubkeyX,
|
|
157
|
+
pubkeyY: opts.pubkeyY
|
|
158
|
+
},
|
|
159
|
+
seed,
|
|
160
|
+
stateProof
|
|
161
|
+
});
|
|
162
|
+
const transaction = await opts.client.transactions.build({
|
|
163
|
+
feePayer: { publicKey: opts.adminPublicKey },
|
|
164
|
+
program: import_passkey_manager.PASSKEY_MANAGER_PROGRAM_ADDRESS,
|
|
165
|
+
instructionData: createIx,
|
|
166
|
+
accounts: {
|
|
167
|
+
readWrite: [walletAddress],
|
|
168
|
+
readOnly: []
|
|
169
|
+
},
|
|
170
|
+
header: { fee: 0n }
|
|
171
|
+
});
|
|
172
|
+
await transaction.sign(opts.adminPrivateKey);
|
|
173
|
+
const signature = await opts.client.transactions.send(transaction.toWire());
|
|
174
|
+
const result = await trackTransaction(opts.client, signature, 6e4);
|
|
175
|
+
if (result.status !== "finalized") {
|
|
176
|
+
throw new Error(
|
|
177
|
+
`Wallet creation failed with error code: ${result.errorCode ?? "unknown"}`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
let credentialLookupAddress;
|
|
182
|
+
if (opts.credentialId) {
|
|
183
|
+
const credentialIdBytes = (0, import_passkey_manager.base64UrlToBytes)(opts.credentialId);
|
|
184
|
+
const lookupAddressBytes = await (0, import_passkey_manager.deriveCredentialLookupAddress)(
|
|
185
|
+
credentialIdBytes,
|
|
186
|
+
walletName,
|
|
187
|
+
import_passkey_manager.PASSKEY_MANAGER_PROGRAM_ADDRESS
|
|
188
|
+
);
|
|
189
|
+
credentialLookupAddress = toThruAddress(lookupAddressBytes);
|
|
190
|
+
let lookupExists = false;
|
|
191
|
+
try {
|
|
192
|
+
await opts.client.accounts.get(credentialLookupAddress);
|
|
193
|
+
lookupExists = true;
|
|
194
|
+
} catch {
|
|
195
|
+
lookupExists = false;
|
|
196
|
+
}
|
|
197
|
+
if (!lookupExists) {
|
|
198
|
+
try {
|
|
199
|
+
const credSeed = await (0, import_passkey_manager.createCredentialLookupSeed)(credentialIdBytes, walletName);
|
|
200
|
+
const stateProof = await getStateProof(opts.client, credentialLookupAddress);
|
|
201
|
+
const accountCtx = (0, import_passkey_manager.buildAccountContext)({
|
|
202
|
+
walletAddress,
|
|
203
|
+
readWriteAccounts: [lookupAddressBytes],
|
|
204
|
+
readOnlyAccounts: [],
|
|
205
|
+
feePayerAddress: opts.adminAddress,
|
|
206
|
+
programAddress: import_passkey_manager.PASSKEY_MANAGER_PROGRAM_ADDRESS
|
|
207
|
+
});
|
|
208
|
+
const registerIx = (0, import_passkey_manager.encodeRegisterCredentialInstruction)({
|
|
209
|
+
walletAccountIdx: accountCtx.walletAccountIdx,
|
|
210
|
+
lookupAccountIdx: accountCtx.getAccountIndex(lookupAddressBytes),
|
|
211
|
+
seed: credSeed,
|
|
212
|
+
stateProof
|
|
213
|
+
});
|
|
214
|
+
const transaction = await opts.client.transactions.build({
|
|
215
|
+
feePayer: { publicKey: opts.adminPublicKey },
|
|
216
|
+
program: import_passkey_manager.PASSKEY_MANAGER_PROGRAM_ADDRESS,
|
|
217
|
+
instructionData: registerIx,
|
|
218
|
+
accounts: {
|
|
219
|
+
readWrite: [walletAddress, credentialLookupAddress],
|
|
220
|
+
readOnly: []
|
|
221
|
+
},
|
|
222
|
+
header: { fee: 0n }
|
|
223
|
+
});
|
|
224
|
+
await transaction.sign(opts.adminPrivateKey);
|
|
225
|
+
const signature = await opts.client.transactions.send(transaction.toWire());
|
|
226
|
+
const result = await trackTransaction(opts.client, signature, 6e4);
|
|
227
|
+
if (result.status !== "finalized") {
|
|
228
|
+
throw new Error(
|
|
229
|
+
`Credential registration failed with status: ${result.status}${result.errorCode !== void 0 ? ` (error code: ${result.errorCode})` : ""}`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.warn("Credential registration failed (non-fatal):", error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
walletAddress,
|
|
239
|
+
credentialLookupAddress
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/server/challenge.ts
|
|
244
|
+
var import_passkey_manager2 = require("@thru/passkey-manager");
|
|
245
|
+
async function createPasskeyChallenge(opts) {
|
|
246
|
+
const nonce = await (0, import_passkey_manager2.fetchWalletNonce)(opts.client, opts.walletAddress);
|
|
247
|
+
const challenge = await (0, import_passkey_manager2.createValidateChallenge)(
|
|
248
|
+
nonce,
|
|
249
|
+
opts.accountCtx.accountAddresses,
|
|
250
|
+
opts.invokeIx
|
|
251
|
+
);
|
|
252
|
+
return {
|
|
253
|
+
challenge: (0, import_passkey_manager2.bytesToBase64Url)(challenge),
|
|
254
|
+
nonce: nonce.toString()
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/server/submit.ts
|
|
259
|
+
var import_passkey_manager3 = require("@thru/passkey-manager");
|
|
260
|
+
async function submitPasskeyTransaction(opts) {
|
|
261
|
+
const validateIx = (0, import_passkey_manager3.encodeValidateInstruction)({
|
|
262
|
+
walletAccountIdx: opts.accountCtx.walletAccountIdx,
|
|
263
|
+
authIdx: 0,
|
|
264
|
+
signatureR: (0, import_passkey_manager3.hexToBytes)(opts.signatureR),
|
|
265
|
+
signatureS: (0, import_passkey_manager3.hexToBytes)(opts.signatureS),
|
|
266
|
+
authenticatorData: Buffer.from(opts.authenticatorData, "base64"),
|
|
267
|
+
clientDataJSON: Buffer.from(opts.clientDataJSON, "base64")
|
|
268
|
+
});
|
|
269
|
+
const instructionData = (0, import_passkey_manager3.concatenateInstructions)([validateIx, opts.invokeIx]);
|
|
270
|
+
const transaction = await opts.client.transactions.build({
|
|
271
|
+
feePayer: { publicKey: opts.adminPublicKey },
|
|
272
|
+
program: import_passkey_manager3.PASSKEY_MANAGER_PROGRAM_ADDRESS,
|
|
273
|
+
instructionData,
|
|
274
|
+
accounts: {
|
|
275
|
+
readWrite: opts.accountCtx.readWriteAddresses,
|
|
276
|
+
readOnly: opts.accountCtx.readOnlyAddresses
|
|
277
|
+
},
|
|
278
|
+
header: { fee: 0n }
|
|
279
|
+
});
|
|
280
|
+
await transaction.sign(opts.adminPrivateKey);
|
|
281
|
+
const signature = await opts.client.transactions.send(transaction.toWire());
|
|
282
|
+
return trackTransaction(opts.client, signature);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/server/handlers.ts
|
|
286
|
+
function createPasskeyHandlers(opts) {
|
|
287
|
+
const pendingContexts = /* @__PURE__ */ new Map();
|
|
288
|
+
const challengeTtlMs = opts.challengeTtlMs ?? 5 * 6e4;
|
|
289
|
+
function createPendingContextKey(walletAddress, nonce, challenge) {
|
|
290
|
+
return `${walletAddress}:${nonce}:${challenge}`;
|
|
291
|
+
}
|
|
292
|
+
function prunePendingContexts(now = Date.now()) {
|
|
293
|
+
for (const [nonce, entry] of pendingContexts.entries()) {
|
|
294
|
+
if (now - entry.createdAt > challengeTtlMs) {
|
|
295
|
+
pendingContexts.delete(nonce);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
challenge: async (walletAddress, params) => {
|
|
301
|
+
prunePendingContexts();
|
|
302
|
+
const context = await opts.buildContext(params);
|
|
303
|
+
const challenge = await createPasskeyChallenge({
|
|
304
|
+
client: opts.client,
|
|
305
|
+
walletAddress,
|
|
306
|
+
accountCtx: context.accountCtx,
|
|
307
|
+
invokeIx: context.invokeIx
|
|
308
|
+
});
|
|
309
|
+
pendingContexts.set(
|
|
310
|
+
createPendingContextKey(walletAddress, challenge.nonce, challenge.challenge),
|
|
311
|
+
{
|
|
312
|
+
context,
|
|
313
|
+
createdAt: Date.now()
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
return challenge;
|
|
317
|
+
},
|
|
318
|
+
submit: async (walletAddress, params, payload) => {
|
|
319
|
+
void params;
|
|
320
|
+
prunePendingContexts();
|
|
321
|
+
const pendingKey = createPendingContextKey(
|
|
322
|
+
walletAddress,
|
|
323
|
+
payload.nonce,
|
|
324
|
+
payload.challenge
|
|
325
|
+
);
|
|
326
|
+
const pending = pendingContexts.get(pendingKey);
|
|
327
|
+
if (!pending) {
|
|
328
|
+
throw new Error("Missing or expired challenge nonce");
|
|
329
|
+
}
|
|
330
|
+
pendingContexts.delete(pendingKey);
|
|
331
|
+
const { nonce: _nonce, challenge: _challenge, ...signaturePayload } = payload;
|
|
332
|
+
return submitPasskeyTransaction({
|
|
333
|
+
client: opts.client,
|
|
334
|
+
adminPublicKey: opts.adminPublicKey,
|
|
335
|
+
adminPrivateKey: opts.adminPrivateKey,
|
|
336
|
+
walletAddress,
|
|
337
|
+
accountCtx: pending.context.accountCtx,
|
|
338
|
+
invokeIx: pending.context.invokeIx,
|
|
339
|
+
...signaturePayload
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
345
|
+
0 && (module.exports = {
|
|
346
|
+
createPasskeyChallenge,
|
|
347
|
+
createPasskeyHandlers,
|
|
348
|
+
createPasskeyWallet,
|
|
349
|
+
submitPasskeyTransaction
|
|
350
|
+
});
|
|
351
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/index.ts","../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":["export type {\n ThruClient,\n PasskeySignaturePayload,\n PasskeyChallengeSubmitPayload,\n TransactionResult,\n PasskeyChallengeResult,\n PasskeyContextResult,\n} from './types';\n\nexport { createPasskeyWallet } from './create-wallet';\nexport { createPasskeyChallenge } from './challenge';\nexport { submitPasskeyTransaction } from './submit';\nexport { createPasskeyHandlers } from './handlers';\n","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":["import_passkey_manager","import_passkey_manager"]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AccountContext } from '@thru/passkey-manager';
|
|
2
|
+
|
|
3
|
+
interface ThruClient {
|
|
4
|
+
accounts: {
|
|
5
|
+
get: (address: string) => Promise<{
|
|
6
|
+
data?: {
|
|
7
|
+
data?: Uint8Array;
|
|
8
|
+
};
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
blocks: {
|
|
12
|
+
getBlockHeight: () => Promise<{
|
|
13
|
+
finalized: bigint;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
proofs: {
|
|
17
|
+
generate: (params: {
|
|
18
|
+
address: string;
|
|
19
|
+
proofType: number;
|
|
20
|
+
targetSlot: bigint;
|
|
21
|
+
}) => Promise<{
|
|
22
|
+
proof?: Uint8Array;
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
transactions: {
|
|
26
|
+
build: (params: {
|
|
27
|
+
feePayer: {
|
|
28
|
+
publicKey: Uint8Array;
|
|
29
|
+
};
|
|
30
|
+
program: string;
|
|
31
|
+
instructionData: Uint8Array;
|
|
32
|
+
accounts: {
|
|
33
|
+
readWrite: string[];
|
|
34
|
+
readOnly: string[];
|
|
35
|
+
};
|
|
36
|
+
header: {
|
|
37
|
+
fee: bigint;
|
|
38
|
+
};
|
|
39
|
+
}) => Promise<{
|
|
40
|
+
sign: (privateKey: string) => Promise<unknown>;
|
|
41
|
+
toWire: () => Uint8Array;
|
|
42
|
+
}>;
|
|
43
|
+
send: (transaction: Uint8Array) => Promise<string>;
|
|
44
|
+
track: (signature: string, opts: {
|
|
45
|
+
timeoutMs: number;
|
|
46
|
+
}) => AsyncIterable<{
|
|
47
|
+
executionResult?: {
|
|
48
|
+
userErrorCode: bigint;
|
|
49
|
+
};
|
|
50
|
+
statusCode?: number;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
interface PasskeySignaturePayload {
|
|
55
|
+
signatureR: string;
|
|
56
|
+
signatureS: string;
|
|
57
|
+
authenticatorData: string;
|
|
58
|
+
clientDataJSON: string;
|
|
59
|
+
}
|
|
60
|
+
interface PasskeyChallengeSubmitPayload extends PasskeySignaturePayload {
|
|
61
|
+
challenge: string;
|
|
62
|
+
nonce: string;
|
|
63
|
+
}
|
|
64
|
+
interface TransactionResult {
|
|
65
|
+
signature: string;
|
|
66
|
+
status: 'finalized' | 'failed' | 'timeout';
|
|
67
|
+
errorCode?: bigint;
|
|
68
|
+
}
|
|
69
|
+
interface PasskeyChallengeResult {
|
|
70
|
+
challenge: string;
|
|
71
|
+
nonce: string;
|
|
72
|
+
}
|
|
73
|
+
interface PasskeyContextResult {
|
|
74
|
+
accountCtx: AccountContext;
|
|
75
|
+
invokeIx: Uint8Array;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare function createPasskeyWallet(opts: {
|
|
79
|
+
client: ThruClient;
|
|
80
|
+
adminPublicKey: Uint8Array;
|
|
81
|
+
adminPrivateKey: string;
|
|
82
|
+
adminAddress: string;
|
|
83
|
+
pubkeyX: Uint8Array;
|
|
84
|
+
pubkeyY: Uint8Array;
|
|
85
|
+
credentialId?: string;
|
|
86
|
+
walletName?: string;
|
|
87
|
+
}): Promise<{
|
|
88
|
+
walletAddress: string;
|
|
89
|
+
credentialLookupAddress?: string;
|
|
90
|
+
}>;
|
|
91
|
+
|
|
92
|
+
declare function createPasskeyChallenge(opts: {
|
|
93
|
+
client: ThruClient;
|
|
94
|
+
walletAddress: string;
|
|
95
|
+
accountCtx: AccountContext;
|
|
96
|
+
invokeIx: Uint8Array;
|
|
97
|
+
}): Promise<PasskeyChallengeResult>;
|
|
98
|
+
|
|
99
|
+
declare function submitPasskeyTransaction(opts: {
|
|
100
|
+
client: ThruClient;
|
|
101
|
+
adminPublicKey: Uint8Array;
|
|
102
|
+
adminPrivateKey: string;
|
|
103
|
+
walletAddress: string;
|
|
104
|
+
accountCtx: AccountContext;
|
|
105
|
+
invokeIx: Uint8Array;
|
|
106
|
+
} & PasskeySignaturePayload): Promise<TransactionResult>;
|
|
107
|
+
|
|
108
|
+
declare function createPasskeyHandlers<P>(opts: {
|
|
109
|
+
buildContext: (params: P) => Promise<PasskeyContextResult>;
|
|
110
|
+
adminPublicKey: Uint8Array;
|
|
111
|
+
adminPrivateKey: string;
|
|
112
|
+
client: ThruClient;
|
|
113
|
+
challengeTtlMs?: number;
|
|
114
|
+
}): {
|
|
115
|
+
challenge: (walletAddress: string, params: P) => Promise<PasskeyChallengeResult>;
|
|
116
|
+
submit: (walletAddress: string, params: P, payload: PasskeyChallengeSubmitPayload) => Promise<TransactionResult>;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export { type PasskeyChallengeResult, type PasskeyChallengeSubmitPayload, type PasskeyContextResult, type PasskeySignaturePayload, type ThruClient, type TransactionResult, createPasskeyChallenge, createPasskeyHandlers, createPasskeyWallet, submitPasskeyTransaction };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AccountContext } from '@thru/passkey-manager';
|
|
2
|
+
|
|
3
|
+
interface ThruClient {
|
|
4
|
+
accounts: {
|
|
5
|
+
get: (address: string) => Promise<{
|
|
6
|
+
data?: {
|
|
7
|
+
data?: Uint8Array;
|
|
8
|
+
};
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
blocks: {
|
|
12
|
+
getBlockHeight: () => Promise<{
|
|
13
|
+
finalized: bigint;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
proofs: {
|
|
17
|
+
generate: (params: {
|
|
18
|
+
address: string;
|
|
19
|
+
proofType: number;
|
|
20
|
+
targetSlot: bigint;
|
|
21
|
+
}) => Promise<{
|
|
22
|
+
proof?: Uint8Array;
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
transactions: {
|
|
26
|
+
build: (params: {
|
|
27
|
+
feePayer: {
|
|
28
|
+
publicKey: Uint8Array;
|
|
29
|
+
};
|
|
30
|
+
program: string;
|
|
31
|
+
instructionData: Uint8Array;
|
|
32
|
+
accounts: {
|
|
33
|
+
readWrite: string[];
|
|
34
|
+
readOnly: string[];
|
|
35
|
+
};
|
|
36
|
+
header: {
|
|
37
|
+
fee: bigint;
|
|
38
|
+
};
|
|
39
|
+
}) => Promise<{
|
|
40
|
+
sign: (privateKey: string) => Promise<unknown>;
|
|
41
|
+
toWire: () => Uint8Array;
|
|
42
|
+
}>;
|
|
43
|
+
send: (transaction: Uint8Array) => Promise<string>;
|
|
44
|
+
track: (signature: string, opts: {
|
|
45
|
+
timeoutMs: number;
|
|
46
|
+
}) => AsyncIterable<{
|
|
47
|
+
executionResult?: {
|
|
48
|
+
userErrorCode: bigint;
|
|
49
|
+
};
|
|
50
|
+
statusCode?: number;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
interface PasskeySignaturePayload {
|
|
55
|
+
signatureR: string;
|
|
56
|
+
signatureS: string;
|
|
57
|
+
authenticatorData: string;
|
|
58
|
+
clientDataJSON: string;
|
|
59
|
+
}
|
|
60
|
+
interface PasskeyChallengeSubmitPayload extends PasskeySignaturePayload {
|
|
61
|
+
challenge: string;
|
|
62
|
+
nonce: string;
|
|
63
|
+
}
|
|
64
|
+
interface TransactionResult {
|
|
65
|
+
signature: string;
|
|
66
|
+
status: 'finalized' | 'failed' | 'timeout';
|
|
67
|
+
errorCode?: bigint;
|
|
68
|
+
}
|
|
69
|
+
interface PasskeyChallengeResult {
|
|
70
|
+
challenge: string;
|
|
71
|
+
nonce: string;
|
|
72
|
+
}
|
|
73
|
+
interface PasskeyContextResult {
|
|
74
|
+
accountCtx: AccountContext;
|
|
75
|
+
invokeIx: Uint8Array;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare function createPasskeyWallet(opts: {
|
|
79
|
+
client: ThruClient;
|
|
80
|
+
adminPublicKey: Uint8Array;
|
|
81
|
+
adminPrivateKey: string;
|
|
82
|
+
adminAddress: string;
|
|
83
|
+
pubkeyX: Uint8Array;
|
|
84
|
+
pubkeyY: Uint8Array;
|
|
85
|
+
credentialId?: string;
|
|
86
|
+
walletName?: string;
|
|
87
|
+
}): Promise<{
|
|
88
|
+
walletAddress: string;
|
|
89
|
+
credentialLookupAddress?: string;
|
|
90
|
+
}>;
|
|
91
|
+
|
|
92
|
+
declare function createPasskeyChallenge(opts: {
|
|
93
|
+
client: ThruClient;
|
|
94
|
+
walletAddress: string;
|
|
95
|
+
accountCtx: AccountContext;
|
|
96
|
+
invokeIx: Uint8Array;
|
|
97
|
+
}): Promise<PasskeyChallengeResult>;
|
|
98
|
+
|
|
99
|
+
declare function submitPasskeyTransaction(opts: {
|
|
100
|
+
client: ThruClient;
|
|
101
|
+
adminPublicKey: Uint8Array;
|
|
102
|
+
adminPrivateKey: string;
|
|
103
|
+
walletAddress: string;
|
|
104
|
+
accountCtx: AccountContext;
|
|
105
|
+
invokeIx: Uint8Array;
|
|
106
|
+
} & PasskeySignaturePayload): Promise<TransactionResult>;
|
|
107
|
+
|
|
108
|
+
declare function createPasskeyHandlers<P>(opts: {
|
|
109
|
+
buildContext: (params: P) => Promise<PasskeyContextResult>;
|
|
110
|
+
adminPublicKey: Uint8Array;
|
|
111
|
+
adminPrivateKey: string;
|
|
112
|
+
client: ThruClient;
|
|
113
|
+
challengeTtlMs?: number;
|
|
114
|
+
}): {
|
|
115
|
+
challenge: (walletAddress: string, params: P) => Promise<PasskeyChallengeResult>;
|
|
116
|
+
submit: (walletAddress: string, params: P, payload: PasskeyChallengeSubmitPayload) => Promise<TransactionResult>;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export { type PasskeyChallengeResult, type PasskeyChallengeSubmitPayload, type PasskeyContextResult, type PasskeySignaturePayload, type ThruClient, type TransactionResult, createPasskeyChallenge, createPasskeyHandlers, createPasskeyWallet, submitPasskeyTransaction };
|