@orbinum/sdk 0.18.0 → 0.20.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.mts CHANGED
@@ -2357,36 +2357,140 @@ declare const BABYJUB_SUBORDER = 27360303589799094027808007181571593860768139721
2357
2357
  */
2358
2358
  declare function randomBlinding(): bigint;
2359
2359
 
2360
+ /**
2361
+ * SpendingKeyRequest
2362
+ *
2363
+ * What the user signs to derive their Orbinum spending key, per platform.
2364
+ *
2365
+ * These builders produce the *request* (typed data or message string). Turning a
2366
+ * signature into key material lives in `PrivacyKeys` — the split keeps the
2367
+ * platform-specific presentation away from the platform-agnostic KDF.
2368
+ *
2369
+ * SECURITY MODEL
2370
+ *
2371
+ * The signature seeds the spending key, so a deterministic signature over a
2372
+ * fixed, public string is a bearer token: any dapp the user connects to can
2373
+ * request the same string, obtain a byte-identical signature (ECDSA personal_sign
2374
+ * is deterministic, RFC-6979) and reconstruct the spending key, viewing key and
2375
+ * vault key. That is the v1 flaw these builders exist to close.
2376
+ *
2377
+ * The defense has two independent layers:
2378
+ *
2379
+ * 1. Message layer (here) — bind the signature to a domain the user can see.
2380
+ * EVM uses EIP-712, whose domain the wallet renders. Substrate has no
2381
+ * EIP-712, so the warning travels inside the signed text instead. NOTE this
2382
+ * layer is about VISIBILITY, not impossibility: nothing stops a hostile
2383
+ * origin from requesting the same payload, and no wallet verifies that
2384
+ * `verifyingContract` matches the requesting origin.
2385
+ * 2. Derivation layer (`PrivacyKeys`) — the HKDF `info` carries the version, so
2386
+ * v1 and v2 are disjoint identities even given identical signature bytes.
2387
+ * This is the layer that holds when layer 1 fails (e.g. a wallet that
2388
+ * truncates the warning text).
2389
+ *
2390
+ * DETERMINISM IS MANDATORY. No builder may add a nonce, timestamp or challenge:
2391
+ * the digest must stay a pure function of (chainId, address). A signature that
2392
+ * varies per session yields a different spending key each time, which makes
2393
+ * already-shielded notes unspendable — surfacing as an opaque Merkle constraint
2394
+ * failure during witness generation.
2395
+ */
2396
+ /**
2397
+ * EIP-712 `verifyingContract` for spending-key derivation: the shielded pool
2398
+ * precompile, i.e. the component that actually custodies shielded funds and so
2399
+ * the semantically correct domain anchor.
2400
+ *
2401
+ * WARNING: this value is part of the EIP-712 digest. Changing it changes every
2402
+ * derived spending key and orphans every existing note. It is a protocol
2403
+ * constant, not a config knob — which is why it is re-exported from the single
2404
+ * `PRECOMPILE_ADDR` source rather than written out a second time.
2405
+ */
2406
+ declare const SPENDING_KEY_VERIFYING_CONTRACT: "0x0000000000000000000000000000000000000801";
2407
+ /**
2408
+ * Shown to the user inside the wallet prompt. Wallets render EIP-712 message
2409
+ * fields (and Substrate raw text) verbatim, so this is the one surface a hostile
2410
+ * origin can neither suppress nor reword.
2411
+ */
2412
+ declare const SPENDING_KEY_WARNING: string;
2413
+ /** EIP-712 payload for `eth_signTypedData_v4`. */
2414
+ interface SpendingKeyTypedData {
2415
+ domain: {
2416
+ name: string;
2417
+ version: string;
2418
+ chainId: number;
2419
+ verifyingContract: string;
2420
+ };
2421
+ types: {
2422
+ SpendingKeyDerivation: ReadonlyArray<{
2423
+ name: string;
2424
+ type: string;
2425
+ }>;
2426
+ };
2427
+ primaryType: 'SpendingKeyDerivation';
2428
+ message: {
2429
+ warning: string;
2430
+ account: string;
2431
+ };
2432
+ }
2433
+ /**
2434
+ * EIP-712 typed data the user signs to derive their spending key (EVM route).
2435
+ * Pass the result to `eth_signTypedData_v4`.
2436
+ *
2437
+ * @param chainId Chain the identity belongs to; part of the domain separator.
2438
+ * @param address Signer address. Lowercased so checksum casing cannot fork the
2439
+ * identity into two distinct keys for the same account.
2440
+ */
2441
+ declare function deriveSpendingKeyTypedData(chainId: number, address: string): SpendingKeyTypedData;
2442
+ /**
2443
+ * Message the user signs on signers without EIP-712 (Substrate: sr25519 via VRF,
2444
+ * ed25519 via signRaw).
2445
+ *
2446
+ * Substrate wallets render the raw string, so the warning leads the text — it is
2447
+ * the only channel a malicious extension cannot rewrite. Its protection is
2448
+ * therefore conditional on the wallet not truncating the message; when it does,
2449
+ * only the HKDF domain separation in `PrivacyKeys` still applies.
2450
+ */
2451
+ declare function deriveSpendingKeyMessageV2(chainId: number, address: string): string;
2452
+
2360
2453
  /**
2361
2454
  * PrivacyKeys
2362
2455
  *
2363
- * Pure cryptographic derivation functions for the Orbinum shielded pool identity.
2364
- * These are protocol-level operations independent of storage, UI, or session.
2456
+ * Pure cryptographic derivation for the Orbinum shielded pool identity: turns a
2457
+ * wallet signature into key material, and key material into the public values
2458
+ * that make up a privacy address. Protocol-level only — no storage, UI or
2459
+ * session concerns. What the user *signs* to produce that signature lives in
2460
+ * `SpendingKeyRequest`.
2461
+ *
2462
+ * Full derivation chain:
2365
2463
  *
2366
- * Derivation scheme (ECDH viewing key — v2):
2367
- * viewingSecretKey (ivsk) = HKDF-SHA256(ikm=spendingKey_bytes, info="orbinum-ivk-v1") → 32 bytes
2368
- * ivsk_scalar = BigInt(ivsk_BE) % BABYJUB_SUBORDER (clamped to [1, ∞))
2369
- * viewingPublicKey (ivk) = BJJ_mul(Base8, ivsk_scalar) → packPoint([Ax, Ay]) → 32-byte bigint stored LE
2370
- * ownerPk = BabyJubJub Ax from (spendingKey * Base8) → bigint
2464
+ * signature ──HKDF(info="orbinum-sk-{version}:{chainId}:{address}")──► masterBytes (32B)
2465
+ *
2466
+ * ┌─────────────────────────────────────────────────────────────────┤
2467
+ * ▼ ▼
2468
+ * spendingKey = BigInt(masterBytes) % BABYJUB_SUBORDER vaultKey (see vault/)
2469
+ * │ = HKDF(masterBytes, "orbinum-vault-key-v1")
2470
+ * ├──► ownerPk = BJJ_mul(Base8, spendingKey).Ax (public)
2471
+ * │
2472
+ * └──► ivsk = HKDF(LE32(spendingKey), info="orbinum-ivk-v1") (secret)
2473
+ * └──► ivk = packPoint(BJJ_mul(Base8, ivsk_scalar)) (public)
2371
2474
  *
2372
- * Spending key derivation (from wallet signature):
2373
- * message = "orbinum-spending-key-v1\n${chainId}\n${address.toLowerCase()}"
2374
- * skBytes = HKDF-SHA256(ikm=sig_bytes, salt=empty, info="orbinum-sk-v1:${chainId}:${address}")
2375
- * spendingKey = BigInt(skBytes_as_big_endian) % BABYJUB_SUBORDER (if 0 1)
2475
+ * VERSIONING: the HKDF `info` carries the identity version, so v1 and v2 are
2476
+ * cryptographically disjoint even given identical signature bytes. This is the
2477
+ * layer that still separates the identities when the message-level defense fails
2478
+ * see the security model in `SpendingKeyRequest`.
2376
2479
  *
2377
- * IMPORTANT: must reduce mod BABYJUB_SUBORDER (not BN254_R). circomlib's BabyPbk uses
2378
- * Num2Bits(253) which asserts spending_key < 2^253. BABYJUB_SUBORDER < 2^252 satisfies
2379
- * this. BN254_R ≈ 2^254.8 does not — ~34% of values would exceed 2^253 at runtime.
2480
+ * MODULUS: reduce mod BABYJUB_SUBORDER, never BN254_R. circomlib's BabyPbk uses
2481
+ * Num2Bits(253), asserting spending_key < 2^253. BABYJUB_SUBORDER < 2^252
2482
+ * satisfies it; BN254_R ≈ 2^254.8 does not — ~34% of values would fail at runtime.
2380
2483
  */
2381
2484
  /**
2382
- * Returns the message string the user must sign with their wallet to derive
2383
- * a deterministic Orbinum spending key.
2485
+ * Shortest signature any supported signer produces: sr25519 VRF output is 32
2486
+ * bytes, ed25519 is 64, ECDSA `personal_sign` is 65. Anything shorter is not a
2487
+ * signature, so it must never reach the KDF.
2384
2488
  */
2385
- declare function deriveSpendingKeyMessage(chainId: number, address: string): string;
2489
+ declare const MIN_SIGNATURE_BYTES = 32;
2386
2490
  /**
2387
2491
  * Derives the 32-byte master key bytes from a wallet signature.
2388
2492
  *
2389
- * masterBytes = HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v1:{chainId}:{address}")
2493
+ * masterBytes = HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v2:{chainId}:{address}")
2390
2494
  *
2391
2495
  * These bytes are the stable root for ALL derived keys:
2392
2496
  * - spendingKey (circuit scalar) = BigInt(masterBytes) % BABYJUB_SUBORDER
@@ -2396,12 +2500,15 @@ declare function deriveSpendingKeyMessage(chainId: number, address: string): str
2396
2500
  * Separating masterBytes from the circuit scalar means the viewingSecretKey and
2397
2501
  * vault key are STABLE across any future change to the modulus — they never
2398
2502
  * depend on which prime field the circuit uses.
2503
+ *
2504
+ * @throws If the signature is not valid hex, or carries less entropy than the
2505
+ * shortest real signing scheme (see {@link MIN_SIGNATURE_BYTES}).
2399
2506
  */
2400
2507
  declare function deriveMasterKeyBytes(signatureHex: string, chainId: number, address: string): Promise<Uint8Array>;
2401
2508
  /**
2402
2509
  * Derives an Orbinum spending key from a wallet signature.
2403
2510
  *
2404
- * Uses HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v1:{chainId}:{address}")
2511
+ * Uses HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v2:{chainId}:{address}")
2405
2512
  * and reduces the resulting 32-byte value modulo BABYJUB_SUBORDER.
2406
2513
  *
2407
2514
  * IMPORTANT: viewingSecretKey and vaultKey must be derived from masterBytes (via
@@ -2412,6 +2519,8 @@ declare function deriveMasterKeyBytes(signatureHex: string, chainId: number, add
2412
2519
  * @param chainId Chain ID used when building the signing message.
2413
2520
  * @param address Signer address (EVM or SS58) used in the signing message.
2414
2521
  * @returns bigint in [1, BABYJUB_SUBORDER)
2522
+ * @throws If the signature is not valid hex or is shorter than
2523
+ * {@link MIN_SIGNATURE_BYTES} — see `deriveMasterKeyBytes`.
2415
2524
  */
2416
2525
  declare function deriveSpendingKeyFromSignature(signatureHex: string, chainId: number, address: string): Promise<bigint>;
2417
2526
  /**
@@ -4308,4 +4417,4 @@ interface ExtrinsicFailedData {
4308
4417
  dispatch_info: DispatchInfo;
4309
4418
  }
4310
4419
 
4311
- export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, CURRENT_CIRCUIT_VERSION, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, CircuitVersionResolver, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type ResolvedSpendVersion, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, type ScanCommitment, type SelfEphWindowEntry, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type StatusChangeEvent, type StatusListener, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TryDecryptOptions, type TxResult, type UnsafeTxOptions, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, blindTag, buildDummyTransferInput, bytesToBigintLE, computeNoteCommitment, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSelfEphSk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessage, deriveStealthOwnerPk, deriveStealthSk, deriveVaultBlindKey, deriveVaultKey, deriveViewTag, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, noteBlindTag, randomBlinding, recoverOwnerPkPoint, selectNotes, selfEphWindow, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
4420
+ export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, CURRENT_CIRCUIT_VERSION, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, CircuitVersionResolver, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, MIN_SIGNATURE_BYTES, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type ResolvedSpendVersion, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, SPENDING_KEY_VERIFYING_CONTRACT, SPENDING_KEY_WARNING, type ScanCommitment, type SelfEphWindowEntry, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type SpendingKeyTypedData, type StatusChangeEvent, type StatusListener, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TryDecryptOptions, type TxResult, type UnsafeTxOptions, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, blindTag, buildDummyTransferInput, bytesToBigintLE, computeNoteCommitment, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSelfEphSk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessageV2, deriveSpendingKeyTypedData, deriveStealthOwnerPk, deriveStealthSk, deriveVaultBlindKey, deriveVaultKey, deriveViewTag, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, noteBlindTag, randomBlinding, recoverOwnerPkPoint, selectNotes, selfEphWindow, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
package/dist/index.d.ts CHANGED
@@ -2357,36 +2357,140 @@ declare const BABYJUB_SUBORDER = 27360303589799094027808007181571593860768139721
2357
2357
  */
2358
2358
  declare function randomBlinding(): bigint;
2359
2359
 
2360
+ /**
2361
+ * SpendingKeyRequest
2362
+ *
2363
+ * What the user signs to derive their Orbinum spending key, per platform.
2364
+ *
2365
+ * These builders produce the *request* (typed data or message string). Turning a
2366
+ * signature into key material lives in `PrivacyKeys` — the split keeps the
2367
+ * platform-specific presentation away from the platform-agnostic KDF.
2368
+ *
2369
+ * SECURITY MODEL
2370
+ *
2371
+ * The signature seeds the spending key, so a deterministic signature over a
2372
+ * fixed, public string is a bearer token: any dapp the user connects to can
2373
+ * request the same string, obtain a byte-identical signature (ECDSA personal_sign
2374
+ * is deterministic, RFC-6979) and reconstruct the spending key, viewing key and
2375
+ * vault key. That is the v1 flaw these builders exist to close.
2376
+ *
2377
+ * The defense has two independent layers:
2378
+ *
2379
+ * 1. Message layer (here) — bind the signature to a domain the user can see.
2380
+ * EVM uses EIP-712, whose domain the wallet renders. Substrate has no
2381
+ * EIP-712, so the warning travels inside the signed text instead. NOTE this
2382
+ * layer is about VISIBILITY, not impossibility: nothing stops a hostile
2383
+ * origin from requesting the same payload, and no wallet verifies that
2384
+ * `verifyingContract` matches the requesting origin.
2385
+ * 2. Derivation layer (`PrivacyKeys`) — the HKDF `info` carries the version, so
2386
+ * v1 and v2 are disjoint identities even given identical signature bytes.
2387
+ * This is the layer that holds when layer 1 fails (e.g. a wallet that
2388
+ * truncates the warning text).
2389
+ *
2390
+ * DETERMINISM IS MANDATORY. No builder may add a nonce, timestamp or challenge:
2391
+ * the digest must stay a pure function of (chainId, address). A signature that
2392
+ * varies per session yields a different spending key each time, which makes
2393
+ * already-shielded notes unspendable — surfacing as an opaque Merkle constraint
2394
+ * failure during witness generation.
2395
+ */
2396
+ /**
2397
+ * EIP-712 `verifyingContract` for spending-key derivation: the shielded pool
2398
+ * precompile, i.e. the component that actually custodies shielded funds and so
2399
+ * the semantically correct domain anchor.
2400
+ *
2401
+ * WARNING: this value is part of the EIP-712 digest. Changing it changes every
2402
+ * derived spending key and orphans every existing note. It is a protocol
2403
+ * constant, not a config knob — which is why it is re-exported from the single
2404
+ * `PRECOMPILE_ADDR` source rather than written out a second time.
2405
+ */
2406
+ declare const SPENDING_KEY_VERIFYING_CONTRACT: "0x0000000000000000000000000000000000000801";
2407
+ /**
2408
+ * Shown to the user inside the wallet prompt. Wallets render EIP-712 message
2409
+ * fields (and Substrate raw text) verbatim, so this is the one surface a hostile
2410
+ * origin can neither suppress nor reword.
2411
+ */
2412
+ declare const SPENDING_KEY_WARNING: string;
2413
+ /** EIP-712 payload for `eth_signTypedData_v4`. */
2414
+ interface SpendingKeyTypedData {
2415
+ domain: {
2416
+ name: string;
2417
+ version: string;
2418
+ chainId: number;
2419
+ verifyingContract: string;
2420
+ };
2421
+ types: {
2422
+ SpendingKeyDerivation: ReadonlyArray<{
2423
+ name: string;
2424
+ type: string;
2425
+ }>;
2426
+ };
2427
+ primaryType: 'SpendingKeyDerivation';
2428
+ message: {
2429
+ warning: string;
2430
+ account: string;
2431
+ };
2432
+ }
2433
+ /**
2434
+ * EIP-712 typed data the user signs to derive their spending key (EVM route).
2435
+ * Pass the result to `eth_signTypedData_v4`.
2436
+ *
2437
+ * @param chainId Chain the identity belongs to; part of the domain separator.
2438
+ * @param address Signer address. Lowercased so checksum casing cannot fork the
2439
+ * identity into two distinct keys for the same account.
2440
+ */
2441
+ declare function deriveSpendingKeyTypedData(chainId: number, address: string): SpendingKeyTypedData;
2442
+ /**
2443
+ * Message the user signs on signers without EIP-712 (Substrate: sr25519 via VRF,
2444
+ * ed25519 via signRaw).
2445
+ *
2446
+ * Substrate wallets render the raw string, so the warning leads the text — it is
2447
+ * the only channel a malicious extension cannot rewrite. Its protection is
2448
+ * therefore conditional on the wallet not truncating the message; when it does,
2449
+ * only the HKDF domain separation in `PrivacyKeys` still applies.
2450
+ */
2451
+ declare function deriveSpendingKeyMessageV2(chainId: number, address: string): string;
2452
+
2360
2453
  /**
2361
2454
  * PrivacyKeys
2362
2455
  *
2363
- * Pure cryptographic derivation functions for the Orbinum shielded pool identity.
2364
- * These are protocol-level operations independent of storage, UI, or session.
2456
+ * Pure cryptographic derivation for the Orbinum shielded pool identity: turns a
2457
+ * wallet signature into key material, and key material into the public values
2458
+ * that make up a privacy address. Protocol-level only — no storage, UI or
2459
+ * session concerns. What the user *signs* to produce that signature lives in
2460
+ * `SpendingKeyRequest`.
2461
+ *
2462
+ * Full derivation chain:
2365
2463
  *
2366
- * Derivation scheme (ECDH viewing key — v2):
2367
- * viewingSecretKey (ivsk) = HKDF-SHA256(ikm=spendingKey_bytes, info="orbinum-ivk-v1") → 32 bytes
2368
- * ivsk_scalar = BigInt(ivsk_BE) % BABYJUB_SUBORDER (clamped to [1, ∞))
2369
- * viewingPublicKey (ivk) = BJJ_mul(Base8, ivsk_scalar) → packPoint([Ax, Ay]) → 32-byte bigint stored LE
2370
- * ownerPk = BabyJubJub Ax from (spendingKey * Base8) → bigint
2464
+ * signature ──HKDF(info="orbinum-sk-{version}:{chainId}:{address}")──► masterBytes (32B)
2465
+ *
2466
+ * ┌─────────────────────────────────────────────────────────────────┤
2467
+ * ▼ ▼
2468
+ * spendingKey = BigInt(masterBytes) % BABYJUB_SUBORDER vaultKey (see vault/)
2469
+ * │ = HKDF(masterBytes, "orbinum-vault-key-v1")
2470
+ * ├──► ownerPk = BJJ_mul(Base8, spendingKey).Ax (public)
2471
+ * │
2472
+ * └──► ivsk = HKDF(LE32(spendingKey), info="orbinum-ivk-v1") (secret)
2473
+ * └──► ivk = packPoint(BJJ_mul(Base8, ivsk_scalar)) (public)
2371
2474
  *
2372
- * Spending key derivation (from wallet signature):
2373
- * message = "orbinum-spending-key-v1\n${chainId}\n${address.toLowerCase()}"
2374
- * skBytes = HKDF-SHA256(ikm=sig_bytes, salt=empty, info="orbinum-sk-v1:${chainId}:${address}")
2375
- * spendingKey = BigInt(skBytes_as_big_endian) % BABYJUB_SUBORDER (if 0 1)
2475
+ * VERSIONING: the HKDF `info` carries the identity version, so v1 and v2 are
2476
+ * cryptographically disjoint even given identical signature bytes. This is the
2477
+ * layer that still separates the identities when the message-level defense fails
2478
+ * see the security model in `SpendingKeyRequest`.
2376
2479
  *
2377
- * IMPORTANT: must reduce mod BABYJUB_SUBORDER (not BN254_R). circomlib's BabyPbk uses
2378
- * Num2Bits(253) which asserts spending_key < 2^253. BABYJUB_SUBORDER < 2^252 satisfies
2379
- * this. BN254_R ≈ 2^254.8 does not — ~34% of values would exceed 2^253 at runtime.
2480
+ * MODULUS: reduce mod BABYJUB_SUBORDER, never BN254_R. circomlib's BabyPbk uses
2481
+ * Num2Bits(253), asserting spending_key < 2^253. BABYJUB_SUBORDER < 2^252
2482
+ * satisfies it; BN254_R ≈ 2^254.8 does not — ~34% of values would fail at runtime.
2380
2483
  */
2381
2484
  /**
2382
- * Returns the message string the user must sign with their wallet to derive
2383
- * a deterministic Orbinum spending key.
2485
+ * Shortest signature any supported signer produces: sr25519 VRF output is 32
2486
+ * bytes, ed25519 is 64, ECDSA `personal_sign` is 65. Anything shorter is not a
2487
+ * signature, so it must never reach the KDF.
2384
2488
  */
2385
- declare function deriveSpendingKeyMessage(chainId: number, address: string): string;
2489
+ declare const MIN_SIGNATURE_BYTES = 32;
2386
2490
  /**
2387
2491
  * Derives the 32-byte master key bytes from a wallet signature.
2388
2492
  *
2389
- * masterBytes = HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v1:{chainId}:{address}")
2493
+ * masterBytes = HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v2:{chainId}:{address}")
2390
2494
  *
2391
2495
  * These bytes are the stable root for ALL derived keys:
2392
2496
  * - spendingKey (circuit scalar) = BigInt(masterBytes) % BABYJUB_SUBORDER
@@ -2396,12 +2500,15 @@ declare function deriveSpendingKeyMessage(chainId: number, address: string): str
2396
2500
  * Separating masterBytes from the circuit scalar means the viewingSecretKey and
2397
2501
  * vault key are STABLE across any future change to the modulus — they never
2398
2502
  * depend on which prime field the circuit uses.
2503
+ *
2504
+ * @throws If the signature is not valid hex, or carries less entropy than the
2505
+ * shortest real signing scheme (see {@link MIN_SIGNATURE_BYTES}).
2399
2506
  */
2400
2507
  declare function deriveMasterKeyBytes(signatureHex: string, chainId: number, address: string): Promise<Uint8Array>;
2401
2508
  /**
2402
2509
  * Derives an Orbinum spending key from a wallet signature.
2403
2510
  *
2404
- * Uses HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v1:{chainId}:{address}")
2511
+ * Uses HKDF-SHA256(ikm=sigBytes, salt=empty, info="orbinum-sk-v2:{chainId}:{address}")
2405
2512
  * and reduces the resulting 32-byte value modulo BABYJUB_SUBORDER.
2406
2513
  *
2407
2514
  * IMPORTANT: viewingSecretKey and vaultKey must be derived from masterBytes (via
@@ -2412,6 +2519,8 @@ declare function deriveMasterKeyBytes(signatureHex: string, chainId: number, add
2412
2519
  * @param chainId Chain ID used when building the signing message.
2413
2520
  * @param address Signer address (EVM or SS58) used in the signing message.
2414
2521
  * @returns bigint in [1, BABYJUB_SUBORDER)
2522
+ * @throws If the signature is not valid hex or is shorter than
2523
+ * {@link MIN_SIGNATURE_BYTES} — see `deriveMasterKeyBytes`.
2415
2524
  */
2416
2525
  declare function deriveSpendingKeyFromSignature(signatureHex: string, chainId: number, address: string): Promise<bigint>;
2417
2526
  /**
@@ -4308,4 +4417,4 @@ interface ExtrinsicFailedData {
4308
4417
  dispatch_info: DispatchInfo;
4309
4418
  }
4310
4419
 
4311
- export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, CURRENT_CIRCUIT_VERSION, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, CircuitVersionResolver, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type ResolvedSpendVersion, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, type ScanCommitment, type SelfEphWindowEntry, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type StatusChangeEvent, type StatusListener, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TryDecryptOptions, type TxResult, type UnsafeTxOptions, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, blindTag, buildDummyTransferInput, bytesToBigintLE, computeNoteCommitment, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSelfEphSk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessage, deriveStealthOwnerPk, deriveStealthSk, deriveVaultBlindKey, deriveVaultKey, deriveViewTag, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, noteBlindTag, randomBlinding, recoverOwnerPkPoint, selectNotes, selfEphWindow, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
4420
+ export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, CURRENT_CIRCUIT_VERSION, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, CircuitVersionResolver, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, MIN_SIGNATURE_BYTES, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type ResolvedSpendVersion, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, SPENDING_KEY_VERIFYING_CONTRACT, SPENDING_KEY_WARNING, type ScanCommitment, type SelfEphWindowEntry, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type SpendingKeyTypedData, type StatusChangeEvent, type StatusListener, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TryDecryptOptions, type TxResult, type UnsafeTxOptions, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, blindTag, buildDummyTransferInput, bytesToBigintLE, computeNoteCommitment, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSelfEphSk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessageV2, deriveSpendingKeyTypedData, deriveStealthOwnerPk, deriveStealthSk, deriveVaultBlindKey, deriveVaultKey, deriveViewTag, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, noteBlindTag, randomBlinding, recoverOwnerPkPoint, selectNotes, selfEphWindow, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  EvmExplorer: () => EvmExplorer,
38
38
  KNOWN_PRECOMPILES: () => KNOWN_PRECOMPILES,
39
39
  Keccak256: () => import_substrate_bindings3.Keccak256,
40
+ MIN_SIGNATURE_BYTES: () => MIN_SIGNATURE_BYTES,
40
41
  NoteBuilder: () => NoteBuilder,
41
42
  OrbinumClient: () => OrbinumClient,
42
43
  OrbinumClientProvider: () => OrbinumClientProvider,
@@ -45,6 +46,8 @@ __export(index_exports, {
45
46
  PrivacyModule: () => PrivacyModule,
46
47
  RelayerStatusModule: () => RelayerStatusModule,
47
48
  SLIP0044_NAMESPACE: () => SLIP0044_NAMESPACE,
49
+ SPENDING_KEY_VERIFYING_CONTRACT: () => SPENDING_KEY_VERIFYING_CONTRACT,
50
+ SPENDING_KEY_WARNING: () => SPENDING_KEY_WARNING,
48
51
  ShieldedPoolModule: () => ShieldedPoolModule,
49
52
  ShieldedPoolPrecompile: () => ShieldedPoolPrecompile,
50
53
  SignatureScheme: () => SignatureScheme,
@@ -76,7 +79,8 @@ __export(index_exports, {
76
79
  deriveOwnerPk: () => deriveOwnerPk,
77
80
  deriveSelfEphSk: () => deriveSelfEphSk,
78
81
  deriveSpendingKeyFromSignature: () => deriveSpendingKeyFromSignature,
79
- deriveSpendingKeyMessage: () => deriveSpendingKeyMessage,
82
+ deriveSpendingKeyMessageV2: () => deriveSpendingKeyMessageV2,
83
+ deriveSpendingKeyTypedData: () => deriveSpendingKeyTypedData,
80
84
  deriveStealthOwnerPk: () => deriveStealthOwnerPk,
81
85
  deriveStealthSk: () => deriveStealthSk,
82
86
  deriveVaultBlindKey: () => deriveVaultBlindKey,
@@ -4201,19 +4205,58 @@ function randomBlinding() {
4201
4205
  return n === 0n ? 1n : n % BN254_R;
4202
4206
  }
4203
4207
 
4208
+ // src/privacy-keys/SpendingKeyRequest.ts
4209
+ var SPENDING_KEY_VERIFYING_CONTRACT = PRECOMPILE_ADDR.SHIELDED_POOL;
4210
+ var SPENDING_KEY_WARNING = "Signing this grants full control of your Orbinum private funds. Only sign on the official Orbinum app.";
4211
+ function deriveSpendingKeyTypedData(chainId, address) {
4212
+ return {
4213
+ domain: {
4214
+ name: "Orbinum Shielded Pool",
4215
+ version: "2",
4216
+ chainId,
4217
+ verifyingContract: SPENDING_KEY_VERIFYING_CONTRACT
4218
+ },
4219
+ types: {
4220
+ SpendingKeyDerivation: [
4221
+ { name: "warning", type: "string" },
4222
+ { name: "account", type: "address" }
4223
+ ]
4224
+ },
4225
+ primaryType: "SpendingKeyDerivation",
4226
+ message: {
4227
+ warning: SPENDING_KEY_WARNING,
4228
+ account: address.toLowerCase()
4229
+ }
4230
+ };
4231
+ }
4232
+ function deriveSpendingKeyMessageV2(chainId, address) {
4233
+ return `\u26A0 ${SPENDING_KEY_WARNING}
4234
+
4235
+ orbinum-spending-key-v2
4236
+ ${chainId}
4237
+ ${address.toLowerCase()}`;
4238
+ }
4239
+
4204
4240
  // src/privacy-keys/PrivacyKeys.ts
4205
4241
  var import_hkdf2 = require("@noble/hashes/hkdf.js");
4206
4242
  var import_sha24 = require("@noble/hashes/sha2.js");
4207
4243
  var import_baby_jubjub6 = require("@zk-kit/baby-jubjub");
4208
4244
  var IVK_DOMAIN = new TextEncoder().encode("orbinum-ivk-v1");
4209
- function deriveSpendingKeyMessage(chainId, address) {
4210
- return `orbinum-spending-key-v1
4211
- ${chainId}
4212
- ${address.toLowerCase()}`;
4245
+ var KEY_VERSION = "v2";
4246
+ var MIN_SIGNATURE_BYTES = 32;
4247
+ function assertUsableSignature(sigBytes) {
4248
+ if (sigBytes.length < MIN_SIGNATURE_BYTES) {
4249
+ throw new Error(
4250
+ `Cannot derive a spending key: signature is ${sigBytes.length} bytes, expected at least ${MIN_SIGNATURE_BYTES}. The wallet did not return a signature.`
4251
+ );
4252
+ }
4213
4253
  }
4214
4254
  async function deriveMasterKeyBytes(signatureHex, chainId, address) {
4215
4255
  const sigBytes = fromHex(signatureHex);
4216
- const info = new TextEncoder().encode(`orbinum-sk-v1:${chainId}:${address.toLowerCase()}`);
4256
+ assertUsableSignature(sigBytes);
4257
+ const info = new TextEncoder().encode(
4258
+ `orbinum-sk-${KEY_VERSION}:${chainId}:${address.toLowerCase()}`
4259
+ );
4217
4260
  return (0, import_hkdf2.hkdf)(import_sha24.sha256, sigBytes, new Uint8Array(0), info, 32);
4218
4261
  }
4219
4262
  async function deriveSpendingKeyFromSignature(signatureHex, chainId, address) {
@@ -5434,6 +5477,7 @@ var import_polkadot_api4 = require("polkadot-api");
5434
5477
  EvmExplorer,
5435
5478
  KNOWN_PRECOMPILES,
5436
5479
  Keccak256,
5480
+ MIN_SIGNATURE_BYTES,
5437
5481
  NoteBuilder,
5438
5482
  OrbinumClient,
5439
5483
  OrbinumClientProvider,
@@ -5442,6 +5486,8 @@ var import_polkadot_api4 = require("polkadot-api");
5442
5486
  PrivacyModule,
5443
5487
  RelayerStatusModule,
5444
5488
  SLIP0044_NAMESPACE,
5489
+ SPENDING_KEY_VERIFYING_CONTRACT,
5490
+ SPENDING_KEY_WARNING,
5445
5491
  ShieldedPoolModule,
5446
5492
  ShieldedPoolPrecompile,
5447
5493
  SignatureScheme,
@@ -5473,7 +5519,8 @@ var import_polkadot_api4 = require("polkadot-api");
5473
5519
  deriveOwnerPk,
5474
5520
  deriveSelfEphSk,
5475
5521
  deriveSpendingKeyFromSignature,
5476
- deriveSpendingKeyMessage,
5522
+ deriveSpendingKeyMessageV2,
5523
+ deriveSpendingKeyTypedData,
5477
5524
  deriveStealthOwnerPk,
5478
5525
  deriveStealthSk,
5479
5526
  deriveVaultBlindKey,
package/dist/index.mjs CHANGED
@@ -4069,19 +4069,58 @@ function randomBlinding() {
4069
4069
  return n === 0n ? 1n : n % BN254_R;
4070
4070
  }
4071
4071
 
4072
+ // src/privacy-keys/SpendingKeyRequest.ts
4073
+ var SPENDING_KEY_VERIFYING_CONTRACT = PRECOMPILE_ADDR.SHIELDED_POOL;
4074
+ var SPENDING_KEY_WARNING = "Signing this grants full control of your Orbinum private funds. Only sign on the official Orbinum app.";
4075
+ function deriveSpendingKeyTypedData(chainId, address) {
4076
+ return {
4077
+ domain: {
4078
+ name: "Orbinum Shielded Pool",
4079
+ version: "2",
4080
+ chainId,
4081
+ verifyingContract: SPENDING_KEY_VERIFYING_CONTRACT
4082
+ },
4083
+ types: {
4084
+ SpendingKeyDerivation: [
4085
+ { name: "warning", type: "string" },
4086
+ { name: "account", type: "address" }
4087
+ ]
4088
+ },
4089
+ primaryType: "SpendingKeyDerivation",
4090
+ message: {
4091
+ warning: SPENDING_KEY_WARNING,
4092
+ account: address.toLowerCase()
4093
+ }
4094
+ };
4095
+ }
4096
+ function deriveSpendingKeyMessageV2(chainId, address) {
4097
+ return `\u26A0 ${SPENDING_KEY_WARNING}
4098
+
4099
+ orbinum-spending-key-v2
4100
+ ${chainId}
4101
+ ${address.toLowerCase()}`;
4102
+ }
4103
+
4072
4104
  // src/privacy-keys/PrivacyKeys.ts
4073
4105
  import { hkdf as hkdf2 } from "@noble/hashes/hkdf.js";
4074
4106
  import { sha256 as sha2564 } from "@noble/hashes/sha2.js";
4075
4107
  import { mulPointEscalar as mulPointEscalar4, Base8 as Base82, packPoint as packPoint3 } from "@zk-kit/baby-jubjub";
4076
4108
  var IVK_DOMAIN = new TextEncoder().encode("orbinum-ivk-v1");
4077
- function deriveSpendingKeyMessage(chainId, address) {
4078
- return `orbinum-spending-key-v1
4079
- ${chainId}
4080
- ${address.toLowerCase()}`;
4109
+ var KEY_VERSION = "v2";
4110
+ var MIN_SIGNATURE_BYTES = 32;
4111
+ function assertUsableSignature(sigBytes) {
4112
+ if (sigBytes.length < MIN_SIGNATURE_BYTES) {
4113
+ throw new Error(
4114
+ `Cannot derive a spending key: signature is ${sigBytes.length} bytes, expected at least ${MIN_SIGNATURE_BYTES}. The wallet did not return a signature.`
4115
+ );
4116
+ }
4081
4117
  }
4082
4118
  async function deriveMasterKeyBytes(signatureHex, chainId, address) {
4083
4119
  const sigBytes = fromHex(signatureHex);
4084
- const info = new TextEncoder().encode(`orbinum-sk-v1:${chainId}:${address.toLowerCase()}`);
4120
+ assertUsableSignature(sigBytes);
4121
+ const info = new TextEncoder().encode(
4122
+ `orbinum-sk-${KEY_VERSION}:${chainId}:${address.toLowerCase()}`
4123
+ );
4085
4124
  return hkdf2(sha2564, sigBytes, new Uint8Array(0), info, 32);
4086
4125
  }
4087
4126
  async function deriveSpendingKeyFromSignature(signatureHex, chainId, address) {
@@ -5324,6 +5363,7 @@ export {
5324
5363
  EvmExplorer,
5325
5364
  KNOWN_PRECOMPILES,
5326
5365
  Keccak256,
5366
+ MIN_SIGNATURE_BYTES,
5327
5367
  NoteBuilder,
5328
5368
  OrbinumClient,
5329
5369
  OrbinumClientProvider,
@@ -5332,6 +5372,8 @@ export {
5332
5372
  PrivacyModule,
5333
5373
  RelayerStatusModule,
5334
5374
  SLIP0044_NAMESPACE,
5375
+ SPENDING_KEY_VERIFYING_CONTRACT,
5376
+ SPENDING_KEY_WARNING,
5335
5377
  ShieldedPoolModule,
5336
5378
  ShieldedPoolPrecompile,
5337
5379
  SignatureScheme,
@@ -5363,7 +5405,8 @@ export {
5363
5405
  deriveOwnerPk,
5364
5406
  deriveSelfEphSk,
5365
5407
  deriveSpendingKeyFromSignature,
5366
- deriveSpendingKeyMessage,
5408
+ deriveSpendingKeyMessageV2,
5409
+ deriveSpendingKeyTypedData,
5367
5410
  deriveStealthOwnerPk,
5368
5411
  deriveStealthSk,
5369
5412
  deriveVaultBlindKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbinum/sdk",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Official TypeScript SDK for Orbinum.",
5
5
  "author": "Orbinum",
6
6
  "license": "MIT",