@cavos/kit 0.0.4 → 0.0.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/dist/{Cavos-x9qFpOvJ.d.mts → Cavos-D20EtgOK.d.mts} +289 -188
- package/dist/{Cavos-x9qFpOvJ.d.ts → Cavos-D20EtgOK.d.ts} +289 -188
- package/dist/{chunk-F2J25XSL.mjs → chunk-M5BGBODC.mjs} +1517 -608
- package/dist/chunk-M5BGBODC.mjs.map +1 -0
- package/dist/index.d.mts +290 -92
- package/dist/index.d.ts +290 -92
- package/dist/index.js +1533 -610
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/react/index.d.mts +8 -3
- package/dist/react/index.d.ts +8 -3
- package/dist/react/index.js +1501 -603
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +32 -10
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-F2J25XSL.mjs.map +0 -1
|
@@ -184,11 +184,20 @@ declare class SolanaAdapter {
|
|
|
184
184
|
readonly chain: "solana";
|
|
185
185
|
readonly programId: PublicKey;
|
|
186
186
|
constructor(opts?: SolanaAdapterOptions);
|
|
187
|
-
/**
|
|
188
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Deterministic account address: PDA of [ACCOUNT_SEED, addressSeed] — the
|
|
189
|
+
* device pubkey is NOT part of the seeds, so the address is recomputable
|
|
190
|
+
* from (userId, appSalt) alone. Anti-squatting is the integrator's
|
|
191
|
+
* responsibility (keep `appSalt` secret; deploy on first login).
|
|
192
|
+
*/
|
|
193
|
+
computeAddress(addressSeed: Uint8Array): string;
|
|
189
194
|
private pda;
|
|
190
|
-
/**
|
|
191
|
-
|
|
195
|
+
/**
|
|
196
|
+
* `initialize` instruction: creates the account PDA and registers the first
|
|
197
|
+
* device signer. No attestation is required — anti-squatting is NOT enforced
|
|
198
|
+
* on-chain.
|
|
199
|
+
*/
|
|
200
|
+
buildInitialize(addressSeed: Uint8Array, payer: string, initialSigner: DevicePublicKey): TransactionInstruction[];
|
|
192
201
|
/** `[precompile, add_signer]` bundle, authorized by an existing device signer. */
|
|
193
202
|
buildAddSigner(account: string, newSigner: DevicePublicKey): Promise<TransactionInstruction[]>;
|
|
194
203
|
/** `[precompile, remove_signer]` bundle, authorized by an existing device signer. */
|
|
@@ -333,6 +342,67 @@ declare class PasskeySigner {
|
|
|
333
342
|
assert(challenge: Uint8Array): Promise<PasskeyAssertion>;
|
|
334
343
|
}
|
|
335
344
|
|
|
345
|
+
/** A chain-native contract call (Starknet `Call`-shaped; generic for portability). */
|
|
346
|
+
interface ChainCall {
|
|
347
|
+
contractAddress: string;
|
|
348
|
+
entrypoint: string;
|
|
349
|
+
calldata: string[];
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Options for state-changing wallet calls (`execute`, `addSigner`, etc.).
|
|
353
|
+
*
|
|
354
|
+
* await wallet.execute(calls, { sponsored: false }); // self-funded
|
|
355
|
+
*
|
|
356
|
+
* `sponsored` defaults to `true`: the Cavos relayer / paymaster pays gas (and, on
|
|
357
|
+
* Stellar, the reserve) so the user signs but never holds gas tokens. Pass
|
|
358
|
+
* `sponsored: false` to submit directly — the account pays its own fee / reserve
|
|
359
|
+
* from its own balance (ETH on Starknet, SOL on Solana, XLM on Stellar). Useful
|
|
360
|
+
* for testing the device signature, for fee transparency, or as a fallback when
|
|
361
|
+
* the relayer is unreachable. Self-funded mode requires the account to actually
|
|
362
|
+
* hold enough native balance for the fee (and Stellar reserve, if the call adds
|
|
363
|
+
* subentries).
|
|
364
|
+
*/
|
|
365
|
+
interface ExecuteOptions {
|
|
366
|
+
sponsored?: boolean;
|
|
367
|
+
}
|
|
368
|
+
interface ComputeAddressParams {
|
|
369
|
+
addressSeed: bigint;
|
|
370
|
+
/**
|
|
371
|
+
* First device signer. Required by chains whose address derivation still
|
|
372
|
+
* includes the device pubkey (Solana PDA seeds, Stellar factory salt). The
|
|
373
|
+
* Starknet adapter IGNORES this — its address is `f(addressSeed)` only.
|
|
374
|
+
*/
|
|
375
|
+
initialSigner?: DevicePublicKey;
|
|
376
|
+
/** Defaults to `addressSeed` when omitted. */
|
|
377
|
+
salt?: bigint;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Per-chain implementation surface. Phase 1 ships only Starknet, but the kit is
|
|
381
|
+
* designed so Stellar and Solana adapters drop in behind the same interface.
|
|
382
|
+
*/
|
|
383
|
+
interface ChainAdapter {
|
|
384
|
+
readonly chain: "starknet" | "stellar" | "solana";
|
|
385
|
+
/**
|
|
386
|
+
* Deterministic account address. Starknet: `f(addressSeed)` only (device
|
|
387
|
+
* pubkey not in the derivation — recovery is self-custodial). Solana: also
|
|
388
|
+
* `f(addressSeed)` (PDA seeds use only the seed). Stellar: classic `G…`
|
|
389
|
+
* multisig where the address is the source account.
|
|
390
|
+
*/
|
|
391
|
+
computeAddress(params: ComputeAddressParams): string;
|
|
392
|
+
/** Call(s) to deploy the account with its first device signer (UDC). */
|
|
393
|
+
buildDeploy(params: ComputeAddressParams): ChainCall[];
|
|
394
|
+
buildAddSigner(accountAddress: string, signer: DevicePublicKey): ChainCall;
|
|
395
|
+
buildRemoveSigner(accountAddress: string, signer: DevicePublicKey): ChainCall;
|
|
396
|
+
/** Read whether a pubkey is a currently-authorized signer of the account. */
|
|
397
|
+
isAuthorizedSigner(accountAddress: string, signer: DevicePublicKey): Promise<boolean>;
|
|
398
|
+
/**
|
|
399
|
+
* Compute the signature payload for an outgoing transaction: given the chain's
|
|
400
|
+
* tx hash, obtain a device assertion and serialize it to the chain's expected
|
|
401
|
+
* signature encoding.
|
|
402
|
+
*/
|
|
403
|
+
buildSignature(txHash: bigint): Promise<string[]>;
|
|
404
|
+
}
|
|
405
|
+
|
|
336
406
|
interface ConnectSolanaOptions {
|
|
337
407
|
network: SolanaNetwork;
|
|
338
408
|
/** Authenticated user (pass `identity` directly, or an `auth` provider). */
|
|
@@ -362,7 +432,7 @@ interface ConnectSolanaOptions {
|
|
|
362
432
|
*/
|
|
363
433
|
feePayer?: Keypair;
|
|
364
434
|
}
|
|
365
|
-
type ConnectStatus$
|
|
435
|
+
type ConnectStatus$1 = "ready" | "needs-device-approval";
|
|
366
436
|
/**
|
|
367
437
|
* Options for recovering a Solana account after losing every device signer.
|
|
368
438
|
* Mirrors `RecoveryOptions` (Starknet), adapted to the Solana path: the backup
|
|
@@ -407,7 +477,7 @@ interface RecoverSolanaOptions {
|
|
|
407
477
|
declare class CavosSolana {
|
|
408
478
|
readonly identity: Identity;
|
|
409
479
|
readonly address: string;
|
|
410
|
-
readonly status: ConnectStatus$
|
|
480
|
+
readonly status: ConnectStatus$1;
|
|
411
481
|
readonly connection: Connection;
|
|
412
482
|
private readonly adapter;
|
|
413
483
|
private readonly devicePubkey;
|
|
@@ -458,7 +528,7 @@ declare class CavosSolana {
|
|
|
458
528
|
transactionHash: string;
|
|
459
529
|
}>;
|
|
460
530
|
/** Move `amount` lamports out of the account to `destination` (device-signed). */
|
|
461
|
-
execute(amount: bigint, destination: string): Promise<string>;
|
|
531
|
+
execute(amount: bigint, destination: string, opts?: ExecuteOptions): Promise<string>;
|
|
462
532
|
/**
|
|
463
533
|
* Run arbitrary CPI `instructions` with the account PDA as signer (device-
|
|
464
534
|
* signed). The signature commits to sha256 of the canonical Borsh
|
|
@@ -467,9 +537,11 @@ declare class CavosSolana {
|
|
|
467
537
|
*
|
|
468
538
|
* What the relayer will sponsor is constrained by the app's Solana program
|
|
469
539
|
* allowlist (configured in the dashboard) — programs outside the allowlist are
|
|
470
|
-
* rejected before co-signing.
|
|
540
|
+
* rejected before co-signing. Pass `{ sponsored: false }` to bypass the relayer
|
|
541
|
+
* and pay the fee from a configured `feePayer` (e.g. for allowlisted programs
|
|
542
|
+
* the relayer rejects, or to test the device signature end-to-end).
|
|
471
543
|
*/
|
|
472
|
-
executeInstructions(instructions: InstructionData[]): Promise<string>;
|
|
544
|
+
executeInstructions(instructions: InstructionData[], opts?: ExecuteOptions): Promise<string>;
|
|
473
545
|
/**
|
|
474
546
|
* Register the backup signer derived from `code` as an authorized signer of this
|
|
475
547
|
* account (device-signed via precompile). Idempotent: returns without a tx if
|
|
@@ -495,41 +567,79 @@ declare class CavosSolana {
|
|
|
495
567
|
* the backup key. The on-chain program needs no recovery-specific entrypoint.
|
|
496
568
|
*/
|
|
497
569
|
static recover(opts: RecoverSolanaOptions): Promise<CavosSolana>;
|
|
570
|
+
/**
|
|
571
|
+
* Submit a built instruction bundle. Sponsored by default (relayer pays the
|
|
572
|
+
* fee); pass `{ sponsored: false }` to self-fund via the configured `feePayer`.
|
|
573
|
+
* The device signature is embedded inside the secp256r1 precompile instruction,
|
|
574
|
+
* NOT applied as a Solana tx signature — so switching only changes who pays,
|
|
575
|
+
* never the signing identity.
|
|
576
|
+
*/
|
|
498
577
|
private send;
|
|
499
578
|
}
|
|
500
579
|
|
|
501
|
-
/** Cavos device-account primitives on Stellar / Soroban. */
|
|
502
580
|
/**
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
581
|
+
* The device's P-256 **ECDH** key used only to unwrap the account DEK.
|
|
582
|
+
*
|
|
583
|
+
* Note this is a SEPARATE key from the `DeviceSigner` (which is an ECDSA signing
|
|
584
|
+
* key, non-extractable, and therefore cannot do ECDH). This key is per-device
|
|
585
|
+
* and non-syncable — losing the device loses only this convenience factor, not
|
|
586
|
+
* the account (the passkey / recovery factors survive). Its public key goes into
|
|
587
|
+
* the account's `cv:wd:<id>` on-chain envelope slot; the DEK is ECIES-wrapped to
|
|
588
|
+
* it so daily unlock is silent.
|
|
589
|
+
*
|
|
590
|
+
* `LocalDeviceUnwrapKey` holds a raw scalar (Node / tests / React Native secure
|
|
591
|
+
* storage). The browser implementation wraps a non-extractable WebCrypto ECDH
|
|
592
|
+
* key and overrides `unwrap` with `deriveBits`; it never exposes the scalar.
|
|
506
593
|
*/
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
594
|
+
interface DeviceUnwrapKey {
|
|
595
|
+
/** SEC1 *uncompressed* (65-byte) public key — the ECIES recipient key that is
|
|
596
|
+
* published on-chain in the device's envelope slot. */
|
|
597
|
+
publicKeySec1(): Uint8Array;
|
|
598
|
+
/** A short, stable id for this device's envelope slot (`cv:wd:<id>`). */
|
|
599
|
+
slotId(): string;
|
|
600
|
+
/** Unwrap the account DEK from this device's ECIES blob. */
|
|
601
|
+
unwrap(blob: Uint8Array): Promise<Uint8Array>;
|
|
602
|
+
}
|
|
603
|
+
/** Raw-scalar device unwrap key (Node / React Native). */
|
|
604
|
+
declare class LocalDeviceUnwrapKey implements DeviceUnwrapKey {
|
|
605
|
+
private readonly scalar;
|
|
606
|
+
private constructor();
|
|
607
|
+
/** Generate a fresh device unwrap key. */
|
|
608
|
+
static generate(): LocalDeviceUnwrapKey;
|
|
609
|
+
/** Rebuild from a persisted 32-byte scalar. */
|
|
610
|
+
static fromScalar(scalar: Uint8Array): LocalDeviceUnwrapKey;
|
|
611
|
+
/** The raw scalar, for the caller to persist in secure storage. */
|
|
612
|
+
export(): Uint8Array;
|
|
613
|
+
publicKeySec1(): Uint8Array;
|
|
614
|
+
slotId(): string;
|
|
615
|
+
unwrap(blob: Uint8Array): Promise<Uint8Array>;
|
|
616
|
+
}
|
|
617
|
+
/** Stable short slot id for a device's envelope entry: first 8 hex of
|
|
618
|
+
* `sha256(pubkey)`. Deterministic from the public key, so it's the same on
|
|
619
|
+
* every read and can't collide in practice for a handful of devices. */
|
|
620
|
+
declare function deviceSlotId(publicKeySec1: Uint8Array): string;
|
|
621
|
+
|
|
622
|
+
/** Classic-Stellar (`G…`) network configuration.
|
|
623
|
+
*
|
|
624
|
+
* This is now THE Stellar implementation in the kit (the Soroban `C…`
|
|
625
|
+
* device-account path was removed — `G…` classic multisig is the default). Classic
|
|
626
|
+
* Stellar uses Horizon (not the Soroban RPC) to load account state and submit
|
|
627
|
+
* transactions. */
|
|
516
628
|
declare const STELLAR_NETWORKS: {
|
|
517
629
|
readonly "stellar-testnet": {
|
|
518
|
-
readonly rpcUrl: "https://soroban-testnet.stellar.org";
|
|
519
630
|
readonly passphrase: "Test SDF Network ; September 2015";
|
|
520
631
|
};
|
|
521
632
|
readonly "stellar-mainnet": {
|
|
522
|
-
readonly rpcUrl: "https://soroban-rpc.mainnet.stellar.gateway.fm";
|
|
523
633
|
readonly passphrase: "Public Global Stellar Network ; September 2015";
|
|
524
634
|
};
|
|
525
635
|
};
|
|
526
636
|
type StellarNetwork = keyof typeof STELLAR_NETWORKS;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
readonly "stellar-testnet": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC";
|
|
531
|
-
readonly "stellar-mainnet": "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA";
|
|
637
|
+
declare const HORIZON_URL: {
|
|
638
|
+
readonly "stellar-testnet": "https://horizon-testnet.stellar.org";
|
|
639
|
+
readonly "stellar-mainnet": "https://horizon.stellar.org";
|
|
532
640
|
};
|
|
641
|
+
/** Native XLM has 7 decimals (stroops). */
|
|
642
|
+
declare const XLM_DECIMALS = 7;
|
|
533
643
|
|
|
534
644
|
interface StellarRelayerOptions {
|
|
535
645
|
/** Base URL of the Cavos backend exposing /api/stellar/relay. */
|
|
@@ -538,30 +648,33 @@ interface StellarRelayerOptions {
|
|
|
538
648
|
appId: string;
|
|
539
649
|
network: StellarNetwork;
|
|
540
650
|
}
|
|
651
|
+
/** What the transaction is, so the backend applies the right validation gate.
|
|
652
|
+
* - `create` sponsored account creation (relayer = source + sponsor)
|
|
653
|
+
* - `fee-bump` a control-signed payment wrapped in a relayer fee-bump
|
|
654
|
+
* - `sponsored-data` a control-signed data write (add factor/device slot) whose
|
|
655
|
+
* new subentry reserves the relayer sponsors */
|
|
656
|
+
type StellarRelayKind = "create" | "fee-bump" | "sponsored-data";
|
|
541
657
|
/**
|
|
542
|
-
* Client for the
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
658
|
+
* Client for the classic-G sponsoring relayer. Unlike the Soroban relayer (which
|
|
659
|
+
* is the tx *source*), the classic relayer plays two roles:
|
|
660
|
+
* - **create**: it is the tx source + fee payer AND sponsors the new account's
|
|
661
|
+
* reserves (`begin/endSponsoringFutureReserves`), so the user locks no XLM.
|
|
662
|
+
* The SDK sends a master-signed create tx; the relayer co-signs + submits.
|
|
663
|
+
* - **fee-bump**: the user's control-signed inner tx (source = their `G…`) is
|
|
664
|
+
* wrapped in a fee-bump whose fee source is the relayer. The relayer signs the
|
|
665
|
+
* outer envelope only — it pays the fee, never moves the user's funds.
|
|
549
666
|
*
|
|
550
|
-
*
|
|
551
|
-
* entries already device-signed) and hands its unsigned XDR to the relayer, which
|
|
552
|
-
* validates it against its allowlist, signs the envelope and submits.
|
|
667
|
+
* Either way the relayer is a fee payer / reserve sponsor, never a custodian.
|
|
553
668
|
*/
|
|
554
669
|
declare class StellarRelayer {
|
|
555
670
|
private readonly opts;
|
|
556
671
|
private source?;
|
|
557
672
|
constructor(opts: StellarRelayerOptions);
|
|
558
|
-
/** The relayer's source/fee-payer G-account (fetched + cached
|
|
673
|
+
/** The relayer's source/fee-payer/sponsor G-account (fetched + cached). */
|
|
559
674
|
getSource(): Promise<string>;
|
|
560
|
-
/**
|
|
561
|
-
*
|
|
562
|
-
|
|
563
|
-
*/
|
|
564
|
-
submit(transactionXdr: string): Promise<string>;
|
|
675
|
+
/** POST a (partially) signed transaction XDR for the relayer to co-sign + submit.
|
|
676
|
+
* `kind` selects the validation gate. Returns the confirmed transaction hash. */
|
|
677
|
+
submit(kind: StellarRelayKind, transactionXdr: string): Promise<string>;
|
|
565
678
|
}
|
|
566
679
|
|
|
567
680
|
interface ConnectStellarOptions {
|
|
@@ -570,165 +683,136 @@ interface ConnectStellarOptions {
|
|
|
570
683
|
auth?: AuthProvider;
|
|
571
684
|
identity?: Identity;
|
|
572
685
|
appSalt: string;
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
registry?: WalletRegistry;
|
|
576
|
-
/** RPC override (else the network default). */
|
|
577
|
-
rpcUrl?: string;
|
|
578
|
-
/** Factory contract id override (else the per-network default). */
|
|
579
|
-
factoryId?: string;
|
|
580
|
-
/** Override the device signer factory (native / tests); default WebCrypto. */
|
|
581
|
-
createSigner?: (keyId: string) => Promise<DeviceSigner>;
|
|
686
|
+
/** This device's P-256 ECDH unwrap key (provisioned + persisted per device). */
|
|
687
|
+
deviceKey: DeviceUnwrapKey;
|
|
582
688
|
/**
|
|
583
|
-
* Gasless sponsorship via the Cavos relayer. When set (or when `appId` +
|
|
584
|
-
* `backendUrl` are given) the relayer is the
|
|
585
|
-
* the
|
|
586
|
-
* no XLM) gets a seedless, gasless experience.
|
|
689
|
+
* Gasless sponsorship via the Cavos classic relayer. When set (or when `appId` +
|
|
690
|
+
* `backendUrl` are given) the relayer is the tx source + fee payer AND sponsors
|
|
691
|
+
* the account's reserves — the user locks no XLM and pays no fees.
|
|
587
692
|
*/
|
|
588
693
|
relayer?: StellarRelayer;
|
|
694
|
+
/** Cavos App ID — enables the default relayer when no `relayer` is passed. */
|
|
695
|
+
appId?: string;
|
|
696
|
+
/** Cavos backend base URL (default https://cavos.xyz). */
|
|
697
|
+
backendUrl?: string;
|
|
589
698
|
/**
|
|
590
|
-
* Self-funded
|
|
591
|
-
*
|
|
699
|
+
* Self-funded funder + fee payer: creates + submits classic transactions
|
|
700
|
+
* directly (the account pays its own reserves + fees). The advanced /
|
|
701
|
+
* self-hosted fallback used when no relayer is configured.
|
|
592
702
|
*/
|
|
593
703
|
sourceKeypair?: Keypair$1;
|
|
704
|
+
/** Horizon URL override. */
|
|
705
|
+
horizonUrl?: string;
|
|
706
|
+
/** Starting balance for a fresh account, in stroops. */
|
|
707
|
+
startingBalance?: bigint;
|
|
594
708
|
}
|
|
595
|
-
|
|
596
|
-
/** The recovery code the user stored when they ran setupRecovery. */
|
|
597
|
-
code: string;
|
|
598
|
-
/** Authenticated identity (same user who owns the account). */
|
|
599
|
-
identity: Identity;
|
|
600
|
-
}
|
|
601
|
-
type ConnectStatus$1 = "ready" | "needs-device-approval";
|
|
709
|
+
type StellarConnectStatus = "ready" | "needs-device-approval";
|
|
602
710
|
/**
|
|
603
|
-
* High-level
|
|
604
|
-
* `
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
* authorizes every action through the account's `__check_auth`.
|
|
711
|
+
* High-level entry for the classic-Stellar (`G…`) multisig account — the classic
|
|
712
|
+
* analogue of `CavosStellar` (Soroban). One `connect` derives the deterministic
|
|
713
|
+
* `G…` address, creates the account if needed, and on a known device unlocks the
|
|
714
|
+
* control key from the on-chain envelope so `execute` signs silently.
|
|
608
715
|
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
716
|
+
* Multiple unlock **factors** all wrap the same DEK, so opening any one yields the
|
|
717
|
+
* control key:
|
|
718
|
+
* - **device** (P-256 ECIES): silent daily signing, per-device, non-syncable;
|
|
719
|
+
* - **passkey** (WebAuthn PRF): synced anchor to approve a new device / recover;
|
|
720
|
+
* - **recovery code**: offline backup (optional).
|
|
611
721
|
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
722
|
+
* Self-custodial, no backend, no registry: the address is a pure function of
|
|
723
|
+
* identity and the control key lives only in the account's own data entries.
|
|
724
|
+
* Unlike the Soroban `CavosStellar`, this path uses NO wallet registry —
|
|
725
|
+
* creation needs neither an org API key nor a relayer. The optional relayer is
|
|
726
|
+
* only a fee payer + reserve sponsor (never a custodian or identity authority),
|
|
727
|
+
* so a bad/absent relayer can cost fees but can never move funds or squat an
|
|
728
|
+
* address.
|
|
614
729
|
*/
|
|
615
730
|
declare class CavosStellar {
|
|
616
731
|
readonly identity: Identity;
|
|
617
732
|
readonly address: string;
|
|
618
|
-
readonly status: ConnectStatus$1;
|
|
619
733
|
readonly network: StellarNetwork;
|
|
620
734
|
private readonly adapter;
|
|
621
|
-
private readonly
|
|
622
|
-
private
|
|
623
|
-
private
|
|
624
|
-
|
|
735
|
+
private readonly deviceKey;
|
|
736
|
+
private control;
|
|
737
|
+
private dek;
|
|
738
|
+
private readonly relayer;
|
|
625
739
|
readonly chain: "stellar";
|
|
626
|
-
/** True when this connect just created a brand-new account (first sign-up). */
|
|
627
740
|
isNewAccount: boolean;
|
|
741
|
+
private statusValue;
|
|
628
742
|
private constructor();
|
|
629
|
-
get
|
|
743
|
+
get status(): StellarConnectStatus;
|
|
630
744
|
static connect(opts: ConnectStellarOptions): Promise<CavosStellar>;
|
|
631
|
-
/**
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
*/
|
|
637
|
-
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams): Promise<{
|
|
638
|
-
publicKey: DevicePublicKey;
|
|
639
|
-
transactionHash?: string;
|
|
640
|
-
}>;
|
|
641
|
-
/** Register an already-enrolled passkey pubkey as an approver (gasless).
|
|
642
|
-
* Idempotent. Lets one passkey be registered across chains without re-prompting. */
|
|
643
|
-
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
644
|
-
transactionHash?: string;
|
|
645
|
-
}>;
|
|
646
|
-
/** True if this account already has a passkey enrolled as an approver, so a
|
|
647
|
-
* new device can be approved with the passkey instead of the email flow. */
|
|
745
|
+
/** Native XLM balance of the account, in stroops. */
|
|
746
|
+
balance(): Promise<bigint>;
|
|
747
|
+
/** True if the account has a passkey factor enrolled (`cv:wp`), so a new device
|
|
748
|
+
* can be approved with the passkey instead of a recovery code. Mirrors the
|
|
749
|
+
* other chains' `hasPasskey()` for the React provider. */
|
|
648
750
|
hasPasskey(): Promise<boolean>;
|
|
649
|
-
/**
|
|
650
|
-
*
|
|
751
|
+
/** Whether the control key is unlocked on this device (status ready). Classic
|
|
752
|
+
* approvals land synchronously via Horizon, so this reflects state immediately
|
|
753
|
+
* (no indexing delay to poll for). */
|
|
651
754
|
isReady(): Promise<boolean>;
|
|
652
755
|
/**
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
756
|
+
* Move `amount` stroops of native XLM to `destination`, signed by the control
|
|
757
|
+
* key. Sponsored by default (the relayer fee-bumps and pays the fee); pass
|
|
758
|
+
* `{ sponsored: false }` to submit directly — the account pays its own (tiny)
|
|
759
|
+
* fee from its XLM balance. The control key signs identically in both modes;
|
|
760
|
+
* only the fee payer differs.
|
|
657
761
|
*/
|
|
658
|
-
|
|
659
|
-
/** This device's leaf + passkey nonce for a (possibly multi-chain) batch. */
|
|
660
|
-
passkeyLeafForThisDevice(): Promise<{
|
|
661
|
-
leaf: Uint8Array;
|
|
662
|
-
nonce: bigint;
|
|
663
|
-
}>;
|
|
664
|
-
/** Submit `add_signer_via_passkey` given a shared assertion + batch position.
|
|
665
|
-
* No device auth entry — authorized purely by the passkey assertion. */
|
|
666
|
-
submitPasskeyApproval(assertion: PasskeyAssertion, leaves: Uint8Array[], leafIndex: number, nonce: bigint): Promise<{
|
|
667
|
-
transactionHash: string;
|
|
668
|
-
}>;
|
|
669
|
-
/** Move `amount` stroops of native XLM to `destination` (device-signed). */
|
|
670
|
-
execute(amount: bigint, destination: string): Promise<string>;
|
|
671
|
-
/** Read this account's balance of `tokenId` (defaults to native XLM), in stroops. */
|
|
672
|
-
balance(tokenId?: string): Promise<bigint>;
|
|
673
|
-
/** Transfer `amount` of any SEP-41 token out of the account (device-signed). */
|
|
674
|
-
executeTransfer(tokenId: string, amount: bigint, destination: string): Promise<string>;
|
|
762
|
+
execute(amount: bigint, destination: string, opts?: ExecuteOptions): Promise<string>;
|
|
675
763
|
/**
|
|
676
|
-
*
|
|
677
|
-
*
|
|
678
|
-
*
|
|
764
|
+
* Enroll a passkey as an unlock factor: wrap the DEK under the passkey's PRF
|
|
765
|
+
* output and write the `cv:wp` entry. This is the synced anchor used to approve
|
|
766
|
+
* a new device or recover — it survives device loss. Idempotent-ish: writing it
|
|
767
|
+
* again just overwrites the wrap of the same DEK. Requires a ready device.
|
|
679
768
|
*/
|
|
680
|
-
|
|
769
|
+
enrollPasskey(prfOutput: Uint8Array): Promise<string>;
|
|
681
770
|
/**
|
|
682
|
-
*
|
|
683
|
-
*
|
|
684
|
-
*
|
|
771
|
+
* Set up a recovery code as an unlock factor: wrap the DEK under the code's KEK
|
|
772
|
+
* and write the `cv:wr` entry. Optional in v1 — the integrating app decides when
|
|
773
|
+
* to surface it. The code never leaves the device; only the wrap goes on-chain.
|
|
774
|
+
* Requires a ready device.
|
|
685
775
|
*/
|
|
686
|
-
|
|
687
|
-
/** The transaction source/fee-payer G-address (relayer or self-funded). */
|
|
688
|
-
private resolveSource;
|
|
776
|
+
setupRecovery(code: string): Promise<string>;
|
|
689
777
|
/**
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
*
|
|
778
|
+
* From a new browser/device (`needs-device-approval`), approve THIS device using
|
|
779
|
+
* the user's synced passkey: unlock the DEK via the passkey factor, then wrap it
|
|
780
|
+
* to this device's slot so future sessions unlock silently. Flips status to
|
|
781
|
+
* `ready`. No trip back to an already-authorized device.
|
|
693
782
|
*/
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
interface ComputeAddressParams {
|
|
706
|
-
addressSeed: bigint;
|
|
707
|
-
/** First device signer — part of the address, making it unforgeable. */
|
|
708
|
-
initialSigner: DevicePublicKey;
|
|
709
|
-
/** Defaults to `addressSeed` when omitted. */
|
|
710
|
-
salt?: bigint;
|
|
711
|
-
}
|
|
712
|
-
/**
|
|
713
|
-
* Per-chain implementation surface. Phase 1 ships only Starknet, but the kit is
|
|
714
|
-
* designed so Stellar and Solana adapters drop in behind the same interface.
|
|
715
|
-
*/
|
|
716
|
-
interface ChainAdapter {
|
|
717
|
-
readonly chain: "starknet" | "stellar" | "solana";
|
|
718
|
-
/** Deterministic address from identity seed + the first device signer. */
|
|
719
|
-
computeAddress(params: ComputeAddressParams): string;
|
|
720
|
-
/** Call(s) to deploy the account with its first device signer (UDC). */
|
|
721
|
-
buildDeploy(params: ComputeAddressParams): ChainCall[];
|
|
722
|
-
buildAddSigner(accountAddress: string, signer: DevicePublicKey): ChainCall;
|
|
723
|
-
buildRemoveSigner(accountAddress: string, signer: DevicePublicKey): ChainCall;
|
|
724
|
-
/** Read whether a pubkey is a currently-authorized signer of the account. */
|
|
725
|
-
isAuthorizedSigner(accountAddress: string, signer: DevicePublicKey): Promise<boolean>;
|
|
783
|
+
approveThisDeviceWithPasskey(prfOutput: Uint8Array): Promise<string>;
|
|
784
|
+
/** Approve THIS device using the recovery code (same as the passkey path, for
|
|
785
|
+
* the backup factor). */
|
|
786
|
+
approveThisDeviceWithRecovery(code: string): Promise<string>;
|
|
787
|
+
/** The control key's public G address (the weight-1 real signer), for display. */
|
|
788
|
+
get controlAddress(): string | undefined;
|
|
789
|
+
private approveThisDevice;
|
|
790
|
+
/** Write a single-factor wrap (passkey/recovery) into the account data entries,
|
|
791
|
+
* signed by the control key. Overwrites cleanly if the base already existed and
|
|
792
|
+
* the new blob has the same chunk count. */
|
|
793
|
+
private writeFactor;
|
|
726
794
|
/**
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
795
|
+
* Sign an inner (account-sourced) payment tx with the control key and submit it:
|
|
796
|
+
* - sponsored (default) → with a relayer, wrap in a fee-bump (relayer pays
|
|
797
|
+
* the fee) and POST; falls back to self-funded if no relayer;
|
|
798
|
+
* - `{ sponsored: false }` → submit directly (the account pays its own fee).
|
|
799
|
+
* Payments add no subentries, so no reserve sponsorship is needed here.
|
|
730
800
|
*/
|
|
731
|
-
|
|
801
|
+
private submitInner;
|
|
802
|
+
/**
|
|
803
|
+
* Write data entries (add a factor / device slot) — which create NEW subentries
|
|
804
|
+
* that each need ~0.5 XLM of reserve. A relayer-sponsored account holds no XLM,
|
|
805
|
+
* so the write must be sponsored by the relayer (source + sponsor), exactly like
|
|
806
|
+
* account creation — a plain fee-bump would fail with `op_low_reserve`.
|
|
807
|
+
* - sponsored (default) → with a relayer, build a sponsored write (relayer
|
|
808
|
+
* source + begin/end sponsoring), control-sign the account ops, relay
|
|
809
|
+
* co-signs + submits; falls back to self-funded if no relayer;
|
|
810
|
+
* - `{ sponsored: false }` → the account writes directly (it must hold its
|
|
811
|
+
* own reserve for the new subentries).
|
|
812
|
+
*/
|
|
813
|
+
private submitDataWrite;
|
|
814
|
+
private requireControl;
|
|
815
|
+
private requireUnlocked;
|
|
732
816
|
}
|
|
733
817
|
|
|
734
818
|
/**
|
|
@@ -831,8 +915,12 @@ interface ConnectOptions {
|
|
|
831
915
|
stellarRelayer?: StellarRelayer;
|
|
832
916
|
/** Self-funded source/fee-payer Stellar keypair when no relayer is configured. */
|
|
833
917
|
stellarSourceKeypair?: Keypair$1;
|
|
834
|
-
/**
|
|
835
|
-
|
|
918
|
+
/**
|
|
919
|
+
* This device's ECDH unwrap key for the Stellar control-key envelope. Defaults
|
|
920
|
+
* to a persisted `WebCryptoDeviceUnwrapKey` in the browser; pass your own on
|
|
921
|
+
* React Native / server.
|
|
922
|
+
*/
|
|
923
|
+
stellarDeviceKey?: DeviceUnwrapKey;
|
|
836
924
|
}
|
|
837
925
|
/** Whether this device can already operate the wallet, or needs to be added. */
|
|
838
926
|
type ConnectStatus = "ready" | "needs-device-approval";
|
|
@@ -853,6 +941,13 @@ interface RecoveryOptions {
|
|
|
853
941
|
classHash?: string;
|
|
854
942
|
/** Off-chain user_id -> wallet map. Defaults to the hosted registry. */
|
|
855
943
|
registry?: WalletRegistry;
|
|
944
|
+
/**
|
|
945
|
+
* Skip the registry entirely by passing the account address directly. With
|
|
946
|
+
* the seed-only derivation, the user can recompute the address from
|
|
947
|
+
* (userId, appSalt) alone — so recovery no longer depends on the Cavos
|
|
948
|
+
* backend. Pass this to make recovery fully self-custodial.
|
|
949
|
+
*/
|
|
950
|
+
address?: string;
|
|
856
951
|
/** Override the new device's signer (native / tests); default WebCrypto. */
|
|
857
952
|
createSigner?: (keyId: string) => Promise<DeviceSigner>;
|
|
858
953
|
}
|
|
@@ -900,11 +995,14 @@ declare class Cavos {
|
|
|
900
995
|
/** This device's public key (e.g. to request addition to an existing wallet). */
|
|
901
996
|
get publicKey(): DevicePublicKey;
|
|
902
997
|
/** Execute a sponsored (gasless) multicall, signed silently by the device. */
|
|
903
|
-
execute(calls: ChainCall[]): Promise<{
|
|
998
|
+
execute(calls: ChainCall[], opts?: ExecuteOptions): Promise<{
|
|
904
999
|
transactionHash: string;
|
|
905
1000
|
}>;
|
|
906
|
-
/**
|
|
907
|
-
|
|
1001
|
+
/**
|
|
1002
|
+
* Authorize an additional device signer. Sponsored by default; pass
|
|
1003
|
+
* `{ sponsored: false }` to pay the fee from the account's own ETH balance.
|
|
1004
|
+
*/
|
|
1005
|
+
addSigner(pubkey: DevicePublicKey, opts?: ExecuteOptions): Promise<{
|
|
908
1006
|
transactionHash: string;
|
|
909
1007
|
}>;
|
|
910
1008
|
/**
|
|
@@ -914,17 +1012,18 @@ declare class Cavos {
|
|
|
914
1012
|
* approver. Call this whenever the app decides to prompt "turn on device
|
|
915
1013
|
* approvals". Returns the passkey's public key + the enrollment tx hash.
|
|
916
1014
|
*/
|
|
917
|
-
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams): Promise<{
|
|
1015
|
+
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams, opts?: ExecuteOptions): Promise<{
|
|
918
1016
|
publicKey: DevicePublicKey;
|
|
919
1017
|
transactionHash?: string;
|
|
920
1018
|
}>;
|
|
921
1019
|
/**
|
|
922
|
-
* Register an ALREADY-enrolled passkey public key as an approver (gasless
|
|
923
|
-
* device-signed). Idempotent. Use this to register ONE passkey across
|
|
924
|
-
* chains without re-prompting `passkey.enroll()` on each: enroll once,
|
|
925
|
-
* call `addApprover(pubkey)` on each chain's wallet.
|
|
1020
|
+
* Register an ALREADY-enrolled passkey public key as an approver (gasless by
|
|
1021
|
+
* default, device-signed). Idempotent. Use this to register ONE passkey across
|
|
1022
|
+
* multiple chains without re-prompting `passkey.enroll()` on each: enroll once,
|
|
1023
|
+
* then call `addApprover(pubkey)` on each chain's wallet. Pass
|
|
1024
|
+
* `{ sponsored: false }` to pay the fee from the account's own balance.
|
|
926
1025
|
*/
|
|
927
|
-
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
1026
|
+
addApprover(pubkey: DevicePublicKey, opts?: ExecuteOptions): Promise<{
|
|
928
1027
|
transactionHash?: string;
|
|
929
1028
|
}>;
|
|
930
1029
|
/** True if this account already has a passkey enrolled as an approver, so a
|
|
@@ -978,7 +1077,7 @@ declare class Cavos {
|
|
|
978
1077
|
* add_signer (gasless). Returns the transaction hash (or undefined when the
|
|
979
1078
|
* backup was already set up).
|
|
980
1079
|
*/
|
|
981
|
-
setupRecovery(code: string): Promise<{
|
|
1080
|
+
setupRecovery(code: string, opts?: ExecuteOptions): Promise<{
|
|
982
1081
|
transactionHash: string;
|
|
983
1082
|
} | undefined>;
|
|
984
1083
|
/**
|
|
@@ -992,8 +1091,10 @@ declare class Cavos {
|
|
|
992
1091
|
*/
|
|
993
1092
|
static recover(opts: RecoveryOptions): Promise<Cavos>;
|
|
994
1093
|
}
|
|
995
|
-
/** A chain wallet that can approve THIS device via a
|
|
996
|
-
* `Cavos
|
|
1094
|
+
/** A chain wallet that can approve THIS device via a batched WebAuthn assertion
|
|
1095
|
+
* (implemented by `Cavos` and `CavosSolana`). Classic Stellar uses a WebAuthn PRF
|
|
1096
|
+
* factor instead (`CavosStellar.approveThisDeviceWithPasskey`), so it is
|
|
1097
|
+
* not part of this batch. */
|
|
997
1098
|
interface PasskeyApprovable {
|
|
998
1099
|
readonly chain: string;
|
|
999
1100
|
readonly status: string;
|
|
@@ -1012,7 +1113,7 @@ interface PasskeyApprovable {
|
|
|
1012
1113
|
* for all of them. Only wallets whose status is `needs-device-approval` are
|
|
1013
1114
|
* touched. Returns the per-chain tx hashes.
|
|
1014
1115
|
*
|
|
1015
|
-
* await approveDeviceEverywhere([starknet, solana
|
|
1116
|
+
* await approveDeviceEverywhere([starknet, solana], passkey);
|
|
1016
1117
|
*/
|
|
1017
1118
|
declare function approveDeviceEverywhere(wallets: PasskeyApprovable[], passkey: PasskeySigner): Promise<{
|
|
1018
1119
|
chain: string;
|
|
@@ -1020,4 +1121,4 @@ declare function approveDeviceEverywhere(wallets: PasskeyApprovable[], passkey:
|
|
|
1020
1121
|
error?: string;
|
|
1021
1122
|
}[]>;
|
|
1022
1123
|
|
|
1023
|
-
export {
|
|
1124
|
+
export { anchorDiscriminator as $, type AuthProvider as A, type RecoveryOptions as B, type ChainAdapter as C, type DevicePublicKey as D, type EnrolledPasskey as E, SECP256R1_PROGRAM_ID as F, SOLANA_NETWORKS as G, HORIZON_URL as H, type Identity as I, STELLAR_NETWORKS as J, SolanaAdapter as K, LocalDeviceUnwrapKey as L, type SolanaAdapterOptions as M, type NetworkEnv as N, type SolanaNetwork as O, type PendingDeviceRequest as P, SolanaRelayer as Q, type RegisteredWallet as R, type StellarNetwork as S, type SolanaRelayerOptions as T, StaticIdentity as U, type StellarConnectStatus as V, type WalletRegistry as W, type StellarRelayKind as X, StellarRelayer as Y, type StellarRelayerOptions as Z, XLM_DECIMALS as _, type RecoveryClient as a, approveDeviceEverywhere as a0, base64urlEncode as a1, batchChallenge as a2, buildSecp256r1Instruction as a3, compressedPubkey as a4, deviceSlotId as a5, encodeLowSSignature as a6, lowS as a7, recoverCandidatePublicKeys as a8, serializeInstructions as a9, webauthnDigest as aa, type DeviceSigner as b, type DeviceSignature as c, type ComputeAddressParams as d, type ChainCall as e, type PasskeyAssertion as f, type DeviceUnwrapKey as g, Cavos as h, CavosSolana as i, CavosStellar as j, type CavosWallet as k, type Chain as l, type ConnectOptions as m, type ConnectSolanaOptions as n, type ConnectStatus as o, type ConnectStellarOptions as p, DEVICE_ACCOUNT_PROGRAM_ID as q, type ExecuteOptions as r, InMemoryWalletRegistry as s, type InstructionAccount as t, type InstructionData as u, type PasskeyApprovable as v, type PasskeyEnrollParams as w, PasskeySigner as x, type PasskeySignerOptions as y, type RecoverSolanaOptions as z };
|