@cavos/kit 0.0.3 → 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-BH2_tOQ2.d.mts → Cavos-D20EtgOK.d.mts} +312 -182
- package/dist/{Cavos-BH2_tOQ2.d.ts → Cavos-D20EtgOK.d.ts} +312 -182
- package/dist/{chunk-BNGLH3Q3.mjs → chunk-M5BGBODC.mjs} +1660 -582
- package/dist/chunk-M5BGBODC.mjs.map +1 -0
- package/dist/index.d.mts +293 -89
- package/dist/index.d.ts +293 -89
- package/dist/index.js +1601 -593
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -88
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +42 -29
- package/dist/react/index.d.ts +42 -29
- package/dist/react/index.js +2002 -655
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +353 -92
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BNGLH3Q3.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. */
|
|
@@ -209,6 +218,8 @@ declare class SolanaAdapter {
|
|
|
209
218
|
*/
|
|
210
219
|
buildAddSignerViaPasskey(account: string, newSigner: DevicePublicKey, passkey: DevicePublicKey, leaves: Uint8Array[], leafIndex: number, assertion: PasskeyAssertion): TransactionInstruction[];
|
|
211
220
|
/** Read whether `passkey` is a registered approver. */
|
|
221
|
+
/** True if the account has at least one passkey registered as an approver. */
|
|
222
|
+
hasPasskeyApprover(account: string): Promise<boolean>;
|
|
212
223
|
isApprover(account: string, passkey: DevicePublicKey): Promise<boolean>;
|
|
213
224
|
/** Read the current passkey-approval nonce. */
|
|
214
225
|
passkeyNonce(account: string): Promise<bigint>;
|
|
@@ -331,6 +342,67 @@ declare class PasskeySigner {
|
|
|
331
342
|
assert(challenge: Uint8Array): Promise<PasskeyAssertion>;
|
|
332
343
|
}
|
|
333
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
|
+
|
|
334
406
|
interface ConnectSolanaOptions {
|
|
335
407
|
network: SolanaNetwork;
|
|
336
408
|
/** Authenticated user (pass `identity` directly, or an `auth` provider). */
|
|
@@ -360,7 +432,7 @@ interface ConnectSolanaOptions {
|
|
|
360
432
|
*/
|
|
361
433
|
feePayer?: Keypair;
|
|
362
434
|
}
|
|
363
|
-
type ConnectStatus$
|
|
435
|
+
type ConnectStatus$1 = "ready" | "needs-device-approval";
|
|
364
436
|
/**
|
|
365
437
|
* Options for recovering a Solana account after losing every device signer.
|
|
366
438
|
* Mirrors `RecoveryOptions` (Starknet), adapted to the Solana path: the backup
|
|
@@ -405,7 +477,7 @@ interface RecoverSolanaOptions {
|
|
|
405
477
|
declare class CavosSolana {
|
|
406
478
|
readonly identity: Identity;
|
|
407
479
|
readonly address: string;
|
|
408
|
-
readonly status: ConnectStatus$
|
|
480
|
+
readonly status: ConnectStatus$1;
|
|
409
481
|
readonly connection: Connection;
|
|
410
482
|
private readonly adapter;
|
|
411
483
|
private readonly devicePubkey;
|
|
@@ -413,6 +485,8 @@ declare class CavosSolana {
|
|
|
413
485
|
private readonly feePayer?;
|
|
414
486
|
/** Discriminant for the `CavosWallet` union — narrows `execute()` per chain. */
|
|
415
487
|
readonly chain: "solana";
|
|
488
|
+
/** True when this connect just created a brand-new account (first sign-up). */
|
|
489
|
+
isNewAccount: boolean;
|
|
416
490
|
private constructor();
|
|
417
491
|
get publicKey(): DevicePublicKey;
|
|
418
492
|
static connect(opts: ConnectSolanaOptions): Promise<CavosSolana>;
|
|
@@ -431,6 +505,12 @@ declare class CavosSolana {
|
|
|
431
505
|
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
432
506
|
transactionHash?: string;
|
|
433
507
|
}>;
|
|
508
|
+
/** True if this account already has a passkey enrolled as an approver, so a
|
|
509
|
+
* new device can be approved with the passkey instead of the email flow. */
|
|
510
|
+
hasPasskey(): Promise<boolean>;
|
|
511
|
+
/** Re-read (from chain) whether THIS device is now an authorized signer.
|
|
512
|
+
* Used to poll for readiness after a passkey approval before it's indexed. */
|
|
513
|
+
isReady(): Promise<boolean>;
|
|
434
514
|
/**
|
|
435
515
|
* From a fresh browser (status `needs-device-approval`), approve adding THIS
|
|
436
516
|
* device with the user's synced passkey. Gasless via the relayer — the bundle
|
|
@@ -448,7 +528,7 @@ declare class CavosSolana {
|
|
|
448
528
|
transactionHash: string;
|
|
449
529
|
}>;
|
|
450
530
|
/** Move `amount` lamports out of the account to `destination` (device-signed). */
|
|
451
|
-
execute(amount: bigint, destination: string): Promise<string>;
|
|
531
|
+
execute(amount: bigint, destination: string, opts?: ExecuteOptions): Promise<string>;
|
|
452
532
|
/**
|
|
453
533
|
* Run arbitrary CPI `instructions` with the account PDA as signer (device-
|
|
454
534
|
* signed). The signature commits to sha256 of the canonical Borsh
|
|
@@ -457,9 +537,11 @@ declare class CavosSolana {
|
|
|
457
537
|
*
|
|
458
538
|
* What the relayer will sponsor is constrained by the app's Solana program
|
|
459
539
|
* allowlist (configured in the dashboard) — programs outside the allowlist are
|
|
460
|
-
* 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).
|
|
461
543
|
*/
|
|
462
|
-
executeInstructions(instructions: InstructionData[]): Promise<string>;
|
|
544
|
+
executeInstructions(instructions: InstructionData[], opts?: ExecuteOptions): Promise<string>;
|
|
463
545
|
/**
|
|
464
546
|
* Register the backup signer derived from `code` as an authorized signer of this
|
|
465
547
|
* account (device-signed via precompile). Idempotent: returns without a tx if
|
|
@@ -485,41 +567,79 @@ declare class CavosSolana {
|
|
|
485
567
|
* the backup key. The on-chain program needs no recovery-specific entrypoint.
|
|
486
568
|
*/
|
|
487
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
|
+
*/
|
|
488
577
|
private send;
|
|
489
578
|
}
|
|
490
579
|
|
|
491
|
-
/** Cavos device-account primitives on Stellar / Soroban. */
|
|
492
580
|
/**
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
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.
|
|
496
593
|
*/
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
}
|
|
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. */
|
|
506
628
|
declare const STELLAR_NETWORKS: {
|
|
507
629
|
readonly "stellar-testnet": {
|
|
508
|
-
readonly rpcUrl: "https://soroban-testnet.stellar.org";
|
|
509
630
|
readonly passphrase: "Test SDF Network ; September 2015";
|
|
510
631
|
};
|
|
511
632
|
readonly "stellar-mainnet": {
|
|
512
|
-
readonly rpcUrl: "https://soroban-rpc.mainnet.stellar.gateway.fm";
|
|
513
633
|
readonly passphrase: "Public Global Stellar Network ; September 2015";
|
|
514
634
|
};
|
|
515
635
|
};
|
|
516
636
|
type StellarNetwork = keyof typeof STELLAR_NETWORKS;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
readonly "stellar-testnet": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC";
|
|
521
|
-
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";
|
|
522
640
|
};
|
|
641
|
+
/** Native XLM has 7 decimals (stroops). */
|
|
642
|
+
declare const XLM_DECIMALS = 7;
|
|
523
643
|
|
|
524
644
|
interface StellarRelayerOptions {
|
|
525
645
|
/** Base URL of the Cavos backend exposing /api/stellar/relay. */
|
|
@@ -528,30 +648,33 @@ interface StellarRelayerOptions {
|
|
|
528
648
|
appId: string;
|
|
529
649
|
network: StellarNetwork;
|
|
530
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";
|
|
531
657
|
/**
|
|
532
|
-
* Client for the
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
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.
|
|
539
666
|
*
|
|
540
|
-
*
|
|
541
|
-
* entries already device-signed) and hands its unsigned XDR to the relayer, which
|
|
542
|
-
* validates it against its allowlist, signs the envelope and submits.
|
|
667
|
+
* Either way the relayer is a fee payer / reserve sponsor, never a custodian.
|
|
543
668
|
*/
|
|
544
669
|
declare class StellarRelayer {
|
|
545
670
|
private readonly opts;
|
|
546
671
|
private source?;
|
|
547
672
|
constructor(opts: StellarRelayerOptions);
|
|
548
|
-
/** The relayer's source/fee-payer G-account (fetched + cached
|
|
673
|
+
/** The relayer's source/fee-payer/sponsor G-account (fetched + cached). */
|
|
549
674
|
getSource(): Promise<string>;
|
|
550
|
-
/**
|
|
551
|
-
*
|
|
552
|
-
|
|
553
|
-
*/
|
|
554
|
-
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>;
|
|
555
678
|
}
|
|
556
679
|
|
|
557
680
|
interface ConnectStellarOptions {
|
|
@@ -560,157 +683,136 @@ interface ConnectStellarOptions {
|
|
|
560
683
|
auth?: AuthProvider;
|
|
561
684
|
identity?: Identity;
|
|
562
685
|
appSalt: string;
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
registry?: WalletRegistry;
|
|
566
|
-
/** RPC override (else the network default). */
|
|
567
|
-
rpcUrl?: string;
|
|
568
|
-
/** Factory contract id override (else the per-network default). */
|
|
569
|
-
factoryId?: string;
|
|
570
|
-
/** Override the device signer factory (native / tests); default WebCrypto. */
|
|
571
|
-
createSigner?: (keyId: string) => Promise<DeviceSigner>;
|
|
686
|
+
/** This device's P-256 ECDH unwrap key (provisioned + persisted per device). */
|
|
687
|
+
deviceKey: DeviceUnwrapKey;
|
|
572
688
|
/**
|
|
573
|
-
* Gasless sponsorship via the Cavos relayer. When set (or when `appId` +
|
|
574
|
-
* `backendUrl` are given) the relayer is the
|
|
575
|
-
* the
|
|
576
|
-
* 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.
|
|
577
692
|
*/
|
|
578
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;
|
|
579
698
|
/**
|
|
580
|
-
* Self-funded
|
|
581
|
-
*
|
|
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.
|
|
582
702
|
*/
|
|
583
703
|
sourceKeypair?: Keypair$1;
|
|
704
|
+
/** Horizon URL override. */
|
|
705
|
+
horizonUrl?: string;
|
|
706
|
+
/** Starting balance for a fresh account, in stroops. */
|
|
707
|
+
startingBalance?: bigint;
|
|
584
708
|
}
|
|
585
|
-
|
|
586
|
-
/** The recovery code the user stored when they ran setupRecovery. */
|
|
587
|
-
code: string;
|
|
588
|
-
/** Authenticated identity (same user who owns the account). */
|
|
589
|
-
identity: Identity;
|
|
590
|
-
}
|
|
591
|
-
type ConnectStatus$1 = "ready" | "needs-device-approval";
|
|
709
|
+
type StellarConnectStatus = "ready" | "needs-device-approval";
|
|
592
710
|
/**
|
|
593
|
-
* High-level
|
|
594
|
-
* `
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
* 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.
|
|
598
715
|
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
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).
|
|
601
721
|
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
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.
|
|
604
729
|
*/
|
|
605
730
|
declare class CavosStellar {
|
|
606
731
|
readonly identity: Identity;
|
|
607
732
|
readonly address: string;
|
|
608
|
-
readonly status: ConnectStatus$1;
|
|
609
733
|
readonly network: StellarNetwork;
|
|
610
734
|
private readonly adapter;
|
|
611
|
-
private readonly
|
|
612
|
-
private
|
|
613
|
-
private
|
|
614
|
-
|
|
735
|
+
private readonly deviceKey;
|
|
736
|
+
private control;
|
|
737
|
+
private dek;
|
|
738
|
+
private readonly relayer;
|
|
615
739
|
readonly chain: "stellar";
|
|
740
|
+
isNewAccount: boolean;
|
|
741
|
+
private statusValue;
|
|
616
742
|
private constructor();
|
|
617
|
-
get
|
|
743
|
+
get status(): StellarConnectStatus;
|
|
618
744
|
static connect(opts: ConnectStellarOptions): Promise<CavosStellar>;
|
|
619
|
-
/**
|
|
620
|
-
|
|
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. */
|
|
750
|
+
hasPasskey(): Promise<boolean>;
|
|
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). */
|
|
754
|
+
isReady(): Promise<boolean>;
|
|
621
755
|
/**
|
|
622
|
-
*
|
|
623
|
-
*
|
|
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.
|
|
624
761
|
*/
|
|
625
|
-
|
|
626
|
-
publicKey: DevicePublicKey;
|
|
627
|
-
transactionHash?: string;
|
|
628
|
-
}>;
|
|
629
|
-
/** Register an already-enrolled passkey pubkey as an approver (gasless).
|
|
630
|
-
* Idempotent. Lets one passkey be registered across chains without re-prompting. */
|
|
631
|
-
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
632
|
-
transactionHash?: string;
|
|
633
|
-
}>;
|
|
762
|
+
execute(amount: bigint, destination: string, opts?: ExecuteOptions): Promise<string>;
|
|
634
763
|
/**
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
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.
|
|
639
768
|
*/
|
|
640
|
-
|
|
641
|
-
/** This device's leaf + passkey nonce for a (possibly multi-chain) batch. */
|
|
642
|
-
passkeyLeafForThisDevice(): Promise<{
|
|
643
|
-
leaf: Uint8Array;
|
|
644
|
-
nonce: bigint;
|
|
645
|
-
}>;
|
|
646
|
-
/** Submit `add_signer_via_passkey` given a shared assertion + batch position.
|
|
647
|
-
* No device auth entry — authorized purely by the passkey assertion. */
|
|
648
|
-
submitPasskeyApproval(assertion: PasskeyAssertion, leaves: Uint8Array[], leafIndex: number, nonce: bigint): Promise<{
|
|
649
|
-
transactionHash: string;
|
|
650
|
-
}>;
|
|
651
|
-
/** Move `amount` stroops of native XLM to `destination` (device-signed). */
|
|
652
|
-
execute(amount: bigint, destination: string): Promise<string>;
|
|
653
|
-
/** Read this account's balance of `tokenId` (defaults to native XLM), in stroops. */
|
|
654
|
-
balance(tokenId?: string): Promise<bigint>;
|
|
655
|
-
/** Transfer `amount` of any SEP-41 token out of the account (device-signed). */
|
|
656
|
-
executeTransfer(tokenId: string, amount: bigint, destination: string): Promise<string>;
|
|
769
|
+
enrollPasskey(prfOutput: Uint8Array): Promise<string>;
|
|
657
770
|
/**
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
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.
|
|
661
775
|
*/
|
|
662
|
-
setupRecovery(code: string): Promise<string
|
|
776
|
+
setupRecovery(code: string): Promise<string>;
|
|
663
777
|
/**
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
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.
|
|
667
782
|
*/
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
|
|
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;
|
|
671
794
|
/**
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
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.
|
|
675
800
|
*/
|
|
676
|
-
private
|
|
677
|
-
/** Submit a signed tx via RPC and poll to confirmation. Returns the hash. */
|
|
678
|
-
private sendAndConfirm;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
/** A chain-native contract call (Starknet `Call`-shaped; generic for portability). */
|
|
682
|
-
interface ChainCall {
|
|
683
|
-
contractAddress: string;
|
|
684
|
-
entrypoint: string;
|
|
685
|
-
calldata: string[];
|
|
686
|
-
}
|
|
687
|
-
interface ComputeAddressParams {
|
|
688
|
-
addressSeed: bigint;
|
|
689
|
-
/** First device signer — part of the address, making it unforgeable. */
|
|
690
|
-
initialSigner: DevicePublicKey;
|
|
691
|
-
/** Defaults to `addressSeed` when omitted. */
|
|
692
|
-
salt?: bigint;
|
|
693
|
-
}
|
|
694
|
-
/**
|
|
695
|
-
* Per-chain implementation surface. Phase 1 ships only Starknet, but the kit is
|
|
696
|
-
* designed so Stellar and Solana adapters drop in behind the same interface.
|
|
697
|
-
*/
|
|
698
|
-
interface ChainAdapter {
|
|
699
|
-
readonly chain: "starknet" | "stellar" | "solana";
|
|
700
|
-
/** Deterministic address from identity seed + the first device signer. */
|
|
701
|
-
computeAddress(params: ComputeAddressParams): string;
|
|
702
|
-
/** Call(s) to deploy the account with its first device signer (UDC). */
|
|
703
|
-
buildDeploy(params: ComputeAddressParams): ChainCall[];
|
|
704
|
-
buildAddSigner(accountAddress: string, signer: DevicePublicKey): ChainCall;
|
|
705
|
-
buildRemoveSigner(accountAddress: string, signer: DevicePublicKey): ChainCall;
|
|
706
|
-
/** Read whether a pubkey is a currently-authorized signer of the account. */
|
|
707
|
-
isAuthorizedSigner(accountAddress: string, signer: DevicePublicKey): Promise<boolean>;
|
|
801
|
+
private submitInner;
|
|
708
802
|
/**
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
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).
|
|
712
812
|
*/
|
|
713
|
-
|
|
813
|
+
private submitDataWrite;
|
|
814
|
+
private requireControl;
|
|
815
|
+
private requireUnlocked;
|
|
714
816
|
}
|
|
715
817
|
|
|
716
818
|
/**
|
|
@@ -813,8 +915,12 @@ interface ConnectOptions {
|
|
|
813
915
|
stellarRelayer?: StellarRelayer;
|
|
814
916
|
/** Self-funded source/fee-payer Stellar keypair when no relayer is configured. */
|
|
815
917
|
stellarSourceKeypair?: Keypair$1;
|
|
816
|
-
/**
|
|
817
|
-
|
|
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;
|
|
818
924
|
}
|
|
819
925
|
/** Whether this device can already operate the wallet, or needs to be added. */
|
|
820
926
|
type ConnectStatus = "ready" | "needs-device-approval";
|
|
@@ -835,6 +941,13 @@ interface RecoveryOptions {
|
|
|
835
941
|
classHash?: string;
|
|
836
942
|
/** Off-chain user_id -> wallet map. Defaults to the hosted registry. */
|
|
837
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;
|
|
838
951
|
/** Override the new device's signer (native / tests); default WebCrypto. */
|
|
839
952
|
createSigner?: (keyId: string) => Promise<DeviceSigner>;
|
|
840
953
|
}
|
|
@@ -863,6 +976,9 @@ declare class Cavos {
|
|
|
863
976
|
readonly chain: "starknet";
|
|
864
977
|
/** Request id of the pending device-addition, when status is needs-device-approval. */
|
|
865
978
|
pendingRequestId: string | null;
|
|
979
|
+
/** True when this connect just created & deployed a brand-new account (first
|
|
980
|
+
* sign-up), so the UI can offer a one-time "secure your account" step. */
|
|
981
|
+
isNewAccount: boolean;
|
|
866
982
|
private constructor();
|
|
867
983
|
/**
|
|
868
984
|
* Unified entry point. Pick a `chain` and an `network` environment; the kit
|
|
@@ -879,11 +995,14 @@ declare class Cavos {
|
|
|
879
995
|
/** This device's public key (e.g. to request addition to an existing wallet). */
|
|
880
996
|
get publicKey(): DevicePublicKey;
|
|
881
997
|
/** Execute a sponsored (gasless) multicall, signed silently by the device. */
|
|
882
|
-
execute(calls: ChainCall[]): Promise<{
|
|
998
|
+
execute(calls: ChainCall[], opts?: ExecuteOptions): Promise<{
|
|
883
999
|
transactionHash: string;
|
|
884
1000
|
}>;
|
|
885
|
-
/**
|
|
886
|
-
|
|
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<{
|
|
887
1006
|
transactionHash: string;
|
|
888
1007
|
}>;
|
|
889
1008
|
/**
|
|
@@ -893,19 +1012,27 @@ declare class Cavos {
|
|
|
893
1012
|
* approver. Call this whenever the app decides to prompt "turn on device
|
|
894
1013
|
* approvals". Returns the passkey's public key + the enrollment tx hash.
|
|
895
1014
|
*/
|
|
896
|
-
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams): Promise<{
|
|
1015
|
+
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams, opts?: ExecuteOptions): Promise<{
|
|
897
1016
|
publicKey: DevicePublicKey;
|
|
898
1017
|
transactionHash?: string;
|
|
899
1018
|
}>;
|
|
900
1019
|
/**
|
|
901
|
-
* Register an ALREADY-enrolled passkey public key as an approver (gasless
|
|
902
|
-
* device-signed). Idempotent. Use this to register ONE passkey across
|
|
903
|
-
* chains without re-prompting `passkey.enroll()` on each: enroll once,
|
|
904
|
-
* 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.
|
|
905
1025
|
*/
|
|
906
|
-
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
1026
|
+
addApprover(pubkey: DevicePublicKey, opts?: ExecuteOptions): Promise<{
|
|
907
1027
|
transactionHash?: string;
|
|
908
1028
|
}>;
|
|
1029
|
+
/** True if this account already has a passkey enrolled as an approver, so a
|
|
1030
|
+
* new device can be approved with the passkey instead of the email flow. */
|
|
1031
|
+
hasPasskey(): Promise<boolean>;
|
|
1032
|
+
/** Re-read (from chain) whether THIS device is now an authorized signer.
|
|
1033
|
+
* Cheap and side-effect free — used to poll for readiness after a passkey /
|
|
1034
|
+
* device approval submits, before the new signer is indexed. */
|
|
1035
|
+
isReady(): Promise<boolean>;
|
|
909
1036
|
/**
|
|
910
1037
|
* From a brand-new browser (status `needs-device-approval`), use the user's
|
|
911
1038
|
* synced passkey to authorize adding THIS device — no trip back to an already-
|
|
@@ -950,7 +1077,7 @@ declare class Cavos {
|
|
|
950
1077
|
* add_signer (gasless). Returns the transaction hash (or undefined when the
|
|
951
1078
|
* backup was already set up).
|
|
952
1079
|
*/
|
|
953
|
-
setupRecovery(code: string): Promise<{
|
|
1080
|
+
setupRecovery(code: string, opts?: ExecuteOptions): Promise<{
|
|
954
1081
|
transactionHash: string;
|
|
955
1082
|
} | undefined>;
|
|
956
1083
|
/**
|
|
@@ -964,8 +1091,10 @@ declare class Cavos {
|
|
|
964
1091
|
*/
|
|
965
1092
|
static recover(opts: RecoveryOptions): Promise<Cavos>;
|
|
966
1093
|
}
|
|
967
|
-
/** A chain wallet that can approve THIS device via a
|
|
968
|
-
* `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. */
|
|
969
1098
|
interface PasskeyApprovable {
|
|
970
1099
|
readonly chain: string;
|
|
971
1100
|
readonly status: string;
|
|
@@ -984,11 +1113,12 @@ interface PasskeyApprovable {
|
|
|
984
1113
|
* for all of them. Only wallets whose status is `needs-device-approval` are
|
|
985
1114
|
* touched. Returns the per-chain tx hashes.
|
|
986
1115
|
*
|
|
987
|
-
* await approveDeviceEverywhere([starknet, solana
|
|
1116
|
+
* await approveDeviceEverywhere([starknet, solana], passkey);
|
|
988
1117
|
*/
|
|
989
1118
|
declare function approveDeviceEverywhere(wallets: PasskeyApprovable[], passkey: PasskeySigner): Promise<{
|
|
990
1119
|
chain: string;
|
|
991
|
-
transactionHash
|
|
1120
|
+
transactionHash?: string;
|
|
1121
|
+
error?: string;
|
|
992
1122
|
}[]>;
|
|
993
1123
|
|
|
994
|
-
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 };
|