@unicitylabs/sphere-sdk 0.17.2 → 0.17.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.
@@ -445,7 +445,7 @@ interface PaymentsV2 {
445
445
  * }
446
446
  * ```
447
447
  */
448
- type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'TRANSFER_CONFLICT' | 'CERTIFICATION_UNCONFIRMED' | 'CHECKPOINT_PERSIST_FAILED' | 'SPLIT_CHECKPOINT_LOST' | 'CHECKPOINT_TRUSTBASE_MISMATCH' | 'STORAGE_ERROR' | 'SEND_SYNC_PENDING' | 'SEND_PARTIALLY_COMPLETED' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'INVALID_AMOUNT' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE' | 'SIGNING_ERROR' | 'SEND_QUEUE_TIMEOUT' | 'SEND_INSUFFICIENT_BALANCE' | 'SEND_RESERVATION_CANCELLED' | 'SEND_QUEUE_FULL' | 'MODULE_DESTROYED' | 'REENTRANT_GATE' | 'INVOICE_NO_TARGETS' | 'INVOICE_INVALID_ADDRESS' | 'INVOICE_NO_ASSETS' | 'INVOICE_INVALID_ASSET' | 'INVOICE_INVALID_AMOUNT' | 'INVOICE_INVALID_COIN' | 'INVOICE_INVALID_NFT' | 'INVOICE_PAST_DUE_DATE' | 'INVOICE_DUPLICATE_ADDRESS' | 'INVOICE_DUPLICATE_COIN' | 'INVOICE_DUPLICATE_NFT' | 'INVOICE_MINT_FAILED' | 'INVOICE_INVALID_PROOF' | 'INVOICE_WRONG_TOKEN_TYPE' | 'INVOICE_INVALID_DATA' | 'INVOICE_ALREADY_EXISTS' | 'INVOICE_NOT_FOUND' | 'INVOICE_NOT_TARGET' | 'INVOICE_ALREADY_CLOSED' | 'INVOICE_ALREADY_CANCELLED' | 'INVOICE_ORACLE_REQUIRED' | 'INVOICE_TERMINATED' | 'INVOICE_INVALID_TARGET' | 'INVOICE_INVALID_ASSET_INDEX' | 'INVOICE_RETURN_EXCEEDS_BALANCE' | 'INVOICE_INVALID_DELIVERY_METHOD' | 'INVOICE_INVALID_REFUND_ADDRESS' | 'INVOICE_INVALID_CONTACT' | 'INVOICE_INVALID_ID' | 'INVOICE_TOO_MANY_TARGETS' | 'INVOICE_TOO_MANY_ASSETS' | 'INVOICE_MEMO_TOO_LONG' | 'INVOICE_TERMS_TOO_LARGE' | 'INVOICE_NOT_TERMINATED' | 'INVOICE_NOT_CANCELLED' | 'INVOICE_STORAGE_FAILED' | 'RATE_LIMITED' | 'COMMUNICATIONS_UNAVAILABLE' | 'SWAP_INVALID_DEAL' | 'SWAP_INVALID_MANIFEST' | 'SWAP_NOT_FOUND' | 'SWAP_WRONG_STATE' | 'SWAP_RESOLVE_FAILED' | 'SWAP_DM_SEND_FAILED' | 'SWAP_ESCROW_REJECTED' | 'SWAP_DEPOSIT_FAILED' | 'SWAP_PAYOUT_VERIFICATION_FAILED' | 'SWAP_ALREADY_EXISTS' | 'SWAP_ALREADY_COMPLETED' | 'SWAP_ALREADY_CANCELLED' | 'SWAP_TIMEOUT' | 'SWAP_LIMIT_EXCEEDED' | 'SWAP_ALREADY_INITIALIZED' | 'SWAP_MODULE_DESTROYED' | 'SWAP_NOT_INITIALIZED';
448
+ type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'TRANSFER_CONFLICT' | 'CERTIFICATION_UNCONFIRMED' | 'CHECKPOINT_PERSIST_FAILED' | 'SPLIT_CHECKPOINT_LOST' | 'CHECKPOINT_TRUSTBASE_MISMATCH' | 'STORAGE_ERROR' | 'SEND_SYNC_PENDING' | 'SEND_PARTIALLY_COMPLETED' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'INVALID_AMOUNT' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE' | 'PAYMENTS_NOT_COMPOSED' | 'SIGNING_ERROR' | 'SEND_QUEUE_TIMEOUT' | 'SEND_INSUFFICIENT_BALANCE' | 'SEND_RESERVATION_CANCELLED' | 'SEND_QUEUE_FULL' | 'MODULE_DESTROYED' | 'REENTRANT_GATE' | 'INVOICE_NO_TARGETS' | 'INVOICE_INVALID_ADDRESS' | 'INVOICE_NO_ASSETS' | 'INVOICE_INVALID_ASSET' | 'INVOICE_INVALID_AMOUNT' | 'INVOICE_INVALID_COIN' | 'INVOICE_INVALID_NFT' | 'INVOICE_PAST_DUE_DATE' | 'INVOICE_DUPLICATE_ADDRESS' | 'INVOICE_DUPLICATE_COIN' | 'INVOICE_DUPLICATE_NFT' | 'INVOICE_MINT_FAILED' | 'INVOICE_INVALID_PROOF' | 'INVOICE_WRONG_TOKEN_TYPE' | 'INVOICE_INVALID_DATA' | 'INVOICE_ALREADY_EXISTS' | 'INVOICE_NOT_FOUND' | 'INVOICE_NOT_TARGET' | 'INVOICE_ALREADY_CLOSED' | 'INVOICE_ALREADY_CANCELLED' | 'INVOICE_ORACLE_REQUIRED' | 'INVOICE_TERMINATED' | 'INVOICE_INVALID_TARGET' | 'INVOICE_INVALID_ASSET_INDEX' | 'INVOICE_RETURN_EXCEEDS_BALANCE' | 'INVOICE_INVALID_DELIVERY_METHOD' | 'INVOICE_INVALID_REFUND_ADDRESS' | 'INVOICE_INVALID_CONTACT' | 'INVOICE_INVALID_ID' | 'INVOICE_TOO_MANY_TARGETS' | 'INVOICE_TOO_MANY_ASSETS' | 'INVOICE_MEMO_TOO_LONG' | 'INVOICE_TERMS_TOO_LARGE' | 'INVOICE_NOT_TERMINATED' | 'INVOICE_NOT_CANCELLED' | 'INVOICE_STORAGE_FAILED' | 'RATE_LIMITED' | 'COMMUNICATIONS_UNAVAILABLE' | 'SWAP_INVALID_DEAL' | 'SWAP_INVALID_MANIFEST' | 'SWAP_NOT_FOUND' | 'SWAP_WRONG_STATE' | 'SWAP_RESOLVE_FAILED' | 'SWAP_DM_SEND_FAILED' | 'SWAP_ESCROW_REJECTED' | 'SWAP_DEPOSIT_FAILED' | 'SWAP_PAYOUT_VERIFICATION_FAILED' | 'SWAP_ALREADY_EXISTS' | 'SWAP_ALREADY_COMPLETED' | 'SWAP_ALREADY_CANCELLED' | 'SWAP_TIMEOUT' | 'SWAP_LIMIT_EXCEEDED' | 'SWAP_ALREADY_INITIALIZED' | 'SWAP_MODULE_DESTROYED' | 'SWAP_NOT_INITIALIZED';
449
449
  declare class SphereError extends Error {
450
450
  readonly code: SphereErrorCode;
451
451
  readonly cause?: unknown;
@@ -3165,6 +3165,9 @@ interface WalletApiTransportConfig {
3165
3165
  /** DI seam: supply the whole per-address bundle (offline tests, custom hosts). */
3166
3166
  paymentsV2Transport?(args: PaymentsV2TransportArgs): PaymentsV2Transport;
3167
3167
  }
3168
+ /** The messaging-only opt-out (#793) — sharing the `walletApi` field is what makes "configured" and "deliberately absent" mutually exclusive. */
3169
+ declare const NO_PAYMENTS = "none";
3170
+ type WalletApiOption = WalletApiTransportConfig | typeof NO_PAYMENTS;
3168
3171
 
3169
3172
  /**
3170
3173
  * Text Wallet Backup Serialization Types
@@ -3234,14 +3237,17 @@ interface InitProgress {
3234
3237
  /** Callback for tracking wallet initialization progress */
3235
3238
  type InitProgressCallback = (progress: InitProgress) => void;
3236
3239
  /**
3237
- * The wallet-api transport config every wallet needs (money moves only through
3238
- * the wallet-api vertical): `{ network, baseUrl, deviceId?, ... }` —
3239
- * `createWalletApiProviders` (impl/shared/wallet-api) builds it. Shared by all
3240
- * four init-option shapes below.
3240
+ * The wallet-api transport config every wallet that moves money needs:
3241
+ * `{ network, baseUrl, deviceId?, ... }` — `createWalletApiProviders`
3242
+ * (impl/shared/wallet-api) builds it. Shared by all four init-option shapes below.
3241
3243
  */
3242
3244
  interface SphereWalletApiOptions {
3243
- /** Wallet-api transport config — REQUIRED (init throws INVALID_CONFIG without it). */
3244
- walletApi?: WalletApiTransportConfig;
3245
+ /**
3246
+ * Wallet-api transport config — REQUIRED, with one explicit escape: `'none'`
3247
+ * composes no money at all (#793). Omitting the field still throws INVALID_CONFIG:
3248
+ * "I forgot it" must never read the same as "I meant it".
3249
+ */
3250
+ walletApi?: WalletApiOption;
3245
3251
  /** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (invoicing no longer exists in the SDK). */
3246
3252
  accounting?: unknown;
3247
3253
  /** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (swaps no longer exist in the SDK). */
@@ -3530,7 +3536,11 @@ declare class Sphere {
3530
3536
  private _market;
3531
3537
  /** The ACTIVE address's running vertical — §7: exactly one at a time, ever. */
3532
3538
  private _paymentsV2Active;
3533
- /** Resolved wallet-api transport composition (network + per-address factory); set at init, fail-closed. */
3539
+ /**
3540
+ * Money composition, set at init. `null` = never resolved (a construction bug),
3541
+ * `NO_PAYMENTS` = the explicit #793 opt-out, an object = a real composition. One
3542
+ * spelling for the last two would read a forgotten resolve as messaging-only.
3543
+ */
3534
3544
  private _paymentsV2Composition;
3535
3545
  /**
3536
3546
  * §7 lifecycle mutex: every stop/start pair runs strictly serialized, so
@@ -3717,6 +3727,12 @@ declare class Sphere {
3717
3727
  static generateMnemonic(strength?: 128 | 256): string;
3718
3728
  /** Payments (the §4 facade — the active address's running vertical). */
3719
3729
  get payments(): PaymentsV2;
3730
+ /**
3731
+ * Whether this Sphere composes money at all (#793) — fixed for the instance's life,
3732
+ * so a messaging-only wallet can branch without a try/catch. Not a liveness check:
3733
+ * `true` still leaves `payments` throwing NOT_INITIALIZED mid-init or mid-switch.
3734
+ */
3735
+ get hasPayments(): boolean;
3720
3736
  /** Communications module */
3721
3737
  get communications(): CommunicationsModule;
3722
3738
  /** Group chat module (NIP-29). Null if not configured. */
@@ -4891,4 +4907,4 @@ interface CheckNetworkHealthOptions {
4891
4907
  */
4892
4908
  declare function checkNetworkHealth(network?: NetworkType, options?: CheckNetworkHealthOptions): Promise<NetworkHealthResult>;
4893
4909
 
4894
- export { type AddressInfo, type AddressModuleSet, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, DELIVERY_ENCRYPTION_HKDF_INFO, type DeliveryBundle, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, FIELD_ENCRYPTION_HKDF_INFO, FIELD_ENVELOPE_MAX_BYTES, FIELD_ENVELOPE_NONCE_BYTES, FIELD_ENVELOPE_PREFIX, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, PartialSendConflictError, SIGN_MESSAGE_PREFIX, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, type WalletApiTransportConfig, assertFieldEnvelopeShape, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, createKeyPair, createSphere, decrypt, decryptDeliveryBundle, decryptField, decryptFieldBytes, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveDeliveryEncryptionKey, deriveFieldEncryptionKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, encrypt, encryptDeliveryBundle, encryptField, encryptFieldBytes, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressFromMasterKey, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getPublicKey, hash160, hashSignMessage, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isPossiblyCommittedSendOutcome, isSphereError, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, parseTokenAmount, randomBytes, randomHex, randomUUID, recoverPubkeyFromSignature, ripemd160, safeParseTokenAmount, serializeEncrypted, sha256, signMessage, sleep, sphereExists, toHumanReadable, validateMnemonic, verifySignedMessage };
4910
+ export { type AddressInfo, type AddressModuleSet, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, DELIVERY_ENCRYPTION_HKDF_INFO, type DeliveryBundle, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, FIELD_ENCRYPTION_HKDF_INFO, FIELD_ENVELOPE_MAX_BYTES, FIELD_ENVELOPE_NONCE_BYTES, FIELD_ENVELOPE_PREFIX, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, NO_PAYMENTS, PartialSendConflictError, SIGN_MESSAGE_PREFIX, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, type WalletApiOption, type WalletApiTransportConfig, assertFieldEnvelopeShape, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, createKeyPair, createSphere, decrypt, decryptDeliveryBundle, decryptField, decryptFieldBytes, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveDeliveryEncryptionKey, deriveFieldEncryptionKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, encrypt, encryptDeliveryBundle, encryptField, encryptFieldBytes, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressFromMasterKey, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getPublicKey, hash160, hashSignMessage, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isPossiblyCommittedSendOutcome, isSphereError, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, parseTokenAmount, randomBytes, randomHex, randomUUID, recoverPubkeyFromSignature, ripemd160, safeParseTokenAmount, serializeEncrypted, sha256, signMessage, sleep, sphereExists, toHumanReadable, validateMnemonic, verifySignedMessage };
@@ -445,7 +445,7 @@ interface PaymentsV2 {
445
445
  * }
446
446
  * ```
447
447
  */
448
- type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'TRANSFER_CONFLICT' | 'CERTIFICATION_UNCONFIRMED' | 'CHECKPOINT_PERSIST_FAILED' | 'SPLIT_CHECKPOINT_LOST' | 'CHECKPOINT_TRUSTBASE_MISMATCH' | 'STORAGE_ERROR' | 'SEND_SYNC_PENDING' | 'SEND_PARTIALLY_COMPLETED' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'INVALID_AMOUNT' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE' | 'SIGNING_ERROR' | 'SEND_QUEUE_TIMEOUT' | 'SEND_INSUFFICIENT_BALANCE' | 'SEND_RESERVATION_CANCELLED' | 'SEND_QUEUE_FULL' | 'MODULE_DESTROYED' | 'REENTRANT_GATE' | 'INVOICE_NO_TARGETS' | 'INVOICE_INVALID_ADDRESS' | 'INVOICE_NO_ASSETS' | 'INVOICE_INVALID_ASSET' | 'INVOICE_INVALID_AMOUNT' | 'INVOICE_INVALID_COIN' | 'INVOICE_INVALID_NFT' | 'INVOICE_PAST_DUE_DATE' | 'INVOICE_DUPLICATE_ADDRESS' | 'INVOICE_DUPLICATE_COIN' | 'INVOICE_DUPLICATE_NFT' | 'INVOICE_MINT_FAILED' | 'INVOICE_INVALID_PROOF' | 'INVOICE_WRONG_TOKEN_TYPE' | 'INVOICE_INVALID_DATA' | 'INVOICE_ALREADY_EXISTS' | 'INVOICE_NOT_FOUND' | 'INVOICE_NOT_TARGET' | 'INVOICE_ALREADY_CLOSED' | 'INVOICE_ALREADY_CANCELLED' | 'INVOICE_ORACLE_REQUIRED' | 'INVOICE_TERMINATED' | 'INVOICE_INVALID_TARGET' | 'INVOICE_INVALID_ASSET_INDEX' | 'INVOICE_RETURN_EXCEEDS_BALANCE' | 'INVOICE_INVALID_DELIVERY_METHOD' | 'INVOICE_INVALID_REFUND_ADDRESS' | 'INVOICE_INVALID_CONTACT' | 'INVOICE_INVALID_ID' | 'INVOICE_TOO_MANY_TARGETS' | 'INVOICE_TOO_MANY_ASSETS' | 'INVOICE_MEMO_TOO_LONG' | 'INVOICE_TERMS_TOO_LARGE' | 'INVOICE_NOT_TERMINATED' | 'INVOICE_NOT_CANCELLED' | 'INVOICE_STORAGE_FAILED' | 'RATE_LIMITED' | 'COMMUNICATIONS_UNAVAILABLE' | 'SWAP_INVALID_DEAL' | 'SWAP_INVALID_MANIFEST' | 'SWAP_NOT_FOUND' | 'SWAP_WRONG_STATE' | 'SWAP_RESOLVE_FAILED' | 'SWAP_DM_SEND_FAILED' | 'SWAP_ESCROW_REJECTED' | 'SWAP_DEPOSIT_FAILED' | 'SWAP_PAYOUT_VERIFICATION_FAILED' | 'SWAP_ALREADY_EXISTS' | 'SWAP_ALREADY_COMPLETED' | 'SWAP_ALREADY_CANCELLED' | 'SWAP_TIMEOUT' | 'SWAP_LIMIT_EXCEEDED' | 'SWAP_ALREADY_INITIALIZED' | 'SWAP_MODULE_DESTROYED' | 'SWAP_NOT_INITIALIZED';
448
+ type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'TRANSFER_CONFLICT' | 'CERTIFICATION_UNCONFIRMED' | 'CHECKPOINT_PERSIST_FAILED' | 'SPLIT_CHECKPOINT_LOST' | 'CHECKPOINT_TRUSTBASE_MISMATCH' | 'STORAGE_ERROR' | 'SEND_SYNC_PENDING' | 'SEND_PARTIALLY_COMPLETED' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'INVALID_AMOUNT' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE' | 'PAYMENTS_NOT_COMPOSED' | 'SIGNING_ERROR' | 'SEND_QUEUE_TIMEOUT' | 'SEND_INSUFFICIENT_BALANCE' | 'SEND_RESERVATION_CANCELLED' | 'SEND_QUEUE_FULL' | 'MODULE_DESTROYED' | 'REENTRANT_GATE' | 'INVOICE_NO_TARGETS' | 'INVOICE_INVALID_ADDRESS' | 'INVOICE_NO_ASSETS' | 'INVOICE_INVALID_ASSET' | 'INVOICE_INVALID_AMOUNT' | 'INVOICE_INVALID_COIN' | 'INVOICE_INVALID_NFT' | 'INVOICE_PAST_DUE_DATE' | 'INVOICE_DUPLICATE_ADDRESS' | 'INVOICE_DUPLICATE_COIN' | 'INVOICE_DUPLICATE_NFT' | 'INVOICE_MINT_FAILED' | 'INVOICE_INVALID_PROOF' | 'INVOICE_WRONG_TOKEN_TYPE' | 'INVOICE_INVALID_DATA' | 'INVOICE_ALREADY_EXISTS' | 'INVOICE_NOT_FOUND' | 'INVOICE_NOT_TARGET' | 'INVOICE_ALREADY_CLOSED' | 'INVOICE_ALREADY_CANCELLED' | 'INVOICE_ORACLE_REQUIRED' | 'INVOICE_TERMINATED' | 'INVOICE_INVALID_TARGET' | 'INVOICE_INVALID_ASSET_INDEX' | 'INVOICE_RETURN_EXCEEDS_BALANCE' | 'INVOICE_INVALID_DELIVERY_METHOD' | 'INVOICE_INVALID_REFUND_ADDRESS' | 'INVOICE_INVALID_CONTACT' | 'INVOICE_INVALID_ID' | 'INVOICE_TOO_MANY_TARGETS' | 'INVOICE_TOO_MANY_ASSETS' | 'INVOICE_MEMO_TOO_LONG' | 'INVOICE_TERMS_TOO_LARGE' | 'INVOICE_NOT_TERMINATED' | 'INVOICE_NOT_CANCELLED' | 'INVOICE_STORAGE_FAILED' | 'RATE_LIMITED' | 'COMMUNICATIONS_UNAVAILABLE' | 'SWAP_INVALID_DEAL' | 'SWAP_INVALID_MANIFEST' | 'SWAP_NOT_FOUND' | 'SWAP_WRONG_STATE' | 'SWAP_RESOLVE_FAILED' | 'SWAP_DM_SEND_FAILED' | 'SWAP_ESCROW_REJECTED' | 'SWAP_DEPOSIT_FAILED' | 'SWAP_PAYOUT_VERIFICATION_FAILED' | 'SWAP_ALREADY_EXISTS' | 'SWAP_ALREADY_COMPLETED' | 'SWAP_ALREADY_CANCELLED' | 'SWAP_TIMEOUT' | 'SWAP_LIMIT_EXCEEDED' | 'SWAP_ALREADY_INITIALIZED' | 'SWAP_MODULE_DESTROYED' | 'SWAP_NOT_INITIALIZED';
449
449
  declare class SphereError extends Error {
450
450
  readonly code: SphereErrorCode;
451
451
  readonly cause?: unknown;
@@ -3165,6 +3165,9 @@ interface WalletApiTransportConfig {
3165
3165
  /** DI seam: supply the whole per-address bundle (offline tests, custom hosts). */
3166
3166
  paymentsV2Transport?(args: PaymentsV2TransportArgs): PaymentsV2Transport;
3167
3167
  }
3168
+ /** The messaging-only opt-out (#793) — sharing the `walletApi` field is what makes "configured" and "deliberately absent" mutually exclusive. */
3169
+ declare const NO_PAYMENTS = "none";
3170
+ type WalletApiOption = WalletApiTransportConfig | typeof NO_PAYMENTS;
3168
3171
 
3169
3172
  /**
3170
3173
  * Text Wallet Backup Serialization Types
@@ -3234,14 +3237,17 @@ interface InitProgress {
3234
3237
  /** Callback for tracking wallet initialization progress */
3235
3238
  type InitProgressCallback = (progress: InitProgress) => void;
3236
3239
  /**
3237
- * The wallet-api transport config every wallet needs (money moves only through
3238
- * the wallet-api vertical): `{ network, baseUrl, deviceId?, ... }` —
3239
- * `createWalletApiProviders` (impl/shared/wallet-api) builds it. Shared by all
3240
- * four init-option shapes below.
3240
+ * The wallet-api transport config every wallet that moves money needs:
3241
+ * `{ network, baseUrl, deviceId?, ... }` — `createWalletApiProviders`
3242
+ * (impl/shared/wallet-api) builds it. Shared by all four init-option shapes below.
3241
3243
  */
3242
3244
  interface SphereWalletApiOptions {
3243
- /** Wallet-api transport config — REQUIRED (init throws INVALID_CONFIG without it). */
3244
- walletApi?: WalletApiTransportConfig;
3245
+ /**
3246
+ * Wallet-api transport config — REQUIRED, with one explicit escape: `'none'`
3247
+ * composes no money at all (#793). Omitting the field still throws INVALID_CONFIG:
3248
+ * "I forgot it" must never read the same as "I meant it".
3249
+ */
3250
+ walletApi?: WalletApiOption;
3245
3251
  /** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (invoicing no longer exists in the SDK). */
3246
3252
  accounting?: unknown;
3247
3253
  /** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (swaps no longer exist in the SDK). */
@@ -3530,7 +3536,11 @@ declare class Sphere {
3530
3536
  private _market;
3531
3537
  /** The ACTIVE address's running vertical — §7: exactly one at a time, ever. */
3532
3538
  private _paymentsV2Active;
3533
- /** Resolved wallet-api transport composition (network + per-address factory); set at init, fail-closed. */
3539
+ /**
3540
+ * Money composition, set at init. `null` = never resolved (a construction bug),
3541
+ * `NO_PAYMENTS` = the explicit #793 opt-out, an object = a real composition. One
3542
+ * spelling for the last two would read a forgotten resolve as messaging-only.
3543
+ */
3534
3544
  private _paymentsV2Composition;
3535
3545
  /**
3536
3546
  * §7 lifecycle mutex: every stop/start pair runs strictly serialized, so
@@ -3717,6 +3727,12 @@ declare class Sphere {
3717
3727
  static generateMnemonic(strength?: 128 | 256): string;
3718
3728
  /** Payments (the §4 facade — the active address's running vertical). */
3719
3729
  get payments(): PaymentsV2;
3730
+ /**
3731
+ * Whether this Sphere composes money at all (#793) — fixed for the instance's life,
3732
+ * so a messaging-only wallet can branch without a try/catch. Not a liveness check:
3733
+ * `true` still leaves `payments` throwing NOT_INITIALIZED mid-init or mid-switch.
3734
+ */
3735
+ get hasPayments(): boolean;
3720
3736
  /** Communications module */
3721
3737
  get communications(): CommunicationsModule;
3722
3738
  /** Group chat module (NIP-29). Null if not configured. */
@@ -4891,4 +4907,4 @@ interface CheckNetworkHealthOptions {
4891
4907
  */
4892
4908
  declare function checkNetworkHealth(network?: NetworkType, options?: CheckNetworkHealthOptions): Promise<NetworkHealthResult>;
4893
4909
 
4894
- export { type AddressInfo, type AddressModuleSet, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, DELIVERY_ENCRYPTION_HKDF_INFO, type DeliveryBundle, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, FIELD_ENCRYPTION_HKDF_INFO, FIELD_ENVELOPE_MAX_BYTES, FIELD_ENVELOPE_NONCE_BYTES, FIELD_ENVELOPE_PREFIX, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, PartialSendConflictError, SIGN_MESSAGE_PREFIX, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, type WalletApiTransportConfig, assertFieldEnvelopeShape, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, createKeyPair, createSphere, decrypt, decryptDeliveryBundle, decryptField, decryptFieldBytes, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveDeliveryEncryptionKey, deriveFieldEncryptionKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, encrypt, encryptDeliveryBundle, encryptField, encryptFieldBytes, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressFromMasterKey, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getPublicKey, hash160, hashSignMessage, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isPossiblyCommittedSendOutcome, isSphereError, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, parseTokenAmount, randomBytes, randomHex, randomUUID, recoverPubkeyFromSignature, ripemd160, safeParseTokenAmount, serializeEncrypted, sha256, signMessage, sleep, sphereExists, toHumanReadable, validateMnemonic, verifySignedMessage };
4910
+ export { type AddressInfo, type AddressModuleSet, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, DELIVERY_ENCRYPTION_HKDF_INFO, type DeliveryBundle, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, FIELD_ENCRYPTION_HKDF_INFO, FIELD_ENVELOPE_MAX_BYTES, FIELD_ENVELOPE_NONCE_BYTES, FIELD_ENVELOPE_PREFIX, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, NO_PAYMENTS, PartialSendConflictError, SIGN_MESSAGE_PREFIX, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, type WalletApiOption, type WalletApiTransportConfig, assertFieldEnvelopeShape, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, createKeyPair, createSphere, decrypt, decryptDeliveryBundle, decryptField, decryptFieldBytes, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveDeliveryEncryptionKey, deriveFieldEncryptionKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, encrypt, encryptDeliveryBundle, encryptField, encryptFieldBytes, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressFromMasterKey, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getPublicKey, hash160, hashSignMessage, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isPossiblyCommittedSendOutcome, isSphereError, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, parseTokenAmount, randomBytes, randomHex, randomUUID, recoverPubkeyFromSignature, ripemd160, safeParseTokenAmount, serializeEncrypted, sha256, signMessage, sleep, sphereExists, toHumanReadable, validateMnemonic, verifySignedMessage };
@@ -16976,7 +16976,16 @@ var WalletApiSplitCheckpointStore = class {
16976
16976
  };
16977
16977
 
16978
16978
  // core/payments-v2-wiring.ts
16979
+ var NO_PAYMENTS = "none";
16980
+ function readPaymentsOptOut(walletApi) {
16981
+ if (walletApi === NO_PAYMENTS) return NO_PAYMENTS;
16982
+ throw new SphereError(
16983
+ `walletApi must be a wallet-api transport config or the literal '${NO_PAYMENTS}' (the explicit messaging-only opt-out, #793) \u2014 received ${JSON.stringify(walletApi)}.`,
16984
+ "INVALID_CONFIG"
16985
+ );
16986
+ }
16979
16987
  function resolvePaymentsV2Composition(walletApi, sphereNetwork) {
16988
+ if (typeof walletApi === "string") return readPaymentsOptOut(walletApi);
16980
16989
  const source = walletApi;
16981
16990
  const network = typeof source?.network === "string" && source.network !== "" ? source.network : null;
16982
16991
  if (!source || network === null) {
@@ -17256,7 +17265,11 @@ var Sphere = class _Sphere {
17256
17265
  // The payments vertical (the ONLY money path since the P11 flip)
17257
17266
  /** The ACTIVE address's running vertical — §7: exactly one at a time, ever. */
17258
17267
  _paymentsV2Active = null;
17259
- /** Resolved wallet-api transport composition (network + per-address factory); set at init, fail-closed. */
17268
+ /**
17269
+ * Money composition, set at init. `null` = never resolved (a construction bug),
17270
+ * `NO_PAYMENTS` = the explicit #793 opt-out, an object = a real composition. One
17271
+ * spelling for the last two would read a forgotten resolve as messaging-only.
17272
+ */
17260
17273
  _paymentsV2Composition = null;
17261
17274
  /**
17262
17275
  * §7 lifecycle mutex: every stop/start pair runs strictly serialized, so
@@ -17932,10 +17945,24 @@ var Sphere = class _Sphere {
17932
17945
  get payments() {
17933
17946
  const facade = this._paymentsV2Active?.facade;
17934
17947
  if (!facade) {
17948
+ if (this._paymentsV2Composition === NO_PAYMENTS) {
17949
+ throw new SphereError(
17950
+ "payments is not composed: this Sphere was initialised with `walletApi: 'none'`, the explicit messaging-only composition. Money has no path here \u2014 re-init with a wallet-api transport config to move any.",
17951
+ "PAYMENTS_NOT_COMPOSED"
17952
+ );
17953
+ }
17935
17954
  throw new SphereError("Sphere not initialized", "NOT_INITIALIZED");
17936
17955
  }
17937
17956
  return facade;
17938
17957
  }
17958
+ /**
17959
+ * Whether this Sphere composes money at all (#793) — fixed for the instance's life,
17960
+ * so a messaging-only wallet can branch without a try/catch. Not a liveness check:
17961
+ * `true` still leaves `payments` throwing NOT_INITIALIZED mid-init or mid-switch.
17962
+ */
17963
+ get hasPayments() {
17964
+ return this._paymentsV2Composition !== NO_PAYMENTS;
17965
+ }
17939
17966
  /** Communications module */
17940
17967
  get communications() {
17941
17968
  this.ensureReady();
@@ -19963,6 +19990,7 @@ var Sphere = class _Sphere {
19963
19990
  * breaks initialization.
19964
19991
  */
19965
19992
  async buildTokenEngine(identity) {
19993
+ if (this._paymentsV2Composition === NO_PAYMENTS) return void 0;
19966
19994
  const oracle = this._oracle;
19967
19995
  const privateKey = (identity ?? this._identity)?.privateKey;
19968
19996
  const trustBaseJson = oracle.getTrustBaseJson?.() ?? null;
@@ -20068,6 +20096,7 @@ var Sphere = class _Sphere {
20068
20096
  * setOracleApiKey rebuild is what future operations snapshot.
20069
20097
  */
20070
20098
  async startPaymentsV2Inner(index, identity) {
20099
+ if (this._paymentsV2Composition === NO_PAYMENTS) return;
20071
20100
  if (!this._paymentsV2Composition) {
20072
20101
  throw new SphereError("wallet-api composition required for money", "INVALID_CONFIG");
20073
20102
  }
@@ -20447,6 +20476,7 @@ export {
20447
20476
  FIELD_ENVELOPE_MAX_BYTES,
20448
20477
  FIELD_ENVELOPE_NONCE_BYTES,
20449
20478
  FIELD_ENVELOPE_PREFIX,
20479
+ NO_PAYMENTS,
20450
20480
  PartialSendConflictError,
20451
20481
  SIGN_MESSAGE_PREFIX,
20452
20482
  Sphere,