@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
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export { BackupSigner, Cavos, CavosAuth, CavosSolana, CavosStellar, DEVICE_ACCOUNT_CLASS_HASH, DEVICE_ACCOUNT_PROGRAM_ID, DEVICE_ACCOUNT_WASM_HASH, FACTORY_CONTRACT_ID, HttpRecoveryClient, HttpWalletRegistry, InMemoryWalletRegistry, NATIVE_SAC_ID, SECP256R1_PROGRAM_ID, SOLANA_NETWORKS, STARKNET_NETWORKS, STELLAR_NETWORKS, SolanaAdapter, SolanaRelayer, StarknetAdapter, StarknetDeviceSigner, StellarAdapter, StellarRelayer, UDC_ADDRESS, WebCryptoSigner, anchorDiscriminator, approveDeviceEverywhere, base64urlEncode, batchChallenge, bigIntTo32Bytes, buildSecp256r1Instruction, bytesToBigInt, bytesToHex, compressedPubkey, deriveAddressSeed, deriveAddressSeedSolana, deriveAddressSeedStellar, deriveBackupKey, deviceSignatureScVal, encodeLowSSignature, encodeLowSSignature2 as encodeStellarLowSSignature, generateRecoveryCode, hexToBytes, lowS, recoverCandidatePublicKeys, recoverYParity, sec1Pubkey, serializeInstructions, signatureToFelts, u256ToFelts, webauthnDigest } from './chunk-BNGLH3Q3.mjs';
|
|
3
|
-
import { sha256 } from '@noble/hashes/sha256';
|
|
1
|
+
export { BackupSigner, Cavos, CavosAuth, CavosSolana, CavosStellar, DEVICE_ACCOUNT_CLASS_HASH, DEVICE_ACCOUNT_PROGRAM_ID, HORIZON_URL, HttpRecoveryClient, HttpWalletRegistry, InMemoryWalletRegistry, LocalDeviceUnwrapKey, PasskeyPrf, PasskeySigner, SECP256R1_PROGRAM_ID, SOLANA_NETWORKS, STARKNET_NETWORKS, STELLAR_NETWORKS, SolanaAdapter, SolanaRelayer, StarknetAdapter, StarknetDeviceSigner, StellarAdapter, StellarRelayer, UDC_ADDRESS, WebCryptoDeviceUnwrapKey, WebCryptoSigner, XLM_DECIMALS, anchorDiscriminator, approveDeviceEverywhere, base64urlEncode, batchChallenge, bigIntTo32Bytes, buildSecp256r1Instruction, bytesToBigInt, bytesToHex, compressedPubkey, deriveAddressSeed, deriveAddressSeedSolana, deriveAddressSeedStellar, deriveBackupKey, derivePasskeyKEK, deriveRecoveryKEK, deriveStellarAddress, deriveStellarMasterKeypair, deviceSlotId, eciesUnwrapDEK, eciesWrapDEK, encodeLowSSignature, fromDataEntries, generateControlKey, generateDEK, generateRecoveryCode, hexToBytes, lowS, openControlSeed, recoverCandidatePublicKeys, recoverYParity, sealControlSeed, serializeInstructions, signatureToFelts, toDataEntries, u256ToFelts, unwrapDEK, webauthnDigest, wrapDEK } from './chunk-M5BGBODC.mjs';
|
|
4
2
|
|
|
5
3
|
// src/auth/AuthProvider.ts
|
|
6
4
|
var StaticIdentity = class {
|
|
@@ -11,91 +9,7 @@ var StaticIdentity = class {
|
|
|
11
9
|
return this.identity;
|
|
12
10
|
}
|
|
13
11
|
};
|
|
14
|
-
var PasskeySigner = class {
|
|
15
|
-
constructor(opts = {}) {
|
|
16
|
-
if (typeof window === "undefined" || !navigator.credentials) {
|
|
17
|
-
throw new Error("kit/passkey: WebAuthn is only available in a browser");
|
|
18
|
-
}
|
|
19
|
-
this.rpId = opts.rpId ?? window.location.hostname;
|
|
20
|
-
this.rpName = opts.rpName ?? this.rpId;
|
|
21
|
-
if (isIpAddress(this.rpId)) {
|
|
22
|
-
throw new Error(
|
|
23
|
-
`kit/passkey: passkeys can't use an IP address as the domain ("${this.rpId}"). Use http://localhost, a real HTTPS domain, or a tunnel (cloudflared/ngrok) \u2014 or pass an explicit \`rpId\`. (The silent device key works over an IP; passkeys don't.)`
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/** True if this platform advertises a usable passkey (platform authenticator). */
|
|
28
|
-
static async isSupported() {
|
|
29
|
-
if (typeof window === "undefined" || !window.PublicKeyCredential) return false;
|
|
30
|
-
try {
|
|
31
|
-
return await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
|
|
32
|
-
} catch {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/** Create a new synced passkey and return its P-256 public key. */
|
|
37
|
-
async enroll(params) {
|
|
38
|
-
const challenge = crypto.getRandomValues(new Uint8Array(32));
|
|
39
|
-
const cred = await navigator.credentials.create({
|
|
40
|
-
publicKey: {
|
|
41
|
-
challenge: buf(challenge),
|
|
42
|
-
rp: { id: this.rpId, name: this.rpName },
|
|
43
|
-
user: {
|
|
44
|
-
id: buf(userHandle(params.userId)),
|
|
45
|
-
name: params.userName,
|
|
46
|
-
displayName: params.displayName ?? params.userName
|
|
47
|
-
},
|
|
48
|
-
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
|
|
49
|
-
// ES256 (P-256)
|
|
50
|
-
authenticatorSelection: {
|
|
51
|
-
residentKey: "required",
|
|
52
|
-
requireResidentKey: true,
|
|
53
|
-
userVerification: "preferred"
|
|
54
|
-
},
|
|
55
|
-
attestation: "none"
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
if (!cred) throw new Error("kit/passkey: enrollment cancelled");
|
|
59
|
-
const response = cred.response;
|
|
60
|
-
const spki = new Uint8Array(response.getPublicKey());
|
|
61
|
-
return { publicKey: spkiToPublicKey(spki), credentialId: new Uint8Array(cred.rawId) };
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Produce a WebAuthn assertion over `challenge` (a 32-byte value the caller
|
|
65
|
-
* derives from the signer being added + the on-chain nonce). Uses discoverable
|
|
66
|
-
* credentials — no `allowCredentials` — so it works on a brand-new browser.
|
|
67
|
-
*/
|
|
68
|
-
async assert(challenge) {
|
|
69
|
-
const cred = await navigator.credentials.get({
|
|
70
|
-
publicKey: {
|
|
71
|
-
challenge: buf(challenge),
|
|
72
|
-
rpId: this.rpId,
|
|
73
|
-
allowCredentials: [],
|
|
74
|
-
userVerification: "preferred"
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
if (!cred) throw new Error("kit/passkey: assertion cancelled");
|
|
78
|
-
const response = cred.response;
|
|
79
|
-
const authenticatorData = new Uint8Array(response.authenticatorData);
|
|
80
|
-
const clientDataJSON = new Uint8Array(response.clientDataJSON);
|
|
81
|
-
const { r, s } = derToRs(new Uint8Array(response.signature));
|
|
82
|
-
const challengeOffset = challengeOffsetOf(clientDataJSON, base64urlEncode(challenge));
|
|
83
|
-
return { authenticatorData, clientDataJSON, r, s, challengeOffset };
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
function isIpAddress(host) {
|
|
87
|
-
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(host)) return true;
|
|
88
|
-
if (host.includes(":")) return true;
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
function userHandle(userId) {
|
|
92
|
-
const bytes = new TextEncoder().encode(userId);
|
|
93
|
-
return bytes.length <= 64 ? bytes : sha256(bytes);
|
|
94
|
-
}
|
|
95
|
-
function buf(bytes) {
|
|
96
|
-
return bytes.slice();
|
|
97
|
-
}
|
|
98
12
|
|
|
99
|
-
export {
|
|
13
|
+
export { StaticIdentity };
|
|
100
14
|
//# sourceMappingURL=index.mjs.map
|
|
101
15
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/AuthProvider.ts","../src/signer/PasskeySigner.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Identity for a Cavos wallet. Login (email / social / OTP) only ever produces a\n * stable `userId`; that's all the wallet needs to derive its address. Auth never\n * touches signing — the device key does that, silently.\n *\n * Privy-style UX: the user \"logs in\" and the wallet is provisioned behind the\n * scenes (device key + auto-deployed smart account). The app never handles keys.\n */\nexport interface Identity {\n /** Stable, backend-managed user identifier. */\n userId: string;\n /** Optional metadata (email, provider) for display only. */\n email?: string;\n provider?: \"google\" | \"apple\" | \"email\" | \"otp\" | string;\n}\n\n/**\n * Authenticates a user and returns their stable identity. Implementations:\n * - `CavosAuth` (hosted, mirrors `@cavos/react`: Google/Apple/email/OTP via the\n * Cavos backend) — the default, Privy-like experience.\n * - any custom provider (the app already authenticated the user elsewhere).\n */\nexport interface AuthProvider {\n authenticate(): Promise<Identity>;\n}\n\n/** Trivial provider when the app already has the user's stable id. */\nexport class StaticIdentity implements AuthProvider {\n constructor(private readonly identity: Identity) {}\n async authenticate(): Promise<Identity> {\n return this.identity;\n }\n}\n","import { sha256 } from \"@noble/hashes/sha256\";\nimport type { DevicePublicKey } from \"./DeviceSigner\";\nimport {\n base64urlEncode,\n challengeOffsetOf,\n derToRs,\n spkiToPublicKey,\n type PasskeyAssertion,\n} from \"../crypto/webauthn\";\n\nexport interface PasskeySignerOptions {\n /** Relying-Party id (usually the eTLD+1). Defaults to `window.location.hostname`. */\n rpId?: string;\n /** Human-readable RP name shown in the OS passkey UI. */\n rpName?: string;\n}\n\nexport interface PasskeyEnrollParams {\n /** Stable user handle for the credential (e.g. the account address or userId). */\n userId: string;\n /** Account name shown in the OS passkey UI (e.g. an email). */\n userName: string;\n displayName?: string;\n}\n\nexport interface EnrolledPasskey {\n publicKey: DevicePublicKey;\n credentialId: Uint8Array;\n}\n\n/**\n * Browser passkey signer. Creates a discoverable (resident) secp256r1 credential\n * that syncs across the user's devices (iCloud Keychain / Google Password\n * Manager), and produces WebAuthn assertions used to authorize `add_signer`.\n *\n * This is a step-up primitive: the app decides WHEN to enroll (e.g. after\n * onboarding, as a \"turn on device approvals\" / 2FA moment). Enrollment\n * registers the passkey on-chain as an approver; later, from any browser, an\n * assertion approves adding that browser's new device key.\n */\nexport class PasskeySigner {\n private readonly rpId: string;\n private readonly rpName: string;\n\n constructor(opts: PasskeySignerOptions = {}) {\n if (typeof window === \"undefined\" || !navigator.credentials) {\n throw new Error(\"kit/passkey: WebAuthn is only available in a browser\");\n }\n this.rpId = opts.rpId ?? window.location.hostname;\n this.rpName = opts.rpName ?? this.rpId;\n // WebAuthn requires the RP ID to be a registrable domain (or \"localhost\").\n // An IP address always fails with a cryptic \"invalid domain\" — surface an\n // actionable message instead (common when devs test over a LAN IP).\n if (isIpAddress(this.rpId)) {\n throw new Error(\n `kit/passkey: passkeys can't use an IP address as the domain (\"${this.rpId}\"). ` +\n \"Use http://localhost, a real HTTPS domain, or a tunnel (cloudflared/ngrok) — \" +\n \"or pass an explicit `rpId`. (The silent device key works over an IP; passkeys don't.)\",\n );\n }\n }\n\n /** True if this platform advertises a usable passkey (platform authenticator). */\n static async isSupported(): Promise<boolean> {\n if (typeof window === \"undefined\" || !window.PublicKeyCredential) return false;\n try {\n return await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();\n } catch {\n return false;\n }\n }\n\n /** Create a new synced passkey and return its P-256 public key. */\n async enroll(params: PasskeyEnrollParams): Promise<EnrolledPasskey> {\n const challenge = crypto.getRandomValues(new Uint8Array(32));\n const cred = (await navigator.credentials.create({\n publicKey: {\n challenge: buf(challenge),\n rp: { id: this.rpId, name: this.rpName },\n user: {\n id: buf(userHandle(params.userId)),\n name: params.userName,\n displayName: params.displayName ?? params.userName,\n },\n pubKeyCredParams: [{ type: \"public-key\", alg: -7 }], // ES256 (P-256)\n authenticatorSelection: {\n residentKey: \"required\",\n requireResidentKey: true,\n userVerification: \"preferred\",\n },\n attestation: \"none\",\n },\n })) as PublicKeyCredential | null;\n if (!cred) throw new Error(\"kit/passkey: enrollment cancelled\");\n\n const response = cred.response as AuthenticatorAttestationResponse;\n const spki = new Uint8Array(response.getPublicKey()!);\n return { publicKey: spkiToPublicKey(spki), credentialId: new Uint8Array(cred.rawId) };\n }\n\n /**\n * Produce a WebAuthn assertion over `challenge` (a 32-byte value the caller\n * derives from the signer being added + the on-chain nonce). Uses discoverable\n * credentials — no `allowCredentials` — so it works on a brand-new browser.\n */\n async assert(challenge: Uint8Array): Promise<PasskeyAssertion> {\n const cred = (await navigator.credentials.get({\n publicKey: {\n challenge: buf(challenge),\n rpId: this.rpId,\n allowCredentials: [],\n userVerification: \"preferred\",\n },\n })) as PublicKeyCredential | null;\n if (!cred) throw new Error(\"kit/passkey: assertion cancelled\");\n\n const response = cred.response as AuthenticatorAssertionResponse;\n const authenticatorData = new Uint8Array(response.authenticatorData);\n const clientDataJSON = new Uint8Array(response.clientDataJSON);\n const { r, s } = derToRs(new Uint8Array(response.signature));\n const challengeOffset = challengeOffsetOf(clientDataJSON, base64urlEncode(challenge));\n return { authenticatorData, clientDataJSON, r, s, challengeOffset };\n }\n}\n\n/**\n * WebAuthn requires the user handle to be 1..64 bytes. `userId` may be longer\n * (e.g. a 66-char Starknet address), so hash anything over 64 bytes to a stable\n * 32-byte handle. The handle is opaque — only its stability matters.\n */\n/** True for IPv4/IPv6 literals — WebAuthn rejects these as an RP ID. */\nfunction isIpAddress(host: string): boolean {\n if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(host)) return true; // IPv4\n if (host.includes(\":\")) return true; // IPv6 literal\n return false;\n}\n\nfunction userHandle(userId: string): Uint8Array {\n const bytes = new TextEncoder().encode(userId);\n return bytes.length <= 64 ? bytes : sha256(bytes);\n}\n\n/** Coerce a `Uint8Array` to the `BufferSource` the WebAuthn DOM types want\n * (works around the TS5.7 `ArrayBufferLike` vs `ArrayBuffer` mismatch). */\nfunction buf(bytes: Uint8Array): BufferSource {\n return bytes.slice() as unknown as BufferSource;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/AuthProvider.ts"],"names":[],"mappings":";;;AA2BO,IAAM,iBAAN,MAA6C;AAAA,EAClD,YAA6B,QAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAAqB;AAAA,EAClD,MAAM,YAAA,GAAkC;AACtC,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AACF","file":"index.mjs","sourcesContent":["/**\n * Identity for a Cavos wallet. Login (email / social / OTP) only ever produces a\n * stable `userId`; that's all the wallet needs to derive its address. Auth never\n * touches signing — the device key does that, silently.\n *\n * Privy-style UX: the user \"logs in\" and the wallet is provisioned behind the\n * scenes (device key + auto-deployed smart account). The app never handles keys.\n */\nexport interface Identity {\n /** Stable, backend-managed user identifier. */\n userId: string;\n /** Optional metadata (email, provider) for display only. */\n email?: string;\n provider?: \"google\" | \"apple\" | \"email\" | \"otp\" | string;\n}\n\n/**\n * Authenticates a user and returns their stable identity. Implementations:\n * - `CavosAuth` (hosted, mirrors `@cavos/react`: Google/Apple/email/OTP via the\n * Cavos backend) — the default, Privy-like experience.\n * - any custom provider (the app already authenticated the user elsewhere).\n */\nexport interface AuthProvider {\n authenticate(): Promise<Identity>;\n}\n\n/** Trivial provider when the app already has the user's stable id. */\nexport class StaticIdentity implements AuthProvider {\n constructor(private readonly identity: Identity) {}\n async authenticate(): Promise<Identity> {\n return this.identity;\n }\n}\n"]}
|
package/dist/react/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import react__default, { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { l as Chain, N as NetworkEnv, k as CavosWallet, e as ChainCall, r as ExecuteOptions, x as PasskeySigner, w as PasskeyEnrollParams } from '../Cavos-D20EtgOK.mjs';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@solana/web3.js';
|
|
6
6
|
import '@stellar/stellar-sdk';
|
|
@@ -44,6 +44,12 @@ interface WalletStatus {
|
|
|
44
44
|
awaitingApproval: boolean;
|
|
45
45
|
/** The pending device-addition request id, when awaitingApproval. */
|
|
46
46
|
pendingRequestId: string | null;
|
|
47
|
+
/** True if the account already has a passkey enrolled as an approver, so the
|
|
48
|
+
* modal can offer passkey approval over email on the new-device path. */
|
|
49
|
+
hasPasskey: boolean;
|
|
50
|
+
/** True right after a brand-new account is created (first sign-up), so the UI
|
|
51
|
+
* can offer a one-time "secure your account" step. Cleared once handled. */
|
|
52
|
+
isNewAccount: boolean;
|
|
47
53
|
}
|
|
48
54
|
interface UserInfo {
|
|
49
55
|
userId: string;
|
|
@@ -56,12 +62,12 @@ interface CavosContextValue {
|
|
|
56
62
|
closeModal: () => void;
|
|
57
63
|
isAuthenticated: boolean;
|
|
58
64
|
user: UserInfo | null;
|
|
59
|
-
/** The active chain ('starknet' | 'solana'). */
|
|
65
|
+
/** The active chain ('starknet' | 'solana' | 'stellar'). */
|
|
60
66
|
chain: Chain;
|
|
61
67
|
/**
|
|
62
|
-
* The
|
|
63
|
-
* chain-native calls (e.g. Solana `wallet.execute(amount,
|
|
64
|
-
* `
|
|
68
|
+
* The connected wallet, discriminated by `wallet.chain`. Narrow on
|
|
69
|
+
* `wallet.chain` before chain-native calls (e.g. Solana `wallet.execute(amount,
|
|
70
|
+
* dest)`). Null until connected.
|
|
65
71
|
*/
|
|
66
72
|
wallet: CavosWallet | null;
|
|
67
73
|
address: string | null;
|
|
@@ -82,8 +88,13 @@ interface CavosContextValue {
|
|
|
82
88
|
verifyOtp: (email: string, code: string) => Promise<void>;
|
|
83
89
|
/** Resolve identity from an OAuth callback (?auth_data=…) and deploy. */
|
|
84
90
|
handleCallback: (authData: string) => Promise<void>;
|
|
85
|
-
/**
|
|
86
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Execute a multicall signed by the device key (Starknet-only — on Solana /
|
|
93
|
+
* Stellar call `wallet.execute(...)` directly). Sponsored (gasless) by default;
|
|
94
|
+
* pass `{ sponsored: false }` to submit directly with the account paying its
|
|
95
|
+
* own fee.
|
|
96
|
+
*/
|
|
97
|
+
execute: (calls: ChainCall[], opts?: ExecuteOptions) => Promise<{
|
|
87
98
|
transactionHash: string;
|
|
88
99
|
}>;
|
|
89
100
|
/** Authorize another device signer on this wallet (sponsored add_signer). */
|
|
@@ -96,9 +107,8 @@ interface CavosContextValue {
|
|
|
96
107
|
/** Re-request the device-approval email for the current pending request. */
|
|
97
108
|
resendDeviceApproval: () => Promise<void>;
|
|
98
109
|
/**
|
|
99
|
-
* Enroll a passkey as an approver (2FA-style step-up).
|
|
100
|
-
*
|
|
101
|
-
* Requires a ready device; returns the passkey's public key.
|
|
110
|
+
* Enroll a passkey as an approver (2FA-style step-up). Requires a ready device;
|
|
111
|
+
* returns the passkey's public key.
|
|
102
112
|
*/
|
|
103
113
|
enrollPasskey: (passkey: PasskeySigner, params: PasskeyEnrollParams) => Promise<{
|
|
104
114
|
publicKey: {
|
|
@@ -107,46 +117,49 @@ interface CavosContextValue {
|
|
|
107
117
|
};
|
|
108
118
|
transactionHash?: string;
|
|
109
119
|
}>;
|
|
120
|
+
/** Whether this device can use a platform passkey (Face ID / Touch ID / PIN). */
|
|
121
|
+
passkeySupported: boolean;
|
|
110
122
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* requires a `submit` relayer callback; Solana/Stellar go through the
|
|
114
|
-
* configured relayer). Returns the tx hash.
|
|
123
|
+
* Modal-friendly wrapper: enroll a synced passkey as an approver using the
|
|
124
|
+
* signed-in user's identity + the app name. Requires a ready device.
|
|
115
125
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
enrollPasskeyDefault: () => Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Modal-friendly wrapper for the new-device flow: prompt the user's synced
|
|
129
|
+
* passkey to approve THIS device, then refresh to a ready state. Sponsored by
|
|
130
|
+
* the default paymaster/relayer.
|
|
131
|
+
*/
|
|
132
|
+
approveDeviceWithPasskey: () => Promise<void>;
|
|
121
133
|
/**
|
|
122
|
-
* Register a backup signer derived from
|
|
123
|
-
*
|
|
124
|
-
* Resolves with the code so the caller can display it.
|
|
134
|
+
* Register a backup signer derived from a generated recovery code (gasless).
|
|
135
|
+
* Resolves with the code so the caller can display it once.
|
|
125
136
|
*/
|
|
126
137
|
setupRecovery: () => Promise<string>;
|
|
127
138
|
/**
|
|
128
|
-
* Recover access after losing every device. Requires the recovery code.
|
|
129
|
-
* the
|
|
139
|
+
* Recover access after losing every device. Requires the recovery code. Brings
|
|
140
|
+
* the provider to a ready state.
|
|
130
141
|
*/
|
|
131
142
|
recover: (code: string) => Promise<void>;
|
|
132
143
|
logout: () => void;
|
|
133
144
|
}
|
|
134
145
|
interface CavosProviderProps {
|
|
146
|
+
/** A single chain config. The provider manages exactly one chain. */
|
|
135
147
|
config: CavosConfig;
|
|
136
148
|
modal?: CavosModalConfig;
|
|
137
149
|
children: ReactNode;
|
|
138
150
|
}
|
|
139
151
|
/**
|
|
140
|
-
* Drop-in Cavos provider. Wrap your app once; descendants call
|
|
152
|
+
* Drop-in Cavos provider for ONE chain. Wrap your app once; descendants call
|
|
153
|
+
* `useCavos()`.
|
|
141
154
|
*
|
|
142
|
-
* <CavosProvider config={{ network: '
|
|
143
|
-
* modal={{ appName: 'My App', theme: 'dark'
|
|
155
|
+
* <CavosProvider config={{ chain: 'solana', network: 'testnet', appId, appSalt }}
|
|
156
|
+
* modal={{ appName: 'My App', theme: 'dark' }}>
|
|
144
157
|
* <App />
|
|
145
158
|
* </CavosProvider>
|
|
146
159
|
*
|
|
147
160
|
* Behind the scenes: login (social / email) resolves a stable identity, the kit
|
|
148
|
-
* deploys a device-signer smart account gaslessly, and
|
|
149
|
-
* gasless
|
|
161
|
+
* deploys a device-signer smart account gaslessly, and the wallet handle submits
|
|
162
|
+
* gasless transactions signed silently by the browser's device key.
|
|
150
163
|
*/
|
|
151
164
|
declare function CavosProvider({ config, modal, children }: CavosProviderProps): react.JSX.Element;
|
|
152
165
|
declare function useCavos(): CavosContextValue;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import react__default, { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { l as Chain, N as NetworkEnv, k as CavosWallet, e as ChainCall, r as ExecuteOptions, x as PasskeySigner, w as PasskeyEnrollParams } from '../Cavos-D20EtgOK.js';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@solana/web3.js';
|
|
6
6
|
import '@stellar/stellar-sdk';
|
|
@@ -44,6 +44,12 @@ interface WalletStatus {
|
|
|
44
44
|
awaitingApproval: boolean;
|
|
45
45
|
/** The pending device-addition request id, when awaitingApproval. */
|
|
46
46
|
pendingRequestId: string | null;
|
|
47
|
+
/** True if the account already has a passkey enrolled as an approver, so the
|
|
48
|
+
* modal can offer passkey approval over email on the new-device path. */
|
|
49
|
+
hasPasskey: boolean;
|
|
50
|
+
/** True right after a brand-new account is created (first sign-up), so the UI
|
|
51
|
+
* can offer a one-time "secure your account" step. Cleared once handled. */
|
|
52
|
+
isNewAccount: boolean;
|
|
47
53
|
}
|
|
48
54
|
interface UserInfo {
|
|
49
55
|
userId: string;
|
|
@@ -56,12 +62,12 @@ interface CavosContextValue {
|
|
|
56
62
|
closeModal: () => void;
|
|
57
63
|
isAuthenticated: boolean;
|
|
58
64
|
user: UserInfo | null;
|
|
59
|
-
/** The active chain ('starknet' | 'solana'). */
|
|
65
|
+
/** The active chain ('starknet' | 'solana' | 'stellar'). */
|
|
60
66
|
chain: Chain;
|
|
61
67
|
/**
|
|
62
|
-
* The
|
|
63
|
-
* chain-native calls (e.g. Solana `wallet.execute(amount,
|
|
64
|
-
* `
|
|
68
|
+
* The connected wallet, discriminated by `wallet.chain`. Narrow on
|
|
69
|
+
* `wallet.chain` before chain-native calls (e.g. Solana `wallet.execute(amount,
|
|
70
|
+
* dest)`). Null until connected.
|
|
65
71
|
*/
|
|
66
72
|
wallet: CavosWallet | null;
|
|
67
73
|
address: string | null;
|
|
@@ -82,8 +88,13 @@ interface CavosContextValue {
|
|
|
82
88
|
verifyOtp: (email: string, code: string) => Promise<void>;
|
|
83
89
|
/** Resolve identity from an OAuth callback (?auth_data=…) and deploy. */
|
|
84
90
|
handleCallback: (authData: string) => Promise<void>;
|
|
85
|
-
/**
|
|
86
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Execute a multicall signed by the device key (Starknet-only — on Solana /
|
|
93
|
+
* Stellar call `wallet.execute(...)` directly). Sponsored (gasless) by default;
|
|
94
|
+
* pass `{ sponsored: false }` to submit directly with the account paying its
|
|
95
|
+
* own fee.
|
|
96
|
+
*/
|
|
97
|
+
execute: (calls: ChainCall[], opts?: ExecuteOptions) => Promise<{
|
|
87
98
|
transactionHash: string;
|
|
88
99
|
}>;
|
|
89
100
|
/** Authorize another device signer on this wallet (sponsored add_signer). */
|
|
@@ -96,9 +107,8 @@ interface CavosContextValue {
|
|
|
96
107
|
/** Re-request the device-approval email for the current pending request. */
|
|
97
108
|
resendDeviceApproval: () => Promise<void>;
|
|
98
109
|
/**
|
|
99
|
-
* Enroll a passkey as an approver (2FA-style step-up).
|
|
100
|
-
*
|
|
101
|
-
* Requires a ready device; returns the passkey's public key.
|
|
110
|
+
* Enroll a passkey as an approver (2FA-style step-up). Requires a ready device;
|
|
111
|
+
* returns the passkey's public key.
|
|
102
112
|
*/
|
|
103
113
|
enrollPasskey: (passkey: PasskeySigner, params: PasskeyEnrollParams) => Promise<{
|
|
104
114
|
publicKey: {
|
|
@@ -107,46 +117,49 @@ interface CavosContextValue {
|
|
|
107
117
|
};
|
|
108
118
|
transactionHash?: string;
|
|
109
119
|
}>;
|
|
120
|
+
/** Whether this device can use a platform passkey (Face ID / Touch ID / PIN). */
|
|
121
|
+
passkeySupported: boolean;
|
|
110
122
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* requires a `submit` relayer callback; Solana/Stellar go through the
|
|
114
|
-
* configured relayer). Returns the tx hash.
|
|
123
|
+
* Modal-friendly wrapper: enroll a synced passkey as an approver using the
|
|
124
|
+
* signed-in user's identity + the app name. Requires a ready device.
|
|
115
125
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
enrollPasskeyDefault: () => Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Modal-friendly wrapper for the new-device flow: prompt the user's synced
|
|
129
|
+
* passkey to approve THIS device, then refresh to a ready state. Sponsored by
|
|
130
|
+
* the default paymaster/relayer.
|
|
131
|
+
*/
|
|
132
|
+
approveDeviceWithPasskey: () => Promise<void>;
|
|
121
133
|
/**
|
|
122
|
-
* Register a backup signer derived from
|
|
123
|
-
*
|
|
124
|
-
* Resolves with the code so the caller can display it.
|
|
134
|
+
* Register a backup signer derived from a generated recovery code (gasless).
|
|
135
|
+
* Resolves with the code so the caller can display it once.
|
|
125
136
|
*/
|
|
126
137
|
setupRecovery: () => Promise<string>;
|
|
127
138
|
/**
|
|
128
|
-
* Recover access after losing every device. Requires the recovery code.
|
|
129
|
-
* the
|
|
139
|
+
* Recover access after losing every device. Requires the recovery code. Brings
|
|
140
|
+
* the provider to a ready state.
|
|
130
141
|
*/
|
|
131
142
|
recover: (code: string) => Promise<void>;
|
|
132
143
|
logout: () => void;
|
|
133
144
|
}
|
|
134
145
|
interface CavosProviderProps {
|
|
146
|
+
/** A single chain config. The provider manages exactly one chain. */
|
|
135
147
|
config: CavosConfig;
|
|
136
148
|
modal?: CavosModalConfig;
|
|
137
149
|
children: ReactNode;
|
|
138
150
|
}
|
|
139
151
|
/**
|
|
140
|
-
* Drop-in Cavos provider. Wrap your app once; descendants call
|
|
152
|
+
* Drop-in Cavos provider for ONE chain. Wrap your app once; descendants call
|
|
153
|
+
* `useCavos()`.
|
|
141
154
|
*
|
|
142
|
-
* <CavosProvider config={{ network: '
|
|
143
|
-
* modal={{ appName: 'My App', theme: 'dark'
|
|
155
|
+
* <CavosProvider config={{ chain: 'solana', network: 'testnet', appId, appSalt }}
|
|
156
|
+
* modal={{ appName: 'My App', theme: 'dark' }}>
|
|
144
157
|
* <App />
|
|
145
158
|
* </CavosProvider>
|
|
146
159
|
*
|
|
147
160
|
* Behind the scenes: login (social / email) resolves a stable identity, the kit
|
|
148
|
-
* deploys a device-signer smart account gaslessly, and
|
|
149
|
-
* gasless
|
|
161
|
+
* deploys a device-signer smart account gaslessly, and the wallet handle submits
|
|
162
|
+
* gasless transactions signed silently by the browser's device key.
|
|
150
163
|
*/
|
|
151
164
|
declare function CavosProvider({ config, modal, children }: CavosProviderProps): react.JSX.Element;
|
|
152
165
|
declare function useCavos(): CavosContextValue;
|