@cavos/kit 0.0.2 → 0.0.3
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-C2KHZxxu.d.mts → Cavos-BH2_tOQ2.d.mts} +409 -5
- package/dist/{Cavos-C2KHZxxu.d.ts → Cavos-BH2_tOQ2.d.ts} +409 -5
- package/dist/{chunk-PEUQQZB5.mjs → chunk-BNGLH3Q3.mjs} +1122 -17
- package/dist/chunk-BNGLH3Q3.mjs.map +1 -0
- package/dist/index.d.mts +125 -5
- package/dist/index.d.ts +125 -5
- package/dist/index.js +1223 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +88 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +25 -1
- package/dist/react/index.d.ts +25 -1
- package/dist/react/index.js +1072 -8
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +21 -1
- package/dist/react/index.mjs.map +1 -1
- package/package.json +3 -1
- package/dist/chunk-PEUQQZB5.mjs.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Account } from 'starknet';
|
|
2
2
|
import { PublicKey, Connection, TransactionInstruction, Keypair } from '@solana/web3.js';
|
|
3
|
+
import { Keypair as Keypair$1 } from '@stellar/stellar-sdk';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Identity for a Cavos wallet. Login (email / social / OTP) only ever produces a
|
|
@@ -114,6 +115,39 @@ declare class InMemoryWalletRegistry implements WalletRegistry {
|
|
|
114
115
|
}): Promise<void>;
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
/** A parsed passkey assertion, chain-agnostic. */
|
|
119
|
+
interface PasskeyAssertion {
|
|
120
|
+
authenticatorData: Uint8Array;
|
|
121
|
+
clientDataJSON: Uint8Array;
|
|
122
|
+
/** ECDSA signature components (raw, as returned by the authenticator). */
|
|
123
|
+
r: bigint;
|
|
124
|
+
s: bigint;
|
|
125
|
+
/** Byte index where the base64url challenge starts inside clientDataJSON. */
|
|
126
|
+
challengeOffset: number;
|
|
127
|
+
}
|
|
128
|
+
/** base64url (no padding) of a byte array. */
|
|
129
|
+
declare function base64urlEncode(bytes: Uint8Array): string;
|
|
130
|
+
/**
|
|
131
|
+
* Batch challenge over ordered per-chain leaves: `sha256(leaf_0 ‖ … ‖ leaf_n)`.
|
|
132
|
+
* A single passkey assertion over this challenge authorizes `add_signer` on every
|
|
133
|
+
* chain in the batch (each chain verifies only its own leaf sits at its index).
|
|
134
|
+
* For a single chain the batch is one leaf, so the challenge is `sha256(leaf)`.
|
|
135
|
+
*/
|
|
136
|
+
declare function batchChallenge(leaves: Uint8Array[]): Uint8Array;
|
|
137
|
+
/** The WebAuthn signed digest: `sha256(authenticatorData || sha256(clientDataJSON))`. */
|
|
138
|
+
declare function webauthnDigest(authenticatorData: Uint8Array, clientDataJSON: Uint8Array): Uint8Array;
|
|
139
|
+
/** Both candidate public keys recoverable from `(r, s)` over `digest`, tagged
|
|
140
|
+
* with their y-parity. On a fresh browser the assertion does not carry the
|
|
141
|
+
* pubkey, so the caller identifies the real one via the on-chain `is_approver`
|
|
142
|
+
* view. */
|
|
143
|
+
declare function recoverCandidatePublicKeys(r: bigint, s: bigint, digest: Uint8Array): {
|
|
144
|
+
publicKey: DevicePublicKey;
|
|
145
|
+
yParity: boolean;
|
|
146
|
+
}[];
|
|
147
|
+
/** Normalize `s` to the low half of the curve order (required by the Stellar
|
|
148
|
+
* and Solana verifiers, which do not normalize on-chain). */
|
|
149
|
+
declare function lowS(s: bigint): bigint;
|
|
150
|
+
|
|
117
151
|
/** An account meta candidate for a CPI instruction inside `execute`. Mirrors the
|
|
118
152
|
* on-chain `AccountMetaCandidate` (Borsh). */
|
|
119
153
|
interface InstructionAccount {
|
|
@@ -159,6 +193,25 @@ declare class SolanaAdapter {
|
|
|
159
193
|
buildAddSigner(account: string, newSigner: DevicePublicKey): Promise<TransactionInstruction[]>;
|
|
160
194
|
/** `[precompile, remove_signer]` bundle, authorized by an existing device signer. */
|
|
161
195
|
buildRemoveSigner(account: string, signer: DevicePublicKey): Promise<TransactionInstruction[]>;
|
|
196
|
+
/** `[precompile, add_approver]` bundle enrolling a passkey approver (device-signed). */
|
|
197
|
+
buildAddApprover(account: string, passkey: DevicePublicKey): Promise<TransactionInstruction[]>;
|
|
198
|
+
/** `[precompile, remove_approver]` bundle (device-signed). */
|
|
199
|
+
buildRemoveApprover(account: string, passkey: DevicePublicKey): Promise<TransactionInstruction[]>;
|
|
200
|
+
/** This chain's leaf for approving `add_signer(newSigner)` at `nonce`:
|
|
201
|
+
* `sha256(compressed(new_signer) || passkey_nonce_le8)`. The batch challenge the
|
|
202
|
+
* passkey signs is `sha256(concat(leaves))` across chains. */
|
|
203
|
+
passkeyLeaf(newSigner: DevicePublicKey, nonce: bigint): Uint8Array;
|
|
204
|
+
/**
|
|
205
|
+
* `[precompile(passkey), add_signer_via_passkey]` bundle. The precompile ix
|
|
206
|
+
* verifies the PASSKEY's WebAuthn assertion over `authData || sha256(clientDataJSON)`;
|
|
207
|
+
* the program ix binds the challenge to `newSigner` + the passkey nonce and adds
|
|
208
|
+
* the signer. No device signature — a gasless relayer can submit it.
|
|
209
|
+
*/
|
|
210
|
+
buildAddSignerViaPasskey(account: string, newSigner: DevicePublicKey, passkey: DevicePublicKey, leaves: Uint8Array[], leafIndex: number, assertion: PasskeyAssertion): TransactionInstruction[];
|
|
211
|
+
/** Read whether `passkey` is a registered approver. */
|
|
212
|
+
isApprover(account: string, passkey: DevicePublicKey): Promise<boolean>;
|
|
213
|
+
/** Read the current passkey-approval nonce. */
|
|
214
|
+
passkeyNonce(account: string): Promise<bigint>;
|
|
162
215
|
/** `[precompile, execute_transfer]` bundle moving lamports out of the account. */
|
|
163
216
|
buildExecuteTransfer(account: string, destination: string, amount: bigint): Promise<TransactionInstruction[]>;
|
|
164
217
|
/**
|
|
@@ -179,6 +232,7 @@ declare class SolanaAdapter {
|
|
|
179
232
|
private signToPrecompile;
|
|
180
233
|
private fetchNonce;
|
|
181
234
|
private fetchSigners;
|
|
235
|
+
private fetchApprovers;
|
|
182
236
|
private requireConnection;
|
|
183
237
|
}
|
|
184
238
|
/** Compressed SEC1 P-256 pubkey (33 bytes) from {x, y}. */
|
|
@@ -234,6 +288,49 @@ declare class SolanaRelayer {
|
|
|
234
288
|
send(instructions: TransactionInstruction[]): Promise<string>;
|
|
235
289
|
}
|
|
236
290
|
|
|
291
|
+
interface PasskeySignerOptions {
|
|
292
|
+
/** Relying-Party id (usually the eTLD+1). Defaults to `window.location.hostname`. */
|
|
293
|
+
rpId?: string;
|
|
294
|
+
/** Human-readable RP name shown in the OS passkey UI. */
|
|
295
|
+
rpName?: string;
|
|
296
|
+
}
|
|
297
|
+
interface PasskeyEnrollParams {
|
|
298
|
+
/** Stable user handle for the credential (e.g. the account address or userId). */
|
|
299
|
+
userId: string;
|
|
300
|
+
/** Account name shown in the OS passkey UI (e.g. an email). */
|
|
301
|
+
userName: string;
|
|
302
|
+
displayName?: string;
|
|
303
|
+
}
|
|
304
|
+
interface EnrolledPasskey {
|
|
305
|
+
publicKey: DevicePublicKey;
|
|
306
|
+
credentialId: Uint8Array;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Browser passkey signer. Creates a discoverable (resident) secp256r1 credential
|
|
310
|
+
* that syncs across the user's devices (iCloud Keychain / Google Password
|
|
311
|
+
* Manager), and produces WebAuthn assertions used to authorize `add_signer`.
|
|
312
|
+
*
|
|
313
|
+
* This is a step-up primitive: the app decides WHEN to enroll (e.g. after
|
|
314
|
+
* onboarding, as a "turn on device approvals" / 2FA moment). Enrollment
|
|
315
|
+
* registers the passkey on-chain as an approver; later, from any browser, an
|
|
316
|
+
* assertion approves adding that browser's new device key.
|
|
317
|
+
*/
|
|
318
|
+
declare class PasskeySigner {
|
|
319
|
+
private readonly rpId;
|
|
320
|
+
private readonly rpName;
|
|
321
|
+
constructor(opts?: PasskeySignerOptions);
|
|
322
|
+
/** True if this platform advertises a usable passkey (platform authenticator). */
|
|
323
|
+
static isSupported(): Promise<boolean>;
|
|
324
|
+
/** Create a new synced passkey and return its P-256 public key. */
|
|
325
|
+
enroll(params: PasskeyEnrollParams): Promise<EnrolledPasskey>;
|
|
326
|
+
/**
|
|
327
|
+
* Produce a WebAuthn assertion over `challenge` (a 32-byte value the caller
|
|
328
|
+
* derives from the signer being added + the on-chain nonce). Uses discoverable
|
|
329
|
+
* credentials — no `allowCredentials` — so it works on a brand-new browser.
|
|
330
|
+
*/
|
|
331
|
+
assert(challenge: Uint8Array): Promise<PasskeyAssertion>;
|
|
332
|
+
}
|
|
333
|
+
|
|
237
334
|
interface ConnectSolanaOptions {
|
|
238
335
|
network: SolanaNetwork;
|
|
239
336
|
/** Authenticated user (pass `identity` directly, or an `auth` provider). */
|
|
@@ -263,7 +360,7 @@ interface ConnectSolanaOptions {
|
|
|
263
360
|
*/
|
|
264
361
|
feePayer?: Keypair;
|
|
265
362
|
}
|
|
266
|
-
type ConnectStatus$
|
|
363
|
+
type ConnectStatus$2 = "ready" | "needs-device-approval";
|
|
267
364
|
/**
|
|
268
365
|
* Options for recovering a Solana account after losing every device signer.
|
|
269
366
|
* Mirrors `RecoveryOptions` (Starknet), adapted to the Solana path: the backup
|
|
@@ -308,7 +405,7 @@ interface RecoverSolanaOptions {
|
|
|
308
405
|
declare class CavosSolana {
|
|
309
406
|
readonly identity: Identity;
|
|
310
407
|
readonly address: string;
|
|
311
|
-
readonly status: ConnectStatus$
|
|
408
|
+
readonly status: ConnectStatus$2;
|
|
312
409
|
readonly connection: Connection;
|
|
313
410
|
private readonly adapter;
|
|
314
411
|
private readonly devicePubkey;
|
|
@@ -321,6 +418,35 @@ declare class CavosSolana {
|
|
|
321
418
|
static connect(opts: ConnectSolanaOptions): Promise<CavosSolana>;
|
|
322
419
|
/** Authorize an additional device signer (device-signed via precompile). */
|
|
323
420
|
addSigner(pubkey: DevicePublicKey): Promise<string>;
|
|
421
|
+
/**
|
|
422
|
+
* Enroll a passkey as an approver (2FA-style step-up). Device-signed + gasless;
|
|
423
|
+
* requires a ready device. Idempotent. Returns the passkey pubkey + tx hash.
|
|
424
|
+
*/
|
|
425
|
+
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams): Promise<{
|
|
426
|
+
publicKey: DevicePublicKey;
|
|
427
|
+
transactionHash?: string;
|
|
428
|
+
}>;
|
|
429
|
+
/** Register an already-enrolled passkey pubkey as an approver (gasless).
|
|
430
|
+
* Idempotent. Lets one passkey be registered across chains without re-prompting. */
|
|
431
|
+
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
432
|
+
transactionHash?: string;
|
|
433
|
+
}>;
|
|
434
|
+
/**
|
|
435
|
+
* From a fresh browser (status `needs-device-approval`), approve adding THIS
|
|
436
|
+
* device with the user's synced passkey. Gasless via the relayer — the bundle
|
|
437
|
+
* carries the passkey's WebAuthn assertion, so no device signature is needed.
|
|
438
|
+
*/
|
|
439
|
+
approveThisDeviceWithPasskey(passkey: PasskeySigner): Promise<string>;
|
|
440
|
+
/** This device's leaf + passkey nonce for a (possibly multi-chain) batch. */
|
|
441
|
+
passkeyLeafForThisDevice(): Promise<{
|
|
442
|
+
leaf: Uint8Array;
|
|
443
|
+
nonce: bigint;
|
|
444
|
+
}>;
|
|
445
|
+
/** Submit `add_signer_via_passkey` given a shared assertion + batch position.
|
|
446
|
+
* Used by `approveThisDeviceWithPasskey` and `approveDeviceEverywhere`. */
|
|
447
|
+
submitPasskeyApproval(assertion: PasskeyAssertion, leaves: Uint8Array[], leafIndex: number, _nonce: bigint): Promise<{
|
|
448
|
+
transactionHash: string;
|
|
449
|
+
}>;
|
|
324
450
|
/** Move `amount` lamports out of the account to `destination` (device-signed). */
|
|
325
451
|
execute(amount: bigint, destination: string): Promise<string>;
|
|
326
452
|
/**
|
|
@@ -362,6 +488,196 @@ declare class CavosSolana {
|
|
|
362
488
|
private send;
|
|
363
489
|
}
|
|
364
490
|
|
|
491
|
+
/** Cavos device-account primitives on Stellar / Soroban. */
|
|
492
|
+
/**
|
|
493
|
+
* Deployed `cavos-account-factory` contract id per network (see
|
|
494
|
+
* account-contracts/stellar/deployments). The factory is the fixed deployer that
|
|
495
|
+
* makes account addresses a deterministic function of (identity, device pubkey).
|
|
496
|
+
*/
|
|
497
|
+
declare const FACTORY_CONTRACT_ID: {
|
|
498
|
+
readonly "stellar-testnet": "CBCJIODXIEBOXXD66KCUCF7ZDYJARKI4ZIVQOVWPULOBH5XGNCDP6W3I";
|
|
499
|
+
readonly "stellar-mainnet": "";
|
|
500
|
+
};
|
|
501
|
+
/** Uploaded Wasm hash of `cavos-device-account` (informational / verification). */
|
|
502
|
+
declare const DEVICE_ACCOUNT_WASM_HASH: {
|
|
503
|
+
readonly "stellar-testnet": "2671b085578e59a385ef5a5664e42f0450322fe3249539f588e1263ed5a31dce";
|
|
504
|
+
readonly "stellar-mainnet": "";
|
|
505
|
+
};
|
|
506
|
+
declare const STELLAR_NETWORKS: {
|
|
507
|
+
readonly "stellar-testnet": {
|
|
508
|
+
readonly rpcUrl: "https://soroban-testnet.stellar.org";
|
|
509
|
+
readonly passphrase: "Test SDF Network ; September 2015";
|
|
510
|
+
};
|
|
511
|
+
readonly "stellar-mainnet": {
|
|
512
|
+
readonly rpcUrl: "https://soroban-rpc.mainnet.stellar.gateway.fm";
|
|
513
|
+
readonly passphrase: "Public Global Stellar Network ; September 2015";
|
|
514
|
+
};
|
|
515
|
+
};
|
|
516
|
+
type StellarNetwork = keyof typeof STELLAR_NETWORKS;
|
|
517
|
+
/** Native XLM Stellar Asset Contract (SAC) id per network — the token the demo
|
|
518
|
+
* moves. Any SEP-41 token contract works; this is a convenience default. */
|
|
519
|
+
declare const NATIVE_SAC_ID: {
|
|
520
|
+
readonly "stellar-testnet": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC";
|
|
521
|
+
readonly "stellar-mainnet": "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA";
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
interface StellarRelayerOptions {
|
|
525
|
+
/** Base URL of the Cavos backend exposing /api/stellar/relay. */
|
|
526
|
+
baseUrl: string;
|
|
527
|
+
/** Cavos App ID (authorizes the sponsored request). */
|
|
528
|
+
appId: string;
|
|
529
|
+
network: StellarNetwork;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Client for the Cavos Stellar sponsoring relayer. On Stellar the account is a
|
|
533
|
+
* *contract*, which cannot be a transaction source — so the relayer's own
|
|
534
|
+
* G-account is the transaction source AND fee payer. The user's silent device
|
|
535
|
+
* key never pays: it only signs the Soroban *authorization entry* (verified by
|
|
536
|
+
* the account's `__check_auth`), which is independent of who submits or pays.
|
|
537
|
+
* That gives a seedless, gasless experience with no fee-payer keypair on the
|
|
538
|
+
* integrator side — the same "relayer pays, device authorizes" split as Solana.
|
|
539
|
+
*
|
|
540
|
+
* The SDK builds the fully-assembled transaction (source = relayer, Soroban auth
|
|
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.
|
|
543
|
+
*/
|
|
544
|
+
declare class StellarRelayer {
|
|
545
|
+
private readonly opts;
|
|
546
|
+
private source?;
|
|
547
|
+
constructor(opts: StellarRelayerOptions);
|
|
548
|
+
/** The relayer's source/fee-payer G-account (fetched + cached from the backend). */
|
|
549
|
+
getSource(): Promise<string>;
|
|
550
|
+
/**
|
|
551
|
+
* POST the assembled, device-authorized transaction XDR to the relayer to sign
|
|
552
|
+
* the envelope + submit. Returns the confirmed transaction hash.
|
|
553
|
+
*/
|
|
554
|
+
submit(transactionXdr: string): Promise<string>;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
interface ConnectStellarOptions {
|
|
558
|
+
network: StellarNetwork;
|
|
559
|
+
/** Authenticated user (pass `identity` directly, or an `auth` provider). */
|
|
560
|
+
auth?: AuthProvider;
|
|
561
|
+
identity?: Identity;
|
|
562
|
+
appSalt: string;
|
|
563
|
+
appId?: string;
|
|
564
|
+
backendUrl?: string;
|
|
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>;
|
|
572
|
+
/**
|
|
573
|
+
* Gasless sponsorship via the Cavos relayer. When set (or when `appId` +
|
|
574
|
+
* `backendUrl` are given) the relayer is the transaction source + fee payer, so
|
|
575
|
+
* the integrator needs NO Stellar keypair — the silent device key (which holds
|
|
576
|
+
* no XLM) gets a seedless, gasless experience.
|
|
577
|
+
*/
|
|
578
|
+
relayer?: StellarRelayer;
|
|
579
|
+
/**
|
|
580
|
+
* Self-funded fallback: a Stellar `Keypair` that is the transaction source +
|
|
581
|
+
* fee payer. Used only when no `relayer` is configured (tests / advanced).
|
|
582
|
+
*/
|
|
583
|
+
sourceKeypair?: Keypair$1;
|
|
584
|
+
}
|
|
585
|
+
interface RecoverStellarOptions extends Omit<ConnectStellarOptions, "auth"> {
|
|
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";
|
|
592
|
+
/**
|
|
593
|
+
* High-level Stellar entry — the Soroban analogue of `Cavos.connect` /
|
|
594
|
+
* `CavosSolana.connect`. One call derives the deterministic device-bound account,
|
|
595
|
+
* deploys it via the factory if needed, registers it for cross-device
|
|
596
|
+
* recognition, and returns a ready handle whose silent P-256 device key
|
|
597
|
+
* authorizes every action through the account's `__check_auth`.
|
|
598
|
+
*
|
|
599
|
+
* const cavos = await CavosStellar.connect({ network: "stellar-testnet", identity, appSalt, relayer });
|
|
600
|
+
* if (cavos.status === "ready") await cavos.execute(10_000_000n, dest); // 1 XLM
|
|
601
|
+
*
|
|
602
|
+
* Gasless by default: with an `appId` the Cavos relayer is the tx source + fee
|
|
603
|
+
* payer. `sourceKeypair` is the self-funded fallback.
|
|
604
|
+
*/
|
|
605
|
+
declare class CavosStellar {
|
|
606
|
+
readonly identity: Identity;
|
|
607
|
+
readonly address: string;
|
|
608
|
+
readonly status: ConnectStatus$1;
|
|
609
|
+
readonly network: StellarNetwork;
|
|
610
|
+
private readonly adapter;
|
|
611
|
+
private readonly devicePubkey;
|
|
612
|
+
private readonly relayer?;
|
|
613
|
+
private readonly sourceKeypair?;
|
|
614
|
+
/** Discriminant for the `CavosWallet` union — narrows `execute()` per chain. */
|
|
615
|
+
readonly chain: "stellar";
|
|
616
|
+
private constructor();
|
|
617
|
+
get publicKey(): DevicePublicKey;
|
|
618
|
+
static connect(opts: ConnectStellarOptions): Promise<CavosStellar>;
|
|
619
|
+
/** Authorize an additional device signer (device-signed via `__check_auth`). */
|
|
620
|
+
addSigner(pubkey: DevicePublicKey): Promise<string>;
|
|
621
|
+
/**
|
|
622
|
+
* Enroll a passkey as an approver (2FA-style step-up). Device-signed + gasless;
|
|
623
|
+
* requires a ready device. Idempotent. Returns the passkey pubkey + tx hash.
|
|
624
|
+
*/
|
|
625
|
+
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams): Promise<{
|
|
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
|
+
}>;
|
|
634
|
+
/**
|
|
635
|
+
* From a fresh browser (status `needs-device-approval`), approve adding THIS
|
|
636
|
+
* device using the user's synced passkey. Gasless via the relayer — the call
|
|
637
|
+
* carries the WebAuthn assertion, so no device signature is needed. Returns the
|
|
638
|
+
* tx hash. No trip back to an already-authorized device.
|
|
639
|
+
*/
|
|
640
|
+
approveThisDeviceWithPasskey(passkey: PasskeySigner): Promise<string>;
|
|
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>;
|
|
657
|
+
/**
|
|
658
|
+
* Register the backup signer derived from `code` as an authorized signer of
|
|
659
|
+
* this account (device-signed). Idempotent. The code never leaves the device —
|
|
660
|
+
* only the derived public key travels on-chain. Mirrors the other chains.
|
|
661
|
+
*/
|
|
662
|
+
setupRecovery(code: string): Promise<string | undefined>;
|
|
663
|
+
/**
|
|
664
|
+
* Recover an account after losing every device signer: derive the backup key
|
|
665
|
+
* from `code`, use it (not the new device) to authorize `add_signer(newDevice)`,
|
|
666
|
+
* and return a ready handle bound to the new device. The address is unchanged.
|
|
667
|
+
*/
|
|
668
|
+
static recover(opts: RecoverStellarOptions): Promise<CavosStellar>;
|
|
669
|
+
/** The transaction source/fee-payer G-address (relayer or self-funded). */
|
|
670
|
+
private resolveSource;
|
|
671
|
+
/**
|
|
672
|
+
* Build → simulate → device-sign auth → assemble → submit an invoke-contract
|
|
673
|
+
* host function. `authAccount` is the account whose `__check_auth` must sign the
|
|
674
|
+
* operation's Soroban auth entry (undefined for a plain factory deploy).
|
|
675
|
+
*/
|
|
676
|
+
private submitHostFunction;
|
|
677
|
+
/** Submit a signed tx via RPC and poll to confirmation. Returns the hash. */
|
|
678
|
+
private sendAndConfirm;
|
|
679
|
+
}
|
|
680
|
+
|
|
365
681
|
/** A chain-native contract call (Starknet `Call`-shaped; generic for portability). */
|
|
366
682
|
interface ChainCall {
|
|
367
683
|
contractAddress: string;
|
|
@@ -445,14 +761,14 @@ interface PendingDeviceRequest {
|
|
|
445
761
|
}
|
|
446
762
|
|
|
447
763
|
/** The chains the unified `Cavos.connect` can target. */
|
|
448
|
-
type Chain = "starknet" | "solana";
|
|
764
|
+
type Chain = "starknet" | "solana" | "stellar";
|
|
449
765
|
/**
|
|
450
766
|
* Environment selector. `Cavos.connect` resolves it to the chain's concrete
|
|
451
767
|
* network: starknet → sepolia/mainnet, solana → solana-devnet/solana-mainnet.
|
|
452
768
|
*/
|
|
453
769
|
type NetworkEnv = "mainnet" | "testnet";
|
|
454
770
|
/** A connected wallet: discriminated by `chain`, so `execute()` stays native. */
|
|
455
|
-
type CavosWallet = Cavos | CavosSolana;
|
|
771
|
+
type CavosWallet = Cavos | CavosSolana | CavosStellar;
|
|
456
772
|
interface ConnectOptions {
|
|
457
773
|
/** Target chain. The returned wallet is discriminated by this same value. */
|
|
458
774
|
chain: Chain;
|
|
@@ -493,6 +809,12 @@ interface ConnectOptions {
|
|
|
493
809
|
relayer?: SolanaRelayer;
|
|
494
810
|
/** Self-funded fee-payer fallback when no relayer is configured. */
|
|
495
811
|
feePayer?: Keypair;
|
|
812
|
+
/** Gasless sponsorship relayer (defaults to the hosted one when `appId` set). */
|
|
813
|
+
stellarRelayer?: StellarRelayer;
|
|
814
|
+
/** Self-funded source/fee-payer Stellar keypair when no relayer is configured. */
|
|
815
|
+
stellarSourceKeypair?: Keypair$1;
|
|
816
|
+
/** Factory contract id override (else the per-network default). */
|
|
817
|
+
factoryId?: string;
|
|
496
818
|
}
|
|
497
819
|
/** Whether this device can already operate the wallet, or needs to be added. */
|
|
498
820
|
type ConnectStatus = "ready" | "needs-device-approval";
|
|
@@ -535,6 +857,8 @@ declare class Cavos {
|
|
|
535
857
|
readonly account: Account;
|
|
536
858
|
private readonly adapter;
|
|
537
859
|
private readonly devicePubkey;
|
|
860
|
+
/** Paymaster URL + API key, for the sponsored passkey-approval path. */
|
|
861
|
+
private readonly paymaster?;
|
|
538
862
|
/** Discriminant for the `CavosWallet` union — narrows `execute()` per chain. */
|
|
539
863
|
readonly chain: "starknet";
|
|
540
864
|
/** Request id of the pending device-addition, when status is needs-device-approval. */
|
|
@@ -562,6 +886,60 @@ declare class Cavos {
|
|
|
562
886
|
addSigner(pubkey: DevicePublicKey): Promise<{
|
|
563
887
|
transactionHash: string;
|
|
564
888
|
}>;
|
|
889
|
+
/**
|
|
890
|
+
* Enroll a passkey as an APPROVER so the user can later add devices from any
|
|
891
|
+
* browser (2FA-style step-up). Requires a ready device (the enrollment call is
|
|
892
|
+
* device-signed and gasless). Idempotent: a no-op if the passkey is already an
|
|
893
|
+
* approver. Call this whenever the app decides to prompt "turn on device
|
|
894
|
+
* approvals". Returns the passkey's public key + the enrollment tx hash.
|
|
895
|
+
*/
|
|
896
|
+
enrollPasskey(passkey: PasskeySigner, params: PasskeyEnrollParams): Promise<{
|
|
897
|
+
publicKey: DevicePublicKey;
|
|
898
|
+
transactionHash?: string;
|
|
899
|
+
}>;
|
|
900
|
+
/**
|
|
901
|
+
* Register an ALREADY-enrolled passkey public key as an approver (gasless,
|
|
902
|
+
* device-signed). Idempotent. Use this to register ONE passkey across multiple
|
|
903
|
+
* chains without re-prompting `passkey.enroll()` on each: enroll once, then
|
|
904
|
+
* call `addApprover(pubkey)` on each chain's wallet.
|
|
905
|
+
*/
|
|
906
|
+
addApprover(pubkey: DevicePublicKey): Promise<{
|
|
907
|
+
transactionHash?: string;
|
|
908
|
+
}>;
|
|
909
|
+
/**
|
|
910
|
+
* From a brand-new browser (status `needs-device-approval`), use the user's
|
|
911
|
+
* synced passkey to authorize adding THIS device — no trip back to an already-
|
|
912
|
+
* authorized device.
|
|
913
|
+
*
|
|
914
|
+
* `add_signer_via_passkey` is a public external authorized by the embedded
|
|
915
|
+
* WebAuthn assertion (no device signature), so by default we sponsor it through
|
|
916
|
+
* the Cavos paymaster's `paymaster_executeDirectTransaction` (the forwarder's
|
|
917
|
+
* `execute_sponsored` runs a generic call — it does NOT require SNIP-9). Pass a
|
|
918
|
+
* custom `submit` to route it through your own relayer instead. Returns the tx.
|
|
919
|
+
*/
|
|
920
|
+
approveThisDeviceWithPasskey(opts: {
|
|
921
|
+
passkey: PasskeySigner;
|
|
922
|
+
submit?: (call: ChainCall) => Promise<{
|
|
923
|
+
transactionHash: string;
|
|
924
|
+
}>;
|
|
925
|
+
}): Promise<{
|
|
926
|
+
transactionHash: string;
|
|
927
|
+
}>;
|
|
928
|
+
/** This device's leaf + the current passkey nonce, for a (possibly multi-chain)
|
|
929
|
+
* passkey approval batch. See `approveDeviceEverywhere`. */
|
|
930
|
+
passkeyLeafForThisDevice(): Promise<{
|
|
931
|
+
leaf: Uint8Array;
|
|
932
|
+
nonce: bigint;
|
|
933
|
+
}>;
|
|
934
|
+
/** Submit `add_signer_via_passkey` given a (shared) assertion + this chain's
|
|
935
|
+
* position in the batch. The assertion doesn't carry the passkey pubkey, so we
|
|
936
|
+
* recover both candidates and pick the enrolled approver via the on-chain view
|
|
937
|
+
* (no backend). Defaults to sponsoring through the paymaster. */
|
|
938
|
+
submitPasskeyApproval(assertion: PasskeyAssertion, leaves: Uint8Array[], leafIndex: number, nonce: bigint, submit?: (call: ChainCall) => Promise<{
|
|
939
|
+
transactionHash: string;
|
|
940
|
+
}>): Promise<{
|
|
941
|
+
transactionHash: string;
|
|
942
|
+
}>;
|
|
565
943
|
/**
|
|
566
944
|
* Register a self-custodial backup signer derived from `code`, so the account
|
|
567
945
|
* can be recovered after the user loses every device. Idempotent: if the
|
|
@@ -586,5 +964,31 @@ declare class Cavos {
|
|
|
586
964
|
*/
|
|
587
965
|
static recover(opts: RecoveryOptions): Promise<Cavos>;
|
|
588
966
|
}
|
|
967
|
+
/** A chain wallet that can approve THIS device via a passkey (implemented by
|
|
968
|
+
* `Cavos`, `CavosSolana`, `CavosStellar`). */
|
|
969
|
+
interface PasskeyApprovable {
|
|
970
|
+
readonly chain: string;
|
|
971
|
+
readonly status: string;
|
|
972
|
+
passkeyLeafForThisDevice(): Promise<{
|
|
973
|
+
leaf: Uint8Array;
|
|
974
|
+
nonce: bigint;
|
|
975
|
+
}>;
|
|
976
|
+
submitPasskeyApproval(assertion: PasskeyAssertion, leaves: Uint8Array[], leafIndex: number, nonce: bigint): Promise<{
|
|
977
|
+
transactionHash: string;
|
|
978
|
+
}>;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Approve THIS device across several chains with a SINGLE passkey prompt. Each
|
|
982
|
+
* chain is a separate account, so the device must be added per chain — but one
|
|
983
|
+
* WebAuthn assertion over the batch challenge (`sha256(concat(leaves))`) suffices
|
|
984
|
+
* for all of them. Only wallets whose status is `needs-device-approval` are
|
|
985
|
+
* touched. Returns the per-chain tx hashes.
|
|
986
|
+
*
|
|
987
|
+
* await approveDeviceEverywhere([starknet, solana, stellar], passkey);
|
|
988
|
+
*/
|
|
989
|
+
declare function approveDeviceEverywhere(wallets: PasskeyApprovable[], passkey: PasskeySigner): Promise<{
|
|
990
|
+
chain: string;
|
|
991
|
+
transactionHash: string;
|
|
992
|
+
}[]>;
|
|
589
993
|
|
|
590
|
-
export { type AuthProvider as A,
|
|
994
|
+
export { batchChallenge as $, type AuthProvider as A, type RecoverStellarOptions as B, type ChainAdapter as C, type DevicePublicKey as D, type EnrolledPasskey as E, FACTORY_CONTRACT_ID as F, type RecoveryOptions as G, SECP256R1_PROGRAM_ID as H, type Identity as I, SOLANA_NETWORKS as J, STELLAR_NETWORKS as K, SolanaAdapter as L, type SolanaAdapterOptions as M, NATIVE_SAC_ID 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, StellarRelayer as V, type WalletRegistry as W, type StellarRelayerOptions as X, anchorDiscriminator as Y, approveDeviceEverywhere as Z, base64urlEncode as _, type RecoveryClient as a, buildSecp256r1Instruction as a0, compressedPubkey as a1, encodeLowSSignature as a2, lowS as a3, recoverCandidatePublicKeys as a4, serializeInstructions as a5, webauthnDigest as a6, type DeviceSigner as b, type DeviceSignature as c, type ComputeAddressParams as d, type ChainCall as e, type PasskeyAssertion as f, Cavos as g, CavosSolana as h, CavosStellar as i, type CavosWallet as j, type Chain as k, type ConnectOptions as l, type ConnectSolanaOptions as m, type ConnectStatus as n, type ConnectStellarOptions as o, DEVICE_ACCOUNT_PROGRAM_ID as p, DEVICE_ACCOUNT_WASM_HASH as q, InMemoryWalletRegistry as r, type InstructionAccount as s, type InstructionData as t, type NetworkEnv as u, type PasskeyApprovable as v, type PasskeyEnrollParams as w, PasskeySigner as x, type PasskeySignerOptions as y, type RecoverSolanaOptions as z };
|