@unlink-xyz/core 0.1.3-canary.79048c8 → 0.1.3-canary.7a2ea6a

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.
Files changed (247) hide show
  1. package/README.md +9 -0
  2. package/dist/account/{zkAccount.d.ts → account.d.ts} +36 -5
  3. package/dist/account/account.d.ts.map +1 -0
  4. package/dist/account/{zkAccount.js → account.js} +57 -38
  5. package/dist/account/accounts.d.ts +42 -0
  6. package/dist/account/accounts.d.ts.map +1 -0
  7. package/dist/account/accounts.js +119 -0
  8. package/dist/account/seed.d.ts +45 -0
  9. package/dist/account/seed.d.ts.map +1 -0
  10. package/dist/account/seed.js +91 -0
  11. package/dist/account/serialization.d.ts +6 -0
  12. package/dist/account/serialization.d.ts.map +1 -0
  13. package/dist/account/serialization.js +53 -0
  14. package/dist/browser/index.js +56217 -0
  15. package/dist/browser/index.js.map +1 -0
  16. package/dist/browser/wallet/index.js +55942 -0
  17. package/dist/browser/wallet/index.js.map +1 -0
  18. package/dist/circuits.json +54 -6
  19. package/dist/clients/broadcaster.d.ts +8 -2
  20. package/dist/clients/broadcaster.d.ts.map +1 -1
  21. package/dist/clients/broadcaster.js +32 -1
  22. package/dist/clients/http.d.ts.map +1 -1
  23. package/dist/clients/http.js +16 -9
  24. package/dist/clients/indexer.d.ts +15 -0
  25. package/dist/clients/indexer.d.ts.map +1 -1
  26. package/dist/clients/indexer.js +44 -13
  27. package/dist/config.d.ts +28 -16
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +61 -40
  30. package/dist/constants.d.ts +6 -0
  31. package/dist/constants.d.ts.map +1 -0
  32. package/dist/constants.js +5 -0
  33. package/dist/core.d.ts.map +1 -1
  34. package/dist/core.js +3 -4
  35. package/dist/crypto/adapters/index.d.ts +17 -0
  36. package/dist/crypto/adapters/index.d.ts.map +1 -0
  37. package/dist/crypto/adapters/index.js +53 -0
  38. package/dist/crypto/adapters/polyfills.d.ts +5 -0
  39. package/dist/crypto/adapters/polyfills.d.ts.map +1 -0
  40. package/dist/crypto/adapters/polyfills.js +8 -0
  41. package/dist/crypto/encrypt.d.ts +33 -0
  42. package/dist/crypto/encrypt.d.ts.map +1 -0
  43. package/dist/crypto/encrypt.js +84 -0
  44. package/dist/crypto/secure-memory.d.ts.map +1 -0
  45. package/dist/errors.d.ts +17 -0
  46. package/dist/errors.d.ts.map +1 -1
  47. package/dist/errors.js +32 -0
  48. package/dist/history/service.d.ts +4 -4
  49. package/dist/history/service.d.ts.map +1 -1
  50. package/dist/history/service.js +1 -1
  51. package/dist/index.d.ts +11 -8
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +9 -8
  54. package/dist/keys/address.d.ts +13 -0
  55. package/dist/keys/address.d.ts.map +1 -0
  56. package/dist/keys/address.js +55 -0
  57. package/dist/keys/derive.d.ts +37 -0
  58. package/dist/keys/derive.d.ts.map +1 -0
  59. package/dist/keys/derive.js +109 -0
  60. package/dist/keys/hex.d.ts +14 -0
  61. package/dist/keys/hex.d.ts.map +1 -0
  62. package/dist/keys/hex.js +47 -0
  63. package/dist/keys/index.d.ts +5 -0
  64. package/dist/keys/index.d.ts.map +1 -0
  65. package/dist/keys/index.js +4 -0
  66. package/dist/keys/mnemonic.d.ts +6 -0
  67. package/dist/keys/mnemonic.d.ts.map +1 -0
  68. package/dist/keys/mnemonic.js +16 -0
  69. package/dist/keys.d.ts +1 -0
  70. package/dist/keys.d.ts.map +1 -1
  71. package/dist/keys.js +1 -0
  72. package/dist/prover/config.d.ts +53 -22
  73. package/dist/prover/config.d.ts.map +1 -1
  74. package/dist/prover/config.js +65 -23
  75. package/dist/prover/integrity.d.ts +20 -0
  76. package/dist/prover/integrity.d.ts.map +1 -0
  77. package/dist/prover/integrity.js +93 -0
  78. package/dist/prover/prover.d.ts +16 -20
  79. package/dist/prover/prover.d.ts.map +1 -1
  80. package/dist/prover/prover.js +262 -137
  81. package/dist/prover/registry.d.ts +3 -30
  82. package/dist/prover/registry.d.ts.map +1 -1
  83. package/dist/prover/registry.js +12 -51
  84. package/dist/state/merkle/hydrator.d.ts +21 -19
  85. package/dist/state/merkle/hydrator.d.ts.map +1 -1
  86. package/dist/state/merkle/hydrator.js +20 -27
  87. package/dist/state/merkle/index.d.ts +1 -1
  88. package/dist/state/merkle/index.d.ts.map +1 -1
  89. package/dist/state/merkle/merkle-tree.d.ts.map +1 -1
  90. package/dist/state/merkle/merkle-tree.js +8 -7
  91. package/dist/state/store/ciphertext-store.d.ts +11 -0
  92. package/dist/state/store/ciphertext-store.d.ts.map +1 -1
  93. package/dist/state/store/ciphertext-store.js +26 -0
  94. package/dist/state/store/index.d.ts +1 -1
  95. package/dist/state/store/index.d.ts.map +1 -1
  96. package/dist/state/store/job-store.d.ts +7 -7
  97. package/dist/state/store/job-store.d.ts.map +1 -1
  98. package/dist/state/store/job-store.js +74 -37
  99. package/dist/state/store/jobs.d.ts +62 -30
  100. package/dist/state/store/jobs.d.ts.map +1 -1
  101. package/dist/state/store/leaf-store.d.ts +4 -0
  102. package/dist/state/store/leaf-store.d.ts.map +1 -1
  103. package/dist/state/store/leaf-store.js +11 -1
  104. package/dist/state/store/note-store.d.ts +6 -2
  105. package/dist/state/store/note-store.d.ts.map +1 -1
  106. package/dist/state/store/note-store.js +22 -4
  107. package/dist/state/store/nullifier-store.d.ts +9 -0
  108. package/dist/state/store/nullifier-store.d.ts.map +1 -1
  109. package/dist/state/store/nullifier-store.js +31 -1
  110. package/dist/state/store/records.d.ts +14 -0
  111. package/dist/state/store/records.d.ts.map +1 -1
  112. package/dist/state/store/store.d.ts +42 -8
  113. package/dist/state/store/store.d.ts.map +1 -1
  114. package/dist/state/store/store.js +158 -1
  115. package/dist/storage/indexeddb.d.ts.map +1 -1
  116. package/dist/storage/indexeddb.js +70 -32
  117. package/dist/storage/memory.d.ts.map +1 -1
  118. package/dist/storage/memory.js +10 -0
  119. package/dist/transactions/adapter.d.ts +31 -0
  120. package/dist/transactions/adapter.d.ts.map +1 -0
  121. package/dist/transactions/adapter.js +106 -0
  122. package/dist/transactions/deposit.d.ts +6 -4
  123. package/dist/transactions/deposit.d.ts.map +1 -1
  124. package/dist/transactions/deposit.js +176 -85
  125. package/dist/transactions/index.d.ts +7 -4
  126. package/dist/transactions/index.d.ts.map +1 -1
  127. package/dist/transactions/index.js +5 -3
  128. package/dist/transactions/note-selection.d.ts +1 -1
  129. package/dist/transactions/note-selection.d.ts.map +1 -1
  130. package/dist/transactions/note-selection.js +14 -9
  131. package/dist/transactions/note-sync.d.ts +3 -8
  132. package/dist/transactions/note-sync.d.ts.map +1 -1
  133. package/dist/transactions/note-sync.js +476 -170
  134. package/dist/transactions/reconcile.d.ts +3 -3
  135. package/dist/transactions/reconcile.d.ts.map +1 -1
  136. package/dist/transactions/reconcile.js +27 -10
  137. package/dist/transactions/transact.d.ts +27 -5
  138. package/dist/transactions/transact.d.ts.map +1 -1
  139. package/dist/transactions/transact.js +265 -163
  140. package/dist/transactions/transaction-planner.d.ts +2 -2
  141. package/dist/transactions/transaction-planner.d.ts.map +1 -1
  142. package/dist/transactions/transaction-planner.js +16 -13
  143. package/dist/transactions/transfer-planner.d.ts +37 -0
  144. package/dist/transactions/transfer-planner.d.ts.map +1 -0
  145. package/dist/transactions/transfer-planner.js +91 -0
  146. package/dist/transactions/types/deposit.d.ts +36 -14
  147. package/dist/transactions/types/deposit.d.ts.map +1 -1
  148. package/dist/transactions/types/domain.d.ts +3 -0
  149. package/dist/transactions/types/domain.d.ts.map +1 -1
  150. package/dist/transactions/types/options.d.ts +18 -1
  151. package/dist/transactions/types/options.d.ts.map +1 -1
  152. package/dist/transactions/types/planning.d.ts +2 -0
  153. package/dist/transactions/types/planning.d.ts.map +1 -1
  154. package/dist/transactions/types/state-stores.d.ts +113 -13
  155. package/dist/transactions/types/state-stores.d.ts.map +1 -1
  156. package/dist/transactions/types/transact.d.ts +39 -17
  157. package/dist/transactions/types/transact.d.ts.map +1 -1
  158. package/dist/transactions/withdrawal-planner.d.ts +25 -28
  159. package/dist/transactions/withdrawal-planner.d.ts.map +1 -1
  160. package/dist/transactions/withdrawal-planner.js +77 -47
  161. package/dist/tsconfig.tsbuildinfo +1 -1
  162. package/dist/tsup.browser.config.d.ts +7 -0
  163. package/dist/tsup.browser.config.d.ts.map +1 -0
  164. package/dist/tsup.browser.config.js +34 -0
  165. package/dist/types.d.ts +1 -0
  166. package/dist/types.d.ts.map +1 -1
  167. package/dist/utils/amounts.d.ts +1 -14
  168. package/dist/utils/amounts.d.ts.map +1 -1
  169. package/dist/utils/amounts.js +6 -39
  170. package/dist/utils/async.d.ts +9 -0
  171. package/dist/utils/async.d.ts.map +1 -1
  172. package/dist/utils/async.js +24 -0
  173. package/dist/utils/bigint.d.ts +0 -2
  174. package/dist/utils/bigint.d.ts.map +1 -1
  175. package/dist/utils/bigint.js +5 -17
  176. package/dist/utils/json-codec.js +1 -1
  177. package/dist/utils/polling.d.ts +5 -0
  178. package/dist/utils/polling.d.ts.map +1 -1
  179. package/dist/utils/polling.js +5 -0
  180. package/dist/utils/random.d.ts +5 -0
  181. package/dist/utils/random.d.ts.map +1 -1
  182. package/dist/utils/random.js +7 -0
  183. package/dist/utils/signature.js +1 -1
  184. package/dist/utils/validators.d.ts +16 -3
  185. package/dist/utils/validators.d.ts.map +1 -1
  186. package/dist/utils/validators.js +28 -21
  187. package/dist/vitest.config.d.ts.map +1 -1
  188. package/dist/vitest.config.js +0 -11
  189. package/dist/wallet/adapter.d.ts +21 -0
  190. package/dist/wallet/adapter.d.ts.map +1 -0
  191. package/dist/wallet/adapter.js +210 -0
  192. package/dist/wallet/burner/service.d.ts +32 -0
  193. package/dist/wallet/burner/service.d.ts.map +1 -0
  194. package/dist/wallet/burner/service.js +121 -0
  195. package/dist/wallet/burner/types.d.ts +47 -0
  196. package/dist/wallet/burner/types.d.ts.map +1 -0
  197. package/dist/wallet/burner/types.js +1 -0
  198. package/dist/wallet/index.d.ts +20 -0
  199. package/dist/wallet/index.d.ts.map +1 -0
  200. package/dist/wallet/index.js +12 -0
  201. package/dist/wallet/sdk.d.ts +48 -0
  202. package/dist/wallet/sdk.d.ts.map +1 -0
  203. package/dist/wallet/sdk.js +706 -0
  204. package/dist/wallet/types.d.ts +457 -0
  205. package/dist/wallet/types.d.ts.map +1 -0
  206. package/dist/wallet/types.js +2 -0
  207. package/dist/wallet/unlink-wallet.d.ts +187 -0
  208. package/dist/wallet/unlink-wallet.d.ts.map +1 -0
  209. package/dist/wallet/unlink-wallet.js +345 -0
  210. package/package.json +33 -11
  211. package/dist/account/zkAccount.d.ts.map +0 -1
  212. package/dist/crypto-adapters/auto-init.d.ts +0 -2
  213. package/dist/crypto-adapters/auto-init.d.ts.map +0 -1
  214. package/dist/crypto-adapters/auto-init.js +0 -7
  215. package/dist/crypto-adapters/index.d.ts +0 -22
  216. package/dist/crypto-adapters/index.d.ts.map +0 -1
  217. package/dist/crypto-adapters/index.js +0 -46
  218. package/dist/crypto-adapters/polyfills.d.ts +0 -5
  219. package/dist/crypto-adapters/polyfills.d.ts.map +0 -1
  220. package/dist/crypto-adapters/polyfills.js +0 -8
  221. package/dist/key-derivation/bech32.d.ts +0 -22
  222. package/dist/key-derivation/bech32.d.ts.map +0 -1
  223. package/dist/key-derivation/bech32.js +0 -86
  224. package/dist/key-derivation/bip32.d.ts +0 -17
  225. package/dist/key-derivation/bip32.d.ts.map +0 -1
  226. package/dist/key-derivation/bip32.js +0 -41
  227. package/dist/key-derivation/bip39.d.ts +0 -22
  228. package/dist/key-derivation/bip39.d.ts.map +0 -1
  229. package/dist/key-derivation/bip39.js +0 -57
  230. package/dist/key-derivation/bytes.d.ts +0 -19
  231. package/dist/key-derivation/bytes.d.ts.map +0 -1
  232. package/dist/key-derivation/bytes.js +0 -92
  233. package/dist/key-derivation/hash.d.ts +0 -3
  234. package/dist/key-derivation/hash.d.ts.map +0 -1
  235. package/dist/key-derivation/hash.js +0 -10
  236. package/dist/key-derivation/index.d.ts +0 -7
  237. package/dist/key-derivation/index.d.ts.map +0 -1
  238. package/dist/key-derivation/index.js +0 -6
  239. package/dist/key-derivation/wallet-node.d.ts +0 -47
  240. package/dist/key-derivation/wallet-node.d.ts.map +0 -1
  241. package/dist/key-derivation/wallet-node.js +0 -110
  242. package/dist/utils/crypto.d.ts +0 -12
  243. package/dist/utils/crypto.d.ts.map +0 -1
  244. package/dist/utils/crypto.js +0 -39
  245. package/dist/utils/secure-memory.d.ts.map +0 -1
  246. /package/dist/{utils → crypto}/secure-memory.d.ts +0 -0
  247. /package/dist/{utils → crypto}/secure-memory.js +0 -0
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @unlink-xyz/core
2
+
3
+ Low-level TypeScript SDK for the Unlink privacy protocol.
4
+
5
+ ## Overview
6
+
7
+ Core library providing key derivation, proof generation, transaction construction, state management, and high-level wallet API for UTXO-based private transactions on EVM blockchains. Used as a foundation by `@unlink-xyz/react` and consumed directly for server-side applications.
8
+
9
+ > **Documentation:** [SDK overview](../../docs/sdk/index.mdx) | [Architecture](../../docs/concepts/4-architecture/sdk.mdx)
@@ -1,4 +1,4 @@
1
- import { type SpendingKeyPair, type ViewingKeyPair } from "../key-derivation/wallet-node.js";
1
+ import { type SpendingKeyPair, type ViewingKeyPair } from "../keys/derive.js";
2
2
  import type { Storage } from "../types.js";
3
3
  export type MasterSeedCrypto = {
4
4
  encrypt(seed: Uint8Array): Promise<Uint8Array> | Uint8Array;
@@ -14,14 +14,45 @@ export type GenerateMasterSeedOptions = {
14
14
  export declare const MASTER_SEED_LENGTH = 64;
15
15
  export declare const MASTER_SEED_KEY = "cfg:wallet:master_seed/v1";
16
16
  export declare const MASTER_MNEMONIC_KEY = "cfg:wallet:master_mnemonic/v1";
17
- export type ZkAccount = {
17
+ export type Account = {
18
18
  spendingKeyPair: SpendingKeyPair;
19
19
  viewingKeyPair: ViewingKeyPair;
20
20
  nullifyingKey: bigint;
21
21
  masterPublicKey: bigint;
22
+ /** Bech32m address (0zk1...) for this account */
23
+ address: string;
22
24
  };
23
- export declare function deriveZkAccount(masterSeed: Uint8Array, accountIndex?: number): Promise<ZkAccount>;
24
- export declare function deriveZkAccountFromMnemonic(mnemonic: string, accountIndex?: number, password?: string): Promise<ZkAccount>;
25
+ /**
26
+ * Read-only account identity the fields needed by the transaction layer
27
+ * without any signing capability. Both Account and MultisigAccount satisfy this.
28
+ */
29
+ export type AccountView = {
30
+ nullifyingKey: bigint;
31
+ masterPublicKey: bigint;
32
+ viewingKeyPair: ViewingKeyPair;
33
+ address: string;
34
+ };
35
+ /**
36
+ * Signing capability decoupled from account identity.
37
+ * Async to support multi-round protocols (FROST), hardware wallets, etc.
38
+ */
39
+ export type Signer = {
40
+ publicKey: [bigint, bigint];
41
+ sign(message: bigint): Promise<{
42
+ R8: [bigint, bigint];
43
+ S: bigint;
44
+ }>;
45
+ };
46
+ /**
47
+ * Extract an AccountView from a full Account.
48
+ */
49
+ export declare function toAccountView(account: Account): AccountView;
50
+ /**
51
+ * Create a Signer from a single spending key pair.
52
+ */
53
+ export declare function createSingleKeySigner(privateKey: Uint8Array, pubkey: [bigint, bigint]): Signer;
54
+ export declare function deriveAccount(masterSeed: Uint8Array, accountIndex?: number): Account;
55
+ export declare function deriveAccountFromMnemonic(mnemonic: string, accountIndex?: number, password?: string): Account;
25
56
  export declare function generateMasterSeed({ storage, rng, crypto, overwrite, mnemonicPassphrase, }: GenerateMasterSeedOptions): Promise<Uint8Array>;
26
57
  export declare function loadMasterSeed(storage: Storage, crypto?: MasterSeedCrypto): Promise<Uint8Array | null>;
27
58
  export declare function storeMasterSeed(storage: Storage, seed: Uint8Array, crypto?: MasterSeedCrypto): Promise<void>;
@@ -35,4 +66,4 @@ export type ImportMasterMnemonicOptions = {
35
66
  };
36
67
  export declare function importMasterMnemonic({ storage, mnemonic, crypto, overwrite, password, }: ImportMasterMnemonicOptions): Promise<Uint8Array>;
37
68
  export declare function storeMasterMnemonic(storage: Storage, mnemonic: string, crypto?: MasterSeedCrypto): Promise<void>;
38
- //# sourceMappingURL=zkAccount.d.ts.map
69
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../account/account.ts"],"names":[],"mappings":"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"}
@@ -1,47 +1,68 @@
1
- import { Mnemonic } from "../key-derivation/bip39.js";
2
- import { ByteUtils } from "../key-derivation/bytes.js";
3
- import { deriveNodesFromSeed, WalletNode, } from "../key-derivation/wallet-node.js";
4
- import { zeroize } from "../utils/secure-memory.js";
1
+ import { zeroize } from "../crypto/secure-memory.js";
2
+ import { ValidationError } from "../errors.js";
3
+ import { encodeAddress } from "../keys/address.js";
4
+ import { deriveAccountKeys, } from "../keys/derive.js";
5
+ import { Hex } from "../keys/hex.js";
6
+ import { Mnemonic } from "../keys/mnemonic.js";
7
+ import { signTransactMessage } from "../utils/signature.js";
5
8
  export const MASTER_SEED_LENGTH = 64;
6
9
  export const MASTER_SEED_KEY = "cfg:wallet:master_seed/v1";
7
10
  export const MASTER_MNEMONIC_KEY = "cfg:wallet:master_mnemonic/v1";
8
11
  const MNEMONIC_ENTROPY_BYTES = 32;
9
12
  const textEncoder = new TextEncoder();
10
13
  const textDecoder = new TextDecoder();
11
- export async function deriveZkAccount(masterSeed, accountIndex = 0) {
14
+ /**
15
+ * Extract an AccountView from a full Account.
16
+ */
17
+ export function toAccountView(account) {
18
+ return {
19
+ nullifyingKey: account.nullifyingKey,
20
+ masterPublicKey: account.masterPublicKey,
21
+ viewingKeyPair: account.viewingKeyPair,
22
+ address: account.address,
23
+ };
24
+ }
25
+ /**
26
+ * Create a Signer from a single spending key pair.
27
+ */
28
+ export function createSingleKeySigner(privateKey, pubkey) {
29
+ return {
30
+ publicKey: pubkey,
31
+ sign: async (message) => signTransactMessage(privateKey, message),
32
+ };
33
+ }
34
+ export function deriveAccount(masterSeed, accountIndex = 0) {
12
35
  const seed = normalizeMasterSeed(masterSeed);
13
36
  if (!Number.isInteger(accountIndex) || accountIndex < 0) {
14
- throw new Error("accountIndex must be a non-negative integer");
37
+ throw new ValidationError("accountIndex must be a non-negative integer");
15
38
  }
16
- const { spending, viewing } = deriveNodesFromSeed(seed, accountIndex);
17
- const spendingKeyPair = spending.getSpendingKeyPair();
18
- const viewingKeyPair = await viewing.getViewingKeyPair();
19
- const nullifyingKey = WalletNode.getNullifyingKey(viewingKeyPair.privateKey);
20
- const masterPublicKey = WalletNode.getMasterPublicKey(spendingKeyPair.pubkey, nullifyingKey);
39
+ const keys = deriveAccountKeys(seed, accountIndex);
40
+ const address = encodeAddress({
41
+ masterPublicKey: keys.masterPublicKey,
42
+ viewingPublicKey: keys.viewing.pubkey,
43
+ });
21
44
  return {
22
- spendingKeyPair,
23
- viewingKeyPair,
24
- nullifyingKey,
25
- masterPublicKey,
45
+ spendingKeyPair: keys.spending,
46
+ viewingKeyPair: keys.viewing,
47
+ nullifyingKey: keys.nullifyingKey,
48
+ masterPublicKey: keys.masterPublicKey,
49
+ address,
26
50
  };
27
51
  }
28
- export async function deriveZkAccountFromMnemonic(mnemonic, accountIndex = 0, password = "") {
52
+ export function deriveAccountFromMnemonic(mnemonic, accountIndex = 0, password = "") {
29
53
  const normalized = normalizeMnemonic(mnemonic);
30
54
  const seed = mnemonicToSeed(normalized, password);
31
55
  try {
32
- return await deriveZkAccount(seed, accountIndex);
56
+ return deriveAccount(seed, accountIndex);
33
57
  }
34
58
  finally {
35
59
  zeroize(seed);
36
60
  }
37
61
  }
62
+ /** Passthrough crypto, storage handles buffer isolation */
38
63
  const identityMasterSeedCrypto = {
39
- encrypt(seed) {
40
- return clone(seed);
41
- },
42
- decrypt(payload) {
43
- return clone(payload);
44
- },
64
+ encrypt: (seed) => seed,
65
+ decrypt: (payload) => payload,
45
66
  };
46
67
  export async function generateMasterSeed({ storage, rng, crypto = identityMasterSeedCrypto, overwrite = false, mnemonicPassphrase, }) {
47
68
  if (!overwrite) {
@@ -57,10 +78,10 @@ export async function generateMasterSeed({ storage, rng, crypto = identityMaster
57
78
  }
58
79
  const entropy = rng(MNEMONIC_ENTROPY_BYTES);
59
80
  if (entropy.length !== MNEMONIC_ENTROPY_BYTES) {
60
- throw new Error(`mnemonic entropy must be ${MNEMONIC_ENTROPY_BYTES} bytes`);
81
+ throw new ValidationError(`mnemonic entropy must be ${MNEMONIC_ENTROPY_BYTES} bytes`);
61
82
  }
62
83
  try {
63
- const mnemonic = Mnemonic.fromEntropy(ByteUtils.bytesToHex(entropy));
84
+ const mnemonic = Mnemonic.fromEntropy(Hex.fromBytes(entropy));
64
85
  await storeMasterMnemonic(storage, mnemonic, crypto);
65
86
  const seed = mnemonicToSeed(mnemonic, mnemonicPassphrase);
66
87
  await storeMasterSeed(storage, seed, crypto);
@@ -81,9 +102,9 @@ export async function storeMasterSeed(storage, seed, crypto = identityMasterSeed
81
102
  const normalized = normalizeMasterSeed(seed);
82
103
  const encrypted = await crypto.encrypt(normalized);
83
104
  if (!(encrypted instanceof Uint8Array)) {
84
- throw new Error("master seed encryptor must return Uint8Array");
105
+ throw new ValidationError("master seed encryptor must return Uint8Array");
85
106
  }
86
- await storage.put(MASTER_SEED_KEY, clone(encrypted));
107
+ await storage.put(MASTER_SEED_KEY, encrypted);
87
108
  }
88
109
  export async function loadMasterMnemonic(storage, crypto = identityMasterSeedCrypto) {
89
110
  const stored = await storage.get(MASTER_MNEMONIC_KEY);
@@ -102,7 +123,7 @@ export async function importMasterMnemonic({ storage, mnemonic, crypto = identit
102
123
  if (!overwrite) {
103
124
  const existing = await loadMasterMnemonic(storage, crypto);
104
125
  if (existing) {
105
- throw new Error("master mnemonic already exists; set overwrite to true to replace it");
126
+ throw new ValidationError("master mnemonic already exists; set overwrite to true to replace it");
106
127
  }
107
128
  }
108
129
  const normalized = normalizeMnemonic(mnemonic);
@@ -115,30 +136,28 @@ export async function storeMasterMnemonic(storage, mnemonic, crypto = identityMa
115
136
  const normalized = normalizeMnemonic(mnemonic);
116
137
  const encrypted = await crypto.encrypt(textEncoder.encode(normalized));
117
138
  if (!(encrypted instanceof Uint8Array)) {
118
- throw new Error("master mnemonic encryptor must return Uint8Array");
139
+ throw new ValidationError("master mnemonic encryptor must return Uint8Array");
119
140
  }
120
- await storage.put(MASTER_MNEMONIC_KEY, clone(encrypted));
121
- }
122
- function clone(bytes) {
123
- return new Uint8Array(bytes);
141
+ await storage.put(MASTER_MNEMONIC_KEY, encrypted);
124
142
  }
143
+ /** Validates seed format. Storage handles buffer isolation on put/get. */
125
144
  function normalizeMasterSeed(seed) {
126
145
  if (!(seed instanceof Uint8Array)) {
127
- throw new Error("master seed must be a Uint8Array");
146
+ throw new ValidationError("master seed must be a Uint8Array");
128
147
  }
129
148
  if (seed.length !== MASTER_SEED_LENGTH) {
130
- throw new Error(`master seed must be ${MASTER_SEED_LENGTH} bytes`);
149
+ throw new ValidationError(`master seed must be ${MASTER_SEED_LENGTH} bytes`);
131
150
  }
132
- return clone(seed);
151
+ return seed;
133
152
  }
134
153
  function normalizeMnemonic(mnemonic) {
135
154
  const formatted = mnemonic.trim().replace(/\s+/g, " ");
136
155
  if (!Mnemonic.validate(formatted)) {
137
- throw new Error("invalid BIP-39 mnemonic phrase");
156
+ throw new ValidationError("invalid BIP-39 mnemonic phrase");
138
157
  }
139
158
  return formatted;
140
159
  }
141
160
  function mnemonicToSeed(mnemonic, password = "") {
142
161
  const seedHex = Mnemonic.toSeed(mnemonic, password);
143
- return ByteUtils.hexStringToBytes(seedHex);
162
+ return Hex.toBytes(seedHex);
144
163
  }
@@ -0,0 +1,42 @@
1
+ import type { Storage } from "../types.js";
2
+ import type { AccountInfo } from "../wallet/types.js";
3
+ import { deriveAccount as deriveAccountFn, type Account } from "./account.js";
4
+ export declare const DERIVED_ACCOUNTS_KEY = "cfg:wallet:derived_accounts";
5
+ export declare const ACTIVE_ACCOUNT_INDEX_KEY = "cfg:wallet:active_account_index";
6
+ export declare const ACCOUNT_KEY_PREFIX = "cfg:wallet:account:";
7
+ export type AccountsServiceDeps = {
8
+ storage: Storage;
9
+ deriveAccount: typeof deriveAccountFn;
10
+ getMasterSeed: () => Promise<Uint8Array>;
11
+ };
12
+ export type AccountsService = {
13
+ /**
14
+ * List all derived accounts (index + mpk only, safe to display).
15
+ */
16
+ list(): Promise<AccountInfo[]>;
17
+ /**
18
+ * Get full Account by index (null if not derived yet).
19
+ */
20
+ get(index: number): Promise<Account | null>;
21
+ /**
22
+ * Derive and persist a new account at the specified index.
23
+ * If index is not specified, uses the next available index.
24
+ * @throws If the index is already used
25
+ */
26
+ create(index?: number): Promise<Account>;
27
+ /**
28
+ * Get the currently active account (null if none).
29
+ */
30
+ getActive(): Promise<Account | null>;
31
+ /**
32
+ * Get the currently active account index (null if none).
33
+ */
34
+ getActiveIndex(): Promise<number | null>;
35
+ /**
36
+ * Switch to a different account by index.
37
+ * @throws If the account at the given index doesn't exist
38
+ */
39
+ setActive(index: number): Promise<void>;
40
+ };
41
+ export declare function createAccountsService(deps: AccountsServiceDeps): AccountsService;
42
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../account/accounts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAM9E,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAClE,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,wBAAwB,CAAC;AAExD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,eAAe,CAAC;IACtC,aAAa,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAE/B;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE5C;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEzC;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAErC;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzC;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC,CAAC;AAyBF,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,mBAAmB,GACxB,eAAe,CAkHjB"}
@@ -0,0 +1,119 @@
1
+ import { ValidationError } from "../errors.js";
2
+ import { deserializeAccountRecord, serializeAccountRecord, } from "./serialization.js";
3
+ export const DERIVED_ACCOUNTS_KEY = "cfg:wallet:derived_accounts";
4
+ export const ACTIVE_ACCOUNT_INDEX_KEY = "cfg:wallet:active_account_index";
5
+ export const ACCOUNT_KEY_PREFIX = "cfg:wallet:account:";
6
+ const encoder = new TextEncoder();
7
+ const decoder = new TextDecoder();
8
+ function accountKey(index) {
9
+ return `${ACCOUNT_KEY_PREFIX}${index}`;
10
+ }
11
+ function encodeIndices(indices) {
12
+ return encoder.encode(JSON.stringify(indices));
13
+ }
14
+ function decodeIndices(data) {
15
+ return JSON.parse(decoder.decode(data));
16
+ }
17
+ function encodeIndex(index) {
18
+ return encoder.encode(JSON.stringify(index));
19
+ }
20
+ function decodeIndex(data) {
21
+ return JSON.parse(decoder.decode(data));
22
+ }
23
+ export function createAccountsService(deps) {
24
+ const { storage, deriveAccount, getMasterSeed } = deps;
25
+ async function getDerivedIndices() {
26
+ const stored = await storage.get(DERIVED_ACCOUNTS_KEY);
27
+ if (!stored)
28
+ return [];
29
+ return decodeIndices(stored);
30
+ }
31
+ async function setDerivedIndices(indices) {
32
+ await storage.put(DERIVED_ACCOUNTS_KEY, encodeIndices(indices));
33
+ }
34
+ async function loadAccount(index) {
35
+ const stored = await storage.get(accountKey(index));
36
+ if (!stored)
37
+ return null;
38
+ return deserializeAccountRecord(stored);
39
+ }
40
+ async function persistAccount(index, account) {
41
+ await storage.put(accountKey(index), serializeAccountRecord(account));
42
+ }
43
+ async function list() {
44
+ const indices = await getDerivedIndices();
45
+ const accounts = [];
46
+ for (const index of indices) {
47
+ const account = await loadAccount(index);
48
+ if (account) {
49
+ accounts.push({
50
+ index,
51
+ masterPublicKey: account.masterPublicKey,
52
+ address: account.address,
53
+ });
54
+ }
55
+ }
56
+ return accounts;
57
+ }
58
+ async function get(index) {
59
+ const indices = await getDerivedIndices();
60
+ if (!indices.includes(index))
61
+ return null;
62
+ return loadAccount(index);
63
+ }
64
+ async function create(index) {
65
+ const indices = await getDerivedIndices();
66
+ // Determine the index to use
67
+ let targetIndex;
68
+ if (index !== undefined) {
69
+ if (indices.includes(index)) {
70
+ throw new ValidationError(`Account at index ${index} already exists`);
71
+ }
72
+ targetIndex = index;
73
+ }
74
+ else {
75
+ // Use next available index
76
+ targetIndex = indices.length > 0 ? Math.max(...indices) + 1 : 0;
77
+ }
78
+ // Derive the account
79
+ const masterSeed = await getMasterSeed();
80
+ const account = deriveAccount(masterSeed, targetIndex);
81
+ // Persist the account (storage handles buffer isolation)
82
+ await persistAccount(targetIndex, account);
83
+ // Update the indices list
84
+ const newIndices = [...indices, targetIndex].sort((a, b) => a - b);
85
+ await setDerivedIndices(newIndices);
86
+ // If this is the first account, set it as active
87
+ if (indices.length === 0) {
88
+ await setActive(targetIndex);
89
+ }
90
+ return account;
91
+ }
92
+ async function getActiveIndex() {
93
+ const stored = await storage.get(ACTIVE_ACCOUNT_INDEX_KEY);
94
+ if (!stored)
95
+ return null;
96
+ return decodeIndex(stored);
97
+ }
98
+ async function getActive() {
99
+ const activeIndex = await getActiveIndex();
100
+ if (activeIndex === null)
101
+ return null;
102
+ return loadAccount(activeIndex);
103
+ }
104
+ async function setActive(index) {
105
+ const indices = await getDerivedIndices();
106
+ if (!indices.includes(index)) {
107
+ throw new ValidationError(`Cannot set active: account at index ${index} does not exist`);
108
+ }
109
+ await storage.put(ACTIVE_ACCOUNT_INDEX_KEY, encodeIndex(index));
110
+ }
111
+ return {
112
+ list,
113
+ get,
114
+ create,
115
+ getActive,
116
+ getActiveIndex,
117
+ setActive,
118
+ };
119
+ }
@@ -0,0 +1,45 @@
1
+ import type { Storage } from "../types.js";
2
+ import { type MasterSeedCrypto } from "./account.js";
3
+ export type SeedServiceDeps = {
4
+ storage: Storage;
5
+ rng: (n: number) => Uint8Array;
6
+ crypto?: MasterSeedCrypto;
7
+ };
8
+ export type SeedService = {
9
+ /**
10
+ * Check if a wallet exists (has mnemonic stored).
11
+ */
12
+ exists(): Promise<boolean>;
13
+ /**
14
+ * Create a new wallet. Generates a BIP-39 mnemonic and derives the master seed.
15
+ * Returns the mnemonic so the user can back it up.
16
+ * @throws If a wallet already exists (use import with overwrite instead)
17
+ */
18
+ create(): Promise<{
19
+ mnemonic: string;
20
+ }>;
21
+ /**
22
+ * Import an existing BIP-39 mnemonic.
23
+ * @throws If the mnemonic is invalid
24
+ * @throws If a wallet already exists and overwrite is false
25
+ */
26
+ importMnemonic(mnemonic: string, opts?: {
27
+ overwrite?: boolean;
28
+ }): Promise<void>;
29
+ /**
30
+ * Export the stored mnemonic for backup.
31
+ * @throws If no wallet exists
32
+ */
33
+ exportMnemonic(): Promise<string>;
34
+ /**
35
+ * Get the master seed (for account derivation).
36
+ * @throws If no wallet exists
37
+ */
38
+ getMasterSeed(): Promise<Uint8Array>;
39
+ /**
40
+ * Delete all wallet data. This is destructive and cannot be undone.
41
+ */
42
+ delete(): Promise<void>;
43
+ };
44
+ export declare function createSeedService(deps: SeedServiceDeps): SeedService;
45
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../account/seed.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAOL,KAAK,gBAAgB,EACtB,MAAM,cAAc,CAAC;AAOtB,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;IAC/B,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3B;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAExC;;;;OAIG;IACH,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;OAGG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAElC;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAErC;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,CAgHpE"}
@@ -0,0 +1,91 @@
1
+ import { ValidationError } from "../errors.js";
2
+ import { generateMasterSeed, importMasterMnemonic, loadMasterMnemonic, loadMasterSeed, MASTER_MNEMONIC_KEY, MASTER_SEED_KEY, } from "./account.js";
3
+ import { ACCOUNT_KEY_PREFIX, ACTIVE_ACCOUNT_INDEX_KEY, DERIVED_ACCOUNTS_KEY, } from "./accounts.js";
4
+ export function createSeedService(deps) {
5
+ const { storage, rng, crypto } = deps;
6
+ async function exists() {
7
+ const mnemonic = await loadMasterMnemonic(storage, crypto);
8
+ return mnemonic !== null;
9
+ }
10
+ async function create() {
11
+ // Check if wallet already exists
12
+ const walletExists = await exists();
13
+ if (walletExists) {
14
+ throw new ValidationError("Wallet already exists. Use import with overwrite option to replace it.");
15
+ }
16
+ // Generate new mnemonic and seed
17
+ await generateMasterSeed({
18
+ storage,
19
+ rng,
20
+ crypto,
21
+ mnemonicPassphrase: "",
22
+ overwrite: false,
23
+ });
24
+ // Load and return the mnemonic so user can back it up
25
+ const mnemonic = await loadMasterMnemonic(storage, crypto);
26
+ if (!mnemonic) {
27
+ throw new ValidationError("Failed to create wallet: mnemonic not stored");
28
+ }
29
+ return { mnemonic };
30
+ }
31
+ async function importMnemonic(mnemonic, opts) {
32
+ const overwrite = opts?.overwrite ?? false;
33
+ // Check if wallet already exists
34
+ if (!overwrite) {
35
+ const walletExists = await exists();
36
+ if (walletExists) {
37
+ throw new ValidationError("Wallet already exists. Use overwrite option to replace it.");
38
+ }
39
+ }
40
+ // Import the mnemonic first
41
+ await importMasterMnemonic({
42
+ storage,
43
+ mnemonic,
44
+ crypto,
45
+ overwrite,
46
+ password: "",
47
+ });
48
+ // Clear account data after successful import to avoid data loss on failure
49
+ if (overwrite) {
50
+ await clearAccountData();
51
+ }
52
+ }
53
+ async function exportMnemonic() {
54
+ const mnemonic = await loadMasterMnemonic(storage, crypto);
55
+ if (!mnemonic) {
56
+ throw new ValidationError("No wallet exists. Create or import a wallet first.");
57
+ }
58
+ return mnemonic;
59
+ }
60
+ async function getMasterSeed() {
61
+ const seed = await loadMasterSeed(storage, crypto);
62
+ if (!seed) {
63
+ throw new ValidationError("No wallet exists. Create or import a wallet first.");
64
+ }
65
+ return seed;
66
+ }
67
+ async function clearAccountData() {
68
+ // Delete all account records by prefix
69
+ const accountRecords = await storage.iter({ prefix: ACCOUNT_KEY_PREFIX });
70
+ for (const { key } of accountRecords) {
71
+ await storage.delete(key);
72
+ }
73
+ // Clear metadata keys
74
+ await storage.delete(DERIVED_ACCOUNTS_KEY);
75
+ await storage.delete(ACTIVE_ACCOUNT_INDEX_KEY);
76
+ }
77
+ async function deleteWallet() {
78
+ // Clear all wallet data
79
+ await storage.delete(MASTER_MNEMONIC_KEY);
80
+ await storage.delete(MASTER_SEED_KEY);
81
+ await clearAccountData();
82
+ }
83
+ return {
84
+ exists,
85
+ create,
86
+ importMnemonic,
87
+ exportMnemonic,
88
+ getMasterSeed,
89
+ delete: deleteWallet,
90
+ };
91
+ }
@@ -0,0 +1,6 @@
1
+ import { formatUint256 } from "../utils/bigint.js";
2
+ import type { Account } from "./account.js";
3
+ export { formatUint256 };
4
+ export declare function serializeAccountRecord(account: Account): Uint8Array;
5
+ export declare function deserializeAccountRecord(payload: Uint8Array): Account;
6
+ //# sourceMappingURL=serialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../account/serialization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,CAAC;AAQzB,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAmBnE;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CA6BrE"}
@@ -0,0 +1,53 @@
1
+ import { formatUint256 } from "../utils/bigint.js";
2
+ import { ACCOUNT_RECORD_VERSION, BIGINT_RADIX, } from "../wallet/types.js";
3
+ export { formatUint256 };
4
+ const encoder = new TextEncoder();
5
+ const decoder = new TextDecoder();
6
+ const encodeBigInt = (value) => value.toString(BIGINT_RADIX);
7
+ const decodeBigInt = (value) => BigInt(`0x${value}`);
8
+ export function serializeAccountRecord(account) {
9
+ const record = {
10
+ version: ACCOUNT_RECORD_VERSION,
11
+ spendingKeyPair: {
12
+ privateKey: Array.from(account.spendingKeyPair.privateKey),
13
+ pubkey: [
14
+ encodeBigInt(account.spendingKeyPair.pubkey[0]),
15
+ encodeBigInt(account.spendingKeyPair.pubkey[1]),
16
+ ],
17
+ },
18
+ viewingKeyPair: {
19
+ privateKey: Array.from(account.viewingKeyPair.privateKey),
20
+ pubkey: Array.from(account.viewingKeyPair.pubkey),
21
+ },
22
+ nullifyingKey: encodeBigInt(account.nullifyingKey),
23
+ masterPublicKey: encodeBigInt(account.masterPublicKey),
24
+ address: account.address,
25
+ };
26
+ return encoder.encode(JSON.stringify(record));
27
+ }
28
+ export function deserializeAccountRecord(payload) {
29
+ const parsed = JSON.parse(decoder.decode(payload));
30
+ if (parsed.version !== ACCOUNT_RECORD_VERSION) {
31
+ throw new Error(`unsupported wallet account version ${parsed.version}`);
32
+ }
33
+ const spendingPubkey = [
34
+ decodeBigInt(parsed.spendingKeyPair.pubkey[0]),
35
+ decodeBigInt(parsed.spendingKeyPair.pubkey[1]),
36
+ ];
37
+ const viewingPubkey = Uint8Array.from(parsed.viewingKeyPair.pubkey);
38
+ const masterPublicKey = decodeBigInt(parsed.masterPublicKey);
39
+ const address = parsed.address;
40
+ return {
41
+ spendingKeyPair: {
42
+ privateKey: Uint8Array.from(parsed.spendingKeyPair.privateKey),
43
+ pubkey: spendingPubkey,
44
+ },
45
+ viewingKeyPair: {
46
+ privateKey: Uint8Array.from(parsed.viewingKeyPair.privateKey),
47
+ pubkey: viewingPubkey,
48
+ },
49
+ nullifyingKey: decodeBigInt(parsed.nullifyingKey),
50
+ masterPublicKey,
51
+ address,
52
+ };
53
+ }