passkey-kit 0.7.0 → 0.7.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "passkey-kit",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "A helper library for creating and using passkey accounts on the Stellar blockchain.",
5
5
  "author": "Tyler van der Hoeven",
6
6
  "license": "MIT",
@@ -13,8 +13,8 @@
13
13
  "@stellar/stellar-sdk": "12.3.0",
14
14
  "base64url": "^3.0.1",
15
15
  "buffer": "^6.0.3",
16
- "passkey-factory-sdk": "0.3.0",
17
- "passkey-kit-sdk": "0.3.0",
16
+ "passkey-factory-sdk": "0.3.1",
17
+ "passkey-kit-sdk": "0.3.1",
18
18
  "sac-sdk": "0.1.0"
19
19
  },
20
20
  "devDependencies": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.3.0",
2
+ "version": "0.3.1",
3
3
  "name": "passkey-factory-sdk",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
@@ -30,7 +30,7 @@ if (typeof window !== 'undefined') {
30
30
  export const networks = {
31
31
  testnet: {
32
32
  networkPassphrase: "Test SDF Network ; September 2015",
33
- contractId: "CDYJAGTWL2RE3LAOH4B6UOA5TZWTMEFOG5M7FKJZTIIXGFBRJS53TI4C",
33
+ contractId: "CA3WONARSZHZQCCM5WF5HLD27MIP7RWCQJMID4TLZIWPHQYGJT2CIYWX",
34
34
  }
35
35
  } as const
36
36
 
@@ -4,7 +4,7 @@ import type { Option } from '@stellar/stellar-sdk/contract';
4
4
  export declare const networks: {
5
5
  readonly testnet: {
6
6
  readonly networkPassphrase: "Test SDF Network ; September 2015";
7
- readonly contractId: "CDYJAGTWL2RE3LAOH4B6UOA5TZWTMEFOG5M7FKJZTIIXGFBRJS53TI4C";
7
+ readonly contractId: "CA3WONARSZHZQCCM5WF5HLD27MIP7RWCQJMID4TLZIWPHQYGJT2CIYWX";
8
8
  };
9
9
  };
10
10
  export type SignerLimits = readonly [Map<string, Option<Array<SignerKey>>>];
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.3.0",
2
+ "version": "0.3.1",
3
3
  "name": "passkey-kit-sdk",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
@@ -30,20 +30,24 @@ if (typeof window !== 'undefined') {
30
30
  export const networks = {
31
31
  testnet: {
32
32
  networkPassphrase: "Test SDF Network ; September 2015",
33
- contractId: "CDYJAGTWL2RE3LAOH4B6UOA5TZWTMEFOG5M7FKJZTIIXGFBRJS53TI4C",
33
+ contractId: "CA3WONARSZHZQCCM5WF5HLD27MIP7RWCQJMID4TLZIWPHQYGJT2CIYWX",
34
34
  }
35
35
  } as const
36
36
 
37
37
  export const Errors = {
38
38
  1: { message: "NotFound" },
39
39
 
40
- 2: { message: "NotAuthorized" },
40
+ 2: { message: "MissingContext" },
41
41
 
42
- 3: { message: "ClientDataJsonChallengeIncorrect" },
42
+ 3: { message: "MissingSignerLimits" },
43
43
 
44
- 4: { message: "JsonParseError" },
44
+ 4: { message: "FailedPolicySignerLimits" },
45
45
 
46
- 5: { message: "SignatureKeyValueMismatch" }
46
+ 5: { message: "SignatureKeyValueMismatch" },
47
+
48
+ 6: { message: "ClientDataJsonChallengeIncorrect" },
49
+
50
+ 7: { message: "JsonParseError" }
47
51
  }
48
52
  export type SignerLimits = readonly [Map<string, Option<Array<SignerKey>>>];
49
53
  export type SignerKey = { tag: "Policy", values: readonly [string] } | { tag: "Ed25519", values: readonly [Buffer] } | { tag: "Secp256r1", values: readonly [Buffer] };
@@ -129,7 +133,7 @@ export interface Client {
129
133
  export class Client extends ContractClient {
130
134
  constructor(public readonly options: ContractClientOptions) {
131
135
  super(
132
- new ContractSpec(["AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAABQAAAAAAAAAITm90Rm91bmQAAAABAAAAAAAAAA1Ob3RBdXRob3JpemVkAAAAAAAAAgAAAAAAAAAgQ2xpZW50RGF0YUpzb25DaGFsbGVuZ2VJbmNvcnJlY3QAAAADAAAAAAAAAA5Kc29uUGFyc2VFcnJvcgAAAAAABAAAAAAAAAAZU2lnbmF0dXJlS2V5VmFsdWVNaXNtYXRjaAAAAAAAAAU=",
136
+ new ContractSpec(["AAAABAAAAAAAAAAAAAAABUVycm9yAAAAAAAABwAAAAAAAAAITm90Rm91bmQAAAABAAAAAAAAAA5NaXNzaW5nQ29udGV4dAAAAAAAAgAAAAAAAAATTWlzc2luZ1NpZ25lckxpbWl0cwAAAAADAAAAAAAAABhGYWlsZWRQb2xpY3lTaWduZXJMaW1pdHMAAAAEAAAAAAAAABlTaWduYXR1cmVLZXlWYWx1ZU1pc21hdGNoAAAAAAAABQAAAAAAAAAgQ2xpZW50RGF0YUpzb25DaGFsbGVuZ2VJbmNvcnJlY3QAAAAGAAAAAAAAAA5Kc29uUGFyc2VFcnJvcgAAAAAABw==",
133
137
  "AAAAAQAAAAAAAAAAAAAADFNpZ25lckxpbWl0cwAAAAEAAAAAAAAAATAAAAAAAAPsAAAAEwAAA+gAAAPqAAAH0AAAAAlTaWduZXJLZXkAAAA=",
134
138
  "AAAAAgAAAAAAAAAAAAAACVNpZ25lcktleQAAAAAAAAMAAAABAAAAAAAAAAZQb2xpY3kAAAAAAAEAAAATAAAAAQAAAAAAAAAHRWQyNTUxOQAAAAABAAAD7gAAACAAAAABAAAAAAAAAAlTZWNwMjU2cjEAAAAAAAABAAAADg==",
135
139
  "AAAAAgAAAAAAAAAAAAAACVNpZ25lclZhbAAAAAAAAAMAAAABAAAAAAAAAAZQb2xpY3kAAAAAAAEAAAfQAAAADFNpZ25lckxpbWl0cwAAAAEAAAAAAAAAB0VkMjU1MTkAAAAAAQAAB9AAAAAMU2lnbmVyTGltaXRzAAAAAQAAAAAAAAAJU2VjcDI1NnIxAAAAAAAAAgAAA+4AAABBAAAH0AAAAAxTaWduZXJMaW1pdHM=",
@@ -4,7 +4,7 @@ import type { Option } from '@stellar/stellar-sdk/contract';
4
4
  export declare const networks: {
5
5
  readonly testnet: {
6
6
  readonly networkPassphrase: "Test SDF Network ; September 2015";
7
- readonly contractId: "CDYJAGTWL2RE3LAOH4B6UOA5TZWTMEFOG5M7FKJZTIIXGFBRJS53TI4C";
7
+ readonly contractId: "CA3WONARSZHZQCCM5WF5HLD27MIP7RWCQJMID4TLZIWPHQYGJT2CIYWX";
8
8
  };
9
9
  };
10
10
  export declare const Errors: {
@@ -23,6 +23,12 @@ export declare const Errors: {
23
23
  5: {
24
24
  message: string;
25
25
  };
26
+ 6: {
27
+ message: string;
28
+ };
29
+ 7: {
30
+ message: string;
31
+ };
26
32
  };
27
33
  export type SignerLimits = readonly [Map<string, Option<Array<SignerKey>>>];
28
34
  export type SignerKey = {
package/src/kit.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { Client as PasskeyClient, type Secp256r1Signature, type Signature } from 'passkey-kit-sdk'
1
+ import { Client as PasskeyClient, type Signature, type SignerKey } from 'passkey-kit-sdk'
2
2
  import { Client as FactoryClient } from 'passkey-factory-sdk'
3
- import { Address, StrKey, hash, xdr, Transaction, SorobanRpc, Operation, TransactionBuilder } from '@stellar/stellar-sdk'
3
+ import { Address, StrKey, hash, xdr, Transaction, SorobanRpc, Operation, TransactionBuilder, Keypair } from '@stellar/stellar-sdk'
4
4
  import base64url from 'base64url'
5
5
  import { startRegistration, startAuthentication } from "@simplewebauthn/browser"
6
6
  import type { AuthenticatorAttestationResponseJSON, AuthenticatorSelectionCriteria } from "@simplewebauthn/types"
7
7
  import { Buffer } from 'buffer'
8
8
  import { PasskeyBase } from './base'
9
+ import { DEFAULT_TIMEOUT } from '@stellar/stellar-sdk/contract'
9
10
 
10
11
  export const DEFAULT_LTL = 12
11
12
 
@@ -51,17 +52,17 @@ export class PasskeyKit extends PasskeyBase {
51
52
  signer: {
52
53
  tag: 'Secp256r1',
53
54
  values: [
54
- keyId,
55
- publicKey,
55
+ keyId,
56
+ publicKey,
56
57
  [new Map()],
57
- {tag: 'Persistent', values: undefined},
58
+ { tag: 'Persistent', values: undefined },
58
59
  ]
59
60
  },
60
61
  })
61
62
 
62
63
  if (result.isErr())
63
64
  throw new Error(result.unwrapErr().message)
64
-
65
+
65
66
  if (!built)
66
67
  throw new Error('Failed to create wallet')
67
68
 
@@ -99,11 +100,6 @@ export class PasskeyKit extends PasskeyBase {
99
100
  displayName
100
101
  },
101
102
  authenticatorSelection,
102
- // authenticatorSelection: {
103
- // requireResidentKey: false,
104
- // residentKey: "preferred",
105
- // userVerification: "discouraged",
106
- // },
107
103
  pubKeyCredParams: [{ alg: -7, type: "public-key" }],
108
104
  // attestation: "none",
109
105
  // timeout: 120_000,
@@ -188,98 +184,124 @@ export class PasskeyKit extends PasskeyBase {
188
184
  public async signAuthEntry(
189
185
  entry: xdr.SorobanAuthorizationEntry,
190
186
  options?: {
191
- keyId?: 'any' | string | Uint8Array
192
187
  rpId?: string,
193
- ledgersToLive?: number
188
+ keyId?: 'any' | string | Uint8Array
189
+ keypair?: Keypair,
190
+ validUntilLedgerSeq?: number
194
191
  }
195
192
  ) {
196
- let { keyId, rpId, ledgersToLive = DEFAULT_LTL } = options || {}
193
+ let { rpId, keyId, keypair, validUntilLedgerSeq } = options || {}
194
+
195
+ if (keyId && keypair)
196
+ throw new Error('Provide either `options.keyId` or `options.keypair` but not both')
197
+
198
+ if (!validUntilLedgerSeq) {
199
+ const lastLedger = await this.rpc.getLatestLedger().then(({ sequence }) => sequence)
200
+ validUntilLedgerSeq = lastLedger + DEFAULT_TIMEOUT / 5;
201
+ }
197
202
 
198
- const lastLedger = await this.rpc.getLatestLedger().then(({ sequence }) => sequence)
199
203
  const credentials = entry.credentials().address();
200
204
  const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(
201
205
  new xdr.HashIdPreimageSorobanAuthorization({
202
206
  networkId: hash(Buffer.from(this.networkPassphrase)),
203
207
  nonce: credentials.nonce(),
204
- // TODO maybe if folks set `ledgersToLive` that should be the TTL vs the extension from `lastLedger`. Will make it easier to coordinate multisig
205
- // Call it `validUntilLedgerSeq` like the JS SDK
206
- signatureExpirationLedger: lastLedger + ledgersToLive,
208
+ signatureExpirationLedger: validUntilLedgerSeq,
207
209
  invocation: entry.rootInvocation()
208
210
  })
209
211
  )
210
212
  const payload = hash(preimage.toXDR())
211
213
 
212
- const authenticationResponse = await this.WebAuthn.startAuthentication(
213
- keyId === 'any'
214
- || (!keyId && !this.keyId)
215
- ? {
216
- challenge: base64url(payload),
217
- rpId,
218
- // userVerification: "discouraged",
219
- // timeout: 120_000
220
- }
221
- : {
222
- challenge: base64url(payload),
223
- rpId,
224
- allowCredentials: [
225
- {
226
- id: keyId instanceof Uint8Array
227
- ? base64url(Buffer.from(keyId))
228
- : keyId || this.keyId!,
229
- type: "public-key",
230
- },
231
- ],
232
- // userVerification: "discouraged",
233
- // timeout: 120_000
234
- }
235
- );
214
+ let key: SignerKey
215
+ let val: Signature
216
+
217
+ // Sign with the keypair as an ed25519 signer
218
+ if (keypair) {
219
+ const signature = keypair.sign(payload);
220
+
221
+ key = {
222
+ tag: "Ed25519",
223
+ values: [keypair.rawPublicKey()]
224
+ }
225
+ val = {
226
+ tag: "Ed25519",
227
+ values: [signature],
228
+ }
229
+ }
230
+
231
+ // Default, use passkey
232
+ else {
233
+ const authenticationResponse = await this.WebAuthn.startAuthentication(
234
+ keyId === 'any'
235
+ || (!keyId && !this.keyId)
236
+ ? {
237
+ challenge: base64url(payload),
238
+ rpId,
239
+ // userVerification: "discouraged",
240
+ // timeout: 120_000
241
+ }
242
+ : {
243
+ challenge: base64url(payload),
244
+ rpId,
245
+ allowCredentials: [
246
+ {
247
+ id: keyId instanceof Uint8Array
248
+ ? base64url(Buffer.from(keyId))
249
+ : keyId || this.keyId!,
250
+ type: "public-key",
251
+ },
252
+ ],
253
+ // userVerification: "discouraged",
254
+ // timeout: 120_000
255
+ }
256
+ );
257
+
258
+ key = {
259
+ tag: "Secp256r1",
260
+ values: [base64url.toBuffer(authenticationResponse.id)]
261
+ }
262
+ val = {
263
+ tag: "Secp256r1",
264
+ values: [
265
+ {
266
+ authenticator_data: base64url.toBuffer(
267
+ authenticationResponse.response.authenticatorData,
268
+ ),
269
+ client_data_json: base64url.toBuffer(
270
+ authenticationResponse.response.clientDataJSON,
271
+ ),
272
+ signature: this.compactSignature(
273
+ base64url.toBuffer(authenticationResponse.response.signature)
274
+ ),
275
+ },
276
+ ],
277
+ }
278
+ }
236
279
 
237
- const signature = this.compactSignature(
238
- base64url.toBuffer(authenticationResponse.response.signature)
280
+ const scKeyType = xdr.ScSpecTypeDef.scSpecTypeUdt(
281
+ new xdr.ScSpecTypeUdt({ name: "SignerKey" }),
282
+ );
283
+ const scValType = xdr.ScSpecTypeDef.scSpecTypeUdt(
284
+ new xdr.ScSpecTypeUdt({ name: "Signature" }),
239
285
  );
286
+ const scVal = this.wallet!.spec.nativeToScVal(val, scValType);
287
+ const scKey = this.wallet!.spec.nativeToScVal(key, scKeyType);
288
+ const scEntry = new xdr.ScMapEntry({
289
+ key: scKey,
290
+ val: scVal,
291
+ })
240
292
 
241
- // TODO No idea how to make this work
242
- // https://discord.com/channels/@me/1025113063583666246/1281789018979438672
243
- // const t: Signature = {
244
- // tag: 'Secp256r1',
245
- // values: [{
246
- // authenticator_data: base64url.toBuffer(authenticationResponse.response.authenticatorData),
247
- // client_data_json: base64url.toBuffer(authenticationResponse.response.clientDataJSON),
248
- // id: [base64url.toBuffer(authenticationResponse.id)],
249
- // signature
250
- // }]
251
- // }
252
-
253
- // const test = this.wallet!.spec.nativeToScVal(t, )
254
-
255
- const sig = xdr.ScVal.scvMap([
256
- new xdr.ScMapEntry({
257
- key: xdr.ScVal.scvVec([
258
- xdr.ScVal.scvSymbol('Secp256r1'),
259
- xdr.ScVal.scvBytes(base64url.toBuffer(authenticationResponse.id))
260
- ]),
261
- val: xdr.ScVal.scvVec([
262
- xdr.ScVal.scvSymbol('Secp256r1'),
263
- xdr.ScVal.scvMap([
264
- new xdr.ScMapEntry({
265
- key: xdr.ScVal.scvSymbol('authenticator_data'),
266
- val: xdr.ScVal.scvBytes(base64url.toBuffer(authenticationResponse.response.authenticatorData)),
267
- }),
268
- new xdr.ScMapEntry({
269
- key: xdr.ScVal.scvSymbol('client_data_json'),
270
- val: xdr.ScVal.scvBytes(base64url.toBuffer(authenticationResponse.response.clientDataJSON)),
271
- }),
272
- new xdr.ScMapEntry({
273
- key: xdr.ScVal.scvSymbol('signature'),
274
- val: xdr.ScVal.scvBytes(signature),
275
- }),
276
- ])
277
- ])
278
- })
279
- ])
293
+ switch (credentials.signature().switch().name) {
294
+ case 'scvVoid':
295
+ credentials.signature(xdr.ScVal.scvMap([scEntry]))
296
+ break;
297
+ case 'scvMap':
298
+ credentials.signature().map()?.push(scEntry)
299
+ break;
300
+ default:
301
+ throw new Error('Unsupported signature')
302
+ }
280
303
 
281
- credentials.signatureExpirationLedger(lastLedger + ledgersToLive)
282
- credentials.signature(sig)
304
+ credentials.signatureExpirationLedger(validUntilLedgerSeq)
283
305
 
284
306
  return entry
285
307
  }
@@ -287,8 +309,10 @@ export class PasskeyKit extends PasskeyBase {
287
309
  public async signAuthEntries(
288
310
  entries: xdr.SorobanAuthorizationEntry[],
289
311
  options?: {
312
+ rpId?: string,
290
313
  keyId?: 'any' | string | Uint8Array
291
- ledgersToLive?: number
314
+ keypair?: Keypair,
315
+ validUntilLedgerSeq?: number
292
316
  }
293
317
  ) {
294
318
  for (const auth of entries) {
@@ -308,15 +332,133 @@ export class PasskeyKit extends PasskeyBase {
308
332
  public async sign(
309
333
  txn: Transaction | string,
310
334
  options?: {
335
+ rpId?: string,
311
336
  keyId?: 'any' | string | Uint8Array
312
- ledgersToLive?: number
337
+ keypair?: Keypair,
338
+ validUntilLedgerSeq?: number
313
339
  }
314
340
  ) {
315
- /*
316
- - Hack to ensure we don't stack fees when simulating and assembling multiple times
317
- AssembleTransaction always adds the resource fee onto the transaction fee.
318
- This is bad in cases where you need to simulate multiple times
319
- */
341
+ txn = this.getTxn(txn)
342
+
343
+ // Only need to sign auth for `invokeHostFunction` operations
344
+ if (txn.operations[0].type === 'invokeHostFunction') {
345
+ const entries = txn.operations[0].auth
346
+
347
+ if (entries)
348
+ await this.signAuthEntries(entries, options)
349
+ }
350
+
351
+ return txn.toXDR()
352
+ }
353
+
354
+ public async attachPolicy(
355
+ txn: Transaction | string,
356
+ index: number,
357
+ policy: string
358
+ ) {
359
+ txn = this.getTxn(txn)
360
+
361
+ // Only need to sign auth for `invokeHostFunction` operations
362
+ if (txn.operations[0].type !== 'invokeHostFunction')
363
+ return txn.toXDR()
364
+
365
+ if (!this.wallet)
366
+ throw new Error('Wallet not connected')
367
+
368
+ let context_arg: xdr.ScVal
369
+
370
+ const auth = txn.operations[0].auth?.[index]
371
+ const context = auth?.rootInvocation().function()
372
+
373
+ if (!auth || !context)
374
+ throw new Error('No context found')
375
+
376
+ switch (context.switch().name) {
377
+ case 'sorobanAuthorizedFunctionTypeContractFn':
378
+ switch (context.contractFn().contractAddress().switch().name) {
379
+ case 'scAddressTypeContract':
380
+ context_arg = xdr.ScVal.scvVec([
381
+ xdr.ScVal.scvSymbol("Contract"),
382
+ xdr.ScVal.scvMap([
383
+ new xdr.ScMapEntry({
384
+ key: xdr.ScVal.scvSymbol("args"),
385
+ val: xdr.ScVal.scvVec(context.contractFn().args()),
386
+ }),
387
+ new xdr.ScMapEntry({
388
+ key: xdr.ScVal.scvSymbol("contract"),
389
+ val: Address.contract(context.contractFn().contractAddress().contractId()).toScVal(),
390
+ }),
391
+ new xdr.ScMapEntry({
392
+ key: xdr.ScVal.scvSymbol("fn_name"),
393
+ val: xdr.ScVal.scvSymbol(context.contractFn().functionName()),
394
+ }),
395
+ ]),
396
+ ])
397
+ break;
398
+ default:
399
+ throw new Error('Unsupported contractAddress')
400
+ }
401
+ break;
402
+ case 'sorobanAuthorizedFunctionTypeCreateContractHostFn':
403
+ switch (context.createContractHostFn().contractIdPreimage().switch().name) {
404
+ case 'contractIdPreimageFromAddress':
405
+ context_arg = xdr.ScVal.scvVec([
406
+ xdr.ScVal.scvSymbol("CreateContractHostFn"),
407
+ xdr.ScVal.scvMap([
408
+ new xdr.ScMapEntry({
409
+ key: xdr.ScVal.scvSymbol("executable"),
410
+ val: xdr.ScVal.scvVec([
411
+ xdr.ScVal.scvSymbol("Wasm"),
412
+ xdr.ScVal.scvBytes(context.createContractHostFn().executable().wasmHash())
413
+ ]),
414
+ }),
415
+ new xdr.ScMapEntry({
416
+ key: xdr.ScVal.scvSymbol("salt"),
417
+ val: xdr.ScVal.scvBytes(context.createContractHostFn().contractIdPreimage().fromAddress().salt()),
418
+ }),
419
+ ]),
420
+ ])
421
+ break;
422
+ default:
423
+ throw new Error('Unsupported contractIdPreimage')
424
+ }
425
+ break;
426
+ default:
427
+ throw new Error('Unsupported context')
428
+ }
429
+
430
+ const __check_auth_args = new xdr.InvokeContractArgs({
431
+ contractAddress: Address.fromString(this.wallet.options.contractId).toScAddress(),
432
+ functionName: "__check_auth",
433
+ args: [context_arg],
434
+ });
435
+
436
+ const __check_auth_invocation = new xdr.SorobanAuthorizedInvocation({
437
+ function:
438
+ xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn(
439
+ __check_auth_args,
440
+ ),
441
+ subInvocations: [],
442
+ });
443
+
444
+ const __check_auth = new xdr.SorobanAuthorizationEntry({
445
+ credentials: xdr.SorobanCredentials.sorobanCredentialsAddress(
446
+ new xdr.SorobanAddressCredentials({
447
+ address: Address.fromString(policy).toScAddress(),
448
+ nonce: auth.credentials().address().nonce(),
449
+ signatureExpirationLedger: auth.credentials().address().signatureExpirationLedger(),
450
+ signature: xdr.ScVal.scvVec([]),
451
+ }),
452
+ ),
453
+ rootInvocation: __check_auth_invocation,
454
+ });
455
+
456
+ txn.operations[0].auth?.push(__check_auth)
457
+
458
+ return txn.toXDR()
459
+ }
460
+
461
+ private getTxn(txn: Transaction | string): Transaction {
320
462
  txn = TransactionBuilder.cloneFrom(new Transaction(
321
463
  typeof txn === 'string'
322
464
  ? txn
@@ -335,28 +477,12 @@ export class PasskeyKit extends PasskeyBase {
335
477
  ) throw new Error('Must include only one operation of type `invokeHostFunction` or `extendFootprintTtl` or `restoreFootprint`')
336
478
  }
337
479
 
338
- // Only need to sign auth for `invokeHostFunction` operations
339
- if (txn.operations[0].type === 'invokeHostFunction') {
340
- const entries = (txn.operations[0] as Operation.InvokeHostFunction).auth
341
-
342
- if (entries)
343
- await this.signAuthEntries(entries, options)
344
- }
345
-
346
- const sim = await this.rpc.simulateTransaction(txn)
347
-
348
- if (
349
- SorobanRpc.Api.isSimulationError(sim)
350
- || SorobanRpc.Api.isSimulationRestore(sim) // TODO handle state archival
351
- ) throw sim
352
-
353
- return SorobanRpc.assembleTransaction(txn, sim).build().toXDR()
480
+ return txn
354
481
  }
355
482
 
356
- /* TODO
483
+ /* LATER
357
484
  - Add a getKeyInfo action to get info about a specific passkey
358
485
  Specifically looking for name, type, etc. data so a user could grok what signer mapped to what passkey
359
- @Later
360
486
  */
361
487
 
362
488
  private async getPublicKey(response: AuthenticatorAttestationResponseJSON) {
@@ -399,10 +525,10 @@ export class PasskeyKit extends PasskeyBase {
399
525
  ])
400
526
  }
401
527
 
402
- /* TODO
528
+ /* TODO
403
529
  - We're doing some pretty "smart" public key decoding stuff so we should verify the signature against this final public key before assuming it's safe to use and save on-chain
404
530
  Hmm...Given that `startRegistration` doesn't produce a signature, verifying we've got the correct public key isn't really possible
405
- @Later
531
+ - This probably needs to be an onchain check, even if just a simulation, just to ensure everything looks good before we get too far adding value etc.
406
532
  */
407
533
 
408
534
  return publicKey
package/src/server.ts CHANGED
@@ -119,20 +119,20 @@ export class PasskeyServer extends PasskeyBase {
119
119
  return res || undefined as string | undefined
120
120
  }
121
121
 
122
- /* TODO
122
+ /* LATER
123
123
  - Add a method for getting a paginated or filtered list of all a wallet's events
124
- @Later
125
124
  */
126
125
 
127
- // TODO maybe fee should default to something more dynamic since we have endpoints for getting fee information now
128
- public async send(xdr: string, fee: number = 10_000) {
126
+ public async send(xdr: string, fee?: number) {
129
127
  if (!this.launchtubeUrl || !this.launchtubeJwt)
130
128
  throw new Error('Launchtube service not configured')
131
129
 
132
130
  const data = new FormData();
133
131
 
134
132
  data.set('xdr', xdr);
135
- data.set('fee', fee.toString());
133
+
134
+ if (fee)
135
+ data.set('fee', fee.toString());
136
136
 
137
137
  return fetch(this.launchtubeUrl, {
138
138
  method: 'POST',
package/types/kit.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Client as PasskeyClient } from 'passkey-kit-sdk';
2
2
  import { Client as FactoryClient } from 'passkey-factory-sdk';
3
- import { xdr, Transaction, SorobanRpc } from '@stellar/stellar-sdk';
3
+ import { xdr, Transaction, SorobanRpc, Keypair } from '@stellar/stellar-sdk';
4
4
  import { startRegistration, startAuthentication } from "@simplewebauthn/browser";
5
5
  import type { AuthenticatorSelectionCriteria } from "@simplewebauthn/types";
6
6
  import { Buffer } from 'buffer';
@@ -47,18 +47,25 @@ export declare class PasskeyKit extends PasskeyBase {
47
47
  contractId: string;
48
48
  }>;
49
49
  signAuthEntry(entry: xdr.SorobanAuthorizationEntry, options?: {
50
- keyId?: 'any' | string | Uint8Array;
51
50
  rpId?: string;
52
- ledgersToLive?: number;
51
+ keyId?: 'any' | string | Uint8Array;
52
+ keypair?: Keypair;
53
+ validUntilLedgerSeq?: number;
53
54
  }): Promise<xdr.SorobanAuthorizationEntry>;
54
55
  signAuthEntries(entries: xdr.SorobanAuthorizationEntry[], options?: {
56
+ rpId?: string;
55
57
  keyId?: 'any' | string | Uint8Array;
56
- ledgersToLive?: number;
58
+ keypair?: Keypair;
59
+ validUntilLedgerSeq?: number;
57
60
  }): Promise<xdr.SorobanAuthorizationEntry[]>;
58
61
  sign(txn: Transaction | string, options?: {
62
+ rpId?: string;
59
63
  keyId?: 'any' | string | Uint8Array;
60
- ledgersToLive?: number;
64
+ keypair?: Keypair;
65
+ validUntilLedgerSeq?: number;
61
66
  }): Promise<string>;
67
+ attachPolicy(txn: Transaction | string, index: number, policy: string): Promise<string>;
68
+ private getTxn;
62
69
  private getPublicKey;
63
70
  private compactSignature;
64
71
  }