decane-connect-kit 1.0.3 → 2.0.0

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/index.d.cts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as _simplewebauthn_browser from '@simplewebauthn/browser';
1
2
  import React, { ReactNode } from 'react';
2
3
 
3
4
  type ChainType = "evm" | "solana" | "tron" | "bitcoin";
@@ -133,14 +134,6 @@ interface BitcoinProvider {
133
134
 
134
135
  declare function createDecane(config?: DecaneConfig): DecaneProvider;
135
136
 
136
- interface PhraseGenerationResult {
137
- phrase: string;
138
- challenge: Array<{
139
- position: number;
140
- expected: string;
141
- }>;
142
- }
143
-
144
137
  declare class ApiClient {
145
138
  private readonly baseUrl;
146
139
  private readonly apiKey;
@@ -162,6 +155,8 @@ declare class ApiClient {
162
155
  evmAddress: string;
163
156
  solanaAddress: string;
164
157
  }): Promise<void>;
158
+ getWebAuthnRegisterOptions(jwt: string, rpId: string, rpName: string): Promise<_simplewebauthn_browser.PublicKeyCredentialCreationOptionsJSON>;
159
+ postWebAuthnRegister(jwt: string, response: _simplewebauthn_browser.RegistrationResponseJSON, origin: string): Promise<void>;
165
160
  revoke(jwt: string): Promise<void>;
166
161
  hasRecoveryBackup(jwt: string): Promise<boolean>;
167
162
  getRecoveryBackup(jwt: string): Promise<{
@@ -180,7 +175,14 @@ declare class ApiClient {
180
175
  prfSalt: Uint8Array;
181
176
  }): Promise<void>;
182
177
  deleteRecoveryBackup(jwt: string): Promise<void>;
183
- markPhraseSaved(jwt: string): Promise<void>;
178
+ markRecoveryShareSaved(jwt: string): Promise<void>;
179
+ getRecoveryStatus(jwt: string): Promise<{
180
+ hasRecoveryShare: boolean;
181
+ savedAt: string | null;
182
+ nagged: boolean;
183
+ shareSetVersion: number;
184
+ }>;
185
+ dismissRecoveryNag(jwt: string): Promise<void>;
184
186
  }
185
187
 
186
188
  type RecoveryProgress = {
@@ -189,11 +191,57 @@ type RecoveryProgress = {
189
191
  type: 'passkey-failed';
190
192
  reason: string;
191
193
  } | {
192
- type: 'phrase-prompt';
194
+ type: 'recovery-file-prompt';
193
195
  } | {
194
- type: 'phrase-verifying';
196
+ type: 'password-prompt';
197
+ passwordHint: string | null;
198
+ } | {
199
+ type: 'recovery-verifying';
200
+ } | {
201
+ type: 'rotated';
202
+ shareSetVersion: number;
195
203
  };
196
204
 
205
+ interface RecoveryShareFile {
206
+ version: number;
207
+ type: 'decane-recovery-share';
208
+ shareSetVersion: number;
209
+ kdf: 'pbkdf2-sha256';
210
+ kdfParams: {
211
+ iterations: number;
212
+ salt: string;
213
+ };
214
+ cipher: 'aes-256-gcm';
215
+ iv: string;
216
+ ciphertext: string;
217
+ addresses: {
218
+ evm: string;
219
+ solana: string;
220
+ };
221
+ passwordHint: string | null;
222
+ createdAt: string;
223
+ }
224
+
225
+ interface PortableBackup {
226
+ version: number;
227
+ type: 'decane-portable-backup';
228
+ shareSetVersion: number;
229
+ kdf: 'pbkdf2-sha256';
230
+ kdfParams: {
231
+ iterations: number;
232
+ salt: string;
233
+ };
234
+ cipher: 'aes-256-gcm';
235
+ iv: string;
236
+ ciphertext: string;
237
+ addresses: {
238
+ evm: string;
239
+ solana: string;
240
+ };
241
+ passwordHint: string | null;
242
+ createdAt: string;
243
+ }
244
+
197
245
  type Chain = `evm:${number}` | `solana:${'mainnet' | 'devnet'}`;
198
246
  interface DecaneConnectConfig {
199
247
  apiKey: string;
@@ -206,18 +254,36 @@ interface DecaneConnectConfig {
206
254
  rpName?: string;
207
255
  rpcUrls?: Record<string, string>;
208
256
  teeUrl?: string;
209
- /** Offer phrase generation during signup. Default true. */
210
- offerPhraseAtSignup?: boolean;
211
- /** Show the phrase to the user; return their confirmation answers. */
212
- onPhraseGenerated?: (result: PhraseGenerationResult) => Promise<{
213
- userConfirmed: boolean;
214
- userAnswers: Array<{
215
- position: number;
216
- word: string;
217
- }>;
257
+ /** Offer to save a recovery-share file at signup. Default true. Never blocks onboarding. */
258
+ offerRecoveryAtSignup?: boolean;
259
+ /** Ask the user whether they want a recovery share and, if so, a password for it. */
260
+ onRecoveryShareOffer?: (addresses: {
261
+ evmAddress: string;
262
+ solanaAddress: string;
263
+ }) => Promise<{
264
+ wants: boolean;
265
+ password: string;
266
+ passwordHint?: string;
267
+ }>;
268
+ /** Hand the built file + suggested filename to the dApp, which owns the actual download. */
269
+ onRecoveryFileReady?: (file: RecoveryShareFile, filename: string) => Promise<void>;
270
+ /** Prompt for a recovery-share file (and its password) during Flow B. Return null to cancel. */
271
+ promptForRecoveryFile?: () => Promise<{
272
+ value: unknown;
273
+ getPassword: () => Promise<string | null>;
274
+ } | null>;
275
+ /**
276
+ * Every successful recovery/rotation invalidates the previous recovery
277
+ * file — this MUST prompt for a new password and block progress until the
278
+ * dApp confirms the user saved the new file (see MIGRATE_SSS_RECOVERY.md §10).
279
+ */
280
+ onRecoveryRotated?: (addresses: {
281
+ evmAddress: string;
282
+ solanaAddress: string;
283
+ }) => Promise<{
284
+ password: string;
285
+ passwordHint?: string;
218
286
  }>;
219
- /** Prompt for a phrase during recovery. Return null to cancel. */
220
- promptForRecoveryPhrase?: () => Promise<string | null>;
221
287
  /** Recovery stage callbacks, for dApp UI. */
222
288
  onRecoveryProgress?: (event: RecoveryProgress) => void;
223
289
  }
@@ -259,16 +325,32 @@ interface DecaneConnect {
259
325
  evm?: string;
260
326
  solana?: string;
261
327
  } | null;
262
- /** Generate a recovery phrase. Re-prompts for unlock; does not cache the share. */
263
- generateRecoveryPhrase(): Promise<PhraseGenerationResult>;
264
- /** Record that the user confirmed they saved the phrase. */
265
- markPhraseSaved(challenge: Array<{
266
- position: number;
267
- expected: string;
268
- }>, userAnswers: Array<{
269
- position: number;
270
- word: string;
271
- }>): Promise<boolean>;
328
+ /**
329
+ * Voluntary share rotation — after a suspected device compromise, or just
330
+ * to invalidate an old recovery file. Requires a fresh WebAuthn assertion.
331
+ * Returns the new recovery-share file (the caller still owns delivering it
332
+ * to the user — this does not download anything itself).
333
+ */
334
+ rotateShares(opts: {
335
+ password: string;
336
+ passwordHint?: string;
337
+ }): Promise<RecoveryShareFile>;
338
+ /**
339
+ * The two-share bearer portable backup (device + recovery). This file plus
340
+ * its password gives complete control of the wallet — see the mandatory
341
+ * warning-screen requirements in MIGRATE_SSS_RECOVERY.md §10. Requires a
342
+ * fresh WebAuthn assertion and rotates the share set on every export.
343
+ */
344
+ exportPortableBackup(opts: {
345
+ password: string;
346
+ passwordHint?: string;
347
+ }): Promise<PortableBackup>;
348
+ /** Whether the user has ever saved a recovery-share file (UX flag only — Decane never stores the share). */
349
+ hasRecoveryShare(): Promise<boolean>;
350
+ /** True at most once per account: no recovery share saved, never nagged, wallet holds value. */
351
+ shouldPromptRecovery(): Promise<boolean>;
352
+ /** Call regardless of the user's answer — the recovery nag fires once, ever. */
353
+ dismissRecoveryPrompt(): Promise<void>;
272
354
  /** Whether a wrapped-share backup exists on the server. */
273
355
  hasBackup(): Promise<boolean>;
274
356
  /** Delete the server-side backup. Disables Flow A recovery. */
@@ -349,7 +431,16 @@ declare class AttestationError extends DecaneConnectError {
349
431
  declare class RecoveryFailedError extends DecaneConnectError {
350
432
  constructor(reason: string);
351
433
  }
352
- declare class InvalidPhraseError extends DecaneConnectError {
434
+ declare class InvalidRecoveryFileError extends DecaneConnectError {
435
+ constructor();
436
+ }
437
+ declare class WrongPasswordError extends DecaneConnectError {
438
+ constructor();
439
+ }
440
+ declare class RecoveryWalletMismatchError extends DecaneConnectError {
441
+ constructor();
442
+ }
443
+ declare class ExportNotAuthorizedError extends DecaneConnectError {
353
444
  constructor();
354
445
  }
355
446
 
@@ -605,4 +696,4 @@ declare function useSignTypedData(): {
605
696
  reset: () => void;
606
697
  };
607
698
 
608
- export { type ActiveSession, AttestationError, type AuthResult, BUILT_IN_CHAINS, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, type DecaneProvider, InvalidApiKeyError, InvalidPhraseError, InvalidPinError, NetworkError, NewDeviceError, OriginNotAllowedError, type PhraseGenerationResult, PromptPinNotConfiguredError, RecoveryFailedError, type RecoveryProgress, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SocialAuthState, type SocialConfig, SocialWalletModal, type Theme, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, createDecane, createDecaneConnect, startEmailAuth, useChainSwitch, useDecane, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialWallet, useWalletSelector, verifyEmailCode };
699
+ export { type ActiveSession, AttestationError, type AuthResult, BUILT_IN_CHAINS, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, type DecaneProvider, ExportNotAuthorizedError, InvalidApiKeyError, InvalidPinError, InvalidRecoveryFileError, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPinNotConfiguredError, RecoveryFailedError, type RecoveryProgress, type RecoveryShareFile, RecoveryWalletMismatchError, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SocialAuthState, type SocialConfig, SocialWalletModal, type Theme, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, createDecane, createDecaneConnect, startEmailAuth, useChainSwitch, useDecane, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialWallet, useWalletSelector, verifyEmailCode };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as _simplewebauthn_browser from '@simplewebauthn/browser';
1
2
  import React, { ReactNode } from 'react';
2
3
 
3
4
  type ChainType = "evm" | "solana" | "tron" | "bitcoin";
@@ -133,14 +134,6 @@ interface BitcoinProvider {
133
134
 
134
135
  declare function createDecane(config?: DecaneConfig): DecaneProvider;
135
136
 
136
- interface PhraseGenerationResult {
137
- phrase: string;
138
- challenge: Array<{
139
- position: number;
140
- expected: string;
141
- }>;
142
- }
143
-
144
137
  declare class ApiClient {
145
138
  private readonly baseUrl;
146
139
  private readonly apiKey;
@@ -162,6 +155,8 @@ declare class ApiClient {
162
155
  evmAddress: string;
163
156
  solanaAddress: string;
164
157
  }): Promise<void>;
158
+ getWebAuthnRegisterOptions(jwt: string, rpId: string, rpName: string): Promise<_simplewebauthn_browser.PublicKeyCredentialCreationOptionsJSON>;
159
+ postWebAuthnRegister(jwt: string, response: _simplewebauthn_browser.RegistrationResponseJSON, origin: string): Promise<void>;
165
160
  revoke(jwt: string): Promise<void>;
166
161
  hasRecoveryBackup(jwt: string): Promise<boolean>;
167
162
  getRecoveryBackup(jwt: string): Promise<{
@@ -180,7 +175,14 @@ declare class ApiClient {
180
175
  prfSalt: Uint8Array;
181
176
  }): Promise<void>;
182
177
  deleteRecoveryBackup(jwt: string): Promise<void>;
183
- markPhraseSaved(jwt: string): Promise<void>;
178
+ markRecoveryShareSaved(jwt: string): Promise<void>;
179
+ getRecoveryStatus(jwt: string): Promise<{
180
+ hasRecoveryShare: boolean;
181
+ savedAt: string | null;
182
+ nagged: boolean;
183
+ shareSetVersion: number;
184
+ }>;
185
+ dismissRecoveryNag(jwt: string): Promise<void>;
184
186
  }
185
187
 
186
188
  type RecoveryProgress = {
@@ -189,11 +191,57 @@ type RecoveryProgress = {
189
191
  type: 'passkey-failed';
190
192
  reason: string;
191
193
  } | {
192
- type: 'phrase-prompt';
194
+ type: 'recovery-file-prompt';
193
195
  } | {
194
- type: 'phrase-verifying';
196
+ type: 'password-prompt';
197
+ passwordHint: string | null;
198
+ } | {
199
+ type: 'recovery-verifying';
200
+ } | {
201
+ type: 'rotated';
202
+ shareSetVersion: number;
195
203
  };
196
204
 
205
+ interface RecoveryShareFile {
206
+ version: number;
207
+ type: 'decane-recovery-share';
208
+ shareSetVersion: number;
209
+ kdf: 'pbkdf2-sha256';
210
+ kdfParams: {
211
+ iterations: number;
212
+ salt: string;
213
+ };
214
+ cipher: 'aes-256-gcm';
215
+ iv: string;
216
+ ciphertext: string;
217
+ addresses: {
218
+ evm: string;
219
+ solana: string;
220
+ };
221
+ passwordHint: string | null;
222
+ createdAt: string;
223
+ }
224
+
225
+ interface PortableBackup {
226
+ version: number;
227
+ type: 'decane-portable-backup';
228
+ shareSetVersion: number;
229
+ kdf: 'pbkdf2-sha256';
230
+ kdfParams: {
231
+ iterations: number;
232
+ salt: string;
233
+ };
234
+ cipher: 'aes-256-gcm';
235
+ iv: string;
236
+ ciphertext: string;
237
+ addresses: {
238
+ evm: string;
239
+ solana: string;
240
+ };
241
+ passwordHint: string | null;
242
+ createdAt: string;
243
+ }
244
+
197
245
  type Chain = `evm:${number}` | `solana:${'mainnet' | 'devnet'}`;
198
246
  interface DecaneConnectConfig {
199
247
  apiKey: string;
@@ -206,18 +254,36 @@ interface DecaneConnectConfig {
206
254
  rpName?: string;
207
255
  rpcUrls?: Record<string, string>;
208
256
  teeUrl?: string;
209
- /** Offer phrase generation during signup. Default true. */
210
- offerPhraseAtSignup?: boolean;
211
- /** Show the phrase to the user; return their confirmation answers. */
212
- onPhraseGenerated?: (result: PhraseGenerationResult) => Promise<{
213
- userConfirmed: boolean;
214
- userAnswers: Array<{
215
- position: number;
216
- word: string;
217
- }>;
257
+ /** Offer to save a recovery-share file at signup. Default true. Never blocks onboarding. */
258
+ offerRecoveryAtSignup?: boolean;
259
+ /** Ask the user whether they want a recovery share and, if so, a password for it. */
260
+ onRecoveryShareOffer?: (addresses: {
261
+ evmAddress: string;
262
+ solanaAddress: string;
263
+ }) => Promise<{
264
+ wants: boolean;
265
+ password: string;
266
+ passwordHint?: string;
267
+ }>;
268
+ /** Hand the built file + suggested filename to the dApp, which owns the actual download. */
269
+ onRecoveryFileReady?: (file: RecoveryShareFile, filename: string) => Promise<void>;
270
+ /** Prompt for a recovery-share file (and its password) during Flow B. Return null to cancel. */
271
+ promptForRecoveryFile?: () => Promise<{
272
+ value: unknown;
273
+ getPassword: () => Promise<string | null>;
274
+ } | null>;
275
+ /**
276
+ * Every successful recovery/rotation invalidates the previous recovery
277
+ * file — this MUST prompt for a new password and block progress until the
278
+ * dApp confirms the user saved the new file (see MIGRATE_SSS_RECOVERY.md §10).
279
+ */
280
+ onRecoveryRotated?: (addresses: {
281
+ evmAddress: string;
282
+ solanaAddress: string;
283
+ }) => Promise<{
284
+ password: string;
285
+ passwordHint?: string;
218
286
  }>;
219
- /** Prompt for a phrase during recovery. Return null to cancel. */
220
- promptForRecoveryPhrase?: () => Promise<string | null>;
221
287
  /** Recovery stage callbacks, for dApp UI. */
222
288
  onRecoveryProgress?: (event: RecoveryProgress) => void;
223
289
  }
@@ -259,16 +325,32 @@ interface DecaneConnect {
259
325
  evm?: string;
260
326
  solana?: string;
261
327
  } | null;
262
- /** Generate a recovery phrase. Re-prompts for unlock; does not cache the share. */
263
- generateRecoveryPhrase(): Promise<PhraseGenerationResult>;
264
- /** Record that the user confirmed they saved the phrase. */
265
- markPhraseSaved(challenge: Array<{
266
- position: number;
267
- expected: string;
268
- }>, userAnswers: Array<{
269
- position: number;
270
- word: string;
271
- }>): Promise<boolean>;
328
+ /**
329
+ * Voluntary share rotation — after a suspected device compromise, or just
330
+ * to invalidate an old recovery file. Requires a fresh WebAuthn assertion.
331
+ * Returns the new recovery-share file (the caller still owns delivering it
332
+ * to the user — this does not download anything itself).
333
+ */
334
+ rotateShares(opts: {
335
+ password: string;
336
+ passwordHint?: string;
337
+ }): Promise<RecoveryShareFile>;
338
+ /**
339
+ * The two-share bearer portable backup (device + recovery). This file plus
340
+ * its password gives complete control of the wallet — see the mandatory
341
+ * warning-screen requirements in MIGRATE_SSS_RECOVERY.md §10. Requires a
342
+ * fresh WebAuthn assertion and rotates the share set on every export.
343
+ */
344
+ exportPortableBackup(opts: {
345
+ password: string;
346
+ passwordHint?: string;
347
+ }): Promise<PortableBackup>;
348
+ /** Whether the user has ever saved a recovery-share file (UX flag only — Decane never stores the share). */
349
+ hasRecoveryShare(): Promise<boolean>;
350
+ /** True at most once per account: no recovery share saved, never nagged, wallet holds value. */
351
+ shouldPromptRecovery(): Promise<boolean>;
352
+ /** Call regardless of the user's answer — the recovery nag fires once, ever. */
353
+ dismissRecoveryPrompt(): Promise<void>;
272
354
  /** Whether a wrapped-share backup exists on the server. */
273
355
  hasBackup(): Promise<boolean>;
274
356
  /** Delete the server-side backup. Disables Flow A recovery. */
@@ -349,7 +431,16 @@ declare class AttestationError extends DecaneConnectError {
349
431
  declare class RecoveryFailedError extends DecaneConnectError {
350
432
  constructor(reason: string);
351
433
  }
352
- declare class InvalidPhraseError extends DecaneConnectError {
434
+ declare class InvalidRecoveryFileError extends DecaneConnectError {
435
+ constructor();
436
+ }
437
+ declare class WrongPasswordError extends DecaneConnectError {
438
+ constructor();
439
+ }
440
+ declare class RecoveryWalletMismatchError extends DecaneConnectError {
441
+ constructor();
442
+ }
443
+ declare class ExportNotAuthorizedError extends DecaneConnectError {
353
444
  constructor();
354
445
  }
355
446
 
@@ -605,4 +696,4 @@ declare function useSignTypedData(): {
605
696
  reset: () => void;
606
697
  };
607
698
 
608
- export { type ActiveSession, AttestationError, type AuthResult, BUILT_IN_CHAINS, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, type DecaneProvider, InvalidApiKeyError, InvalidPhraseError, InvalidPinError, NetworkError, NewDeviceError, OriginNotAllowedError, type PhraseGenerationResult, PromptPinNotConfiguredError, RecoveryFailedError, type RecoveryProgress, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SocialAuthState, type SocialConfig, SocialWalletModal, type Theme, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, createDecane, createDecaneConnect, startEmailAuth, useChainSwitch, useDecane, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialWallet, useWalletSelector, verifyEmailCode };
699
+ export { type ActiveSession, AttestationError, type AuthResult, BUILT_IN_CHAINS, type CAIP25Method, type CAIP25SessionRequest, type CAIP25SessionResult, CHAINS, CallSequenceError, type Chain, type ChainDescriptor, type ChainId, type ChainScope, type ChainSupport, type ChainType, type ConnectMode, type ConnectResult, type DecaneConfig, type DecaneConnect, type DecaneConnectConfig, DecaneConnectError, DecaneError, DecaneErrorCode, DecaneKit, type DecaneProvider, ExportNotAuthorizedError, InvalidApiKeyError, InvalidPinError, InvalidRecoveryFileError, NetworkError, NewDeviceError, OriginNotAllowedError, type PortableBackup, PromptPinNotConfiguredError, RecoveryFailedError, type RecoveryProgress, type RecoveryShareFile, RecoveryWalletMismatchError, type SdkEvent, type SendTransactionRequest, SessionExpiredError, ShareCorruptedError, type SignMessageRequest, type SocialAuthState, type SocialConfig, SocialWalletModal, type Theme, type TxParams, type UnifiedWalletAccount, UnlockRequiredError, UserCancelledError, WalletSelector, WebAuthnNotSupportedError, type WrappedShareMeta, WrongPasswordError, createDecane, createDecaneConnect, startEmailAuth, useChainSwitch, useDecane, useSendTransaction, useSignMessage, useSignTypedData, useSocialAuth, useSocialWallet, useWalletSelector, verifyEmailCode };