@unlink-xyz/core 0.1.0 → 0.1.3-canary.01ac52d

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 (269) 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/accounts.d.ts +42 -0
  5. package/dist/account/accounts.d.ts.map +1 -0
  6. package/dist/account/seed.d.ts +45 -0
  7. package/dist/account/seed.d.ts.map +1 -0
  8. package/dist/account/serialization.d.ts +6 -0
  9. package/dist/account/serialization.d.ts.map +1 -0
  10. package/dist/browser/index.js +56253 -0
  11. package/dist/browser/index.js.map +1 -0
  12. package/dist/browser/wallet/index.js +55974 -0
  13. package/dist/browser/wallet/index.js.map +1 -0
  14. package/dist/clients/broadcaster.d.ts +8 -2
  15. package/dist/clients/broadcaster.d.ts.map +1 -1
  16. package/dist/clients/http.d.ts +6 -0
  17. package/dist/clients/http.d.ts.map +1 -1
  18. package/dist/clients/indexer.d.ts +16 -0
  19. package/dist/clients/indexer.d.ts.map +1 -1
  20. package/dist/config.d.ts +35 -9
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/constants.d.ts +6 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/core.d.ts.map +1 -1
  25. package/dist/crypto/adapters/index.d.ts +17 -0
  26. package/dist/crypto/adapters/index.d.ts.map +1 -0
  27. package/dist/crypto/adapters/polyfills.d.ts +5 -0
  28. package/dist/crypto/adapters/polyfills.d.ts.map +1 -0
  29. package/dist/crypto/encrypt.d.ts +33 -0
  30. package/dist/crypto/encrypt.d.ts.map +1 -0
  31. package/dist/crypto/secure-memory.d.ts +25 -0
  32. package/dist/crypto/secure-memory.d.ts.map +1 -0
  33. package/dist/errors.d.ts +17 -0
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/history/index.d.ts +3 -0
  36. package/dist/history/index.d.ts.map +1 -0
  37. package/dist/history/service.d.ts +46 -0
  38. package/dist/history/service.d.ts.map +1 -0
  39. package/dist/history/types.d.ts +21 -0
  40. package/dist/history/types.d.ts.map +1 -0
  41. package/dist/index.d.ts +16 -5
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +9969 -16
  44. package/dist/index.js.map +1 -0
  45. package/dist/keys/address.d.ts +13 -0
  46. package/dist/keys/address.d.ts.map +1 -0
  47. package/dist/keys/derive.d.ts +37 -0
  48. package/dist/keys/derive.d.ts.map +1 -0
  49. package/dist/keys/hex.d.ts +14 -0
  50. package/dist/keys/hex.d.ts.map +1 -0
  51. package/dist/keys/index.d.ts +5 -0
  52. package/dist/keys/index.d.ts.map +1 -0
  53. package/dist/keys/mnemonic.d.ts +6 -0
  54. package/dist/keys/mnemonic.d.ts.map +1 -0
  55. package/dist/keys.d.ts +5 -1
  56. package/dist/keys.d.ts.map +1 -1
  57. package/dist/prover/config.d.ts +53 -22
  58. package/dist/prover/config.d.ts.map +1 -1
  59. package/dist/prover/integrity.d.ts +20 -0
  60. package/dist/prover/integrity.d.ts.map +1 -0
  61. package/dist/prover/prover.d.ts +16 -20
  62. package/dist/prover/prover.d.ts.map +1 -1
  63. package/dist/prover/registry.d.ts +3 -30
  64. package/dist/prover/registry.d.ts.map +1 -1
  65. package/dist/state/merkle/hydrator.d.ts +21 -19
  66. package/dist/state/merkle/hydrator.d.ts.map +1 -1
  67. package/dist/state/merkle/index.d.ts +2 -2
  68. package/dist/state/merkle/index.d.ts.map +1 -1
  69. package/dist/state/merkle/merkle-tree.d.ts +8 -0
  70. package/dist/state/merkle/merkle-tree.d.ts.map +1 -1
  71. package/dist/state/store/ciphertext-store.d.ts +11 -0
  72. package/dist/state/store/ciphertext-store.d.ts.map +1 -1
  73. package/dist/state/store/history-store.d.ts +24 -0
  74. package/dist/state/store/history-store.d.ts.map +1 -0
  75. package/dist/state/store/index.d.ts +3 -2
  76. package/dist/state/store/index.d.ts.map +1 -1
  77. package/dist/state/store/job-store.d.ts +7 -7
  78. package/dist/state/store/job-store.d.ts.map +1 -1
  79. package/dist/state/store/jobs.d.ts +70 -25
  80. package/dist/state/store/jobs.d.ts.map +1 -1
  81. package/dist/state/store/leaf-store.d.ts +4 -0
  82. package/dist/state/store/leaf-store.d.ts.map +1 -1
  83. package/dist/state/store/note-store.d.ts +7 -7
  84. package/dist/state/store/note-store.d.ts.map +1 -1
  85. package/dist/state/store/nullifier-store.d.ts +9 -0
  86. package/dist/state/store/nullifier-store.d.ts.map +1 -1
  87. package/dist/state/store/records.d.ts +39 -2
  88. package/dist/state/store/records.d.ts.map +1 -1
  89. package/dist/state/store/root-store.d.ts.map +1 -1
  90. package/dist/state/store/store.d.ts +79 -27
  91. package/dist/state/store/store.d.ts.map +1 -1
  92. package/dist/storage/indexeddb.d.ts.map +1 -1
  93. package/dist/storage/memory.d.ts.map +1 -1
  94. package/dist/transactions/adapter.d.ts +31 -0
  95. package/dist/transactions/adapter.d.ts.map +1 -0
  96. package/dist/transactions/deposit.d.ts +12 -17
  97. package/dist/transactions/deposit.d.ts.map +1 -1
  98. package/dist/transactions/index.d.ts +9 -4
  99. package/dist/transactions/index.d.ts.map +1 -1
  100. package/dist/transactions/note-selection.d.ts +17 -0
  101. package/dist/transactions/note-selection.d.ts.map +1 -0
  102. package/dist/transactions/note-sync.d.ts +5 -33
  103. package/dist/transactions/note-sync.d.ts.map +1 -1
  104. package/dist/transactions/reconcile.d.ts +9 -11
  105. package/dist/transactions/reconcile.d.ts.map +1 -1
  106. package/dist/transactions/transact.d.ts +30 -27
  107. package/dist/transactions/transact.d.ts.map +1 -1
  108. package/dist/transactions/transaction-planner.d.ts +34 -0
  109. package/dist/transactions/transaction-planner.d.ts.map +1 -0
  110. package/dist/transactions/transfer-planner.d.ts +37 -0
  111. package/dist/transactions/transfer-planner.d.ts.map +1 -0
  112. package/dist/transactions/types/deposit.d.ts +67 -0
  113. package/dist/transactions/types/deposit.d.ts.map +1 -0
  114. package/dist/transactions/types/domain.d.ts +70 -0
  115. package/dist/transactions/types/domain.d.ts.map +1 -0
  116. package/dist/transactions/types/index.d.ts +18 -0
  117. package/dist/transactions/types/index.d.ts.map +1 -0
  118. package/dist/transactions/types/options.d.ts +54 -0
  119. package/dist/transactions/types/options.d.ts.map +1 -0
  120. package/dist/transactions/types/planning.d.ts +82 -0
  121. package/dist/transactions/types/planning.d.ts.map +1 -0
  122. package/dist/transactions/types/state-stores.d.ts +151 -0
  123. package/dist/transactions/types/state-stores.d.ts.map +1 -0
  124. package/dist/transactions/types/transact.d.ts +83 -0
  125. package/dist/transactions/types/transact.d.ts.map +1 -0
  126. package/dist/transactions/withdrawal-planner.d.ts +58 -0
  127. package/dist/transactions/withdrawal-planner.d.ts.map +1 -0
  128. package/dist/tsconfig.tsbuildinfo +1 -1
  129. package/dist/tsup.browser.config.d.ts +7 -0
  130. package/dist/tsup.browser.config.d.ts.map +1 -0
  131. package/dist/tsup.config.d.ts +8 -0
  132. package/dist/tsup.config.d.ts.map +1 -0
  133. package/dist/types.d.ts +1 -0
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/utils/amounts.d.ts +26 -0
  136. package/dist/utils/amounts.d.ts.map +1 -0
  137. package/dist/utils/async.d.ts +9 -0
  138. package/dist/utils/async.d.ts.map +1 -1
  139. package/dist/utils/async.js +38 -11
  140. package/dist/utils/async.js.map +1 -0
  141. package/dist/utils/bigint.d.ts +0 -2
  142. package/dist/utils/bigint.d.ts.map +1 -1
  143. package/dist/utils/format.d.ts +25 -0
  144. package/dist/utils/format.d.ts.map +1 -0
  145. package/dist/utils/notes.d.ts +15 -0
  146. package/dist/utils/notes.d.ts.map +1 -0
  147. package/dist/utils/polling.d.ts +5 -0
  148. package/dist/utils/polling.d.ts.map +1 -1
  149. package/dist/utils/random.d.ts +18 -0
  150. package/dist/utils/random.d.ts.map +1 -0
  151. package/dist/utils/signature.d.ts +6 -0
  152. package/dist/utils/signature.d.ts.map +1 -1
  153. package/dist/utils/validators.d.ts +21 -10
  154. package/dist/utils/validators.d.ts.map +1 -1
  155. package/dist/vitest.config.d.ts +3 -0
  156. package/dist/vitest.config.d.ts.map +1 -0
  157. package/dist/wallet/adapter.d.ts +21 -0
  158. package/dist/wallet/adapter.d.ts.map +1 -0
  159. package/dist/wallet/burner/service.d.ts +32 -0
  160. package/dist/wallet/burner/service.d.ts.map +1 -0
  161. package/dist/wallet/burner/types.d.ts +47 -0
  162. package/dist/wallet/burner/types.d.ts.map +1 -0
  163. package/dist/wallet/index.d.ts +20 -0
  164. package/dist/wallet/index.d.ts.map +1 -0
  165. package/dist/wallet/index.js +9712 -0
  166. package/dist/wallet/index.js.map +1 -0
  167. package/dist/wallet/sdk.d.ts +47 -0
  168. package/dist/wallet/sdk.d.ts.map +1 -0
  169. package/dist/wallet/types.d.ts +455 -0
  170. package/dist/wallet/types.d.ts.map +1 -0
  171. package/dist/wallet/unlink-wallet.d.ts +186 -0
  172. package/dist/wallet/unlink-wallet.d.ts.map +1 -0
  173. package/package.json +40 -14
  174. package/dist/account/zkAccount.d.ts.map +0 -1
  175. package/dist/account/zkAccount.js +0 -128
  176. package/dist/clients/broadcaster.js +0 -23
  177. package/dist/clients/http.js +0 -57
  178. package/dist/clients/indexer.js +0 -67
  179. package/dist/config.js +0 -29
  180. package/dist/core.js +0 -12
  181. package/dist/errors.js +0 -18
  182. package/dist/key-derivation/babyjubjub.d.ts +0 -9
  183. package/dist/key-derivation/babyjubjub.d.ts.map +0 -1
  184. package/dist/key-derivation/babyjubjub.js +0 -9
  185. package/dist/key-derivation/bech32.d.ts +0 -22
  186. package/dist/key-derivation/bech32.d.ts.map +0 -1
  187. package/dist/key-derivation/bech32.js +0 -86
  188. package/dist/key-derivation/bip32.d.ts +0 -17
  189. package/dist/key-derivation/bip32.d.ts.map +0 -1
  190. package/dist/key-derivation/bip32.js +0 -41
  191. package/dist/key-derivation/bip39.d.ts +0 -22
  192. package/dist/key-derivation/bip39.d.ts.map +0 -1
  193. package/dist/key-derivation/bip39.js +0 -56
  194. package/dist/key-derivation/bytes.d.ts +0 -19
  195. package/dist/key-derivation/bytes.d.ts.map +0 -1
  196. package/dist/key-derivation/bytes.js +0 -92
  197. package/dist/key-derivation/hash.d.ts +0 -3
  198. package/dist/key-derivation/hash.d.ts.map +0 -1
  199. package/dist/key-derivation/hash.js +0 -10
  200. package/dist/key-derivation/index.d.ts +0 -8
  201. package/dist/key-derivation/index.d.ts.map +0 -1
  202. package/dist/key-derivation/index.js +0 -7
  203. package/dist/key-derivation/wallet-node.d.ts +0 -45
  204. package/dist/key-derivation/wallet-node.d.ts.map +0 -1
  205. package/dist/key-derivation/wallet-node.js +0 -109
  206. package/dist/keys.js +0 -41
  207. package/dist/prover/config.js +0 -80
  208. package/dist/prover/index.js +0 -1
  209. package/dist/prover/prover.js +0 -274
  210. package/dist/prover/registry.js +0 -57
  211. package/dist/schema.js +0 -14
  212. package/dist/state/ciphertext-store.d.ts +0 -12
  213. package/dist/state/ciphertext-store.d.ts.map +0 -1
  214. package/dist/state/ciphertext-store.js +0 -25
  215. package/dist/state/index.js +0 -2
  216. package/dist/state/leaf-store.d.ts +0 -17
  217. package/dist/state/leaf-store.d.ts.map +0 -1
  218. package/dist/state/leaf-store.js +0 -35
  219. package/dist/state/merkle/hydrator.js +0 -36
  220. package/dist/state/merkle/index.js +0 -2
  221. package/dist/state/merkle/merkle-tree.js +0 -104
  222. package/dist/state/merkle-tree.d.ts +0 -34
  223. package/dist/state/merkle-tree.d.ts.map +0 -1
  224. package/dist/state/merkle-tree.js +0 -104
  225. package/dist/state/note-store.d.ts +0 -37
  226. package/dist/state/note-store.d.ts.map +0 -1
  227. package/dist/state/note-store.js +0 -133
  228. package/dist/state/nullifier-store.d.ts +0 -13
  229. package/dist/state/nullifier-store.d.ts.map +0 -1
  230. package/dist/state/nullifier-store.js +0 -21
  231. package/dist/state/records.d.ts +0 -57
  232. package/dist/state/records.d.ts.map +0 -1
  233. package/dist/state/records.js +0 -1
  234. package/dist/state/root-store.d.ts +0 -13
  235. package/dist/state/root-store.d.ts.map +0 -1
  236. package/dist/state/root-store.js +0 -30
  237. package/dist/state/store/ciphertext-store.js +0 -25
  238. package/dist/state/store/index.js +0 -8
  239. package/dist/state/store/job-store.js +0 -118
  240. package/dist/state/store/jobs.js +0 -1
  241. package/dist/state/store/leaf-store.js +0 -35
  242. package/dist/state/store/note-store.js +0 -142
  243. package/dist/state/store/nullifier-store.js +0 -30
  244. package/dist/state/store/records.js +0 -1
  245. package/dist/state/store/root-store.js +0 -30
  246. package/dist/state/store/store.js +0 -22
  247. package/dist/state/store.d.ts +0 -26
  248. package/dist/state/store.d.ts.map +0 -1
  249. package/dist/state/store.js +0 -19
  250. package/dist/storage/index.js +0 -2
  251. package/dist/storage/indexeddb.js +0 -205
  252. package/dist/storage/memory.js +0 -87
  253. package/dist/transactions/deposit.js +0 -173
  254. package/dist/transactions/index.js +0 -4
  255. package/dist/transactions/note-sync.js +0 -320
  256. package/dist/transactions/reconcile.js +0 -39
  257. package/dist/transactions/transact.js +0 -561
  258. package/dist/transactions/types.d.ts +0 -114
  259. package/dist/transactions/types.d.ts.map +0 -1
  260. package/dist/transactions/types.js +0 -1
  261. package/dist/types.js +0 -1
  262. package/dist/utils/bigint.js +0 -29
  263. package/dist/utils/crypto.d.ts +0 -12
  264. package/dist/utils/crypto.d.ts.map +0 -1
  265. package/dist/utils/crypto.js +0 -39
  266. package/dist/utils/json-codec.js +0 -25
  267. package/dist/utils/polling.js +0 -6
  268. package/dist/utils/signature.js +0 -12
  269. package/dist/utils/validators.js +0 -70
@@ -1,142 +0,0 @@
1
- import { CoreError } from "../../errors.js";
2
- import { keys } from "../../keys.js";
3
- import { decodeJson, encodeJson, getJson, } from "../../utils/json-codec.js";
4
- import { ensureBigIntString, ensureChainId, ensureMpk, ensurePositiveInt, } from "../../utils/validators.js";
5
- export const emptyBytes = () => new Uint8Array(0);
6
- export function createNoteStore(storage) {
7
- const persistNote = async (record) => {
8
- ensureChainId(record.chainId);
9
- ensurePositiveInt("note index", record.index);
10
- ensureMpk(record.mpk);
11
- ensureBigIntString("note value", record.value);
12
- if (record.spentAt !== undefined) {
13
- ensurePositiveInt("note spentAt", record.spentAt);
14
- }
15
- const noteKey = keys.note(record.chainId, record.index);
16
- const previous = await getJson(storage, noteKey);
17
- const ops = [
18
- { put: [noteKey, encodeJson(record)] },
19
- ];
20
- if (previous && previous.spentAt === undefined) {
21
- ops.push({
22
- del: keys.unspent(previous.chainId, previous.mpk, previous.index),
23
- });
24
- }
25
- if (record.spentAt === undefined) {
26
- // idx:notes:unspent functions as a set, so we only persist the sentinel bytes.
27
- ops.push({
28
- put: [
29
- keys.unspent(record.chainId, record.mpk, record.index),
30
- emptyBytes(),
31
- ],
32
- });
33
- }
34
- else {
35
- ops.push({
36
- del: keys.unspent(record.chainId, record.mpk, record.index),
37
- });
38
- }
39
- await storage.batch(ops);
40
- };
41
- const store = {
42
- /**
43
- * Upsert a note record and maintain the unspent-note index for fast balance queries.
44
- * If the note already exists and is marked as spent, preserve the spentAt field.
45
- */
46
- async putNote(note) {
47
- const noteKey = keys.note(note.chainId, note.index);
48
- const existing = await getJson(storage, noteKey);
49
- if (existing?.spentAt !== undefined) {
50
- // Preserve spentAt if note was already marked as spent
51
- await persistNote({ ...note, spentAt: existing.spentAt });
52
- }
53
- else {
54
- await persistNote({ ...note });
55
- }
56
- },
57
- /**
58
- * Fetch a note by (chainId, index) if it exists in local storage.
59
- */
60
- async getNote(chainId, index) {
61
- ensureChainId(chainId);
62
- ensurePositiveInt("note index", index);
63
- return getJson(storage, keys.note(chainId, index));
64
- },
65
- /**
66
- * List notes matching optional filters (by chainId, mpk) and spent state.
67
- */
68
- async listNotes(options = {}) {
69
- const { chainId, mpk, token, includeSpent = true } = options;
70
- if (chainId !== undefined) {
71
- ensureChainId(chainId);
72
- }
73
- if (mpk !== undefined) {
74
- ensureMpk(mpk);
75
- }
76
- const prefix = chainId !== undefined ? `notes:${chainId}:` : "notes:";
77
- const entries = await storage.iter({ prefix });
78
- const filtered = entries
79
- .map(({ value }) => decodeJson(value))
80
- .filter((note) => (chainId === undefined || note.chainId === chainId) &&
81
- (mpk === undefined || note.mpk === mpk) &&
82
- (token === undefined || note.token === token) &&
83
- (includeSpent || note.spentAt === undefined));
84
- filtered.sort((a, b) => a.index - b.index);
85
- return filtered;
86
- },
87
- /**
88
- * Mark a cached note as spent by setting its timestamp and re-indexing metadata.
89
- */
90
- async markNoteSpent(chainId, index, spentAt = Date.now()) {
91
- ensureChainId(chainId);
92
- ensurePositiveInt("note index", index);
93
- ensurePositiveInt("note spentAt", spentAt);
94
- const existing = await store.getNote(chainId, index);
95
- if (!existing) {
96
- throw new CoreError("note not found");
97
- }
98
- if (existing.spentAt === spentAt) {
99
- return existing;
100
- }
101
- const updated = { ...existing, spentAt };
102
- await persistNote(updated);
103
- return updated;
104
- },
105
- /**
106
- * Drop the spent marker from a cached note, returning it to the unspent index.
107
- */
108
- async markNoteUnspent(chainId, index) {
109
- ensureChainId(chainId);
110
- ensurePositiveInt("note index", index);
111
- const existing = await store.getNote(chainId, index);
112
- if (!existing) {
113
- throw new CoreError("note not found");
114
- }
115
- if (existing.spentAt === undefined) {
116
- return existing;
117
- }
118
- const updated = { ...existing };
119
- delete updated.spentAt;
120
- await persistNote(updated);
121
- return updated;
122
- },
123
- /**
124
- * Aggregate unspent note balances per token for a given master public key.
125
- */
126
- async getZkBalances(mpk, options = {}) {
127
- ensureMpk(mpk);
128
- const notes = await store.listNotes({
129
- chainId: options.chainId,
130
- mpk,
131
- includeSpent: false,
132
- });
133
- const totals = {};
134
- for (const note of notes) {
135
- const amount = BigInt(note.value);
136
- totals[note.token] = (totals[note.token] ?? 0n) + amount;
137
- }
138
- return totals;
139
- },
140
- };
141
- return store;
142
- }
@@ -1,30 +0,0 @@
1
- import { keys } from "../../keys.js";
2
- import { getJson, putJson } from "../../utils/json-codec.js";
3
- import { ensureChainId } from "../../utils/validators.js";
4
- export function createNullifierStore(storage) {
5
- return {
6
- /**
7
- * Record a nullifier observation so later syncs can de-duplicate work.
8
- */
9
- async putNullifier(nullifier) {
10
- ensureChainId(nullifier.chainId);
11
- await putJson(storage, keys.nullifier(nullifier.chainId, nullifier.nullifier), nullifier);
12
- },
13
- /**
14
- * Lookup a previously observed nullifier by value.
15
- */
16
- async getNullifier(chainId, value) {
17
- ensureChainId(chainId);
18
- return getJson(storage, keys.nullifier(chainId, value));
19
- },
20
- /**
21
- * Count all nullifiers stored locally for a given chain.
22
- */
23
- async countNullifiers(chainId) {
24
- ensureChainId(chainId);
25
- const prefix = `nullifiers:${chainId}:`;
26
- const entries = await storage.iter({ prefix });
27
- return entries.length;
28
- },
29
- };
30
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,30 +0,0 @@
1
- import { CoreError } from "../../errors.js";
2
- import { keys, validateKey } from "../../keys.js";
3
- import { getJson, putJson } from "../../utils/json-codec.js";
4
- import { ensureChainId } from "../../utils/validators.js";
5
- export function createRootStore(storage) {
6
- return {
7
- /**
8
- * Persist a historical root snapshot for proof generation.
9
- */
10
- async putRoot(root) {
11
- ensureChainId(root.chainId);
12
- if (typeof root.root !== "string" || root.root.length === 0) {
13
- throw new CoreError("root value must be a non-empty string");
14
- }
15
- const key = keys.root(root.chainId, root.root);
16
- validateKey(key);
17
- await putJson(storage, key, root);
18
- },
19
- /**
20
- * Retrieve a root snapshot by Merkle root value.
21
- */
22
- async getRoot(chainId, value) {
23
- ensureChainId(chainId);
24
- if (typeof value !== "string" || value.length === 0) {
25
- throw new CoreError("root value must be a non-empty string");
26
- }
27
- return getJson(storage, keys.root(chainId, value));
28
- },
29
- };
30
- }
@@ -1,22 +0,0 @@
1
- import { createCiphertextStore } from "./ciphertext-store.js";
2
- import { createJobStore } from "./job-store.js";
3
- import { createLeafStore } from "./leaf-store.js";
4
- import { createNoteStore } from "./note-store.js";
5
- import { createNullifierStore } from "./nullifier-store.js";
6
- import { createRootStore } from "./root-store.js";
7
- export function createStateStore(storage) {
8
- const notes = createNoteStore(storage);
9
- const nullifiers = createNullifierStore(storage);
10
- const leaves = createLeafStore(storage);
11
- const roots = createRootStore(storage);
12
- const ciphertexts = createCiphertextStore(storage);
13
- const jobs = createJobStore(storage);
14
- return {
15
- ...notes,
16
- ...nullifiers,
17
- ...leaves,
18
- ...roots,
19
- ...ciphertexts,
20
- ...jobs,
21
- };
22
- }
@@ -1,26 +0,0 @@
1
- import type { Storage } from "../types.js";
2
- export declare function createStateStore(storage: Storage): {
3
- putCiphertext(chainId: number, index: number, payload: Uint8Array): Promise<void>;
4
- getCiphertext(chainId: number, index: number): Promise<Uint8Array<ArrayBuffer> | null>;
5
- putRoot(root: import("./records.js").RootRecord): Promise<void>;
6
- getRoot(chainId: number, value: string): Promise<import("./records.js").RootRecord | null>;
7
- putLeaf(leaf: import("./records.js").LeafRecord): Promise<void>;
8
- getLeaf(chainId: number, index: number): Promise<import("./records.js").LeafRecord | null>;
9
- clearLeaves(chainId: number): Promise<void>;
10
- putNullifier(nullifier: import("./records.js").NullifierRecord): Promise<void>;
11
- getNullifier(chainId: number, value: string): Promise<import("./records.js").NullifierRecord | null>;
12
- putNote(note: import("./records.js").NoteInsert): Promise<void>;
13
- getNote(chainId: number, index: number): Promise<import("./records.js").NoteRecord | null>;
14
- listNotes(options?: {
15
- chainId?: number;
16
- mpk?: string;
17
- token?: string;
18
- includeSpent?: boolean;
19
- }): Promise<import("./records.js").NoteRecord[]>;
20
- markNoteSpent(chainId: number, index: number, spentAt?: number): Promise<import("./records.js").NoteRecord>;
21
- markNoteUnspent(chainId: number, index: number): Promise<import("./records.js").NoteRecord>;
22
- getZkBalances(mpk: string, options?: {
23
- chainId?: number;
24
- }): Promise<Record<string, bigint>>;
25
- };
26
- //# sourceMappingURL=store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../state/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO;;;;;;;;;;;;;eAe6/C,CAAC;WAAqB,CAAC;aAAuB,CAAC;oBAA8B,CAAC;;;;;eAA+qE,CAAC;;EAD3yH"}
@@ -1,19 +0,0 @@
1
- import { createCiphertextStore } from "./ciphertext-store.js";
2
- import { createLeafStore } from "./leaf-store.js";
3
- import { createNoteStore } from "./note-store.js";
4
- import { createNullifierStore } from "./nullifier-store.js";
5
- import { createRootStore } from "./root-store.js";
6
- export function createStateStore(storage) {
7
- const notes = createNoteStore(storage);
8
- const nullifiers = createNullifierStore(storage);
9
- const leaves = createLeafStore(storage);
10
- const roots = createRootStore(storage);
11
- const ciphertexts = createCiphertextStore(storage);
12
- return {
13
- ...notes,
14
- ...nullifiers,
15
- ...leaves,
16
- ...roots,
17
- ...ciphertexts,
18
- };
19
- }
@@ -1,2 +0,0 @@
1
- export { createMemoryStorage } from "./memory.js";
2
- export { createIndexedDbStorage } from "./indexeddb.js";
@@ -1,205 +0,0 @@
1
- /**
2
- * IndexedDB-backed key/value storage for Unlink Core.
3
- *
4
- * What this is
5
- * - A durable, transactional KV store implemented on top of the browser's IndexedDB.
6
- * - Two object stores: "kv" for app data, "meta" for schema/versioning.
7
- *
8
- * Why we implement it
9
- * - We need persistent client-side state (notes, leaves, nullifiers, cfg, etc.) that survives reloads
10
- * and works in both web apps and browser extensions without introducing a new backend.
11
- *
12
- * When to use
13
- * - Browser UIs and extensions (MV2/MV3) where persistence is required.
14
- * - Any environment with a real IndexedDB (tests use `fake-indexeddb`).
15
- *
16
- * Trade-offs
17
- * - 👍 Durable, quota-managed, non-blocking, transactional writes (atomic batch).
18
- * - 👍 Works offline; no server dependency.
19
- * - ⚠️ Not natively available in Node/SSR; needs a polyfill for tests only.
20
- *
21
- */
22
- import { CoreError } from "../errors.js";
23
- import { validateKey } from "../keys.js";
24
- const DEFAULT_DB_NAME = "unlink-core";
25
- const DB_VERSION = 1;
26
- const KV_STORE = "kv";
27
- const META_STORE = "meta";
28
- const SCHEMA_KEY = "schema_version";
29
- const copy = (value) => new Uint8Array(value);
30
- function assertIndexedDb() {
31
- if (typeof indexedDB === "undefined") {
32
- throw new CoreError("indexedDB is not available in this environment");
33
- }
34
- return indexedDB;
35
- }
36
- // Translate IndexedDB's event-based transaction API into a promise that resolves
37
- // when the transaction completes or rejects on failure/abort.
38
- function txDone(tx) {
39
- return new Promise((resolve, reject) => {
40
- tx.oncomplete = () => resolve();
41
- tx.onerror = () => reject(tx.error ?? new CoreError("indexedDB transaction failed"));
42
- tx.onabort = () => reject(tx.error ?? new CoreError("indexedDB transaction aborted"));
43
- });
44
- }
45
- function wrapRequest(request) {
46
- return new Promise((resolve, reject) => {
47
- request.onsuccess = () => resolve(request.result);
48
- request.onerror = () => reject(request.error ?? new CoreError("indexedDB request failed"));
49
- });
50
- }
51
- // Coerce whatever IndexedDB gives us back into our Bytes type.
52
- function asBytes(raw) {
53
- if (raw instanceof Uint8Array)
54
- return copy(raw);
55
- if (raw instanceof ArrayBuffer)
56
- return copy(new Uint8Array(raw));
57
- if (ArrayBuffer.isView(raw)) {
58
- const view = raw;
59
- const buf = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
60
- return copy(new Uint8Array(buf));
61
- }
62
- throw new CoreError("indexedDB value is not binary data");
63
- }
64
- // IndexedDB-backed implementation implementing the storage API.
65
- export function createIndexedDbStorage(opts = {}) {
66
- const name = opts.name ?? DEFAULT_DB_NAME;
67
- let db = null;
68
- // Lazy-open the database so we only touch IndexedDB when needed.
69
- async function ensureOpen() {
70
- if (db)
71
- return db;
72
- // Guard for environments without IndexedDB (unit tests or SSR).
73
- const idb = assertIndexedDb();
74
- const request = idb.open(name, DB_VERSION);
75
- // Versioned schema: create one store for kv entries and one for metadata.
76
- request.onupgradeneeded = () => {
77
- const upgradeDb = request.result;
78
- if (!upgradeDb.objectStoreNames.contains(KV_STORE)) {
79
- upgradeDb.createObjectStore(KV_STORE);
80
- }
81
- if (!upgradeDb.objectStoreNames.contains(META_STORE)) {
82
- upgradeDb.createObjectStore(META_STORE);
83
- }
84
- };
85
- db = await new Promise((resolve, reject) => {
86
- request.onsuccess = () => resolve(request.result);
87
- request.onerror = () => reject(request.error ?? new CoreError("indexedDB open failed"));
88
- request.onblocked = () => reject(new CoreError("indexedDB open request was blocked"));
89
- });
90
- return db;
91
- }
92
- // Start a transaction and give callers both the store and a completion promise.
93
- const getStore = async (storeName, mode) => {
94
- const database = await ensureOpen();
95
- const tx = database.transaction(storeName, mode);
96
- const done = txDone(tx);
97
- return { store: tx.objectStore(storeName), done };
98
- };
99
- return {
100
- async open() {
101
- await ensureOpen();
102
- },
103
- async get(key) {
104
- validateKey(key);
105
- const { store, done } = await getStore(KV_STORE, "readonly");
106
- const result = await wrapRequest(store.get(key));
107
- await done;
108
- if (result === undefined)
109
- return null;
110
- return asBytes(result);
111
- },
112
- async put(key, value) {
113
- validateKey(key);
114
- const { store, done } = await getStore(KV_STORE, "readwrite");
115
- await wrapRequest(store.put(copy(value), key)); // copy avoids shared mutation; revisit if this becomes costly
116
- await done;
117
- },
118
- async delete(key) {
119
- validateKey(key);
120
- const { store, done } = await getStore(KV_STORE, "readwrite");
121
- await wrapRequest(store.delete(key));
122
- await done;
123
- },
124
- async batch(ops) {
125
- // Execute the batch within a single transaction to preserve atomicity.
126
- const database = await ensureOpen();
127
- const tx = database.transaction(KV_STORE, "readwrite");
128
- const store = tx.objectStore(KV_STORE);
129
- const done = txDone(tx);
130
- try {
131
- // Replay the batch within a single transaction; validation failure aborts everything.
132
- for (const op of ops) {
133
- if (op.put) {
134
- const [key, value] = op.put;
135
- validateKey(key);
136
- store.put(copy(value), key); // copy avoids shared mutation; revisit if this becomes costly
137
- }
138
- if (op.del) {
139
- validateKey(op.del);
140
- store.delete(op.del);
141
- }
142
- }
143
- await done;
144
- }
145
- catch (err) {
146
- try {
147
- tx.abort();
148
- }
149
- catch (_) {
150
- /* noop */
151
- }
152
- await done.catch(() => { });
153
- throw err;
154
- }
155
- },
156
- async iter(options = {}) {
157
- if (options.start && options.end && options.start > options.end) {
158
- throw new CoreError("iter start bound must not exceed end bound");
159
- }
160
- // Pull everything into memory for now. TODO: stream w/ cursor when needed for perf
161
- const database = await ensureOpen();
162
- const tx = database.transaction(KV_STORE, "readonly");
163
- const store = tx.objectStore(KV_STORE);
164
- const done = txDone(tx);
165
- const [keys, values] = await Promise.all([
166
- wrapRequest(store.getAllKeys()),
167
- wrapRequest(store.getAll()),
168
- ]);
169
- await done;
170
- const pairs = keys.map((key, idx) => {
171
- if (typeof key !== "string") {
172
- throw new CoreError("encountered non-string key in indexedDB");
173
- }
174
- const raw = values[idx];
175
- return { key, value: asBytes(raw) };
176
- });
177
- let filtered = pairs.filter(({ key }) => {
178
- if (options.prefix && !key.startsWith(options.prefix))
179
- return false;
180
- if (options.start && key < options.start)
181
- return false;
182
- if (options.end && key > options.end)
183
- return false;
184
- return true;
185
- });
186
- filtered.sort((a, b) => a.key.localeCompare(b.key));
187
- if (options.reverse)
188
- filtered = filtered.reverse();
189
- if (options.limit)
190
- filtered = filtered.slice(0, options.limit);
191
- return filtered;
192
- },
193
- async getSchemaVersion() {
194
- const { store, done } = await getStore(META_STORE, "readonly");
195
- const value = await wrapRequest(store.get(SCHEMA_KEY));
196
- await done;
197
- return value ?? 0;
198
- },
199
- async setSchemaVersion(version) {
200
- const { store, done } = await getStore(META_STORE, "readwrite");
201
- await wrapRequest(store.put(version, SCHEMA_KEY));
202
- await done;
203
- },
204
- };
205
- }
@@ -1,87 +0,0 @@
1
- /**
2
- * In-memory key/value storage for Unlink Core.
3
- *
4
- * What this is
5
- * - A minimal, process-local KV store backed by a `Map<string, Uint8Array>`.
6
- *
7
- * Why we implement it
8
- * - Fast, dependency-free storage for unit tests, demos, and ephemeral runs.
9
- * - Useful as a reference driver for the Storage interface.
10
- *
11
- * When to use
12
- * - Unit tests (deterministic, zero I/O).
13
- * - CLI/Node scripts that do not need persistence beyond process lifetime.
14
- * - Prototyping or sandboxing Core logic.
15
- *
16
- * Trade-offs
17
- * - 👍 Extremely fast; zero external APIs; simple to reason about.
18
- * - 👍 Great for isolation in tests; easy to snapshot/clone.
19
- * - ⚠️ No durability (data is lost on process exit).
20
- * - ⚠️ Per-process only; no cross-tab or reload survival.
21
- *
22
- */
23
- import { CoreError } from "../errors.js";
24
- import { validateKey } from "../keys.js";
25
- const copy = (value) => new Uint8Array(value);
26
- export function createMemoryStorage() {
27
- const data = new Map();
28
- let schema = 0;
29
- return {
30
- async open() { },
31
- async get(k) {
32
- validateKey(k);
33
- return data.has(k) ? copy(data.get(k)) : null;
34
- },
35
- async put(k, v) {
36
- validateKey(k);
37
- data.set(k, copy(v));
38
- },
39
- async delete(k) {
40
- validateKey(k);
41
- data.delete(k);
42
- },
43
- async batch(ops) {
44
- const draft = new Map(data);
45
- for (const op of ops) {
46
- if (op.put) {
47
- const [k, v] = op.put;
48
- validateKey(k);
49
- draft.set(k, copy(v));
50
- }
51
- if (op.del) {
52
- validateKey(op.del);
53
- draft.delete(op.del);
54
- }
55
- }
56
- data.clear();
57
- for (const [k, v] of draft.entries()) {
58
- data.set(k, copy(v));
59
- }
60
- },
61
- async iter(o = {}) {
62
- if (o.start && o.end && o.start > o.end) {
63
- throw new CoreError("iter start bound must not exceed end bound");
64
- }
65
- const all = [...data.entries()].map(([key, value]) => ({
66
- key,
67
- value: copy(value),
68
- }));
69
- let ks = all
70
- .filter(({ key }) => (!o.prefix || key.startsWith(o.prefix)) &&
71
- (!o.start || key >= o.start) &&
72
- (!o.end || key <= o.end))
73
- .sort((a, b) => a.key.localeCompare(b.key));
74
- if (o.reverse)
75
- ks.reverse();
76
- if (o.limit)
77
- ks = ks.slice(0, o.limit);
78
- return ks;
79
- },
80
- async getSchemaVersion() {
81
- return schema;
82
- },
83
- async setSchemaVersion(n) {
84
- schema = n;
85
- },
86
- };
87
- }