@unlink-xyz/core 0.1.2 → 0.1.3-canary.0877bfe
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/account/{zkAccount.d.ts → account.d.ts} +7 -5
- package/dist/account/account.d.ts.map +1 -0
- package/dist/account/{zkAccount.js → account.js} +57 -43
- package/dist/browser/index.js +108202 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/circuits.json +74 -0
- package/dist/clients/broadcaster.d.ts +7 -2
- package/dist/clients/broadcaster.d.ts.map +1 -1
- package/dist/clients/broadcaster.js +9 -1
- package/dist/clients/http.d.ts +6 -0
- package/dist/clients/http.d.ts.map +1 -1
- package/dist/clients/http.js +24 -9
- package/dist/clients/indexer.d.ts +11 -0
- package/dist/clients/indexer.d.ts.map +1 -1
- package/dist/clients/indexer.js +40 -11
- package/dist/config.d.ts +28 -9
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +33 -26
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +5 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +5 -2
- package/dist/crypto-adapters/auto-init.d.ts +2 -0
- package/dist/crypto-adapters/auto-init.d.ts.map +1 -0
- package/dist/crypto-adapters/auto-init.js +7 -0
- package/dist/crypto-adapters/index.d.ts +22 -0
- package/dist/crypto-adapters/index.d.ts.map +1 -0
- package/dist/crypto-adapters/index.js +47 -0
- package/dist/crypto-adapters/polyfills.d.ts +5 -0
- package/dist/crypto-adapters/polyfills.d.ts.map +1 -0
- package/dist/crypto-adapters/polyfills.js +8 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +18 -0
- package/dist/history/index.d.ts +3 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/index.js +2 -0
- package/dist/history/service.d.ts +46 -0
- package/dist/history/service.d.ts.map +1 -0
- package/dist/history/service.js +354 -0
- package/dist/history/types.d.ts +21 -0
- package/dist/history/types.d.ts.map +1 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/keys/address.d.ts +13 -0
- package/dist/keys/address.d.ts.map +1 -0
- package/dist/keys/address.js +55 -0
- package/dist/keys/derive.d.ts +37 -0
- package/dist/keys/derive.d.ts.map +1 -0
- package/dist/keys/derive.js +112 -0
- package/dist/keys/hex.d.ts +17 -0
- package/dist/keys/hex.d.ts.map +1 -0
- package/dist/keys/hex.js +66 -0
- package/dist/keys/index.d.ts +5 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +4 -0
- package/dist/keys/mnemonic.d.ts +8 -0
- package/dist/keys/mnemonic.d.ts.map +1 -0
- package/dist/keys/mnemonic.js +23 -0
- package/dist/keys.d.ts +4 -1
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js +4 -0
- package/dist/prover/config.d.ts +1 -15
- package/dist/prover/config.d.ts.map +1 -1
- package/dist/prover/config.js +1 -11
- package/dist/prover/prover.d.ts +15 -4
- package/dist/prover/prover.d.ts.map +1 -1
- package/dist/prover/prover.js +115 -98
- package/dist/prover/registry.d.ts +3 -30
- package/dist/prover/registry.d.ts.map +1 -1
- package/dist/prover/registry.js +12 -51
- package/dist/state/merkle/hydrator.d.ts.map +1 -1
- package/dist/state/merkle/hydrator.js +3 -2
- package/dist/state/merkle/index.d.ts +1 -1
- package/dist/state/merkle/index.d.ts.map +1 -1
- package/dist/state/merkle/index.js +1 -1
- package/dist/state/merkle/merkle-tree.d.ts +8 -0
- package/dist/state/merkle/merkle-tree.d.ts.map +1 -1
- package/dist/state/merkle/merkle-tree.js +16 -7
- package/dist/state/store/ciphertext-store.d.ts +4 -0
- package/dist/state/store/ciphertext-store.d.ts.map +1 -1
- package/dist/state/store/ciphertext-store.js +12 -0
- package/dist/state/store/history-store.d.ts +24 -0
- package/dist/state/store/history-store.d.ts.map +1 -0
- package/dist/state/store/history-store.js +53 -0
- package/dist/state/store/index.d.ts +3 -2
- package/dist/state/store/index.d.ts.map +1 -1
- package/dist/state/store/index.js +1 -0
- package/dist/state/store/job-store.d.ts +7 -7
- package/dist/state/store/job-store.d.ts.map +1 -1
- package/dist/state/store/job-store.js +65 -39
- package/dist/state/store/jobs.d.ts +65 -18
- package/dist/state/store/jobs.d.ts.map +1 -1
- package/dist/state/store/leaf-store.d.ts.map +1 -1
- package/dist/state/store/leaf-store.js +0 -3
- package/dist/state/store/note-store.d.ts +7 -7
- package/dist/state/store/note-store.d.ts.map +1 -1
- package/dist/state/store/note-store.js +38 -34
- package/dist/state/store/nullifier-store.d.ts +9 -0
- package/dist/state/store/nullifier-store.d.ts.map +1 -1
- package/dist/state/store/nullifier-store.js +32 -2
- package/dist/state/store/records.d.ts +31 -2
- package/dist/state/store/records.d.ts.map +1 -1
- package/dist/state/store/root-store.d.ts.map +1 -1
- package/dist/state/store/root-store.js +0 -4
- package/dist/state/store/store.d.ts +61 -27
- package/dist/state/store/store.d.ts.map +1 -1
- package/dist/state/store/store.js +92 -1
- package/dist/storage/indexeddb.js +1 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +5 -1
- package/dist/transactions/deposit.d.ts +12 -15
- package/dist/transactions/deposit.d.ts.map +1 -1
- package/dist/transactions/deposit.js +203 -152
- package/dist/transactions/index.d.ts +7 -4
- package/dist/transactions/index.d.ts.map +1 -1
- package/dist/transactions/index.js +7 -2
- package/dist/transactions/note-selection.d.ts +17 -0
- package/dist/transactions/note-selection.d.ts.map +1 -0
- package/dist/transactions/note-selection.js +201 -0
- package/dist/transactions/note-sync.d.ts +5 -33
- package/dist/transactions/note-sync.d.ts.map +1 -1
- package/dist/transactions/note-sync.js +320 -155
- package/dist/transactions/reconcile.d.ts +10 -12
- package/dist/transactions/reconcile.d.ts.map +1 -1
- package/dist/transactions/reconcile.js +53 -7
- package/dist/transactions/transact.d.ts +13 -24
- package/dist/transactions/transact.d.ts.map +1 -1
- package/dist/transactions/transact.js +393 -507
- package/dist/transactions/transaction-planner.d.ts +34 -0
- package/dist/transactions/transaction-planner.d.ts.map +1 -0
- package/dist/transactions/transaction-planner.js +116 -0
- package/dist/transactions/transfer-planner.d.ts +36 -0
- package/dist/transactions/transfer-planner.d.ts.map +1 -0
- package/dist/transactions/transfer-planner.js +85 -0
- package/dist/transactions/types/deposit.d.ts +67 -0
- package/dist/transactions/types/deposit.d.ts.map +1 -0
- package/dist/transactions/types/domain.d.ts +67 -0
- package/dist/transactions/types/domain.d.ts.map +1 -0
- package/dist/transactions/types/domain.js +4 -0
- package/dist/transactions/types/index.d.ts +18 -0
- package/dist/transactions/types/index.d.ts.map +1 -0
- package/dist/transactions/types/index.js +17 -0
- package/dist/transactions/types/options.d.ts +45 -0
- package/dist/transactions/types/options.d.ts.map +1 -0
- package/dist/transactions/types/options.js +1 -0
- package/dist/transactions/types/planning.d.ts +80 -0
- package/dist/transactions/types/planning.d.ts.map +1 -0
- package/dist/transactions/types/planning.js +1 -0
- package/dist/transactions/types/state-stores.d.ts +103 -0
- package/dist/transactions/types/state-stores.d.ts.map +1 -0
- package/dist/transactions/types/state-stores.js +1 -0
- package/dist/transactions/types/transact.d.ts +76 -0
- package/dist/transactions/types/transact.d.ts.map +1 -0
- package/dist/transactions/types/transact.js +1 -0
- package/dist/transactions/withdrawal-planner.d.ts +58 -0
- package/dist/transactions/withdrawal-planner.d.ts.map +1 -0
- package/dist/transactions/withdrawal-planner.js +128 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsup.browser.config.d.ts +7 -0
- package/dist/tsup.browser.config.d.ts.map +1 -0
- package/dist/tsup.browser.config.js +34 -0
- package/dist/utils/amounts.d.ts +39 -0
- package/dist/utils/amounts.d.ts.map +1 -0
- package/dist/utils/amounts.js +89 -0
- package/dist/utils/async.d.ts +9 -0
- package/dist/utils/async.d.ts.map +1 -1
- package/dist/utils/async.js +24 -0
- package/dist/utils/bigint.js +7 -7
- package/dist/utils/crypto.d.ts +11 -5
- package/dist/utils/crypto.d.ts.map +1 -1
- package/dist/utils/crypto.js +12 -6
- package/dist/utils/format.d.ts +25 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +33 -0
- package/dist/utils/json-codec.js +1 -1
- package/dist/utils/notes.d.ts +15 -0
- package/dist/utils/notes.d.ts.map +1 -0
- package/dist/utils/notes.js +14 -0
- package/dist/utils/polling.d.ts +5 -0
- package/dist/utils/polling.d.ts.map +1 -1
- package/dist/utils/polling.js +5 -0
- package/dist/utils/random.d.ts +13 -0
- package/dist/utils/random.d.ts.map +1 -0
- package/dist/utils/random.js +27 -0
- package/dist/utils/secure-memory.d.ts +25 -0
- package/dist/utils/secure-memory.d.ts.map +1 -0
- package/dist/utils/secure-memory.js +28 -0
- package/dist/utils/signature.d.ts +6 -0
- package/dist/utils/signature.d.ts.map +1 -1
- package/dist/utils/signature.js +8 -6
- package/dist/utils/validators.d.ts +21 -10
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js +37 -11
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +13 -0
- package/package.json +28 -11
- package/.eslintrc.json +0 -4
- package/account/zkAccount.test.ts +0 -316
- package/account/zkAccount.ts +0 -222
- package/clients/broadcaster.ts +0 -67
- package/clients/http.ts +0 -94
- package/clients/indexer.ts +0 -150
- package/config.ts +0 -39
- package/core.ts +0 -17
- package/dist/account/railgun-imports-prototype.d.ts +0 -12
- package/dist/account/railgun-imports-prototype.d.ts.map +0 -1
- package/dist/account/railgun-imports-prototype.js +0 -30
- package/dist/account/zkAccount.d.ts.map +0 -1
- package/dist/key-derivation/babyjubjub.d.ts +0 -9
- package/dist/key-derivation/babyjubjub.d.ts.map +0 -1
- package/dist/key-derivation/babyjubjub.js +0 -9
- package/dist/key-derivation/bech32.d.ts +0 -22
- package/dist/key-derivation/bech32.d.ts.map +0 -1
- package/dist/key-derivation/bech32.js +0 -86
- package/dist/key-derivation/bip32.d.ts +0 -17
- package/dist/key-derivation/bip32.d.ts.map +0 -1
- package/dist/key-derivation/bip32.js +0 -41
- package/dist/key-derivation/bip39.d.ts +0 -22
- package/dist/key-derivation/bip39.d.ts.map +0 -1
- package/dist/key-derivation/bip39.js +0 -56
- package/dist/key-derivation/bytes.d.ts +0 -19
- package/dist/key-derivation/bytes.d.ts.map +0 -1
- package/dist/key-derivation/bytes.js +0 -92
- package/dist/key-derivation/hash.d.ts +0 -3
- package/dist/key-derivation/hash.d.ts.map +0 -1
- package/dist/key-derivation/hash.js +0 -10
- package/dist/key-derivation/index.d.ts +0 -8
- package/dist/key-derivation/index.d.ts.map +0 -1
- package/dist/key-derivation/index.js +0 -7
- package/dist/key-derivation/wallet-node.d.ts +0 -45
- package/dist/key-derivation/wallet-node.d.ts.map +0 -1
- package/dist/key-derivation/wallet-node.js +0 -109
- package/dist/state/ciphertext-store.d.ts +0 -12
- package/dist/state/ciphertext-store.d.ts.map +0 -1
- package/dist/state/ciphertext-store.js +0 -25
- package/dist/state/hydrator.d.ts +0 -16
- package/dist/state/hydrator.d.ts.map +0 -1
- package/dist/state/hydrator.js +0 -18
- package/dist/state/job-store.d.ts +0 -12
- package/dist/state/job-store.d.ts.map +0 -1
- package/dist/state/job-store.js +0 -118
- package/dist/state/jobs.d.ts +0 -50
- package/dist/state/jobs.d.ts.map +0 -1
- package/dist/state/jobs.js +0 -1
- package/dist/state/leaf-store.d.ts +0 -17
- package/dist/state/leaf-store.d.ts.map +0 -1
- package/dist/state/leaf-store.js +0 -35
- package/dist/state/merkle-tree.d.ts +0 -34
- package/dist/state/merkle-tree.d.ts.map +0 -1
- package/dist/state/merkle-tree.js +0 -104
- package/dist/state/note-store.d.ts +0 -37
- package/dist/state/note-store.d.ts.map +0 -1
- package/dist/state/note-store.js +0 -133
- package/dist/state/nullifier-store.d.ts +0 -13
- package/dist/state/nullifier-store.d.ts.map +0 -1
- package/dist/state/nullifier-store.js +0 -21
- package/dist/state/records.d.ts +0 -57
- package/dist/state/records.d.ts.map +0 -1
- package/dist/state/root-store.d.ts +0 -13
- package/dist/state/root-store.d.ts.map +0 -1
- package/dist/state/root-store.js +0 -30
- package/dist/state/store.d.ts +0 -26
- package/dist/state/store.d.ts.map +0 -1
- package/dist/state/store.js +0 -19
- package/dist/state.d.ts +0 -83
- package/dist/state.d.ts.map +0 -1
- package/dist/state.js +0 -171
- package/dist/transactions/shield.d.ts +0 -5
- package/dist/transactions/shield.d.ts.map +0 -1
- package/dist/transactions/shield.js +0 -93
- package/dist/transactions/types.d.ts +0 -114
- package/dist/transactions/types.d.ts.map +0 -1
- package/dist/transactions/utils.d.ts +0 -10
- package/dist/transactions/utils.d.ts.map +0 -1
- package/dist/transactions/utils.js +0 -17
- package/dist/utils/time.d.ts +0 -2
- package/dist/utils/time.d.ts.map +0 -1
- package/dist/utils/time.js +0 -3
- package/dist/utils/witness.d.ts +0 -11
- package/dist/utils/witness.d.ts.map +0 -1
- package/dist/utils/witness.js +0 -19
- package/errors.ts +0 -20
- package/index.ts +0 -17
- package/key-derivation/babyjubjub.ts +0 -11
- package/key-derivation/bech32.test.ts +0 -90
- package/key-derivation/bech32.ts +0 -124
- package/key-derivation/bip32.ts +0 -56
- package/key-derivation/bip39.ts +0 -76
- package/key-derivation/bytes.ts +0 -118
- package/key-derivation/hash.ts +0 -13
- package/key-derivation/index.ts +0 -7
- package/key-derivation/wallet-node.ts +0 -155
- package/keys.ts +0 -47
- package/prover/config.ts +0 -104
- package/prover/index.ts +0 -1
- package/prover/prover.integration.test.ts +0 -162
- package/prover/prover.test.ts +0 -309
- package/prover/prover.ts +0 -405
- package/prover/registry.test.ts +0 -90
- package/prover/registry.ts +0 -82
- package/schema.ts +0 -17
- package/setup-artifacts.sh +0 -57
- package/state/index.ts +0 -2
- package/state/merkle/hydrator.ts +0 -69
- package/state/merkle/index.ts +0 -12
- package/state/merkle/merkle-tree.test.ts +0 -50
- package/state/merkle/merkle-tree.ts +0 -163
- package/state/store/ciphertext-store.ts +0 -28
- package/state/store/index.ts +0 -24
- package/state/store/job-store.ts +0 -162
- package/state/store/jobs.ts +0 -64
- package/state/store/leaf-store.ts +0 -39
- package/state/store/note-store.ts +0 -177
- package/state/store/nullifier-store.ts +0 -39
- package/state/store/records.ts +0 -61
- package/state/store/root-store.ts +0 -34
- package/state/store/store.ts +0 -25
- package/state.test.ts +0 -235
- package/storage/index.ts +0 -3
- package/storage/indexeddb.test.ts +0 -99
- package/storage/indexeddb.ts +0 -235
- package/storage/memory.test.ts +0 -59
- package/storage/memory.ts +0 -93
- package/transactions/deposit.test.ts +0 -160
- package/transactions/deposit.ts +0 -227
- package/transactions/index.ts +0 -20
- package/transactions/note-sync.test.ts +0 -155
- package/transactions/note-sync.ts +0 -452
- package/transactions/reconcile.ts +0 -73
- package/transactions/transact.test.ts +0 -451
- package/transactions/transact.ts +0 -811
- package/transactions/types.ts +0 -141
- package/tsconfig.json +0 -14
- package/types/global.d.ts +0 -15
- package/types.ts +0 -24
- package/utils/async.ts +0 -15
- package/utils/bigint.ts +0 -34
- package/utils/crypto.test.ts +0 -69
- package/utils/crypto.ts +0 -58
- package/utils/json-codec.ts +0 -38
- package/utils/polling.ts +0 -6
- package/utils/signature.ts +0 -16
- package/utils/validators.test.ts +0 -64
- package/utils/validators.ts +0 -86
- /package/dist/{transactions → history}/types.js +0 -0
- /package/dist/{state/records.js → transactions/types/deposit.js} +0 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State store interfaces for transaction operations.
|
|
3
|
+
*/
|
|
4
|
+
import type { JobKind, JobRecord, JobStatus, LeafRecord, NoteRecord, NullifierRecord, RootRecord } from "../../state/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* Base state store interface with common methods shared across services.
|
|
7
|
+
*/
|
|
8
|
+
export type BaseStateStore = {
|
|
9
|
+
putLeaf(record: LeafRecord): Promise<void>;
|
|
10
|
+
getLeaf(chainId: number, index: number): Promise<LeafRecord | null>;
|
|
11
|
+
clearLeaves(chainId: number): Promise<void>;
|
|
12
|
+
putRoot(record: RootRecord): Promise<void>;
|
|
13
|
+
putJob(job: JobRecord): Promise<void>;
|
|
14
|
+
getJob(relayId: string): Promise<JobRecord | null>;
|
|
15
|
+
listJobs(filter?: {
|
|
16
|
+
kind?: JobKind;
|
|
17
|
+
statuses?: JobStatus[];
|
|
18
|
+
}): Promise<JobRecord[]>;
|
|
19
|
+
deleteJob(relayId: string): Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* State store interface for transaction operations.
|
|
23
|
+
*/
|
|
24
|
+
export type TransactStateStore = BaseStateStore & {
|
|
25
|
+
getNote(chainId: number, index: number): Promise<NoteRecord | null>;
|
|
26
|
+
markNoteSpent(chainId: number, index: number, spentAt?: number, spentTxHash?: string): Promise<NoteRecord>;
|
|
27
|
+
putNullifier(record: NullifierRecord): Promise<void>;
|
|
28
|
+
listNotes(options?: {
|
|
29
|
+
chainId?: number;
|
|
30
|
+
mpk?: string;
|
|
31
|
+
token?: string;
|
|
32
|
+
includeSpent?: boolean;
|
|
33
|
+
}): Promise<NoteRecord[]>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* State store interface for note synchronization operations.
|
|
37
|
+
* Extends BaseStateStore with note-specific methods.
|
|
38
|
+
*/
|
|
39
|
+
export type NoteSyncStateStore = BaseStateStore & {
|
|
40
|
+
putNote(record: NoteRecord): Promise<void>;
|
|
41
|
+
getNote(chainId: number, index: number): Promise<NoteRecord | null>;
|
|
42
|
+
clearNotes(chainId: number): Promise<void>;
|
|
43
|
+
listNotes(options?: {
|
|
44
|
+
chainId?: number;
|
|
45
|
+
mpk?: string;
|
|
46
|
+
token?: string;
|
|
47
|
+
includeSpent?: boolean;
|
|
48
|
+
}): Promise<NoteRecord[]>;
|
|
49
|
+
markNoteSpent(chainId: number, index: number, spentAt?: number, spentTxHash?: string): Promise<NoteRecord>;
|
|
50
|
+
putCiphertext(chainId: number, index: number, payload: Uint8Array): Promise<void>;
|
|
51
|
+
getCiphertext(chainId: number, index: number): Promise<Uint8Array | null>;
|
|
52
|
+
clearCiphertexts(chainId: number): Promise<void>;
|
|
53
|
+
countNullifiers(chainId: number): Promise<number>;
|
|
54
|
+
clearNullifiers(chainId: number): Promise<void>;
|
|
55
|
+
clearNullifiersFromIndex(chainId: number, fromIndex: number): Promise<void>;
|
|
56
|
+
putNullifier(record: {
|
|
57
|
+
chainId: number;
|
|
58
|
+
nullifier: string;
|
|
59
|
+
noteIndex?: number;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Atomically store a commitment's leaf, ciphertext, root, and optionally note.
|
|
63
|
+
* Uses storage.batch() for all-or-nothing semantics.
|
|
64
|
+
*/
|
|
65
|
+
syncCommitment(params: {
|
|
66
|
+
leaf: {
|
|
67
|
+
chainId: number;
|
|
68
|
+
index: number;
|
|
69
|
+
commitment: string;
|
|
70
|
+
txHash?: string;
|
|
71
|
+
eventType?: string;
|
|
72
|
+
insertedAt?: number;
|
|
73
|
+
};
|
|
74
|
+
ciphertext: {
|
|
75
|
+
chainId: number;
|
|
76
|
+
index: number;
|
|
77
|
+
payload: Uint8Array;
|
|
78
|
+
};
|
|
79
|
+
root: {
|
|
80
|
+
chainId: number;
|
|
81
|
+
root: string;
|
|
82
|
+
};
|
|
83
|
+
note?: {
|
|
84
|
+
chainId: number;
|
|
85
|
+
index: number;
|
|
86
|
+
token: string;
|
|
87
|
+
value: string;
|
|
88
|
+
commitment: string;
|
|
89
|
+
npk: string;
|
|
90
|
+
mpk: string;
|
|
91
|
+
random: string;
|
|
92
|
+
nullifier: string;
|
|
93
|
+
createdTxHash?: string;
|
|
94
|
+
createdEventType?: string;
|
|
95
|
+
createdAt?: number;
|
|
96
|
+
spentAt?: number;
|
|
97
|
+
spentTxHash?: string;
|
|
98
|
+
};
|
|
99
|
+
}): Promise<void>;
|
|
100
|
+
/** Clear notes, leaves, ciphertexts, and unspent indices for indices >= fromIndex. */
|
|
101
|
+
clearChainDataFromIndex(chainId: number, fromIndex: number): Promise<void>;
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=state-stores.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-stores.d.ts","sourceRoot":"","sources":["../../../transactions/types/state-stores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for transaction operations.
|
|
3
|
+
*/
|
|
4
|
+
import type { IMTMerkleProof } from "@zk-kit/imt";
|
|
5
|
+
import type { Account } from "../../account/account.js";
|
|
6
|
+
import type { CommitmentRecord } from "../../clients/indexer.js";
|
|
7
|
+
import type { NoteInput, Proof, SpendNoteReference, WithdrawalNoteInput } from "./domain.js";
|
|
8
|
+
/**
|
|
9
|
+
* A single transaction item (used in the transactions array).
|
|
10
|
+
*/
|
|
11
|
+
export type TransactItem = {
|
|
12
|
+
/** Token address */
|
|
13
|
+
token: string;
|
|
14
|
+
/** Input notes to spend */
|
|
15
|
+
inputs: SpendNoteReference[];
|
|
16
|
+
/** Output notes to create */
|
|
17
|
+
outputs: NoteInput[];
|
|
18
|
+
/** Optional withdrawal output */
|
|
19
|
+
withdrawal?: WithdrawalNoteInput;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Parameters required to execute private transaction(s).
|
|
23
|
+
* Always accepts an array of transactions - single tx just passes [item].
|
|
24
|
+
*/
|
|
25
|
+
export type TransactParams = {
|
|
26
|
+
/** Account with keys for signing and viewing */
|
|
27
|
+
account: Account;
|
|
28
|
+
/** Chain ID for the target blockchain */
|
|
29
|
+
chainId: number;
|
|
30
|
+
/** Pool contract address */
|
|
31
|
+
poolAddress: string;
|
|
32
|
+
/** Transactions to execute (proofs generated in parallel, bundled into one call) */
|
|
33
|
+
transactions: TransactItem[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Result of a single transaction within the batch.
|
|
37
|
+
*/
|
|
38
|
+
export type TransactItemResult = {
|
|
39
|
+
/** Generated proof */
|
|
40
|
+
proof: Proof;
|
|
41
|
+
/** Merkle witnesses for inputs */
|
|
42
|
+
witnesses: IMTMerkleProof[];
|
|
43
|
+
/** Nullifiers of spent notes */
|
|
44
|
+
nullifiers: string[];
|
|
45
|
+
/** Predicted commitment hex strings */
|
|
46
|
+
predictedCommitments: string[];
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Result of the transact flow, including calldata and state deltas.
|
|
50
|
+
*/
|
|
51
|
+
export type TransactRelayResult = {
|
|
52
|
+
/** Relay ID for tracking */
|
|
53
|
+
relayId: string;
|
|
54
|
+
/** Calldata to submit on-chain */
|
|
55
|
+
calldata: string;
|
|
56
|
+
/** Individual transaction results */
|
|
57
|
+
transactions: TransactItemResult[];
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Result of syncing a pending transaction.
|
|
61
|
+
*/
|
|
62
|
+
export type TransactSyncResult = {
|
|
63
|
+
/** Chain ID */
|
|
64
|
+
chainId: number;
|
|
65
|
+
/** Merkle root after transaction */
|
|
66
|
+
root: string;
|
|
67
|
+
/** Nullifiers of spent notes (all transactions combined) */
|
|
68
|
+
nullifiers: string[];
|
|
69
|
+
/** New commitment hex strings (all transactions combined) */
|
|
70
|
+
newCommitments: string[];
|
|
71
|
+
/** Transaction hash (if available) */
|
|
72
|
+
txHash?: string;
|
|
73
|
+
/** Indexed commitments */
|
|
74
|
+
indexedCommitments?: CommitmentRecord[];
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=transact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transact.d.ts","sourceRoot":"","sources":["../../../transactions/types/transact.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EACV,SAAS,EACT,KAAK,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,6BAA6B;IAC7B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,iCAAiC;IACjC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,YAAY,EAAE,YAAY,EAAE,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sBAAsB;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,kCAAkC;IAClC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,gCAAgC;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,uCAAuC;IACvC,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,YAAY,EAAE,kBAAkB,EAAE,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,6DAA6D;IAC7D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type CircuitConfig } from "../prover/registry.js";
|
|
2
|
+
import type { NoteInput, SelectableNote, WithdrawalNoteInput } from "./types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Result of planning a withdrawal transaction.
|
|
5
|
+
*/
|
|
6
|
+
export type WithdrawalPlan<T> = {
|
|
7
|
+
/** Selected input notes to spend */
|
|
8
|
+
inputs: SelectableNote<T>[];
|
|
9
|
+
/** Output notes (change only, if any) */
|
|
10
|
+
outputNotes: NoteInput[];
|
|
11
|
+
/** Withdrawal specification */
|
|
12
|
+
withdrawal: WithdrawalNoteInput;
|
|
13
|
+
/** Selected circuit configuration */
|
|
14
|
+
circuit: CircuitConfig;
|
|
15
|
+
/** Total input amount from selected notes */
|
|
16
|
+
totalInput: bigint;
|
|
17
|
+
/** Amount being withdrawn */
|
|
18
|
+
withdrawAmount: bigint;
|
|
19
|
+
/** Change amount returned to sender */
|
|
20
|
+
change: bigint;
|
|
21
|
+
/** Token address */
|
|
22
|
+
token: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Input for a single withdrawal in a batch.
|
|
26
|
+
*/
|
|
27
|
+
export type WithdrawalInput = {
|
|
28
|
+
token: string;
|
|
29
|
+
amount: bigint;
|
|
30
|
+
recipient: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Plan withdrawal transaction(s).
|
|
34
|
+
* Accepts 1 or more withdrawals. When multiple withdrawals use the same token,
|
|
35
|
+
* notes are tracked across withdrawals to avoid double-spending.
|
|
36
|
+
*
|
|
37
|
+
* @param notes - Available unspent notes (all tokens)
|
|
38
|
+
* @param withdrawals - Withdrawals to plan (each with token, amount, recipient)
|
|
39
|
+
* @param senderMpk - Sender's master public key (for change outputs)
|
|
40
|
+
* @returns Array of withdrawal plans, one per withdrawal input
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // Single withdrawal
|
|
45
|
+
* const [plan] = planWithdrawals(notes, [{ token, amount: 100n, recipient: "0x..." }], mpk);
|
|
46
|
+
*
|
|
47
|
+
* // Multiple withdrawals (possibly same token)
|
|
48
|
+
* const plans = planWithdrawals(notes, [
|
|
49
|
+
* { token: ETH, amount: 100n, recipient: "0x..." },
|
|
50
|
+
* { token: USDC, amount: 50n, recipient: "0x..." },
|
|
51
|
+
* ], mpk);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function planWithdrawals<T extends {
|
|
55
|
+
index: number;
|
|
56
|
+
value: bigint | string;
|
|
57
|
+
}>(notes: SelectableNote<T>[], withdrawals: WithdrawalInput[], senderMpk: bigint): WithdrawalPlan<T>[];
|
|
58
|
+
//# sourceMappingURL=withdrawal-planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withdrawal-planner.d.ts","sourceRoot":"","sources":["../../transactions/withdrawal-planner.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG7E,OAAO,KAAK,EACV,SAAS,EACT,cAAc,EACd,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAE1B;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,oCAAoC;IACpC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,yCAAyC;IACzC,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,+BAA+B;IAC/B,UAAU,EAAE,mBAAmB,CAAC;IAChC,qCAAqC;IACrC,OAAO,EAAE,aAAa,CAAC;IACvB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAmFF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAC7B,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAEnD,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,EAC1B,WAAW,EAAE,eAAe,EAAE,EAC9B,SAAS,EAAE,MAAM,GAChB,cAAc,CAAC,CAAC,CAAC,EAAE,CA0ErB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ProofError, ValidationError } from "../errors.js";
|
|
2
|
+
import { CIRCUIT_REGISTRY } from "../prover/registry.js";
|
|
3
|
+
import { randomBigint } from "../utils/random.js";
|
|
4
|
+
import { selectNotesForAmount } from "./note-selection.js";
|
|
5
|
+
/**
|
|
6
|
+
* Select the smallest circuit that fits the given input/output counts.
|
|
7
|
+
* For withdrawals, outputs = change only (0 or 1).
|
|
8
|
+
*/
|
|
9
|
+
function selectCircuitForWithdrawal(inputCount, outputCount) {
|
|
10
|
+
// Sort circuits by total size (inputs + outputs) ascending
|
|
11
|
+
const circuits = Object.values(CIRCUIT_REGISTRY).sort((a, b) => a.inputs + a.outputs - (b.inputs + b.outputs));
|
|
12
|
+
const circuit = circuits.find((c) => c.inputs >= inputCount && c.outputs >= outputCount);
|
|
13
|
+
if (!circuit) {
|
|
14
|
+
throw new ProofError(`No circuit supports ${inputCount} inputs and ${outputCount} outputs. ` +
|
|
15
|
+
`Available: ${circuits.map((c) => `${c.inputs}x${c.outputs}`).join(", ")}`);
|
|
16
|
+
}
|
|
17
|
+
return circuit;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Plan a single withdrawal transaction. Used internally by `planWithdrawals`.
|
|
21
|
+
*/
|
|
22
|
+
function planSingleWithdrawal(notes, withdrawAmount, recipientAddress, senderMpk, token) {
|
|
23
|
+
if (withdrawAmount <= 0n) {
|
|
24
|
+
throw new ValidationError("Withdrawal amount must be positive");
|
|
25
|
+
}
|
|
26
|
+
const selection = selectNotesForAmount(notes, withdrawAmount, {
|
|
27
|
+
recipientCount: 0,
|
|
28
|
+
});
|
|
29
|
+
const { selected: inputs, totalInput, change } = selection;
|
|
30
|
+
const changeOutputCount = change > 0n ? 1 : 0;
|
|
31
|
+
const outputCount = changeOutputCount + 1;
|
|
32
|
+
const circuit = selectCircuitForWithdrawal(inputs.length, outputCount);
|
|
33
|
+
const outputNotes = [];
|
|
34
|
+
if (change > 0n) {
|
|
35
|
+
const random = randomBigint();
|
|
36
|
+
outputNotes.push({
|
|
37
|
+
mpk: senderMpk,
|
|
38
|
+
random,
|
|
39
|
+
token,
|
|
40
|
+
amount: change,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const withdrawal = {
|
|
44
|
+
npk: BigInt(recipientAddress),
|
|
45
|
+
amount: withdrawAmount,
|
|
46
|
+
token,
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
inputs,
|
|
50
|
+
outputNotes,
|
|
51
|
+
withdrawal,
|
|
52
|
+
circuit,
|
|
53
|
+
totalInput,
|
|
54
|
+
withdrawAmount,
|
|
55
|
+
change,
|
|
56
|
+
token,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Plan withdrawal transaction(s).
|
|
61
|
+
* Accepts 1 or more withdrawals. When multiple withdrawals use the same token,
|
|
62
|
+
* notes are tracked across withdrawals to avoid double-spending.
|
|
63
|
+
*
|
|
64
|
+
* @param notes - Available unspent notes (all tokens)
|
|
65
|
+
* @param withdrawals - Withdrawals to plan (each with token, amount, recipient)
|
|
66
|
+
* @param senderMpk - Sender's master public key (for change outputs)
|
|
67
|
+
* @returns Array of withdrawal plans, one per withdrawal input
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Single withdrawal
|
|
72
|
+
* const [plan] = planWithdrawals(notes, [{ token, amount: 100n, recipient: "0x..." }], mpk);
|
|
73
|
+
*
|
|
74
|
+
* // Multiple withdrawals (possibly same token)
|
|
75
|
+
* const plans = planWithdrawals(notes, [
|
|
76
|
+
* { token: ETH, amount: 100n, recipient: "0x..." },
|
|
77
|
+
* { token: USDC, amount: 50n, recipient: "0x..." },
|
|
78
|
+
* ], mpk);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export function planWithdrawals(notes, withdrawals, senderMpk) {
|
|
82
|
+
if (!withdrawals.length) {
|
|
83
|
+
throw new ValidationError("At least one withdrawal is required");
|
|
84
|
+
}
|
|
85
|
+
// Validate all withdrawals upfront
|
|
86
|
+
for (const w of withdrawals) {
|
|
87
|
+
if (w.amount <= 0n) {
|
|
88
|
+
throw new ValidationError(`Invalid withdrawal amount for ${w.token}: ${w.amount}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Pre-validate total balances per token (use normalized tokens for comparison)
|
|
92
|
+
const requiredByToken = new Map();
|
|
93
|
+
for (const w of withdrawals) {
|
|
94
|
+
const tokenLower = w.token.toLowerCase();
|
|
95
|
+
const existing = requiredByToken.get(tokenLower) ?? 0n;
|
|
96
|
+
requiredByToken.set(tokenLower, existing + w.amount);
|
|
97
|
+
}
|
|
98
|
+
for (const [tokenLower, required] of requiredByToken) {
|
|
99
|
+
const available = notes
|
|
100
|
+
.filter((n) => n.token.toLowerCase() ===
|
|
101
|
+
tokenLower)
|
|
102
|
+
.reduce((sum, n) => sum + BigInt(n.value), 0n);
|
|
103
|
+
if (available < required) {
|
|
104
|
+
throw new ValidationError(`Insufficient balance for ${tokenLower}: need ${required}, have ${available}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Track used note indices per token to avoid double-spending
|
|
108
|
+
const usedNotesByToken = new Map();
|
|
109
|
+
const plans = [];
|
|
110
|
+
for (const w of withdrawals) {
|
|
111
|
+
const tokenLower = w.token.toLowerCase();
|
|
112
|
+
// Get available notes for this token, excluding already-used ones
|
|
113
|
+
const usedIndices = usedNotesByToken.get(tokenLower) ?? new Set();
|
|
114
|
+
const availableNotes = notes.filter((n) => n.token.toLowerCase() ===
|
|
115
|
+
tokenLower && !usedIndices.has(n.index));
|
|
116
|
+
// Plan this withdrawal (pass original token for output)
|
|
117
|
+
const plan = planSingleWithdrawal(availableNotes, w.amount, w.recipient, senderMpk, w.token);
|
|
118
|
+
// Mark selected notes as used
|
|
119
|
+
if (!usedNotesByToken.has(tokenLower)) {
|
|
120
|
+
usedNotesByToken.set(tokenLower, new Set());
|
|
121
|
+
}
|
|
122
|
+
for (const input of plan.inputs) {
|
|
123
|
+
usedNotesByToken.get(tokenLower).add(input.index);
|
|
124
|
+
}
|
|
125
|
+
plans.push(plan);
|
|
126
|
+
}
|
|
127
|
+
return plans;
|
|
128
|
+
}
|