passkey-kit 0.7.4 → 0.7.5
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/cheatsheet +4 -2
- package/package.json +8 -5
- package/packages/passkey-factory-sdk/package.json +1 -1
- package/packages/passkey-factory-sdk/src/index.ts +1 -1
- package/packages/passkey-factory-sdk/types/index.d.ts +1 -1
- package/packages/passkey-kit-sdk/package.json +1 -1
- package/packages/passkey-kit-sdk/src/index.ts +1 -1
- package/packages/passkey-kit-sdk/types/index.d.ts +1 -1
- package/packages/sac-sdk/package.json +1 -1
- package/pnpm-workspace.yaml +1 -0
- package/src/kit.ts +91 -171
- package/src/server.ts +3 -2
- package/types/kit.d.ts +8 -15
- package/types/server.d.ts +2 -2
package/cheatsheet
CHANGED
|
@@ -13,8 +13,10 @@ stellar contract deploy --wasm target/wasm32-unknown-unknown/release/sample_poli
|
|
|
13
13
|
|
|
14
14
|
export JWT=???
|
|
15
15
|
mercury-cli --jwt $JWT --local false --mainnet false deploy
|
|
16
|
-
mercury-cli --jwt $JWT --local false --mainnet false catchup --project-name "smart-wallets-data-multi-signer-multi-sig" --contracts "
|
|
16
|
+
mercury-cli --jwt $JWT --local false --mainnet false catchup --project-name "smart-wallets-data-multi-signer-multi-sig" --contracts "CAGXSSDBSFBI5633C4O4KF53XPU64BMX36JMJTJNITOAWGP442XHZSHM"
|
|
17
17
|
curl -X GET https://api.mercurydata.app/catchups/4
|
|
18
18
|
curl -X POST https://api.mercurydata.app/zephyr/execute -H "Authorization: Bearer $MERCURY_JWT" -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "get_signers_by_address", "arguments": "{\"address\": \"CA4G3X75IGGNXNLXFIVFNYIGC6YAVLA7KSIFFDBSR7RQ7KEZMZWLXQBH\"}"}}}'
|
|
19
19
|
curl -X POST https://api.mercurydata.app/zephyr/execute -H "Authorization: Bearer $MERCURY_JWT" -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "get_address_by_signer", "arguments": "{\"id\": [78,127,30,69,248,174,95,168,47,59,161,168,51,120,117,135,112,133,232,92]}"}}}'
|
|
20
|
-
curl -X POST https://api.mercurydata.app/zephyr/execute -H "Authorization: Bearer $MERCURY_JWT" -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "get_events_by_address", "arguments": "{\"address\": \"CA4G3X75IGGNXNLXFIVFNYIGC6YAVLA7KSIFFDBSR7RQ7KEZMZWLXQBH\"}"}}}'
|
|
20
|
+
curl -X POST https://api.mercurydata.app/zephyr/execute -H "Authorization: Bearer $MERCURY_JWT" -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "get_events_by_address", "arguments": "{\"address\": \"CA4G3X75IGGNXNLXFIVFNYIGC6YAVLA7KSIFFDBSR7RQ7KEZMZWLXQBH\"}"}}}'
|
|
21
|
+
|
|
22
|
+
cp -R ext/js-stellar-sdk/lib/. ext/@stellar/stellar-sdk/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "passkey-kit",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
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",
|
|
@@ -10,19 +10,22 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@darkedges/capacitor-native-webauthn": "^0.0.4",
|
|
12
12
|
"@simplewebauthn/browser": "^10.0.0",
|
|
13
|
-
"@stellar/stellar-sdk": "
|
|
13
|
+
"@stellar/stellar-sdk": "file:./ext/js-stellar-sdk",
|
|
14
14
|
"base64url": "^3.0.1",
|
|
15
15
|
"buffer": "^6.0.3",
|
|
16
16
|
"passkey-factory-sdk": "0.3.1",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
17
|
+
"sac-sdk": "0.1.0",
|
|
18
|
+
"passkey-kit-sdk": "0.3.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@simplewebauthn/types": "^10.0.0",
|
|
22
|
+
"@types/node": "^22.7.3",
|
|
22
23
|
"typescript": "^5.6.2"
|
|
23
24
|
},
|
|
24
25
|
"workspaces": [
|
|
25
|
-
"packages
|
|
26
|
+
"packages/passkey-factory-sdk",
|
|
27
|
+
"packages/passkey-kit-sdk",
|
|
28
|
+
"packages/sac-sdk"
|
|
26
29
|
],
|
|
27
30
|
"engine": {
|
|
28
31
|
"node": ">=20"
|
|
@@ -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: "
|
|
33
|
+
contractId: "CBFNOEJVO4WVIHAYIBGES5AFTOWBBN274B3VD32QSD7AYJ6J4EH3K6HC",
|
|
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: "
|
|
7
|
+
readonly contractId: "CBFNOEJVO4WVIHAYIBGES5AFTOWBBN274B3VD32QSD7AYJ6J4EH3K6HC";
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
export type SignerLimits = readonly [Map<string, Option<Array<SignerKey>>>];
|
|
@@ -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: "
|
|
33
|
+
contractId: "CBFNOEJVO4WVIHAYIBGES5AFTOWBBN274B3VD32QSD7AYJ6J4EH3K6HC",
|
|
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: "
|
|
7
|
+
readonly contractId: "CBFNOEJVO4WVIHAYIBGES5AFTOWBBN274B3VD32QSD7AYJ6J4EH3K6HC";
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
export declare const Errors: {
|
package/pnpm-workspace.yaml
CHANGED
package/src/kit.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
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, SorobanRpc, Keypair, Transaction } from '@stellar/stellar-sdk'
|
|
3
|
+
import { Address, StrKey, hash, xdr, SorobanRpc, Keypair, Transaction, Operation } 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, type Tx } from '@stellar/stellar-sdk/contract'
|
|
9
|
+
import { AssembledTransaction, DEFAULT_TIMEOUT, type Tx } from '@stellar/stellar-sdk/contract'
|
|
10
10
|
|
|
11
11
|
export class PasskeyKit extends PasskeyBase {
|
|
12
12
|
declare public rpc: SorobanRpc.Server
|
|
@@ -185,27 +185,28 @@ export class PasskeyKit extends PasskeyBase {
|
|
|
185
185
|
rpId?: string,
|
|
186
186
|
keyId?: 'any' | string | Uint8Array
|
|
187
187
|
keypair?: Keypair,
|
|
188
|
-
|
|
188
|
+
policy?: string,
|
|
189
|
+
expiration?: number
|
|
189
190
|
}
|
|
190
191
|
) {
|
|
191
|
-
let { rpId, keyId, keypair,
|
|
192
|
+
let { rpId, keyId, keypair, policy, expiration } = options || {}
|
|
192
193
|
|
|
193
|
-
if (keyId
|
|
194
|
-
throw new Error('
|
|
194
|
+
if ([keyId, keypair, policy].filter((arg) => arg).length !== 1)
|
|
195
|
+
throw new Error('Exactly one of `options.keyId`, `options.keypair`, or `options.policy` must be provided.');
|
|
195
196
|
|
|
196
197
|
const credentials = entry.credentials().address();
|
|
197
198
|
|
|
198
|
-
if (!
|
|
199
|
-
|
|
199
|
+
if (!expiration) {
|
|
200
|
+
expiration = credentials.signatureExpirationLedger()
|
|
200
201
|
|
|
201
|
-
if (!
|
|
202
|
+
if (!expiration) {
|
|
202
203
|
const lastLedger = await this.rpc.getLatestLedger().then(({ sequence }) => sequence)
|
|
203
|
-
|
|
204
|
+
expiration = lastLedger + DEFAULT_TIMEOUT / 5;
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
|
|
207
|
-
credentials.signatureExpirationLedger(
|
|
208
|
-
|
|
208
|
+
credentials.signatureExpirationLedger(expiration)
|
|
209
|
+
|
|
209
210
|
const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(
|
|
210
211
|
new xdr.HashIdPreimageSorobanAuthorization({
|
|
211
212
|
networkId: hash(Buffer.from(this.networkPassphrase)),
|
|
@@ -214,14 +215,22 @@ export class PasskeyKit extends PasskeyBase {
|
|
|
214
215
|
invocation: entry.rootInvocation()
|
|
215
216
|
})
|
|
216
217
|
)
|
|
217
|
-
|
|
218
|
+
|
|
218
219
|
const payload = hash(preimage.toXDR())
|
|
219
220
|
|
|
220
221
|
let key: SignerKey
|
|
221
|
-
let val: Signature
|
|
222
|
+
let val: Signature | undefined
|
|
223
|
+
|
|
224
|
+
// Sign with a policy
|
|
225
|
+
if (policy) {
|
|
226
|
+
key = {
|
|
227
|
+
tag: "Policy",
|
|
228
|
+
values: [policy]
|
|
229
|
+
}
|
|
230
|
+
}
|
|
222
231
|
|
|
223
232
|
// Sign with the keypair as an ed25519 signer
|
|
224
|
-
if (keypair) {
|
|
233
|
+
else if (keypair) {
|
|
225
234
|
const signature = keypair.sign(payload);
|
|
226
235
|
|
|
227
236
|
key = {
|
|
@@ -289,8 +298,8 @@ export class PasskeyKit extends PasskeyBase {
|
|
|
289
298
|
const scValType = xdr.ScSpecTypeDef.scSpecTypeUdt(
|
|
290
299
|
new xdr.ScSpecTypeUdt({ name: "Signature" }),
|
|
291
300
|
);
|
|
292
|
-
const scVal = this.wallet!.spec.nativeToScVal(val, scValType);
|
|
293
301
|
const scKey = this.wallet!.spec.nativeToScVal(key, scKeyType);
|
|
302
|
+
const scVal = val ? this.wallet!.spec.nativeToScVal(val, scValType) : xdr.ScVal.scvVoid();
|
|
294
303
|
const scEntry = new xdr.ScMapEntry({
|
|
295
304
|
key: scKey,
|
|
296
305
|
val: scVal,
|
|
@@ -303,178 +312,89 @@ export class PasskeyKit extends PasskeyBase {
|
|
|
303
312
|
case 'scvMap':
|
|
304
313
|
// Add the new signature to the existing map
|
|
305
314
|
credentials.signature().map()?.push(scEntry)
|
|
315
|
+
|
|
306
316
|
// Order the map by key
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
317
|
+
// Not using Buffer.compare because Symbols are 9 bytes and unused bytes _append_ 0s vs prepending them, which is too bad
|
|
318
|
+
credentials.signature().map()?.sort((a, b) => {
|
|
319
|
+
return (
|
|
320
|
+
a.key().vec()![0].sym() +
|
|
321
|
+
a.key().vec()![1].toXDR().join('')
|
|
322
|
+
).localeCompare(
|
|
323
|
+
b.key().vec()![0].sym() +
|
|
324
|
+
b.key().vec()![1].toXDR().join('')
|
|
325
|
+
)
|
|
326
|
+
})
|
|
310
327
|
break;
|
|
311
328
|
default:
|
|
312
329
|
throw new Error('Unsupported signature')
|
|
313
330
|
}
|
|
314
|
-
}
|
|
315
331
|
|
|
316
|
-
|
|
317
|
-
entries: xdr.SorobanAuthorizationEntry[],
|
|
318
|
-
options?: {
|
|
319
|
-
rpId?: string,
|
|
320
|
-
keyId?: 'any' | string | Uint8Array
|
|
321
|
-
keypair?: Keypair,
|
|
322
|
-
validUntilLedgerSeq?: number
|
|
323
|
-
}
|
|
324
|
-
) {
|
|
325
|
-
// TODO should there be more control over which auth entries are signed? Especially given we support multiple signers now?
|
|
326
|
-
// As-is .sign() will always sign every smart wallet auth entry. This may be okay but likely we should have more control over which auth entry the signer is signing
|
|
327
|
-
for (const auth of entries) {
|
|
328
|
-
if (
|
|
329
|
-
auth.credentials().switch().name === 'sorobanCredentialsAddress'
|
|
330
|
-
&& auth.credentials().address().address().switch().name === 'scAddressTypeContract'
|
|
331
|
-
) {
|
|
332
|
-
// If auth entry matches our Smart Wallet move forward with the signature request
|
|
333
|
-
if (Address.contract(auth.credentials().address().address().contractId()).toString() === this.wallet?.options.contractId)
|
|
334
|
-
await this.signAuthEntry(auth, options)
|
|
335
|
-
}
|
|
336
|
-
}
|
|
332
|
+
return entry
|
|
337
333
|
}
|
|
338
334
|
|
|
335
|
+
// public async signAuthEntries(
|
|
336
|
+
// entries: xdr.SorobanAuthorizationEntry[],
|
|
337
|
+
// options?: {
|
|
338
|
+
// rpId?: string,
|
|
339
|
+
// keyId?: 'any' | string | Uint8Array
|
|
340
|
+
// keypair?: Keypair,
|
|
341
|
+
// policy?: string,
|
|
342
|
+
// expiration?: number
|
|
343
|
+
// }
|
|
344
|
+
// ) {
|
|
345
|
+
// // TODO should there be more control over which auth entries are signed? Especially given we support multiple signers now?
|
|
346
|
+
// // As-is .sign() will always sign every smart wallet auth entry. This may be okay but likely we should have more control over which auth entry the signer is signing
|
|
347
|
+
// for (const auth of entries) {
|
|
348
|
+
// if (
|
|
349
|
+
// auth.credentials().switch().name === 'sorobanCredentialsAddress'
|
|
350
|
+
// && auth.credentials().address().address().switch().name === 'scAddressTypeContract'
|
|
351
|
+
// ) {
|
|
352
|
+
// // If auth entry matches our Smart Wallet move forward with the signature request
|
|
353
|
+
// if (Address.contract(auth.credentials().address().address().contractId()).toString() === this.wallet?.options.contractId)
|
|
354
|
+
// await this.signAuthEntry(auth, options)
|
|
355
|
+
// }
|
|
356
|
+
// }
|
|
357
|
+
// }
|
|
358
|
+
|
|
339
359
|
public async sign(
|
|
340
|
-
txn:
|
|
360
|
+
txn: AssembledTransaction<unknown>,
|
|
341
361
|
options?: {
|
|
342
362
|
rpId?: string,
|
|
343
363
|
keyId?: 'any' | string | Uint8Array
|
|
344
364
|
keypair?: Keypair,
|
|
345
|
-
|
|
365
|
+
policy?: string,
|
|
366
|
+
expiration?: number
|
|
346
367
|
}
|
|
347
368
|
) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
txn: Transaction,
|
|
356
|
-
index: number,
|
|
357
|
-
policy: string
|
|
358
|
-
) {
|
|
359
|
-
if (!this.wallet)
|
|
360
|
-
throw new Error('Wallet not connected')
|
|
361
|
-
|
|
362
|
-
const entries = this.getAuthEntries(txn)
|
|
363
|
-
const auth = entries?.[index]
|
|
364
|
-
const context = auth?.rootInvocation().function()
|
|
365
|
-
|
|
366
|
-
if (!entries || !auth || !context)
|
|
367
|
-
throw new Error('No context found')
|
|
368
|
-
|
|
369
|
-
let context_arg: xdr.ScVal
|
|
370
|
-
|
|
371
|
-
switch (context.switch().name) {
|
|
372
|
-
case 'sorobanAuthorizedFunctionTypeContractFn':
|
|
373
|
-
switch (context.contractFn().contractAddress().switch().name) {
|
|
374
|
-
case 'scAddressTypeContract':
|
|
375
|
-
context_arg = xdr.ScVal.scvVec([
|
|
376
|
-
xdr.ScVal.scvSymbol("Contract"),
|
|
377
|
-
xdr.ScVal.scvMap([
|
|
378
|
-
new xdr.ScMapEntry({
|
|
379
|
-
key: xdr.ScVal.scvSymbol("args"),
|
|
380
|
-
val: xdr.ScVal.scvVec(context.contractFn().args()),
|
|
381
|
-
}),
|
|
382
|
-
new xdr.ScMapEntry({
|
|
383
|
-
key: xdr.ScVal.scvSymbol("contract"),
|
|
384
|
-
val: Address.contract(context.contractFn().contractAddress().contractId()).toScVal(),
|
|
385
|
-
}),
|
|
386
|
-
new xdr.ScMapEntry({
|
|
387
|
-
key: xdr.ScVal.scvSymbol("fn_name"),
|
|
388
|
-
val: xdr.ScVal.scvSymbol(context.contractFn().functionName()),
|
|
389
|
-
}),
|
|
390
|
-
]),
|
|
391
|
-
])
|
|
392
|
-
break;
|
|
393
|
-
default:
|
|
394
|
-
throw new Error('Unsupported contractAddress')
|
|
395
|
-
}
|
|
396
|
-
break;
|
|
397
|
-
case 'sorobanAuthorizedFunctionTypeCreateContractHostFn':
|
|
398
|
-
switch (context.createContractHostFn().contractIdPreimage().switch().name) {
|
|
399
|
-
case 'contractIdPreimageFromAddress':
|
|
400
|
-
context_arg = xdr.ScVal.scvVec([
|
|
401
|
-
xdr.ScVal.scvSymbol("CreateContractHostFn"),
|
|
402
|
-
xdr.ScVal.scvMap([
|
|
403
|
-
new xdr.ScMapEntry({
|
|
404
|
-
key: xdr.ScVal.scvSymbol("executable"),
|
|
405
|
-
val: xdr.ScVal.scvVec([
|
|
406
|
-
xdr.ScVal.scvSymbol("Wasm"),
|
|
407
|
-
xdr.ScVal.scvBytes(context.createContractHostFn().executable().wasmHash())
|
|
408
|
-
]),
|
|
409
|
-
}),
|
|
410
|
-
new xdr.ScMapEntry({
|
|
411
|
-
key: xdr.ScVal.scvSymbol("salt"),
|
|
412
|
-
val: xdr.ScVal.scvBytes(context.createContractHostFn().contractIdPreimage().fromAddress().salt()),
|
|
413
|
-
}),
|
|
414
|
-
]),
|
|
415
|
-
])
|
|
416
|
-
break;
|
|
417
|
-
default:
|
|
418
|
-
throw new Error('Unsupported contractIdPreimage')
|
|
419
|
-
}
|
|
420
|
-
break;
|
|
421
|
-
default:
|
|
422
|
-
throw new Error('Unsupported context')
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
const __check_auth_args = new xdr.InvokeContractArgs({
|
|
426
|
-
contractAddress: Address.fromString(this.wallet.options.contractId).toScAddress(),
|
|
427
|
-
functionName: "__check_auth",
|
|
428
|
-
args: [context_arg],
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
const __check_auth_invocation = new xdr.SorobanAuthorizedInvocation({
|
|
432
|
-
function:
|
|
433
|
-
xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn(
|
|
434
|
-
__check_auth_args,
|
|
435
|
-
),
|
|
436
|
-
subInvocations: [],
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
const __check_auth = new xdr.SorobanAuthorizationEntry({
|
|
440
|
-
credentials: xdr.SorobanCredentials.sorobanCredentialsAddress(
|
|
441
|
-
new xdr.SorobanAddressCredentials({
|
|
442
|
-
address: Address.fromString(policy).toScAddress(),
|
|
443
|
-
nonce: auth.credentials().address().nonce(),
|
|
444
|
-
signatureExpirationLedger: auth.credentials().address().signatureExpirationLedger(),
|
|
445
|
-
signature: xdr.ScVal.scvVec([]),
|
|
446
|
-
}),
|
|
447
|
-
),
|
|
448
|
-
rootInvocation: __check_auth_invocation,
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
entries.push(__check_auth)
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
public prepareTransaction(txn: Tx) {
|
|
455
|
-
return new Transaction(txn.toXDR(), this.networkPassphrase);
|
|
369
|
+
await txn.signAuthEntries({
|
|
370
|
+
address: this.wallet!.options.contractId,
|
|
371
|
+
authorizeEntry: (entry) => {
|
|
372
|
+
const clone = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR())
|
|
373
|
+
return this.signAuthEntry(clone, options)
|
|
374
|
+
},
|
|
375
|
+
})
|
|
456
376
|
}
|
|
457
377
|
|
|
458
|
-
private getAuthEntries(txn: Transaction) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
}
|
|
378
|
+
// private getAuthEntries(txn: Transaction) {
|
|
379
|
+
// if (txn.operations.length !== 1)
|
|
380
|
+
// throw new Error('Must include only one Soroban operation')
|
|
381
|
+
|
|
382
|
+
// for (const op of txn.operations) {
|
|
383
|
+
// if (
|
|
384
|
+
// op.type !== 'invokeHostFunction'
|
|
385
|
+
// && op.type !== 'extendFootprintTtl'
|
|
386
|
+
// && op.type !== 'restoreFootprint'
|
|
387
|
+
// ) throw new Error('Must include only one operation of type `invokeHostFunction` or `extendFootprintTtl` or `restoreFootprint`')
|
|
388
|
+
// }
|
|
389
|
+
|
|
390
|
+
// // Only need to sign auth for `invokeHostFunction` operations
|
|
391
|
+
// if (txn.operations[0].type === 'invokeHostFunction') {
|
|
392
|
+
// const entries = txn.operations[0].auth
|
|
393
|
+
|
|
394
|
+
// if (entries && entries.length)
|
|
395
|
+
// return entries
|
|
396
|
+
// }
|
|
397
|
+
// }
|
|
478
398
|
|
|
479
399
|
/* LATER
|
|
480
400
|
- Add a getKeyInfo action to get info about a specific passkey
|
package/src/server.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { SorobanRpc,
|
|
1
|
+
import { SorobanRpc, xdr } from "@stellar/stellar-sdk"
|
|
2
2
|
import { PasskeyBase } from "./base"
|
|
3
3
|
import base64url from "base64url"
|
|
4
|
+
import type { Tx } from "@stellar/stellar-sdk/contract"
|
|
4
5
|
|
|
5
6
|
export class PasskeyServer extends PasskeyBase {
|
|
6
7
|
public launchtubeUrl: string | undefined
|
|
@@ -123,7 +124,7 @@ export class PasskeyServer extends PasskeyBase {
|
|
|
123
124
|
- Add a method for getting a paginated or filtered list of all a wallet's events
|
|
124
125
|
*/
|
|
125
126
|
|
|
126
|
-
public async send(txn:
|
|
127
|
+
public async send(txn: Tx, fee?: number) {
|
|
127
128
|
if (!this.launchtubeUrl || !this.launchtubeJwt)
|
|
128
129
|
throw new Error('Launchtube service not configured')
|
|
129
130
|
|
package/types/kit.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Client as PasskeyClient } from 'passkey-kit-sdk';
|
|
2
2
|
import { Client as FactoryClient } from 'passkey-factory-sdk';
|
|
3
|
-
import { xdr, SorobanRpc, Keypair
|
|
3
|
+
import { xdr, 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';
|
|
7
7
|
import { PasskeyBase } from './base';
|
|
8
|
-
import { type Tx } from '@stellar/stellar-sdk/contract';
|
|
8
|
+
import { AssembledTransaction, type Tx } from '@stellar/stellar-sdk/contract';
|
|
9
9
|
export declare class PasskeyKit extends PasskeyBase {
|
|
10
10
|
rpc: SorobanRpc.Server;
|
|
11
11
|
rpcUrl: string;
|
|
@@ -50,23 +50,16 @@ export declare class PasskeyKit extends PasskeyBase {
|
|
|
50
50
|
rpId?: string;
|
|
51
51
|
keyId?: 'any' | string | Uint8Array;
|
|
52
52
|
keypair?: Keypair;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
keyId?: 'any' | string | Uint8Array;
|
|
58
|
-
keypair?: Keypair;
|
|
59
|
-
validUntilLedgerSeq?: number;
|
|
60
|
-
}): Promise<void>;
|
|
61
|
-
sign(txn: Transaction, options?: {
|
|
53
|
+
policy?: string;
|
|
54
|
+
expiration?: number;
|
|
55
|
+
}): Promise<xdr.SorobanAuthorizationEntry>;
|
|
56
|
+
sign(txn: AssembledTransaction<unknown>, options?: {
|
|
62
57
|
rpId?: string;
|
|
63
58
|
keyId?: 'any' | string | Uint8Array;
|
|
64
59
|
keypair?: Keypair;
|
|
65
|
-
|
|
60
|
+
policy?: string;
|
|
61
|
+
expiration?: number;
|
|
66
62
|
}): Promise<void>;
|
|
67
|
-
attachPolicy(txn: Transaction, index: number, policy: string): Promise<void>;
|
|
68
|
-
prepareTransaction(txn: Tx): Transaction<import("@stellar/stellar-sdk").Memo<import("@stellar/stellar-sdk").MemoType>, import("@stellar/stellar-sdk").Operation[]>;
|
|
69
|
-
private getAuthEntries;
|
|
70
63
|
private getPublicKey;
|
|
71
64
|
private compactSignature;
|
|
72
65
|
}
|
package/types/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Transaction } from "@stellar/stellar-sdk";
|
|
2
1
|
import { PasskeyBase } from "./base";
|
|
2
|
+
import type { Tx } from "@stellar/stellar-sdk/contract";
|
|
3
3
|
export declare class PasskeyServer extends PasskeyBase {
|
|
4
4
|
launchtubeUrl: string | undefined;
|
|
5
5
|
launchtubeJwt: string | undefined;
|
|
@@ -20,5 +20,5 @@ export declare class PasskeyServer extends PasskeyBase {
|
|
|
20
20
|
expired?: boolean;
|
|
21
21
|
}[]>;
|
|
22
22
|
getContractId(keyId: string): Promise<any>;
|
|
23
|
-
send(txn:
|
|
23
|
+
send(txn: Tx, fee?: number): Promise<any>;
|
|
24
24
|
}
|