passkey-kit 0.2.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/kit.ts CHANGED
@@ -1,51 +1,37 @@
1
1
  import { Client as PasskeyClient } from 'passkey-kit-sdk'
2
- import { Client as FactoryClient, networks } from 'passkey-factory-sdk'
3
- import { Address, Networks, StrKey, hash, xdr, Transaction, SorobanRpc, Operation, scValToNative, TransactionBuilder } from '@stellar/stellar-sdk'
4
- import { bufToBigint, bigintToBuf } from 'bigint-conversion'
2
+ import { Client as FactoryClient } from 'passkey-factory-sdk'
3
+ import { Address, Networks, StrKey, hash, xdr, Transaction, SorobanRpc, Operation, TransactionBuilder } from '@stellar/stellar-sdk'
5
4
  import base64url from 'base64url'
6
5
  import { startRegistration, startAuthentication } from "@simplewebauthn/browser"
6
+ import type { AuthenticatorAttestationResponseJSON } from "@simplewebauthn/types"
7
7
  import { decode } from 'cbor-x/decode'
8
8
  import { Buffer } from 'buffer'
9
9
  import { PasskeyBase } from './base'
10
10
 
11
- /* TODO
12
- - Clean up these params and the interface as a whole
13
- Might put wallet activities and maybe factory as well into the root of the class vs buried inside this.wallet and this.factory
14
- @Later
15
- - Right now publicKey can mean a Stellar public key or a passkey public key, there should be a noted difference
16
- */
11
+ type GetContractIdFunction = (keyId: string) => Promise<string>;
17
12
 
18
13
  export class PasskeyKit extends PasskeyBase {
19
14
  public keyId: string | undefined
20
- public sudoKeyId: string | undefined
15
+ public keyExpired: boolean | undefined
21
16
  public wallet: PasskeyClient | undefined
22
17
  public factory: FactoryClient
23
18
  public networkPassphrase: Networks
24
19
  public rpcUrl: string
25
20
  public rpc: SorobanRpc.Server
26
- public factoryContractId: string = networks.testnet.contractId
27
-
28
- /* NOTE
29
- - Consider adding the ability to pass in a keyId and maybe even a contractId in order to preconnect to a wallet
30
- If just a keyId call `connectWallet` in order to get the contractId
31
- If both keyId and contractId are passed in then we can skip the connectWallet call (though we won't get the sudoKeyId in that case)
32
- We don't strictly _need_ this as a dev can just call `connectWallet` after class instantiation but it might be a nice convenience
33
- `connectWallet` is async making it tricky to know when the wallet is "ready". Thus I think it's better for `connectWallet` to be called externally
34
- @No
35
- */
21
+
36
22
  constructor(options: {
37
23
  rpcUrl: string,
38
24
  launchtubeUrl?: string,
39
25
  launchtubeJwt?: string,
40
- factoryContractId?: string,
41
26
  networkPassphrase: string,
27
+ factoryContractId: string,
42
28
  }) {
43
29
  const {
44
30
  rpcUrl,
45
31
  launchtubeUrl,
46
32
  launchtubeJwt,
47
- factoryContractId,
48
33
  networkPassphrase,
34
+ factoryContractId,
49
35
  } = options
50
36
 
51
37
  super({
@@ -53,21 +39,18 @@ export class PasskeyKit extends PasskeyBase {
53
39
  launchtubeJwt,
54
40
  })
55
41
 
56
- if (factoryContractId)
57
- this.factoryContractId = factoryContractId
58
-
59
42
  this.rpcUrl = rpcUrl
60
43
  this.rpc = new SorobanRpc.Server(rpcUrl)
61
44
  this.networkPassphrase = networkPassphrase as Networks
62
45
  this.factory = new FactoryClient({
63
- contractId: this.factoryContractId,
46
+ contractId: factoryContractId,
64
47
  networkPassphrase,
65
48
  rpcUrl
66
49
  })
67
50
  }
68
51
 
69
- public async createWallet(name: string, user: string) {
70
- const { keyId, publicKey } = await this.createKey(name, user)
52
+ public async createWallet(app: string, user: string) {
53
+ const { keyId, publicKey } = await this.createKey(app, user)
71
54
 
72
55
  const { result, built } = await this.factory.deploy({
73
56
  id: keyId,
@@ -89,17 +72,19 @@ export class PasskeyKit extends PasskeyBase {
89
72
  }
90
73
  }
91
74
 
92
- public async createKey(name: string, user: string) {
93
- const startRegistrationResponse = await startRegistration({
75
+ public async createKey(app: string, user: string) {
76
+ const now = new Date()
77
+ const displayName = `${user} — ${now.toLocaleString()}`
78
+ const { id, response} = await startRegistration({
94
79
  challenge: base64url("stellaristhebetterblockchain"),
95
80
  rp: {
96
81
  // id: undefined,
97
- name,
82
+ name: app,
98
83
  },
99
- user: {
100
- id: base64url(user),
101
- name: user,
102
- displayName: user,
84
+ user: { // TODO there's a real danger here of overwriting a user's key if they use the same `user` name
85
+ id: base64url(`${user}:${now.getTime()}:${Math.random()}`),
86
+ name: displayName,
87
+ displayName
103
88
  },
104
89
  authenticatorSelection: {
105
90
  requireResidentKey: false,
@@ -110,78 +95,89 @@ export class PasskeyKit extends PasskeyBase {
110
95
  attestation: "none",
111
96
  });
112
97
 
113
- if (!this.keyId) {
114
- this.keyId = startRegistrationResponse.id
115
-
116
- // If there was no keyId we're likely about to deploy a new wallet so we should set the sudoKeyId
117
- if (!this.sudoKeyId)
118
- this.sudoKeyId = startRegistrationResponse.id
119
- }
120
-
121
- const { publicKeyObject } = this.getPublicKeyObject(startRegistrationResponse.response.attestationObject);
98
+ if (!this.keyId)
99
+ this.keyId = id;
122
100
 
123
- const publicKey = Buffer.from([
124
- 4, // (0x04 prefix) https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm
125
- ...publicKeyObject.get('-2')!,
126
- ...publicKeyObject.get('-3')!
127
- ])
101
+ const publicKey = this.getPublicKey(response);
128
102
 
129
103
  return {
130
- keyId: base64url.toBuffer(startRegistrationResponse.id),
104
+ keyId: base64url.toBuffer(id),
131
105
  publicKey
132
106
  }
133
107
  }
134
108
 
135
- public async connectWallet(keyId?: string) {
109
+ public async connectWallet(opts: {
110
+ keyId?: string | Uint8Array,
111
+ getContractId?: GetContractIdFunction
112
+ }) {
113
+ let { keyId, getContractId } = opts
114
+ let keyIdBuffer: Buffer
115
+
136
116
  if (!keyId) {
137
- const { id } = await startAuthentication({
117
+ const response = await startAuthentication({
138
118
  challenge: base64url("stellaristhebetterblockchain"),
139
119
  // rpId: undefined,
140
120
  userVerification: "discouraged",
141
121
  });
142
122
 
143
- keyId = id
123
+ console.log(response);
124
+
125
+ keyId = response.id
126
+ }
127
+
128
+ if (keyId instanceof Uint8Array) {
129
+ keyIdBuffer = Buffer.from(keyId)
130
+ keyId = base64url(keyIdBuffer)
131
+ } else {
132
+ keyIdBuffer = base64url.toBuffer(keyId)
144
133
  }
145
134
 
146
135
  if (!this.keyId)
147
136
  this.keyId = keyId
148
137
 
149
- const keyIdBuffer = base64url.toBuffer(keyId)
150
-
151
- // NOTE might not need this for derivation as all signers are stored in the factory and we can use that lookup as both primary and secondary
152
- let contractId = StrKey.encodeContract(hash(xdr.HashIdPreimage.envelopeTypeContractId(
138
+ // Check for the contractId on-chain as a derivation from the keyId. This is the easiest and "cheapest" check however it will only work for the initially deployed passkey if it was used as derivation
139
+ let contractId: string | undefined = StrKey.encodeContract(hash(xdr.HashIdPreimage.envelopeTypeContractId(
153
140
  new xdr.HashIdPreimageContractId({
154
141
  networkId: hash(Buffer.from(this.networkPassphrase, 'utf-8')),
155
142
  contractIdPreimage: xdr.ContractIdPreimage.contractIdPreimageFromAddress(
156
143
  new xdr.ContractIdPreimageFromAddress({
157
- address: Address.fromString(this.factoryContractId).toScAddress(),
144
+ address: Address.fromString(this.factory.options.contractId).toScAddress(),
158
145
  salt: hash(keyIdBuffer),
159
146
  })
160
147
  )
161
148
  })
162
149
  ).toXDR()));
163
150
 
164
- let contractData: SorobanRpc.Api.LedgerEntryResult | undefined
165
-
166
151
  // attempt passkey id derivation
167
152
  try {
168
- contractData = await this.rpc.getContractData(contractId, xdr.ScVal.scvLedgerKeyContractInstance())
153
+ await this.rpc.getContractData(contractId, xdr.ScVal.scvLedgerKeyContractInstance())
169
154
  }
170
155
  // if that fails look up from the factory mapper
171
156
  catch {
172
- const { val } = await this.rpc.getContractData(this.factoryContractId, xdr.ScVal.scvBytes(keyIdBuffer))
173
- contractId = scValToNative(val.contractData().val())
157
+ contractId = undefined
158
+
159
+ if (getContractId) {
160
+ contractId = await getContractId(keyId)
161
+
162
+ // Handle case where temporary session signer is missing on-chain (so we can queue up a re-add)
163
+ try {
164
+ await this.rpc.getContractData(contractId, xdr.ScVal.scvBytes(keyIdBuffer), SorobanRpc.Durability.Temporary)
165
+ // throw true
166
+ } catch {
167
+ this.keyExpired = true
168
+ }
169
+ }
174
170
  }
175
171
 
172
+ if (!contractId)
173
+ throw new Error('No `contractId` was found')
174
+
176
175
  this.wallet = new PasskeyClient({
177
176
  contractId,
178
177
  networkPassphrase: this.networkPassphrase,
179
178
  rpcUrl: this.rpcUrl
180
179
  })
181
180
 
182
- // get and set the sudo signer (passing in `contractData` from the `getContractData` call above to avoid dupe requests)
183
- await this.getData(contractData)
184
-
185
181
  return {
186
182
  keyId: keyIdBuffer,
187
183
  contractId
@@ -191,7 +187,7 @@ export class PasskeyKit extends PasskeyBase {
191
187
  public async signAuthEntry(
192
188
  entry: xdr.SorobanAuthorizationEntry,
193
189
  options?: {
194
- keyId?: 'any' | 'sudo' | string | Uint8Array
190
+ keyId?: 'any' | string | Uint8Array
195
191
  ledgersToLive?: number
196
192
  }
197
193
  ) {
@@ -212,7 +208,6 @@ export class PasskeyKit extends PasskeyBase {
212
208
 
213
209
  const authenticationResponse = await startAuthentication(
214
210
  keyId === 'any'
215
- || (keyId === 'sudo' && !this.sudoKeyId)
216
211
  || (!keyId && !this.keyId)
217
212
  ? {
218
213
  challenge: base64url(payload),
@@ -224,11 +219,9 @@ export class PasskeyKit extends PasskeyBase {
224
219
  // rpId: undefined,
225
220
  allowCredentials: [
226
221
  {
227
- id: keyId === 'sudo'
228
- ? this.sudoKeyId!
229
- : keyId instanceof Uint8Array
230
- ? base64url(keyId)
231
- : keyId || this.keyId!,
222
+ id: keyId instanceof Uint8Array
223
+ ? base64url(Buffer.from(keyId))
224
+ : keyId || this.keyId!,
232
225
  type: "public-key",
233
226
  },
234
227
  ],
@@ -236,9 +229,10 @@ export class PasskeyKit extends PasskeyBase {
236
229
  }
237
230
  );
238
231
 
239
- const signatureRaw = base64url.toBuffer(authenticationResponse.response.signature);
240
- const signature = this.convertEcdsaSignatureAsnToCompact(signatureRaw);
241
-
232
+ const signature = this.compactSignature(
233
+ base64url.toBuffer(authenticationResponse.response.signature)
234
+ );
235
+
242
236
  credentials.signatureExpirationLedger(lastLedger + ledgersToLive)
243
237
  credentials.signature(xdr.ScVal.scvMap([
244
238
  new xdr.ScMapEntry({
@@ -258,13 +252,13 @@ export class PasskeyKit extends PasskeyBase {
258
252
  val: xdr.ScVal.scvBytes(signature),
259
253
  }),
260
254
  ]))
261
-
255
+
262
256
  return entry
263
257
  }
264
258
  public async signAuthEntries(
265
259
  entries: xdr.SorobanAuthorizationEntry[],
266
260
  options?: {
267
- keyId?: 'any' | 'sudo' | string | Uint8Array
261
+ keyId?: 'any' | string | Uint8Array
268
262
  ledgersToLive?: number
269
263
  }
270
264
  ) {
@@ -281,21 +275,14 @@ export class PasskeyKit extends PasskeyBase {
281
275
 
282
276
  return entries
283
277
  }
284
- /* NOTE
285
- - Is there anything to be done with using the TS bindings `signAuthEntries` logic? Likely not but worth exploring
286
- Perhaps not but maybe the js-sdk's `authorizeEntry` or `authorizeInvocation`
287
- https://stellar.github.io/js-stellar-sdk/global.html#authorizeInvocation
288
- These methods all only support ed25519 Keypairs
289
- @No
290
- */
291
278
  public async sign(
292
279
  txn: Transaction | string,
293
280
  options?: {
294
- keyId?: 'any' | 'sudo' | string | Uint8Array
281
+ keyId?: 'any' | string | Uint8Array
295
282
  ledgersToLive?: number
296
283
  }
297
284
  ) {
298
- /* NOTE
285
+ /*
299
286
  - Hack to ensure we don't stack fees when simulating and assembling multiple times
300
287
  AssembleTransaction always adds the resource fee onto the transaction fee.
301
288
  This is bad in cases where you need to simulate multiple times
@@ -315,7 +302,7 @@ export class PasskeyKit extends PasskeyBase {
315
302
  op.type !== 'invokeHostFunction'
316
303
  && op.type !== 'extendFootprintTtl'
317
304
  && op.type !== 'restoreFootprint'
318
- ) throw new Error('Must include only one operation of type `invokeHostFunction` or `extendFootprintTtl` or `restoreFootprint`')
305
+ ) throw new Error('Must include only one operation of type `invokeHostFunction` or `extendFootprintTtl` or `restoreFootprint`')
319
306
  }
320
307
 
321
308
  // Only need to sign auth for `invokeHostFunction` operations
@@ -336,167 +323,72 @@ export class PasskeyKit extends PasskeyBase {
336
323
  return SorobanRpc.assembleTransaction(txn, sim).build().toXDR()
337
324
  }
338
325
 
339
- public async getData(contractData?: SorobanRpc.Api.LedgerEntryResult) {
340
- const data: Map<string, any> = new Map()
341
-
342
- /* TODO
343
- - Pretty easy to get into a state where there is no contractId and this we error at `this.wallet!.options.contractId,`
344
- We should have a better error or maybe just handle no-wallet scenarios more gracefully
345
- */
346
- const { val } = contractData || await this.rpc.getContractData(
347
- this.wallet!.options.contractId,
348
- xdr.ScVal.scvLedgerKeyContractInstance(),
349
- );
350
-
351
- val.contractData()
352
- .val()
353
- .instance()
354
- .storage()
355
- ?.forEach((entry) => {
356
- data.set(
357
- scValToNative(entry.key()),
358
- scValToNative(entry.val()),
359
- );
360
- });
361
-
362
- this.sudoKeyId = base64url(data.get('sudo_sig'))
363
-
364
- return data
365
- }
366
-
367
326
  /* TODO
368
327
  - Add a getKeyInfo action to get info about a specific passkey
369
328
  Specifically looking for name, type, etc. data so a user could grok what signer mapped to what passkey
370
329
  @Later
371
330
  */
372
331
 
373
- private getPublicKeyObject(attestationObject: string) {
374
- const { authData } = decode(base64url.toBuffer(attestationObject));
375
- const authDataUint8Array = new Uint8Array(authData);
376
- const authDataView = new DataView(authDataUint8Array.buffer, 0, authDataUint8Array.length);
377
-
378
- let offset = 0;
379
-
380
- // RP ID Hash (32 bytes)
381
- const rpIdHash = authData.slice(offset, offset + 32);
382
- offset += 32;
383
-
384
- // Flags (1 byte)
385
- const flags = authDataView.getUint8(offset);
386
- offset += 1;
387
-
388
- // Sign Count (4 bytes, big endian)
389
- const signCount = authDataView.getUint32(offset, false);
390
- offset += 4;
391
-
392
- // Attested Credential Data, if present
393
- if (flags & 0x40) { // Checking the AT flag
394
- // AAGUID (16 bytes)
395
- const aaguid = authData.slice(offset, offset + 16);
396
- offset += 16;
397
-
398
- // Credential ID Length (2 bytes, big endian)
399
- const credIdLength = authDataView.getUint16(offset, false);
400
- offset += 2;
401
-
402
- // Credential ID (variable length)
403
- const credentialId = authData.slice(offset, offset + credIdLength);
404
- offset += credIdLength;
405
-
406
- // Credential Public Key - (77 bytes...I hope)
407
- const credentialPublicKey = authData.slice(offset, offset + 77);
408
- offset += 77;
409
-
410
- // Any leftover bytes. I found some when using a YubiKey
411
- const theRest = authData.slice(offset);
412
-
413
- // Decode the credential public key to COSE
414
- const publicKeyObject = new Map<string, any>(Object.entries(decode(credentialPublicKey)));
415
-
416
- return {
417
- rpIdHash,
418
- flags,
419
- signCount,
420
- aaguid,
421
- credIdLength,
422
- credentialId,
423
- credentialPublicKey,
424
- theRest,
425
- publicKeyObject
426
- };
427
- }
428
-
429
- throw new Error("Attested credential data not present in the flags.");
430
- }
431
-
432
- private convertEcdsaSignatureAsnToCompact(sig: Buffer) {
433
- // Define the order of the curve secp256k1
434
- // https://github.com/RustCrypto/elliptic-curves/blob/master/p256/src/lib.rs#L72
435
- const q = Buffer.from('ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551', 'hex')
436
-
437
- // ASN Sequence
438
- let offset = 0;
439
- if (sig[offset] != 0x30) {
440
- throw "signature is not a sequence";
441
- }
442
- offset += 1;
332
+ private getPublicKey(response: AuthenticatorAttestationResponseJSON) {
333
+ let publicKey: Buffer | undefined
443
334
 
444
- // ASN Sequence Byte Length
445
- offset += 1;
335
+ if (response.publicKey)
336
+ publicKey = base64url.toBuffer(response.publicKey).slice(response.publicKey.length - 65)
446
337
 
447
- // ASN Integer (R)
448
- if (sig[offset] != 0x02) {
449
- throw "first element in sequence is not an integer";
338
+ if (
339
+ !publicKey
340
+ || publicKey[0] !== 0x04
341
+ || publicKey.length !== 65
342
+ ) {
343
+ // Extract and decode attestation object (CBOR), slice authenticator data to get COSE-encoded public key, and decode COSE to obtain key components
344
+ const { authData } = response.authenticatorData ? { authData: base64url.toBuffer(response.authenticatorData) } : decode(base64url.toBuffer(response.attestationObject));
345
+ const credentialIdLength = (authData[53] << 8) + authData[54];
346
+ const publicKeyBytes = authData.slice(55 + credentialIdLength);
347
+ const publicKeyCose = decode(publicKeyBytes);
348
+
349
+ publicKey = Buffer.from([
350
+ 0x04, // (0x04 prefix) https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm
351
+ ...publicKeyCose['-2'],
352
+ ...publicKeyCose['-3']
353
+ ])
450
354
  }
451
- offset += 1;
452
355
 
453
- // ASN Integer (R) Byte Length
454
- const rLen = sig[offset];
455
- offset += 1;
356
+ return publicKey
357
+ }
358
+ private compactSignature(signature: Buffer) {
359
+ // Decode the DER signature
360
+ let offset = 2;
456
361
 
457
- // ASN Integer (R) Byte Value
458
- if (rLen >= 33) {
459
- if (rLen != 33 || sig[offset] != 0x00) {
460
- throw "can only handle larger than 32 byte R's that are len 33 and lead with zero";
461
- }
462
- offset += 1;
463
- }
464
- const r = sig.slice(offset, offset + 32);
465
- offset += 32;
362
+ const rLength = signature[offset + 1];
363
+ const r = signature.slice(offset + 2, offset + 2 + rLength);
466
364
 
467
- // ASN Integer (S)
468
- if (sig[offset] != 0x02) {
469
- throw "second element in sequence is not an integer";
470
- }
471
- offset += 1;
365
+ offset += 2 + rLength;
472
366
 
473
- // ASN Integer (S) Byte Length
474
- const sLen = sig[offset];
475
- offset += 1;
367
+ const sLength = signature[offset + 1];
368
+ const s = signature.slice(offset + 2, offset + 2 + sLength);
476
369
 
477
- // ASN Integer (S) Byte Value
478
- if (sLen >= 33) {
479
- if (sLen != 33 || sig[offset] != 0x00) {
480
- throw "can only handle larger than 32 byte R's that are len 33 and lead with zero";
481
- }
482
- offset += 1;
483
- }
370
+ // Convert r and s to BigInt
371
+ const rBigInt = BigInt('0x' + r.toString('hex'));
372
+ let sBigInt = BigInt('0x' + s.toString('hex'));
484
373
 
485
- const s = sig.slice(offset, offset + 32);
374
+ // Ensure s is in the low-S form
375
+ // https://github.com/stellar/stellar-protocol/discussions/1435#discussioncomment-8809175
376
+ // https://discord.com/channels/897514728459468821/1233048618571927693
377
+ // Define the order of the curve secp256r1
378
+ // https://github.com/RustCrypto/elliptic-curves/blob/master/p256/src/lib.rs#L72
379
+ const n = BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551');
380
+ const halfN = n / 2n;
486
381
 
487
- offset += 32;
382
+ if (sBigInt > halfN)
383
+ sBigInt = n - sBigInt;
488
384
 
489
- let signature64: Buffer
385
+ // Convert back to buffers and ensure they are 32 bytes
386
+ const rPadded = Buffer.from(rBigInt.toString(16).padStart(64, '0'), 'hex');
387
+ const sLowS = Buffer.from(sBigInt.toString(16).padStart(64, '0'), 'hex');
490
388
 
491
- // Force low S range
492
- // https://github.com/stellar/stellar-protocol/discussions/1435#discussioncomment-8809175
493
- // https://discord.com/channels/897514728459468821/1233048618571927693
494
- if (bufToBigint(s) > ((bufToBigint(q) - BigInt(1)) / BigInt(2))) {
495
- signature64 = Buffer.from([...r, ...Buffer.from(bigintToBuf(bufToBigint(q) - bufToBigint(s), true) as ArrayBuffer)]);
496
- } else {
497
- signature64 = Buffer.from([...r, ...s]);
498
- }
389
+ // Concatenate r and low-s
390
+ const concatSignature = Buffer.concat([rPadded, sLowS]);
499
391
 
500
- return signature64;
392
+ return concatSignature;
501
393
  }
502
394
  }
package/tsconfig.json CHANGED
@@ -6,7 +6,6 @@
6
6
  "target": "ESNext",
7
7
  "module": "ESNext",
8
8
  "moduleDetection": "force",
9
- // "allowJs": true,
10
9
 
11
10
  // Bundler mode
12
11
  "moduleResolution": "node",
@@ -26,5 +25,5 @@
26
25
  "noPropertyAccessFromIndexSignature": false,
27
26
  "strictNullChecks": true,
28
27
  },
29
- "exclude": ["./demo", "./packages", "./types", "./contracts"]
28
+ "exclude": ["./demo", "./packages", "./types", "./contracts", "./zephyr", "./bun_tests"]
30
29
  }
package/types/kit.d.ts CHANGED
@@ -3,48 +3,51 @@ import { Client as FactoryClient } from 'passkey-factory-sdk';
3
3
  import { Networks, xdr, Transaction, SorobanRpc } from '@stellar/stellar-sdk';
4
4
  import { Buffer } from 'buffer';
5
5
  import { PasskeyBase } from './base';
6
+ type GetContractIdFunction = (keyId: string) => Promise<string>;
6
7
  export declare class PasskeyKit extends PasskeyBase {
7
8
  keyId: string | undefined;
8
- sudoKeyId: string | undefined;
9
+ keyExpired: boolean | undefined;
9
10
  wallet: PasskeyClient | undefined;
10
11
  factory: FactoryClient;
11
12
  networkPassphrase: Networks;
12
13
  rpcUrl: string;
13
14
  rpc: SorobanRpc.Server;
14
- factoryContractId: string;
15
15
  constructor(options: {
16
16
  rpcUrl: string;
17
17
  launchtubeUrl?: string;
18
18
  launchtubeJwt?: string;
19
- factoryContractId?: string;
20
19
  networkPassphrase: string;
20
+ factoryContractId: string;
21
21
  });
22
- createWallet(name: string, user: string): Promise<{
22
+ createWallet(app: string, user: string): Promise<{
23
23
  keyId: Buffer;
24
24
  contractId: string;
25
25
  xdr: string;
26
26
  }>;
27
- createKey(name: string, user: string): Promise<{
27
+ createKey(app: string, user: string): Promise<{
28
28
  keyId: Buffer;
29
29
  publicKey: Buffer;
30
30
  }>;
31
- connectWallet(keyId?: string): Promise<{
31
+ connectWallet(opts: {
32
+ keyId?: string | Uint8Array;
33
+ getContractId?: GetContractIdFunction;
34
+ }): Promise<{
32
35
  keyId: Buffer;
33
36
  contractId: string;
34
37
  }>;
35
38
  signAuthEntry(entry: xdr.SorobanAuthorizationEntry, options?: {
36
- keyId?: 'any' | 'sudo' | string | Uint8Array;
39
+ keyId?: 'any' | string | Uint8Array;
37
40
  ledgersToLive?: number;
38
41
  }): Promise<xdr.SorobanAuthorizationEntry>;
39
42
  signAuthEntries(entries: xdr.SorobanAuthorizationEntry[], options?: {
40
- keyId?: 'any' | 'sudo' | string | Uint8Array;
43
+ keyId?: 'any' | string | Uint8Array;
41
44
  ledgersToLive?: number;
42
45
  }): Promise<xdr.SorobanAuthorizationEntry[]>;
43
46
  sign(txn: Transaction | string, options?: {
44
- keyId?: 'any' | 'sudo' | string | Uint8Array;
47
+ keyId?: 'any' | string | Uint8Array;
45
48
  ledgersToLive?: number;
46
49
  }): Promise<string>;
47
- getData(contractData?: SorobanRpc.Api.LedgerEntryResult): Promise<Map<string, any>>;
48
- private getPublicKeyObject;
49
- private convertEcdsaSignatureAsnToCompact;
50
+ private getPublicKey;
51
+ private compactSignature;
50
52
  }
53
+ export {};
@@ -0,0 +1,9 @@
1
+ export declare class PasskeyBase {
2
+ launchtubeUrl: string | undefined;
3
+ launchtubeJwt: string | undefined;
4
+ constructor(options: {
5
+ launchtubeUrl?: string;
6
+ launchtubeJwt?: string;
7
+ });
8
+ send(xdr: string, fee?: number): Promise<any>;
9
+ }
@@ -0,0 +1,3 @@
1
+ import { PasskeyBase } from "./base";
2
+ import { PasskeyKit } from "./kit";
3
+ export { PasskeyBase, PasskeyKit };