@unlink-xyz/core 0.1.3-canary.fd5dddf → 0.1.4
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/README.md +9 -0
- package/dist/account/account.d.ts +31 -2
- package/dist/account/account.d.ts.map +1 -1
- package/dist/account/accounts.d.ts +42 -0
- package/dist/account/accounts.d.ts.map +1 -0
- package/dist/account/seed.d.ts +45 -0
- package/dist/account/seed.d.ts.map +1 -0
- package/dist/account/serialization.d.ts +6 -0
- package/dist/account/serialization.d.ts.map +1 -0
- package/dist/browser/index.js +34424 -86406
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/wallet/index.js +55942 -0
- package/dist/browser/wallet/index.js.map +1 -0
- package/dist/clients/broadcaster.d.ts +1 -0
- package/dist/clients/broadcaster.d.ts.map +1 -1
- package/dist/clients/indexer.d.ts +5 -0
- package/dist/clients/indexer.d.ts.map +1 -1
- package/dist/config.d.ts +6 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/crypto/adapters/index.d.ts +17 -0
- package/dist/crypto/adapters/index.d.ts.map +1 -0
- package/dist/crypto/adapters/polyfills.d.ts +5 -0
- package/dist/crypto/adapters/polyfills.d.ts.map +1 -0
- package/dist/crypto/encrypt.d.ts +33 -0
- package/dist/crypto/encrypt.d.ts.map +1 -0
- package/dist/crypto/secure-memory.d.ts.map +1 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6721 -23
- package/dist/index.js.map +1 -0
- package/dist/keys/derive.d.ts +2 -2
- package/dist/keys/derive.d.ts.map +1 -1
- package/dist/keys/hex.d.ts +1 -4
- package/dist/keys/hex.d.ts.map +1 -1
- package/dist/keys/mnemonic.d.ts +0 -2
- package/dist/keys/mnemonic.d.ts.map +1 -1
- package/dist/keys.d.ts +1 -0
- package/dist/keys.d.ts.map +1 -1
- package/dist/prover/config.d.ts +54 -9
- package/dist/prover/config.d.ts.map +1 -1
- package/dist/prover/integrity.d.ts +20 -0
- package/dist/prover/integrity.d.ts.map +1 -0
- package/dist/prover/prover.d.ts +16 -31
- package/dist/prover/prover.d.ts.map +1 -1
- package/dist/state/merkle/hydrator.d.ts +21 -19
- package/dist/state/merkle/hydrator.d.ts.map +1 -1
- package/dist/state/merkle/index.d.ts +1 -1
- package/dist/state/merkle/index.d.ts.map +1 -1
- package/dist/state/store/ciphertext-store.d.ts +7 -0
- package/dist/state/store/ciphertext-store.d.ts.map +1 -1
- package/dist/state/store/index.d.ts +1 -1
- package/dist/state/store/index.d.ts.map +1 -1
- package/dist/state/store/job-store.d.ts.map +1 -1
- package/dist/state/store/jobs.d.ts +14 -16
- package/dist/state/store/jobs.d.ts.map +1 -1
- package/dist/state/store/leaf-store.d.ts +4 -0
- package/dist/state/store/leaf-store.d.ts.map +1 -1
- package/dist/state/store/nullifier-store.d.ts.map +1 -1
- package/dist/state/store/records.d.ts +8 -0
- package/dist/state/store/records.d.ts.map +1 -1
- package/dist/state/store/store.d.ts +18 -0
- package/dist/state/store/store.d.ts.map +1 -1
- package/dist/storage/indexeddb.d.ts.map +1 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/transactions/adapter.d.ts +31 -0
- package/dist/transactions/adapter.d.ts.map +1 -0
- package/dist/transactions/deposit.d.ts +1 -1
- package/dist/transactions/deposit.d.ts.map +1 -1
- package/dist/transactions/index.d.ts +4 -2
- package/dist/transactions/index.d.ts.map +1 -1
- package/dist/transactions/note-sync.d.ts +3 -3
- package/dist/transactions/note-sync.d.ts.map +1 -1
- package/dist/transactions/reconcile.d.ts +1 -1
- package/dist/transactions/reconcile.d.ts.map +1 -1
- package/dist/transactions/transact.d.ts +21 -2
- package/dist/transactions/transact.d.ts.map +1 -1
- package/dist/transactions/transaction-planner.d.ts +1 -1
- package/dist/transactions/transaction-planner.d.ts.map +1 -1
- package/dist/transactions/transfer-planner.d.ts +2 -1
- package/dist/transactions/transfer-planner.d.ts.map +1 -1
- package/dist/transactions/types/deposit.d.ts +3 -3
- package/dist/transactions/types/deposit.d.ts.map +1 -1
- package/dist/transactions/types/domain.d.ts +3 -0
- package/dist/transactions/types/domain.d.ts.map +1 -1
- package/dist/transactions/types/options.d.ts +14 -5
- package/dist/transactions/types/options.d.ts.map +1 -1
- package/dist/transactions/types/planning.d.ts +2 -0
- package/dist/transactions/types/planning.d.ts.map +1 -1
- package/dist/transactions/types/state-stores.d.ts +53 -5
- package/dist/transactions/types/state-stores.d.ts.map +1 -1
- package/dist/transactions/types/transact.d.ts +10 -3
- package/dist/transactions/types/transact.d.ts.map +1 -1
- package/dist/transactions/withdrawal-planner.d.ts +1 -1
- package/dist/transactions/withdrawal-planner.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsup.config.d.ts +8 -0
- package/dist/tsup.config.d.ts.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/amounts.d.ts +0 -13
- package/dist/utils/amounts.d.ts.map +1 -1
- package/dist/utils/async.js +37 -34
- package/dist/utils/async.js.map +1 -0
- package/dist/utils/bigint.d.ts +0 -2
- package/dist/utils/bigint.d.ts.map +1 -1
- package/dist/utils/random.d.ts +5 -0
- package/dist/utils/random.d.ts.map +1 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/wallet/adapter.d.ts +21 -0
- package/dist/wallet/adapter.d.ts.map +1 -0
- package/dist/wallet/burner/service.d.ts +32 -0
- package/dist/wallet/burner/service.d.ts.map +1 -0
- package/dist/wallet/burner/types.d.ts +47 -0
- package/dist/wallet/burner/types.d.ts.map +1 -0
- package/dist/wallet/index.d.ts +20 -0
- package/dist/wallet/index.d.ts.map +1 -0
- package/dist/wallet/index.js +6462 -0
- package/dist/wallet/index.js.map +1 -0
- package/dist/wallet/sdk.d.ts +48 -0
- package/dist/wallet/sdk.d.ts.map +1 -0
- package/dist/wallet/types.d.ts +457 -0
- package/dist/wallet/types.d.ts.map +1 -0
- package/dist/wallet/unlink-wallet.d.ts +187 -0
- package/dist/wallet/unlink-wallet.d.ts.map +1 -0
- package/package.json +16 -6
- package/dist/account/account.js +0 -142
- package/dist/circuits.json +0 -74
- package/dist/clients/broadcaster.js +0 -30
- package/dist/clients/http.js +0 -72
- package/dist/clients/indexer.js +0 -94
- package/dist/config.js +0 -36
- package/dist/constants.js +0 -5
- package/dist/core.js +0 -15
- package/dist/crypto-adapters/auto-init.d.ts +0 -2
- package/dist/crypto-adapters/auto-init.d.ts.map +0 -1
- package/dist/crypto-adapters/auto-init.js +0 -7
- package/dist/crypto-adapters/index.d.ts +0 -22
- package/dist/crypto-adapters/index.d.ts.map +0 -1
- package/dist/crypto-adapters/index.js +0 -47
- package/dist/crypto-adapters/polyfills.d.ts +0 -5
- package/dist/crypto-adapters/polyfills.d.ts.map +0 -1
- package/dist/crypto-adapters/polyfills.js +0 -8
- package/dist/errors.js +0 -36
- package/dist/history/index.js +0 -2
- package/dist/history/service.js +0 -354
- package/dist/history/types.js +0 -1
- package/dist/keys/address.js +0 -55
- package/dist/keys/derive.js +0 -112
- package/dist/keys/hex.js +0 -66
- package/dist/keys/index.js +0 -4
- package/dist/keys/mnemonic.js +0 -23
- package/dist/keys.js +0 -45
- package/dist/prover/config.js +0 -70
- package/dist/prover/index.js +0 -1
- package/dist/prover/prover.js +0 -291
- package/dist/prover/registry.js +0 -18
- package/dist/schema.js +0 -14
- package/dist/state/index.js +0 -2
- package/dist/state/merkle/hydrator.js +0 -37
- package/dist/state/merkle/index.js +0 -2
- package/dist/state/merkle/merkle-tree.js +0 -113
- package/dist/state/store/ciphertext-store.js +0 -37
- package/dist/state/store/history-store.js +0 -53
- package/dist/state/store/index.js +0 -9
- package/dist/state/store/job-store.js +0 -144
- package/dist/state/store/jobs.js +0 -1
- package/dist/state/store/leaf-store.js +0 -32
- package/dist/state/store/note-store.js +0 -146
- package/dist/state/store/nullifier-store.js +0 -60
- package/dist/state/store/records.js +0 -1
- package/dist/state/store/root-store.js +0 -26
- package/dist/state/store/store.js +0 -113
- package/dist/storage/index.js +0 -2
- package/dist/storage/indexeddb.js +0 -205
- package/dist/storage/memory.js +0 -91
- package/dist/transactions/deposit.js +0 -220
- package/dist/transactions/index.js +0 -9
- package/dist/transactions/note-selection.js +0 -201
- package/dist/transactions/note-sync.js +0 -485
- package/dist/transactions/reconcile.js +0 -85
- package/dist/transactions/transact.js +0 -450
- package/dist/transactions/transaction-planner.js +0 -116
- package/dist/transactions/transfer-planner.js +0 -85
- package/dist/transactions/types/deposit.js +0 -1
- package/dist/transactions/types/domain.js +0 -4
- package/dist/transactions/types/index.js +0 -17
- package/dist/transactions/types/options.js +0 -1
- package/dist/transactions/types/planning.js +0 -1
- package/dist/transactions/types/state-stores.js +0 -1
- package/dist/transactions/types/transact.js +0 -1
- package/dist/transactions/withdrawal-planner.js +0 -128
- package/dist/tsup.browser.config.js +0 -34
- package/dist/types.js +0 -1
- package/dist/utils/amounts.js +0 -89
- package/dist/utils/bigint.js +0 -29
- package/dist/utils/crypto.d.ts +0 -18
- package/dist/utils/crypto.d.ts.map +0 -1
- package/dist/utils/crypto.js +0 -45
- package/dist/utils/format.js +0 -33
- package/dist/utils/json-codec.js +0 -25
- package/dist/utils/notes.js +0 -14
- package/dist/utils/polling.js +0 -11
- package/dist/utils/random.js +0 -27
- package/dist/utils/secure-memory.d.ts.map +0 -1
- package/dist/utils/secure-memory.js +0 -28
- package/dist/utils/signature.js +0 -14
- package/dist/utils/validators.js +0 -96
- package/dist/vitest.config.js +0 -13
- /package/dist/{utils → crypto}/secure-memory.d.ts +0 -0
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { ValidationError } from "../errors.js";
|
|
2
|
-
import { planTransaction } from "./transaction-planner.js";
|
|
3
|
-
/**
|
|
4
|
-
* Plan transfer transaction(s).
|
|
5
|
-
* Accepts 1 or more transfers. When multiple transfers use the same token,
|
|
6
|
-
* notes are tracked across transfers to avoid double-spending.
|
|
7
|
-
*
|
|
8
|
-
* @param notes - Available unspent notes (all tokens)
|
|
9
|
-
* @param transfers - Transfers to plan (each with token, amount, recipientMpk)
|
|
10
|
-
* @param senderMpk - Sender's master public key (for change outputs)
|
|
11
|
-
* @returns Array of transaction plans, one per transfer input
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* // Single transfer
|
|
16
|
-
* const [plan] = planTransfers(notes, [{ token, amount: 100n, recipientMpk }], senderMpk);
|
|
17
|
-
*
|
|
18
|
-
* // Multiple transfers (possibly same token)
|
|
19
|
-
* const plans = planTransfers(notes, [
|
|
20
|
-
* { token: ETH, amount: 100n, recipientMpk: recipient1Mpk },
|
|
21
|
-
* { token: USDC, amount: 50n, recipientMpk: recipient2Mpk },
|
|
22
|
-
* ], senderMpk);
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export function planTransfers(notes, transfers, senderMpk) {
|
|
26
|
-
if (!transfers.length) {
|
|
27
|
-
throw new ValidationError("At least one transfer is required");
|
|
28
|
-
}
|
|
29
|
-
// Validate all transfers upfront
|
|
30
|
-
for (const t of transfers) {
|
|
31
|
-
if (!t.token) {
|
|
32
|
-
throw new ValidationError(`Missing token address in transfer: ${JSON.stringify(t)}`);
|
|
33
|
-
}
|
|
34
|
-
// Convert amount to bigint if needed (handles string amounts from frontend)
|
|
35
|
-
const amount = typeof t.amount === "bigint" ? t.amount : BigInt(t.amount);
|
|
36
|
-
if (amount <= 0n) {
|
|
37
|
-
throw new ValidationError(`Invalid transfer amount for ${t.token}: ${t.amount}`);
|
|
38
|
-
}
|
|
39
|
-
// Update amount to bigint for downstream use
|
|
40
|
-
t.amount = amount;
|
|
41
|
-
}
|
|
42
|
-
// Pre-validate total balances per token (use normalized tokens for comparison)
|
|
43
|
-
const requiredByToken = new Map();
|
|
44
|
-
for (const t of transfers) {
|
|
45
|
-
const tokenLower = t.token.toLowerCase();
|
|
46
|
-
const existing = requiredByToken.get(tokenLower) ?? 0n;
|
|
47
|
-
requiredByToken.set(tokenLower, existing + t.amount);
|
|
48
|
-
}
|
|
49
|
-
for (const [tokenLower, required] of requiredByToken) {
|
|
50
|
-
const available = notes
|
|
51
|
-
.filter((n) => {
|
|
52
|
-
const noteToken = n.token;
|
|
53
|
-
return noteToken && noteToken.toLowerCase() === tokenLower;
|
|
54
|
-
})
|
|
55
|
-
.reduce((sum, n) => sum + BigInt(n.value), 0n);
|
|
56
|
-
if (available < required) {
|
|
57
|
-
throw new ValidationError(`Insufficient balance for ${tokenLower}: need ${required}, have ${available}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Track used note indices per token to avoid double-spending
|
|
61
|
-
const usedNotesByToken = new Map();
|
|
62
|
-
const plans = [];
|
|
63
|
-
for (const t of transfers) {
|
|
64
|
-
const tokenLower = t.token.toLowerCase();
|
|
65
|
-
// Get available notes for this token, excluding already-used ones
|
|
66
|
-
const usedIndices = usedNotesByToken.get(tokenLower) ?? new Set();
|
|
67
|
-
const availableNotes = notes.filter((n) => {
|
|
68
|
-
const noteToken = n.token;
|
|
69
|
-
return (noteToken &&
|
|
70
|
-
noteToken.toLowerCase() === tokenLower &&
|
|
71
|
-
!usedIndices.has(n.index));
|
|
72
|
-
});
|
|
73
|
-
// Plan this transfer using the existing planTransaction function
|
|
74
|
-
const plan = planTransaction(availableNotes, [{ mpk: t.recipientMpk, amount: t.amount }], senderMpk, t.token);
|
|
75
|
-
// Mark selected notes as used
|
|
76
|
-
if (!usedNotesByToken.has(tokenLower)) {
|
|
77
|
-
usedNotesByToken.set(tokenLower, new Set());
|
|
78
|
-
}
|
|
79
|
-
for (const input of plan.inputs) {
|
|
80
|
-
usedNotesByToken.get(tokenLower).add(input.index);
|
|
81
|
-
}
|
|
82
|
-
plans.push(plan);
|
|
83
|
-
}
|
|
84
|
-
return plans;
|
|
85
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transaction type definitions.
|
|
3
|
-
*
|
|
4
|
-
* Organized by concern:
|
|
5
|
-
* - state-stores: Database/storage interfaces
|
|
6
|
-
* - options: Configuration for services
|
|
7
|
-
* - domain: Core cryptographic types
|
|
8
|
-
* - deposit: Deposit-specific types
|
|
9
|
-
* - transact: Transaction-specific types
|
|
10
|
-
* - planning: Transaction planning types
|
|
11
|
-
*/
|
|
12
|
-
export * from "./state-stores.js";
|
|
13
|
-
export * from "./options.js";
|
|
14
|
-
export * from "./domain.js";
|
|
15
|
-
export * from "./deposit.js";
|
|
16
|
-
export * from "./transact.js";
|
|
17
|
-
export * from "./planning.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,128 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
|
|
2
|
-
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
|
|
3
|
-
import { defineConfig } from "tsup";
|
|
4
|
-
/**
|
|
5
|
-
* Browser build configuration.
|
|
6
|
-
* Bundles all dependencies with Node.js polyfills for browser compatibility.
|
|
7
|
-
*/
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
entry: ["index.ts"],
|
|
10
|
-
format: ["esm"],
|
|
11
|
-
dts: false, // Types are generated by the main tsc build
|
|
12
|
-
clean: false, // Don't clean dist/ to preserve tsc output
|
|
13
|
-
splitting: false,
|
|
14
|
-
sourcemap: true,
|
|
15
|
-
minify: false,
|
|
16
|
-
// Bundle everything including dependencies for browser compatibility
|
|
17
|
-
noExternal: [/.*/],
|
|
18
|
-
esbuildPlugins: [
|
|
19
|
-
NodeModulesPolyfillPlugin(),
|
|
20
|
-
NodeGlobalsPolyfillPlugin({
|
|
21
|
-
buffer: true,
|
|
22
|
-
process: true,
|
|
23
|
-
}),
|
|
24
|
-
],
|
|
25
|
-
esbuildOptions(options) {
|
|
26
|
-
options.supported = {
|
|
27
|
-
...options.supported,
|
|
28
|
-
"top-level-await": true,
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
platform: "browser",
|
|
32
|
-
target: "es2022",
|
|
33
|
-
outDir: "dist/browser",
|
|
34
|
-
});
|
package/dist/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/utils/amounts.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { ValidationError } from "../errors.js";
|
|
2
|
-
/**
|
|
3
|
-
* Parse a decimal string to bigint with specified decimals.
|
|
4
|
-
*
|
|
5
|
-
* @param value - Decimal string (e.g., "10.5", "42")
|
|
6
|
-
* @param decimals - Number of decimal
|
|
7
|
-
* @returns Amount as bigint in atomic units
|
|
8
|
-
* @throws ValidationError if value is invalid or has too many decimal places
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* parseAmount("10.5", 18) // Returns 10500000000000000000n
|
|
12
|
-
* parseAmount("0.001", 6) // Returns 1000n
|
|
13
|
-
*/
|
|
14
|
-
export function parseAmount(value, decimals) {
|
|
15
|
-
const trimmed = value.trim();
|
|
16
|
-
if (!trimmed) {
|
|
17
|
-
throw new ValidationError("Amount cannot be empty");
|
|
18
|
-
}
|
|
19
|
-
if (!/^\d*(\.\d*)?$/.test(trimmed)) {
|
|
20
|
-
throw new ValidationError("Amount must be numeric and can include decimals (e.g., '10.5')");
|
|
21
|
-
}
|
|
22
|
-
const [rawWhole = "0", rawFraction = ""] = trimmed.split(".");
|
|
23
|
-
const whole = rawWhole === "" ? "0" : rawWhole;
|
|
24
|
-
if (rawFraction.length > decimals) {
|
|
25
|
-
throw new ValidationError(`Amount supports up to ${decimals} decimal places; trim the fractional part`);
|
|
26
|
-
}
|
|
27
|
-
// Pad fraction to full decimal places
|
|
28
|
-
const fraction = rawFraction.padEnd(decimals, "0");
|
|
29
|
-
const combined = `${whole}${fraction}`;
|
|
30
|
-
// Remove leading zeros
|
|
31
|
-
const normalized = combined.replace(/^0+(?=\d)/, "");
|
|
32
|
-
return normalized ? BigInt(normalized) : 0n;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Format a bigint amount to a decimal string.
|
|
36
|
-
*
|
|
37
|
-
* @param amount - Amount in atomic units as bigint
|
|
38
|
-
* @param decimals - Number of decimal places
|
|
39
|
-
* @returns Human-readable decimal string
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* formatAmount(10500000000000000000n, 18) // Returns "10.5"
|
|
43
|
-
* formatAmount(1000n, 6) // Returns "0.001"
|
|
44
|
-
*/
|
|
45
|
-
export function formatAmount(amount, decimals) {
|
|
46
|
-
if (amount < 0n) {
|
|
47
|
-
throw new ValidationError("Amount must be non-negative");
|
|
48
|
-
}
|
|
49
|
-
const amountStr = amount.toString().padStart(decimals + 1, "0");
|
|
50
|
-
const wholePartEnd = amountStr.length - decimals;
|
|
51
|
-
const wholePart = amountStr.slice(0, wholePartEnd) || "0";
|
|
52
|
-
const fractionPart = amountStr.slice(wholePartEnd);
|
|
53
|
-
// Remove trailing zeros from fraction
|
|
54
|
-
const trimmedFraction = fractionPart.replace(/0+$/, "");
|
|
55
|
-
return trimmedFraction ? `${wholePart}.${trimmedFraction}` : wholePart;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Split a total amount into N equal parts, distributing remainder evenly.
|
|
59
|
-
*
|
|
60
|
-
* @param total - Total amount to split
|
|
61
|
-
* @param parts - Number of parts to split into
|
|
62
|
-
* @returns Array of amounts that sum to total
|
|
63
|
-
* @throws ValidationError if parts is invalid or amount is too small to split
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* splitAmount(100n, 3) // Returns [34n, 33n, 33n] (remainder goes to first outputs)
|
|
67
|
-
* splitAmount(10n, 2) // Returns [5n, 5n]
|
|
68
|
-
*/
|
|
69
|
-
export function splitAmount(total, parts) {
|
|
70
|
-
if (parts === 0) {
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
if (parts < 0) {
|
|
74
|
-
throw new ValidationError("Number of parts must be non-negative");
|
|
75
|
-
}
|
|
76
|
-
if (!Number.isInteger(parts)) {
|
|
77
|
-
throw new ValidationError("Number of parts must be an integer");
|
|
78
|
-
}
|
|
79
|
-
if (total < BigInt(parts)) {
|
|
80
|
-
throw new ValidationError(`Amount (${total}) is too small to distribute across ${parts} outputs (minimum 1 per output)`);
|
|
81
|
-
}
|
|
82
|
-
const base = total / BigInt(parts);
|
|
83
|
-
if (base <= 0n) {
|
|
84
|
-
throw new ValidationError("Output share must be positive");
|
|
85
|
-
}
|
|
86
|
-
const remainder = Number(total - base * BigInt(parts));
|
|
87
|
-
// Distribute remainder across first N outputs
|
|
88
|
-
return Array.from({ length: parts }, (_, idx) => base + (idx < remainder ? 1n : 0n));
|
|
89
|
-
}
|
package/dist/utils/bigint.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { ValidationError } from "../errors.js";
|
|
2
|
-
import { FieldSize, Hex } from "../keys/hex.js";
|
|
3
|
-
/**
|
|
4
|
-
* BigInt helpers shared across transaction builders to keep formatting consistent.
|
|
5
|
-
*/
|
|
6
|
-
export function formatUint256(value) {
|
|
7
|
-
assertNonNegative("uint256", value);
|
|
8
|
-
return Hex.fromBigInt(value, FieldSize.SCALAR, true);
|
|
9
|
-
}
|
|
10
|
-
export function parseHexToBigInt(value) {
|
|
11
|
-
return Hex.toBigInt(value);
|
|
12
|
-
}
|
|
13
|
-
export function parseNumToBigInt(value) {
|
|
14
|
-
if (value === undefined) {
|
|
15
|
-
throw new ValidationError("Value is undefined");
|
|
16
|
-
}
|
|
17
|
-
return BigInt(value);
|
|
18
|
-
}
|
|
19
|
-
export function assertNonNegative(label, value) {
|
|
20
|
-
if (value < 0n) {
|
|
21
|
-
throw new ValidationError(`${label} must be non-negative`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
export function ensureBigint(label, value) {
|
|
25
|
-
if (typeof value !== "bigint") {
|
|
26
|
-
throw new ValidationError(`${label} must be provided as a bigint`);
|
|
27
|
-
}
|
|
28
|
-
return value;
|
|
29
|
-
}
|
package/dist/utils/crypto.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Ciphertext, NoteInput } from "../transactions/types/index.js";
|
|
2
|
-
export declare function encryptNote(note: NoteInput): Ciphertext;
|
|
3
|
-
export declare function encrypt(data: bigint, key: bigint): bigint;
|
|
4
|
-
export declare function decryptNote(c: Ciphertext, key: bigint): NoteInput;
|
|
5
|
-
export declare function deriveCommitment(note: {
|
|
6
|
-
npk: bigint;
|
|
7
|
-
amount: bigint;
|
|
8
|
-
token: string;
|
|
9
|
-
}): bigint;
|
|
10
|
-
/**
|
|
11
|
-
* Derive the nullifier public key (npk) from a note.
|
|
12
|
-
*/
|
|
13
|
-
export declare function deriveNpk(note: NoteInput): bigint;
|
|
14
|
-
/**
|
|
15
|
-
* Compute the commitment for a note given its npk.
|
|
16
|
-
*/
|
|
17
|
-
export declare function computeCommitment(note: NoteInput, npk: bigint): bigint;
|
|
18
|
-
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../utils/crypto.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAGvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,CAQvD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAYjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,UAGA;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,UAExC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAG7D"}
|
package/dist/utils/crypto.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { poseidon } from "../crypto-adapters/index.js";
|
|
2
|
-
import { CoreError } from "../errors.js";
|
|
3
|
-
import { parseHexToBigInt } from "./bigint.js";
|
|
4
|
-
export function encryptNote(note) {
|
|
5
|
-
return {
|
|
6
|
-
data: [
|
|
7
|
-
encrypt(note.random, note.mpk),
|
|
8
|
-
encrypt(parseHexToBigInt(note.token), note.mpk),
|
|
9
|
-
encrypt(note.amount, note.mpk),
|
|
10
|
-
],
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export function encrypt(data, key) {
|
|
14
|
-
return poseidon([0x556e6c696e6b, key]) ^ data;
|
|
15
|
-
}
|
|
16
|
-
export function decryptNote(c, key) {
|
|
17
|
-
const token_bigint = encrypt(c.data[1], key);
|
|
18
|
-
if (token_bigint > 0xffffffffffffffffffffffffffffffffffffffffn) {
|
|
19
|
-
throw new CoreError("Invalid Decrypt");
|
|
20
|
-
}
|
|
21
|
-
const result = {
|
|
22
|
-
mpk: key,
|
|
23
|
-
random: encrypt(c.data[0], key),
|
|
24
|
-
token: "0x" + token_bigint.toString(16).padStart(40, "0"),
|
|
25
|
-
amount: encrypt(c.data[2], key),
|
|
26
|
-
};
|
|
27
|
-
return result;
|
|
28
|
-
}
|
|
29
|
-
export function deriveCommitment(note) {
|
|
30
|
-
const tokenScalar = BigInt(note.token);
|
|
31
|
-
return poseidon([note.npk, tokenScalar, note.amount]);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Derive the nullifier public key (npk) from a note.
|
|
35
|
-
*/
|
|
36
|
-
export function deriveNpk(note) {
|
|
37
|
-
return poseidon([note.mpk, note.random]);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Compute the commitment for a note given its npk.
|
|
41
|
-
*/
|
|
42
|
-
export function computeCommitment(note, npk) {
|
|
43
|
-
const tokenScalar = BigInt(note.token);
|
|
44
|
-
return poseidon([npk, tokenScalar, note.amount]);
|
|
45
|
-
}
|
package/dist/utils/format.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { ensureAddress } from "./validators.js";
|
|
2
|
-
/**
|
|
3
|
-
* Normalize and validate an Ethereum address.
|
|
4
|
-
*
|
|
5
|
-
* @param value - Address string to normalize
|
|
6
|
-
* @returns Normalized lowercase address
|
|
7
|
-
* @throws CoreError if the address is invalid
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* normalizeAddress("0xABC123...") // Returns "0xabc123..."
|
|
11
|
-
*/
|
|
12
|
-
export function normalizeAddress(value) {
|
|
13
|
-
return ensureAddress("address", value);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Shorten a hex string for display.
|
|
17
|
-
*
|
|
18
|
-
* @param value - Hex string to shorten
|
|
19
|
-
* @param chars - Number of characters to show at start/end (default: 4)
|
|
20
|
-
* @returns Shortened string like "0x1234…abcd"
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* shortenHex("0x1234567890abcdef1234567890abcdef12345678") // "0x1234…5678"
|
|
24
|
-
* shortenHex("0x1234567890abcdef1234567890abcdef12345678", 6) // "0x123456…345678"
|
|
25
|
-
*/
|
|
26
|
-
export function shortenHex(value, chars = 4) {
|
|
27
|
-
if (!value.startsWith("0x") || value.length <= chars * 2 + 2) {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
return `${value.slice(0, chars + 2)}…${value.slice(-chars)}`;
|
|
31
|
-
}
|
|
32
|
-
// Re-export random utilities from dedicated module
|
|
33
|
-
export { randomHex, randomBigint } from "./random.js";
|
package/dist/utils/json-codec.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { CoreError } from "../errors.js";
|
|
2
|
-
import { validateKey } from "../keys.js";
|
|
3
|
-
const encoder = new TextEncoder();
|
|
4
|
-
const decoder = new TextDecoder();
|
|
5
|
-
export function encodeJson(value) {
|
|
6
|
-
return encoder.encode(JSON.stringify(value));
|
|
7
|
-
}
|
|
8
|
-
export function decodeJson(payload) {
|
|
9
|
-
try {
|
|
10
|
-
return JSON.parse(decoder.decode(payload));
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
throw new CoreError("failed to decode stored state payload");
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export async function putJson(storage, key, record) {
|
|
17
|
-
validateKey(key);
|
|
18
|
-
await storage.put(key, encodeJson(record));
|
|
19
|
-
}
|
|
20
|
-
export async function getJson(storage, key) {
|
|
21
|
-
const payload = await storage.get(key);
|
|
22
|
-
if (!payload)
|
|
23
|
-
return null;
|
|
24
|
-
return decodeJson(payload);
|
|
25
|
-
}
|
package/dist/utils/notes.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Computes token balances from a list of notes.
|
|
3
|
-
*
|
|
4
|
-
* @param notes - Array of notes to compute balances from
|
|
5
|
-
* @returns Record mapping token address to total balance
|
|
6
|
-
*/
|
|
7
|
-
export function computeBalances(notes) {
|
|
8
|
-
const totals = {};
|
|
9
|
-
for (const note of notes) {
|
|
10
|
-
const value = typeof note.value === "bigint" ? note.value : BigInt(note.value);
|
|
11
|
-
totals[note.token] = (totals[note.token] ?? 0n) + value;
|
|
12
|
-
}
|
|
13
|
-
return totals;
|
|
14
|
-
}
|
package/dist/utils/polling.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared polling configuration constants.
|
|
3
|
-
*/
|
|
4
|
-
export const DEFAULT_POLL_INTERVAL_MS = 500;
|
|
5
|
-
export const DEFAULT_POLL_TIMEOUT_MS = 30_000;
|
|
6
|
-
export const MAX_POLL_INTERVAL_MS = 5_000;
|
|
7
|
-
/**
|
|
8
|
-
* Initial delay before first poll for fresh deposits.
|
|
9
|
-
* Reduces wasted 404 requests while commitment is being indexed.
|
|
10
|
-
*/
|
|
11
|
-
export const DEFAULT_INITIAL_POLL_DELAY_MS = 2_000;
|
package/dist/utils/random.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { CoreError } from "../errors.js";
|
|
2
|
-
/**
|
|
3
|
-
* Generate a cryptographically secure random bigint.
|
|
4
|
-
* @param bytes - Number of bytes of randomness (default: 32 for 256-bit)
|
|
5
|
-
* @returns Random bigint
|
|
6
|
-
*/
|
|
7
|
-
export function randomBigint(bytes = 32) {
|
|
8
|
-
if (typeof globalThis.crypto?.getRandomValues !== "function") {
|
|
9
|
-
throw new CoreError("crypto.getRandomValues is not available");
|
|
10
|
-
}
|
|
11
|
-
const buffer = new Uint8Array(bytes);
|
|
12
|
-
globalThis.crypto.getRandomValues(buffer);
|
|
13
|
-
return BigInt("0x" +
|
|
14
|
-
Array.from(buffer)
|
|
15
|
-
.map((b) => b.toString(16).padStart(2, "0"))
|
|
16
|
-
.join(""));
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Generate a cryptographically secure random hex string.
|
|
20
|
-
* @param bytes - Number of bytes of randomness
|
|
21
|
-
* @returns Random hex string with 0x prefix
|
|
22
|
-
*/
|
|
23
|
-
export function randomHex(bytes) {
|
|
24
|
-
return `0x${randomBigint(bytes)
|
|
25
|
-
.toString(16)
|
|
26
|
-
.padStart(bytes * 2, "0")}`;
|
|
27
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"secure-memory.d.ts","sourceRoot":"","sources":["../../utils/secure-memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAI/C"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IMPORTANT limitations:
|
|
3
|
-
* - Garbage collection timing is unpredictable
|
|
4
|
-
* - Strings are immutable
|
|
5
|
-
* - No compiler enforcement to prevent copies
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Securely zeros out a Uint8Array's contents by overwriting with zeros.
|
|
9
|
-
* This should be called on all sensitive cryptographic material after use
|
|
10
|
-
*
|
|
11
|
-
* @param bytes - The Uint8Array to zeroize (will be mutated in place)
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* const privateKey = derivePrivateKey(seed);
|
|
16
|
-
* try {
|
|
17
|
-
* const signature = sign(message, privateKey);
|
|
18
|
-
* return signature;
|
|
19
|
-
* } finally {
|
|
20
|
-
* zeroize(privateKey); // Clear sensitive data
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export function zeroize(bytes) {
|
|
25
|
-
if (!bytes || bytes.length === 0)
|
|
26
|
-
return;
|
|
27
|
-
bytes.fill(0);
|
|
28
|
-
}
|
package/dist/utils/signature.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { signMessage } from "../crypto-adapters/index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Generates an EdDSA signature over a poseidon-hashed message using the spending private key.
|
|
4
|
-
* Used for transact public signal signing.
|
|
5
|
-
*
|
|
6
|
-
* The spendingPrivateKey parameter should be zeroized by the caller after use.
|
|
7
|
-
*
|
|
8
|
-
* @param spendingPrivateKey - The 32-byte spending private key (will not be mutated)
|
|
9
|
-
* @param message - The bigint message to sign
|
|
10
|
-
* @returns The EdDSA signature
|
|
11
|
-
*/
|
|
12
|
-
export function signTransactMessage(spendingPrivateKey, message) {
|
|
13
|
-
return signMessage(spendingPrivateKey, message);
|
|
14
|
-
}
|