@veilo/sdk-core 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +237 -19
- package/accounts.d.ts +2 -0
- package/accounts.js +3 -0
- package/cloak.d.ts +2 -0
- package/cloak.js +3 -0
- package/config.d.ts +2 -0
- package/config.js +3 -0
- package/dist/cjs/events/index.d.ts +6 -0
- package/dist/cjs/events/index.js +22 -0
- package/dist/cjs/events/parsing.d.ts +25 -0
- package/dist/cjs/events/parsing.js +158 -0
- package/dist/cjs/events/position.d.ts +26 -0
- package/dist/cjs/events/position.js +53 -0
- package/dist/cjs/events/recovery.d.ts +87 -0
- package/dist/cjs/events/recovery.js +281 -0
- package/dist/cjs/events/scanning.d.ts +35 -0
- package/dist/cjs/events/scanning.js +98 -0
- package/dist/cjs/events/tree.d.ts +27 -0
- package/dist/cjs/events/tree.js +63 -0
- package/dist/cjs/events/types.d.ts +39 -0
- package/dist/cjs/events/types.js +2 -0
- package/dist/cjs/events.d.ts +1 -77
- package/dist/cjs/events.js +6 -154
- package/dist/cjs/identity/encoding.d.ts +9 -0
- package/dist/cjs/identity/encoding.js +85 -0
- package/dist/cjs/identity/index.d.ts +4 -0
- package/dist/cjs/identity/index.js +20 -0
- package/dist/cjs/identity/noteKey.d.ts +33 -0
- package/dist/cjs/identity/noteKey.js +97 -0
- package/dist/cjs/identity/spending.d.ts +18 -0
- package/dist/cjs/identity/spending.js +46 -0
- package/dist/cjs/identity/viewKey.d.ts +38 -0
- package/dist/cjs/identity/viewKey.js +105 -0
- package/dist/cjs/idl/index.d.ts +18 -0
- package/dist/cjs/idl/index.js +24 -0
- package/dist/cjs/idl/privacy_pool.json +9907 -9907
- package/dist/cjs/idl/privacy_pool_legacy.d.ts +5 -0
- package/dist/cjs/idl/privacy_pool_legacy.js +3307 -0
- package/dist/cjs/idl/privacy_pool_legacy.json +2302 -0
- package/dist/cjs/idl/privacy_pool_legacy2.d.ts +5 -0
- package/dist/cjs/idl/privacy_pool_legacy2.js +3397 -0
- package/dist/cjs/idl/privacy_pool_legacy2.json +2376 -0
- package/dist/cjs/index.d.ts +8 -3
- package/dist/cjs/index.js +12 -2
- package/dist/cjs/notes/amount.d.ts +2 -0
- package/dist/cjs/notes/amount.js +21 -0
- package/dist/cjs/notes/index.d.ts +3 -0
- package/dist/cjs/notes/index.js +3 -0
- package/dist/cjs/notes/recovery.d.ts +16 -6
- package/dist/cjs/notes/recovery.js +33 -16
- package/dist/cjs/notes/selection.d.ts +77 -0
- package/dist/cjs/notes/selection.js +193 -0
- package/dist/cjs/notes/spent.d.ts +60 -0
- package/dist/cjs/notes/spent.js +101 -0
- package/dist/cjs/perps/constants.d.ts +16 -0
- package/dist/cjs/perps/constants.js +52 -0
- package/dist/cjs/perps/index.d.ts +5 -0
- package/dist/cjs/perps/index.js +21 -0
- package/dist/cjs/perps/keys.d.ts +16 -0
- package/dist/cjs/perps/keys.js +43 -0
- package/dist/cjs/perps/pdas.d.ts +29 -0
- package/dist/cjs/perps/pdas.js +55 -0
- package/dist/cjs/perps/relayer.d.ts +9 -0
- package/dist/cjs/perps/relayer.js +35 -0
- package/dist/cjs/perps/types.d.ts +126 -0
- package/dist/cjs/perps/types.js +2 -0
- package/dist/cjs/positions/index.d.ts +4 -0
- package/dist/cjs/positions/index.js +20 -0
- package/dist/cjs/positions/keys.d.ts +29 -0
- package/dist/cjs/positions/keys.js +71 -0
- package/dist/cjs/positions/pdas.d.ts +15 -0
- package/dist/cjs/positions/pdas.js +54 -0
- package/dist/cjs/positions/relayer.d.ts +4 -0
- package/dist/cjs/positions/relayer.js +15 -0
- package/dist/cjs/positions/types.d.ts +97 -0
- package/dist/cjs/positions/types.js +2 -0
- package/dist/cjs/predictions/client.d.ts +41 -0
- package/dist/cjs/predictions/client.js +147 -0
- package/dist/cjs/predictions/index.d.ts +5 -0
- package/dist/cjs/predictions/index.js +21 -0
- package/dist/cjs/predictions/keys.d.ts +14 -0
- package/dist/cjs/predictions/keys.js +40 -0
- package/dist/cjs/predictions/pdas.d.ts +6 -0
- package/dist/cjs/predictions/pdas.js +13 -0
- package/dist/cjs/predictions/relayer.d.ts +3 -0
- package/dist/cjs/predictions/relayer.js +11 -0
- package/dist/cjs/predictions/types.d.ts +178 -0
- package/dist/cjs/predictions/types.js +2 -0
- package/dist/cjs/program.d.ts +2 -0
- package/dist/cjs/program.js +8 -7
- package/dist/cjs/prover.d.ts +27 -4
- package/dist/cjs/prover.js +107 -48
- package/dist/cjs/relayer/api.d.ts +31 -0
- package/dist/cjs/relayer/api.js +86 -0
- package/dist/cjs/relayer/client.d.ts +29 -17
- package/dist/cjs/relayer/client.js +72 -17
- package/dist/cjs/relayer/errors.d.ts +1 -1
- package/dist/cjs/relayer/errors.js +1 -1
- package/dist/cjs/relayer/index.d.ts +4 -1
- package/dist/cjs/relayer/index.js +1 -1
- package/dist/cjs/relayer/internal-config.d.ts +36 -0
- package/dist/cjs/relayer/internal-config.js +9 -0
- package/dist/cjs/relayer/internal.d.ts +6 -0
- package/dist/cjs/relayer/internal.js +14 -0
- package/dist/cjs/relayer/transport.d.ts +4 -2
- package/dist/cjs/relayer/transport.js +10 -5
- package/dist/cjs/relayer/types.d.ts +9 -10
- package/dist/cjs/relayer/types.js +1 -1
- package/dist/cjs/shield/owner.js +1 -4
- package/dist/esm/events/index.d.ts +6 -0
- package/dist/esm/events/index.js +6 -0
- package/dist/esm/events/parsing.d.ts +25 -0
- package/dist/esm/events/parsing.js +120 -0
- package/dist/esm/events/position.d.ts +26 -0
- package/dist/esm/events/position.js +48 -0
- package/dist/esm/events/recovery.d.ts +87 -0
- package/dist/esm/events/recovery.js +237 -0
- package/dist/esm/events/scanning.d.ts +35 -0
- package/dist/esm/events/scanning.js +92 -0
- package/dist/esm/events/tree.d.ts +27 -0
- package/dist/esm/events/tree.js +58 -0
- package/dist/esm/events/types.d.ts +39 -0
- package/dist/esm/events/types.js +1 -0
- package/dist/esm/events.d.ts +1 -77
- package/dist/esm/events.js +3 -129
- package/dist/esm/identity/encoding.d.ts +9 -0
- package/dist/esm/identity/encoding.js +75 -0
- package/dist/esm/identity/index.d.ts +4 -0
- package/dist/esm/identity/index.js +4 -0
- package/dist/esm/identity/noteKey.d.ts +33 -0
- package/dist/esm/identity/noteKey.js +91 -0
- package/dist/esm/identity/spending.d.ts +18 -0
- package/dist/esm/identity/spending.js +35 -0
- package/dist/esm/identity/viewKey.d.ts +38 -0
- package/dist/esm/identity/viewKey.js +96 -0
- package/dist/esm/idl/index.d.ts +18 -0
- package/dist/esm/idl/index.js +18 -0
- package/dist/esm/idl/privacy_pool.json +9907 -9907
- package/dist/esm/idl/privacy_pool_legacy.d.ts +5 -0
- package/dist/esm/idl/privacy_pool_legacy.js +3305 -0
- package/dist/esm/idl/privacy_pool_legacy.json +2302 -0
- package/dist/esm/idl/privacy_pool_legacy2.d.ts +5 -0
- package/dist/esm/idl/privacy_pool_legacy2.js +3395 -0
- package/dist/esm/idl/privacy_pool_legacy2.json +2376 -0
- package/dist/esm/index.d.ts +8 -3
- package/dist/esm/index.js +8 -3
- package/dist/esm/notes/amount.d.ts +2 -0
- package/dist/esm/notes/amount.js +18 -0
- package/dist/esm/notes/index.d.ts +3 -0
- package/dist/esm/notes/index.js +3 -0
- package/dist/esm/notes/recovery.d.ts +16 -6
- package/dist/esm/notes/recovery.js +33 -16
- package/dist/esm/notes/selection.d.ts +77 -0
- package/dist/esm/notes/selection.js +188 -0
- package/dist/esm/notes/spent.d.ts +60 -0
- package/dist/esm/notes/spent.js +96 -0
- package/dist/esm/perps/constants.d.ts +16 -0
- package/dist/esm/perps/constants.js +48 -0
- package/dist/esm/perps/index.d.ts +5 -0
- package/dist/esm/perps/index.js +5 -0
- package/dist/esm/perps/keys.d.ts +16 -0
- package/dist/esm/perps/keys.js +35 -0
- package/dist/esm/perps/pdas.d.ts +29 -0
- package/dist/esm/perps/pdas.js +47 -0
- package/dist/esm/perps/relayer.d.ts +9 -0
- package/dist/esm/perps/relayer.js +25 -0
- package/dist/esm/perps/types.d.ts +126 -0
- package/dist/esm/perps/types.js +1 -0
- package/dist/esm/positions/index.d.ts +4 -0
- package/dist/esm/positions/index.js +4 -0
- package/dist/esm/positions/keys.d.ts +29 -0
- package/dist/esm/positions/keys.js +65 -0
- package/dist/esm/positions/pdas.d.ts +15 -0
- package/dist/esm/positions/pdas.js +44 -0
- package/dist/esm/positions/relayer.d.ts +4 -0
- package/dist/esm/positions/relayer.js +10 -0
- package/dist/esm/positions/types.d.ts +97 -0
- package/dist/esm/positions/types.js +1 -0
- package/dist/esm/predictions/client.d.ts +41 -0
- package/dist/esm/predictions/client.js +141 -0
- package/dist/esm/predictions/index.d.ts +5 -0
- package/dist/esm/predictions/index.js +5 -0
- package/dist/esm/predictions/keys.d.ts +14 -0
- package/dist/esm/predictions/keys.js +33 -0
- package/dist/esm/predictions/pdas.d.ts +6 -0
- package/dist/esm/predictions/pdas.js +10 -0
- package/dist/esm/predictions/relayer.d.ts +3 -0
- package/dist/esm/predictions/relayer.js +7 -0
- package/dist/esm/predictions/types.d.ts +178 -0
- package/dist/esm/predictions/types.js +1 -0
- package/dist/esm/program.d.ts +2 -0
- package/dist/esm/program.js +4 -3
- package/dist/esm/prover.d.ts +27 -4
- package/dist/esm/prover.js +106 -15
- package/dist/esm/relayer/api.d.ts +31 -0
- package/dist/esm/relayer/api.js +55 -0
- package/dist/esm/relayer/client.d.ts +29 -17
- package/dist/esm/relayer/client.js +72 -17
- package/dist/esm/relayer/errors.d.ts +1 -1
- package/dist/esm/relayer/errors.js +1 -1
- package/dist/esm/relayer/index.d.ts +4 -1
- package/dist/esm/relayer/index.js +1 -1
- package/dist/esm/relayer/internal-config.d.ts +36 -0
- package/dist/esm/relayer/internal-config.js +6 -0
- package/dist/esm/relayer/internal.d.ts +6 -0
- package/dist/esm/relayer/internal.js +10 -0
- package/dist/esm/relayer/transport.d.ts +4 -2
- package/dist/esm/relayer/transport.js +10 -5
- package/dist/esm/relayer/types.d.ts +9 -10
- package/dist/esm/relayer/types.js +1 -1
- package/dist/esm/shield/owner.js +1 -4
- package/identity.d.ts +2 -0
- package/identity.js +3 -0
- package/idl.d.ts +2 -0
- package/idl.js +3 -0
- package/notes.d.ts +2 -0
- package/notes.js +3 -0
- package/package.json +85 -3
- package/perps.d.ts +2 -0
- package/perps.js +3 -0
- package/poseidon.d.ts +2 -0
- package/poseidon.js +3 -0
- package/positions.d.ts +2 -0
- package/positions.js +3 -0
- package/predictions.d.ts +2 -0
- package/predictions.js +3 -0
- package/proof.d.ts +2 -0
- package/proof.js +3 -0
- package/prover.d.ts +2 -0
- package/prover.js +3 -0
- package/relayer.d.ts +2 -0
- package/relayer.js +3 -0
- package/shield.d.ts +2 -0
- package/shield.js +3 -0
- package/transactions.d.ts +2 -0
- package/transactions.js +3 -0
package/dist/esm/events.js
CHANGED
|
@@ -1,129 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// Event Scanning
|
|
5
|
-
// -----------------------------------------------------------------------------
|
|
6
|
-
/**
|
|
7
|
-
* Fetch and parse CommitmentEvents for a program, optionally filtered by mint.
|
|
8
|
-
*
|
|
9
|
-
* @param program - Anchor program instance
|
|
10
|
-
* @param mintAddress - Filter to a specific pool; omit to get all pools
|
|
11
|
-
* @param before - Start paging before this signature (exclusive)
|
|
12
|
-
* @param until - Stop paging at this signature (exclusive)
|
|
13
|
-
* @param limit - Max signatures to fetch per page (default 1000)
|
|
14
|
-
*/
|
|
15
|
-
export async function scanCommitmentEvents(params) {
|
|
16
|
-
const { program, mintAddress, before, until, limit = 1000 } = params;
|
|
17
|
-
const out = [];
|
|
18
|
-
const eventParser = new anchor.EventParser(program.programId, new anchor.BorshCoder(program.idl));
|
|
19
|
-
const sigs = await program.provider.connection.getSignaturesForAddress(program.programId, { before, until, limit });
|
|
20
|
-
for (const sigInfo of sigs) {
|
|
21
|
-
if (sigInfo.err)
|
|
22
|
-
continue;
|
|
23
|
-
const tx = await program.provider.connection.getTransaction(sigInfo.signature, { commitment: "confirmed", maxSupportedTransactionVersion: 0 });
|
|
24
|
-
if (!tx)
|
|
25
|
-
continue;
|
|
26
|
-
const events = Array.from(eventParser.parseLogs(tx.meta?.logMessages ?? []));
|
|
27
|
-
for (const ev of events) {
|
|
28
|
-
if (ev.name !== "commitmentEvent")
|
|
29
|
-
continue;
|
|
30
|
-
const d = ev.data;
|
|
31
|
-
const evMint = d.mintAddress;
|
|
32
|
-
if (mintAddress && !evMint.equals(mintAddress))
|
|
33
|
-
continue;
|
|
34
|
-
out.push({
|
|
35
|
-
commitment: new Uint8Array(d.commitment),
|
|
36
|
-
leafIndex: Number(d.leafIndex),
|
|
37
|
-
newRoot: new Uint8Array(d.newRoot),
|
|
38
|
-
timestamp: Number(d.timestamp),
|
|
39
|
-
mintAddress: evMint,
|
|
40
|
-
treeId: Number(d.treeId),
|
|
41
|
-
txSignature: sigInfo.signature,
|
|
42
|
-
slot: sigInfo.slot,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return out;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Fetch and parse NullifierSpent events for a program, optionally filtered by mint.
|
|
50
|
-
*/
|
|
51
|
-
export async function scanNullifierEvents(params) {
|
|
52
|
-
const { program, mintAddress, before, until, limit = 1000 } = params;
|
|
53
|
-
const out = [];
|
|
54
|
-
const eventParser = new anchor.EventParser(program.programId, new anchor.BorshCoder(program.idl));
|
|
55
|
-
const sigs = await program.provider.connection.getSignaturesForAddress(program.programId, { before, until, limit });
|
|
56
|
-
for (const sigInfo of sigs) {
|
|
57
|
-
if (sigInfo.err)
|
|
58
|
-
continue;
|
|
59
|
-
const tx = await program.provider.connection.getTransaction(sigInfo.signature, { commitment: "confirmed", maxSupportedTransactionVersion: 0 });
|
|
60
|
-
if (!tx)
|
|
61
|
-
continue;
|
|
62
|
-
const events = Array.from(eventParser.parseLogs(tx.meta?.logMessages ?? []));
|
|
63
|
-
for (const ev of events) {
|
|
64
|
-
if (ev.name !== "nullifierSpent")
|
|
65
|
-
continue;
|
|
66
|
-
const d = ev.data;
|
|
67
|
-
const evMint = d.mintAddress;
|
|
68
|
-
if (mintAddress && !evMint.equals(mintAddress))
|
|
69
|
-
continue;
|
|
70
|
-
out.push({
|
|
71
|
-
nullifier: new Uint8Array(d.nullifier),
|
|
72
|
-
timestamp: Number(d.timestamp),
|
|
73
|
-
mintAddress: evMint,
|
|
74
|
-
treeId: Number(d.treeId),
|
|
75
|
-
txSignature: sigInfo.signature,
|
|
76
|
-
slot: sigInfo.slot,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return out;
|
|
81
|
-
}
|
|
82
|
-
// -----------------------------------------------------------------------------
|
|
83
|
-
// Tree Reconstruction
|
|
84
|
-
// -----------------------------------------------------------------------------
|
|
85
|
-
/**
|
|
86
|
-
* Rebuild a local MerkleTree from on-chain CommitmentEvents.
|
|
87
|
-
* Use this to get a valid inclusion proof for spending any UTXO.
|
|
88
|
-
*
|
|
89
|
-
* CommitmentEvents are sorted by (treeId, leafIndex) so the local tree
|
|
90
|
-
* matches the on-chain state exactly.
|
|
91
|
-
*
|
|
92
|
-
* @param program - Anchor program instance
|
|
93
|
-
* @param mintAddress - Pool to reconstruct
|
|
94
|
-
* @param treeId - Which tree to reconstruct (default 0)
|
|
95
|
-
* @param depth - Merkle tree depth (default 22, must match on-chain)
|
|
96
|
-
*/
|
|
97
|
-
export async function buildTreeFromEvents(params) {
|
|
98
|
-
const { program, mintAddress, treeId = 0, depth = 22 } = params;
|
|
99
|
-
// Fetch all commitment events for this pool (page until no more results).
|
|
100
|
-
// Oldest-first so we insert leaves in the correct order.
|
|
101
|
-
const allEvents = [];
|
|
102
|
-
let before;
|
|
103
|
-
while (true) {
|
|
104
|
-
const page = await scanCommitmentEvents({
|
|
105
|
-
program,
|
|
106
|
-
mintAddress,
|
|
107
|
-
before,
|
|
108
|
-
limit: 1000,
|
|
109
|
-
});
|
|
110
|
-
if (page.length === 0)
|
|
111
|
-
break;
|
|
112
|
-
allEvents.push(...page);
|
|
113
|
-
before = page[page.length - 1].txSignature;
|
|
114
|
-
if (page.length < 1000)
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
// Keep only events for this treeId, sort by leafIndex ascending
|
|
118
|
-
const treeEvents = allEvents
|
|
119
|
-
.filter((e) => e.treeId === treeId)
|
|
120
|
-
.sort((a, b) => a.leafIndex - b.leafIndex);
|
|
121
|
-
const tree = new MerkleTree(depth);
|
|
122
|
-
for (const ev of treeEvents) {
|
|
123
|
-
tree.insert(ev.commitment);
|
|
124
|
-
}
|
|
125
|
-
const latestSignature = treeEvents.length > 0
|
|
126
|
-
? treeEvents[treeEvents.length - 1].txSignature
|
|
127
|
-
: undefined;
|
|
128
|
-
return { tree, events: treeEvents, latestSignature };
|
|
129
|
-
}
|
|
1
|
+
// Backward-compatible entry point. Event parsing, scanning, and recovery live
|
|
2
|
+
// in focused modules under src/events.
|
|
3
|
+
export * from "./events/index.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function concatBytes(...parts: readonly Uint8Array[]): Uint8Array;
|
|
2
|
+
export declare function utf8(value: string): Uint8Array;
|
|
3
|
+
export declare function uint32Le(value: number, label?: string): Uint8Array;
|
|
4
|
+
export declare function uint64Le(value: bigint, label?: string): Uint8Array;
|
|
5
|
+
export declare function assertBytes(value: Uint8Array, length: number, label: string): void;
|
|
6
|
+
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
7
|
+
export declare function hexToBytes(value: string, length?: number, label?: string): Uint8Array;
|
|
8
|
+
/** Encode bytes using the Bitcoin/Solana base58 alphabet. */
|
|
9
|
+
export declare function encodeBase58(bytes: Uint8Array): string;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
2
|
+
export function concatBytes(...parts) {
|
|
3
|
+
const output = new Uint8Array(parts.reduce((length, part) => length + part.length, 0));
|
|
4
|
+
let offset = 0;
|
|
5
|
+
for (const part of parts) {
|
|
6
|
+
output.set(part, offset);
|
|
7
|
+
offset += part.length;
|
|
8
|
+
}
|
|
9
|
+
return output;
|
|
10
|
+
}
|
|
11
|
+
export function utf8(value) {
|
|
12
|
+
return new TextEncoder().encode(value);
|
|
13
|
+
}
|
|
14
|
+
export function uint32Le(value, label = "value") {
|
|
15
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > 4294967295) {
|
|
16
|
+
throw new RangeError(`${label} must be an unsigned 32-bit integer`);
|
|
17
|
+
}
|
|
18
|
+
const bytes = new Uint8Array(4);
|
|
19
|
+
new DataView(bytes.buffer).setUint32(0, value, true);
|
|
20
|
+
return bytes;
|
|
21
|
+
}
|
|
22
|
+
export function uint64Le(value, label = "value") {
|
|
23
|
+
if (value < 0n || value > 0xffffffffffffffffn) {
|
|
24
|
+
throw new RangeError(`${label} must be an unsigned 64-bit integer`);
|
|
25
|
+
}
|
|
26
|
+
const bytes = new Uint8Array(8);
|
|
27
|
+
new DataView(bytes.buffer).setBigUint64(0, value, true);
|
|
28
|
+
return bytes;
|
|
29
|
+
}
|
|
30
|
+
export function assertBytes(value, length, label) {
|
|
31
|
+
if (value.length !== length) {
|
|
32
|
+
throw new RangeError(`${label} must be ${length} bytes, got ${value.length}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function bytesToHex(bytes) {
|
|
36
|
+
return Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("");
|
|
37
|
+
}
|
|
38
|
+
export function hexToBytes(value, length, label = "hex value") {
|
|
39
|
+
const clean = value.startsWith("0x") ? value.slice(2) : value;
|
|
40
|
+
if (!/^[0-9a-f]*$/i.test(clean) || clean.length % 2 !== 0) {
|
|
41
|
+
throw new TypeError(`${label} must be an even-length hexadecimal string`);
|
|
42
|
+
}
|
|
43
|
+
const bytes = Uint8Array.from({ length: clean.length / 2 }, (_, index) => Number.parseInt(clean.slice(index * 2, index * 2 + 2), 16));
|
|
44
|
+
if (length !== undefined)
|
|
45
|
+
assertBytes(bytes, length, label);
|
|
46
|
+
return bytes;
|
|
47
|
+
}
|
|
48
|
+
/** Encode bytes using the Bitcoin/Solana base58 alphabet. */
|
|
49
|
+
export function encodeBase58(bytes) {
|
|
50
|
+
if (bytes.length === 0)
|
|
51
|
+
return "";
|
|
52
|
+
let zeroes = 0;
|
|
53
|
+
while (zeroes < bytes.length && bytes[zeroes] === 0)
|
|
54
|
+
zeroes++;
|
|
55
|
+
if (zeroes === bytes.length)
|
|
56
|
+
return "1".repeat(zeroes);
|
|
57
|
+
const digits = [0];
|
|
58
|
+
for (let index = zeroes; index < bytes.length; index++) {
|
|
59
|
+
let carry = bytes[index];
|
|
60
|
+
for (let digit = 0; digit < digits.length; digit++) {
|
|
61
|
+
const value = digits[digit] * 256 + carry;
|
|
62
|
+
digits[digit] = value % 58;
|
|
63
|
+
carry = Math.floor(value / 58);
|
|
64
|
+
}
|
|
65
|
+
while (carry > 0) {
|
|
66
|
+
digits.push(carry % 58);
|
|
67
|
+
carry = Math.floor(carry / 58);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let encoded = "1".repeat(zeroes);
|
|
71
|
+
for (let index = digits.length - 1; index >= 0; index--) {
|
|
72
|
+
encoded += BASE58_ALPHABET[digits[index]];
|
|
73
|
+
}
|
|
74
|
+
return encoded;
|
|
75
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Domain-separation label. Permanent — see the header. */
|
|
2
|
+
export declare const VEILO_NOTE_KEY_LABEL = "veilo_note_key_v1";
|
|
3
|
+
/** The note spending key plus the Poseidon public key derived from it. */
|
|
4
|
+
export interface NoteKeypair {
|
|
5
|
+
/** Raw 32-byte scalar, strictly below the BN254 Fr modulus. */
|
|
6
|
+
noteSecretKey: Uint8Array;
|
|
7
|
+
/** Hex form, matching how the relayer has always returned this key. */
|
|
8
|
+
noteSecretKeyHex: string;
|
|
9
|
+
/** Poseidon(noteSecretKey) — the note's committed owner. */
|
|
10
|
+
notePublicKey: bigint;
|
|
11
|
+
/** Decimal string form, as the relayer and note scanner expect it. */
|
|
12
|
+
notePublicKeyString: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Derive the note spending key from a spending-key root.
|
|
16
|
+
*
|
|
17
|
+
* @param spendingKey 32 bytes from `deriveSpendingKeyFromSignature` or a sibling
|
|
18
|
+
*/
|
|
19
|
+
export declare function deriveNoteKeyFromSpendingKey(spendingKey: Uint8Array): Uint8Array;
|
|
20
|
+
/**
|
|
21
|
+
* Derive the note spending key and its Poseidon public key.
|
|
22
|
+
*
|
|
23
|
+
* Call `initPoseidon()` once before this, as with `derivePositionKeys`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function deriveNoteKeypairFromSpendingKey(spendingKey: Uint8Array): NoteKeypair;
|
|
26
|
+
/**
|
|
27
|
+
* One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
|
|
28
|
+
*
|
|
29
|
+
* Prompts a single signature, then returns spend authority for the account.
|
|
30
|
+
* The signature is secret material: keep it in memory, never persist it, and
|
|
31
|
+
* never expose the result on a global.
|
|
32
|
+
*/
|
|
33
|
+
export declare function deriveNoteKeypairWithSigner(signMessage: (message: Uint8Array) => Promise<Uint8Array>, index?: number): Promise<NoteKeypair>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derivation of the Veilo NOTE SPENDING KEY from a spending-key root.
|
|
3
|
+
*
|
|
4
|
+
* ⚠ BYTE-FOR-BYTE PORT — must agree with
|
|
5
|
+
* veilo-browser-extension/extension-ui/src/lib/veiloNoteKey.ts
|
|
6
|
+
* wallet-app/src/lib/veiloNoteKey.ts
|
|
7
|
+
* An account created in one client must be spendable from the others, so the
|
|
8
|
+
* label, the HMAC construction and the rejection rule are all load-bearing.
|
|
9
|
+
* `tests/identity-keys.test.ts` re-implements the client algorithm
|
|
10
|
+
* independently and asserts equality, plus pins a known-answer vector.
|
|
11
|
+
*
|
|
12
|
+
* WHAT THIS KEY IS
|
|
13
|
+
* ----------------
|
|
14
|
+
* `zk-circuits/keypair.circom` defines publicKey = Poseidon(privateKey), and
|
|
15
|
+
* `transaction.circom` constrains Poseidon(privateKey) === the note's committed
|
|
16
|
+
* owner before it will emit a proof, then derives the nullifier from the same
|
|
17
|
+
* key. This one scalar is both proof of ownership and spend authority; there is
|
|
18
|
+
* no second factor anywhere in the circuit. Treat it exactly as you would a
|
|
19
|
+
* wallet secret key.
|
|
20
|
+
*
|
|
21
|
+
* Derivation:
|
|
22
|
+
* spendingKey = deriveSpendingKeyFromSignature(sig) // ./spending.js
|
|
23
|
+
* veiloPrivateKey = rejectionSample(hmac_sha256(spendingKey, "veilo_note_key_v1|N"))
|
|
24
|
+
* veiloPublicKey = Poseidon(veiloPrivateKey)
|
|
25
|
+
*
|
|
26
|
+
* WHY REJECTION SAMPLING AND NOT `mod Fr`
|
|
27
|
+
* ---------------------------------------
|
|
28
|
+
* Reducing a 256-bit hash modulo Fr biases the low end of the range. Note that
|
|
29
|
+
* `derivePositionKeys` uses modular reduction; this key follows the stricter
|
|
30
|
+
* convention because it is a SPENDING key, matching how real note secrets are
|
|
31
|
+
* generated. About 0.3% of draws are retried.
|
|
32
|
+
*
|
|
33
|
+
* ⚠ THE LABEL IS PERMANENT. Once one note exists under "veilo_note_key_v1",
|
|
34
|
+
* changing the label or the sampling method makes that note unspendable
|
|
35
|
+
* forever. Version it, never edit it.
|
|
36
|
+
*
|
|
37
|
+
* ⚠ APPLIES TO `derived-v3` ACCOUNTS ONLY. Accounts whose relayer record has
|
|
38
|
+
* `veiloKeySource` absent or "legacy" have a SERVER-GENERATED note key that no
|
|
39
|
+
* derivation can reproduce — those clients must decrypt the key the relayer
|
|
40
|
+
* serves them. Check the account's key source before assuming this function
|
|
41
|
+
* yields a usable key.
|
|
42
|
+
*/
|
|
43
|
+
import { hmac } from "@noble/hashes/hmac";
|
|
44
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
45
|
+
import { BN254_FR_MODULUS, bytesToBigIntBE, poseidon1 } from "../poseidon.js";
|
|
46
|
+
import { assertBytes, bytesToHex, utf8 } from "./encoding.js";
|
|
47
|
+
import { deriveSpendingKeyWithSigner } from "./spending.js";
|
|
48
|
+
/** Domain-separation label. Permanent — see the header. */
|
|
49
|
+
export const VEILO_NOTE_KEY_LABEL = "veilo_note_key_v1";
|
|
50
|
+
/** Practically unreachable: 256 consecutive rejections is ~1e-640. */
|
|
51
|
+
const MAX_REJECTION_ROUNDS = 256;
|
|
52
|
+
/**
|
|
53
|
+
* Derive the note spending key from a spending-key root.
|
|
54
|
+
*
|
|
55
|
+
* @param spendingKey 32 bytes from `deriveSpendingKeyFromSignature` or a sibling
|
|
56
|
+
*/
|
|
57
|
+
export function deriveNoteKeyFromSpendingKey(spendingKey) {
|
|
58
|
+
assertBytes(spendingKey, 32, "spending key");
|
|
59
|
+
for (let counter = 0; counter < MAX_REJECTION_ROUNDS; counter++) {
|
|
60
|
+
const candidate = hmac(sha256, spendingKey, utf8(`${VEILO_NOTE_KEY_LABEL}|${counter}`));
|
|
61
|
+
if (bytesToBigIntBE(candidate) < BN254_FR_MODULUS)
|
|
62
|
+
return candidate;
|
|
63
|
+
}
|
|
64
|
+
// Reaching here means HMAC-SHA256 is broken, not that we were unlucky.
|
|
65
|
+
throw new Error(`Failed to derive a field element for "${VEILO_NOTE_KEY_LABEL}"`);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Derive the note spending key and its Poseidon public key.
|
|
69
|
+
*
|
|
70
|
+
* Call `initPoseidon()` once before this, as with `derivePositionKeys`.
|
|
71
|
+
*/
|
|
72
|
+
export function deriveNoteKeypairFromSpendingKey(spendingKey) {
|
|
73
|
+
const noteSecretKey = deriveNoteKeyFromSpendingKey(spendingKey);
|
|
74
|
+
const notePublicKey = poseidon1(bytesToBigIntBE(noteSecretKey));
|
|
75
|
+
return {
|
|
76
|
+
noteSecretKey,
|
|
77
|
+
noteSecretKeyHex: bytesToHex(noteSecretKey),
|
|
78
|
+
notePublicKey,
|
|
79
|
+
notePublicKeyString: notePublicKey.toString(),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
|
|
84
|
+
*
|
|
85
|
+
* Prompts a single signature, then returns spend authority for the account.
|
|
86
|
+
* The signature is secret material: keep it in memory, never persist it, and
|
|
87
|
+
* never expose the result on a global.
|
|
88
|
+
*/
|
|
89
|
+
export async function deriveNoteKeypairWithSigner(signMessage, index = 0) {
|
|
90
|
+
return deriveNoteKeypairFromSpendingKey(await deriveSpendingKeyWithSigner(signMessage, index));
|
|
91
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Keypair } from "@solana/web3.js";
|
|
2
|
+
export declare const VEILO_SPENDING_KEY_DOMAIN = "veilo_spending_key_v1";
|
|
3
|
+
/** Exact message signed by Veilo clients to derive a spending-key root. */
|
|
4
|
+
export declare function getSpendingKeyMessage(index?: number): Uint8Array;
|
|
5
|
+
/** Convert the deterministic 64-byte wallet signature into a spending key. */
|
|
6
|
+
export declare function deriveSpendingKeyFromSignature(signature: Uint8Array): Uint8Array;
|
|
7
|
+
/**
|
|
8
|
+
* Wallet-standard-friendly spending-key derivation.
|
|
9
|
+
* The callback owns signing; the SDK never receives the wallet secret key.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deriveSpendingKeyWithSigner(signMessage: (message: Uint8Array) => Promise<Uint8Array>, index?: number): Promise<Uint8Array>;
|
|
12
|
+
/**
|
|
13
|
+
* Keypair convenience matching the wallet-app and extension implementation.
|
|
14
|
+
* Keep the keypair on the user's device and never send it to a service.
|
|
15
|
+
*/
|
|
16
|
+
export declare function deriveSpendingKeyFromKeypair(keypair: Keypair, index?: number): Uint8Array;
|
|
17
|
+
/** Serialize an ephemeral claimant secret for an encrypted relayer request. */
|
|
18
|
+
export declare function encodeClaimantSecretKey(keypairOrSecret: Keypair | Uint8Array): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
2
|
+
import nacl from "tweetnacl";
|
|
3
|
+
import { assertBytes, concatBytes, encodeBase58, uint32Le, utf8, } from "./encoding.js";
|
|
4
|
+
export const VEILO_SPENDING_KEY_DOMAIN = "veilo_spending_key_v1";
|
|
5
|
+
/** Exact message signed by Veilo clients to derive a spending-key root. */
|
|
6
|
+
export function getSpendingKeyMessage(index = 0) {
|
|
7
|
+
return concatBytes(utf8(VEILO_SPENDING_KEY_DOMAIN), uint32Le(index, "spending-key index"));
|
|
8
|
+
}
|
|
9
|
+
/** Convert the deterministic 64-byte wallet signature into a spending key. */
|
|
10
|
+
export function deriveSpendingKeyFromSignature(signature) {
|
|
11
|
+
assertBytes(signature, 64, "spending-key signature");
|
|
12
|
+
return sha256(signature);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Wallet-standard-friendly spending-key derivation.
|
|
16
|
+
* The callback owns signing; the SDK never receives the wallet secret key.
|
|
17
|
+
*/
|
|
18
|
+
export async function deriveSpendingKeyWithSigner(signMessage, index = 0) {
|
|
19
|
+
return deriveSpendingKeyFromSignature(await signMessage(getSpendingKeyMessage(index)));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Keypair convenience matching the wallet-app and extension implementation.
|
|
23
|
+
* Keep the keypair on the user's device and never send it to a service.
|
|
24
|
+
*/
|
|
25
|
+
export function deriveSpendingKeyFromKeypair(keypair, index = 0) {
|
|
26
|
+
return deriveSpendingKeyFromSignature(nacl.sign.detached(getSpendingKeyMessage(index), keypair.secretKey));
|
|
27
|
+
}
|
|
28
|
+
/** Serialize an ephemeral claimant secret for an encrypted relayer request. */
|
|
29
|
+
export function encodeClaimantSecretKey(keypairOrSecret) {
|
|
30
|
+
const secret = keypairOrSecret instanceof Uint8Array
|
|
31
|
+
? keypairOrSecret
|
|
32
|
+
: keypairOrSecret.secretKey;
|
|
33
|
+
assertBytes(secret, 64, "claimant secret key");
|
|
34
|
+
return encodeBase58(secret);
|
|
35
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CompactNoteCipher } from "../compactNote.js";
|
|
2
|
+
/** HKDF salt. Provisional — see the header. */
|
|
3
|
+
export declare const VEILO_VIEW_KEY_SALT = "veilo_view_v1";
|
|
4
|
+
/** HKDF info. Provisional — see the header. */
|
|
5
|
+
export declare const VEILO_VIEW_KEY_INFO = "x25519";
|
|
6
|
+
/** An X25519 keypair used only to decrypt notes. */
|
|
7
|
+
export interface ViewKeypair {
|
|
8
|
+
/** 32-byte clamped X25519 scalar. Secret: decrypts every note sent to it. */
|
|
9
|
+
viewSecretKey: Uint8Array;
|
|
10
|
+
/** 32-byte X25519 public key — the value senders encrypt to. */
|
|
11
|
+
viewPublicKey: Uint8Array;
|
|
12
|
+
}
|
|
13
|
+
/** Derive the view keypair from a spending-key root. */
|
|
14
|
+
export declare function deriveViewKeypairFromSpendingKey(spendingKey: Uint8Array): ViewKeypair;
|
|
15
|
+
/**
|
|
16
|
+
* One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
|
|
17
|
+
*
|
|
18
|
+
* Uses the same signature as `deriveNoteKeypairWithSigner`, so a client that
|
|
19
|
+
* wants both prompts once and derives the spending key itself rather than
|
|
20
|
+
* calling both helpers.
|
|
21
|
+
*/
|
|
22
|
+
export declare function deriveViewKeypairWithSigner(signMessage: (message: Uint8Array) => Promise<Uint8Array>, index?: number): Promise<ViewKeypair>;
|
|
23
|
+
/**
|
|
24
|
+
* Scan one candidate cipher with a view key.
|
|
25
|
+
*
|
|
26
|
+
* Returns `null` both for a view-tag miss and for a blob that was not encrypted
|
|
27
|
+
* to this key — the expected outcome for nearly every candidate. The shared
|
|
28
|
+
* secret is computed once and reused for the tag check and the open, which is
|
|
29
|
+
* the cheapest correct order for a scan loop: the tag rejects ~255/256
|
|
30
|
+
* candidates for one scalar multiplication and one hash.
|
|
31
|
+
*
|
|
32
|
+
* ⚠ Only decrypts notes encrypted TO `viewPublicKey`. Notes sealed to a wallet
|
|
33
|
+
* Ed25519 key — every note written before the v2 format — will not open here.
|
|
34
|
+
*/
|
|
35
|
+
export declare function openCompactNoteWithViewKey(viewSecretKey: Uint8Array, cipher: CompactNoteCipher): {
|
|
36
|
+
blinding: Uint8Array;
|
|
37
|
+
amount: bigint;
|
|
38
|
+
} | null;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derivation of a VIEW-ONLY note decryption key from a spending-key root.
|
|
3
|
+
*
|
|
4
|
+
* ⚠ PROVISIONAL — NOT YET CONSUMED BY ANY NOTE FORMAT.
|
|
5
|
+
* Today's compact note ciphers are ECDH'd to the recipient's *wallet* Ed25519
|
|
6
|
+
* key (see `createCompactNoteCipher`), so nothing on-chain or in the relayer is
|
|
7
|
+
* encrypted to the key this module derives. It exists so the v2 note format —
|
|
8
|
+
* where senders encrypt to a published `viewPublicKey` instead of the wallet
|
|
9
|
+
* key — can be built and tested against a fixed derivation. The labels below
|
|
10
|
+
* become permanent the moment the first note is written under them; until then
|
|
11
|
+
* they are safe to change.
|
|
12
|
+
*
|
|
13
|
+
* WHY THIS EXISTS
|
|
14
|
+
* ---------------
|
|
15
|
+
* Note decryption currently requires the wallet Ed25519 secret, which is the
|
|
16
|
+
* one thing a dapp cannot have. Spend authority, by contrast, is already
|
|
17
|
+
* signature-derived (`./noteKey.js`). So a dapp can reconstruct the ability to
|
|
18
|
+
* spend but not the ability to *read*, and since a spend witness needs each
|
|
19
|
+
* note's amount and blinding, reading gates spending. Publishing a
|
|
20
|
+
* signature-derived `viewPublicKey` and encrypting to it closes that gap.
|
|
21
|
+
*
|
|
22
|
+
* Splitting viewing from spending is the point: `viewSecretKey` decrypts notes
|
|
23
|
+
* and nothing more. It cannot produce a nullifier, so it cannot spend, and it
|
|
24
|
+
* cannot determine on its own whether a note is already spent — a view-only
|
|
25
|
+
* client relies on the relayer's `spent` flag for that.
|
|
26
|
+
*
|
|
27
|
+
* Derivation:
|
|
28
|
+
* viewSecretKey = clamp(HKDF-SHA256(ikm=spendingKey, salt="veilo_view_v1",
|
|
29
|
+
* info="x25519", len=32))
|
|
30
|
+
* viewPublicKey = X25519_base(viewSecretKey)
|
|
31
|
+
*
|
|
32
|
+
* Both salt and info are given explicitly rather than left empty, so a sibling
|
|
33
|
+
* implementation never has to guess how its HKDF library treats an absent salt.
|
|
34
|
+
*/
|
|
35
|
+
import { hkdf } from "@noble/hashes/hkdf";
|
|
36
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
37
|
+
import nacl from "tweetnacl";
|
|
38
|
+
import { decryptCompactNoteCipher } from "../compactNote.js";
|
|
39
|
+
import { ed25519PublicKeyToX25519 } from "../notes/mailbox.js";
|
|
40
|
+
import { assertBytes, utf8 } from "./encoding.js";
|
|
41
|
+
import { deriveSpendingKeyWithSigner } from "./spending.js";
|
|
42
|
+
/** HKDF salt. Provisional — see the header. */
|
|
43
|
+
export const VEILO_VIEW_KEY_SALT = "veilo_view_v1";
|
|
44
|
+
/** HKDF info. Provisional — see the header. */
|
|
45
|
+
export const VEILO_VIEW_KEY_INFO = "x25519";
|
|
46
|
+
/**
|
|
47
|
+
* Apply RFC 7748 clamping so the stored scalar is canonical.
|
|
48
|
+
*
|
|
49
|
+
* TweetNaCl clamps internally on every scalar multiplication, so this changes
|
|
50
|
+
* no result; it means the bytes we hand out are the bytes actually used, which
|
|
51
|
+
* keeps a sibling implementation from disagreeing about what was stored.
|
|
52
|
+
*/
|
|
53
|
+
function clampX25519(scalar) {
|
|
54
|
+
const clamped = new Uint8Array(scalar);
|
|
55
|
+
clamped[0] &= 248;
|
|
56
|
+
clamped[31] &= 127;
|
|
57
|
+
clamped[31] |= 64;
|
|
58
|
+
return clamped;
|
|
59
|
+
}
|
|
60
|
+
/** Derive the view keypair from a spending-key root. */
|
|
61
|
+
export function deriveViewKeypairFromSpendingKey(spendingKey) {
|
|
62
|
+
assertBytes(spendingKey, 32, "spending key");
|
|
63
|
+
const viewSecretKey = clampX25519(hkdf(sha256, spendingKey, utf8(VEILO_VIEW_KEY_SALT), utf8(VEILO_VIEW_KEY_INFO), 32));
|
|
64
|
+
return { viewSecretKey, viewPublicKey: nacl.scalarMult.base(viewSecretKey) };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* One-shot derivation for a dapp holding only a wallet-standard `signMessage`.
|
|
68
|
+
*
|
|
69
|
+
* Uses the same signature as `deriveNoteKeypairWithSigner`, so a client that
|
|
70
|
+
* wants both prompts once and derives the spending key itself rather than
|
|
71
|
+
* calling both helpers.
|
|
72
|
+
*/
|
|
73
|
+
export async function deriveViewKeypairWithSigner(signMessage, index = 0) {
|
|
74
|
+
return deriveViewKeypairFromSpendingKey(await deriveSpendingKeyWithSigner(signMessage, index));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Scan one candidate cipher with a view key.
|
|
78
|
+
*
|
|
79
|
+
* Returns `null` both for a view-tag miss and for a blob that was not encrypted
|
|
80
|
+
* to this key — the expected outcome for nearly every candidate. The shared
|
|
81
|
+
* secret is computed once and reused for the tag check and the open, which is
|
|
82
|
+
* the cheapest correct order for a scan loop: the tag rejects ~255/256
|
|
83
|
+
* candidates for one scalar multiplication and one hash.
|
|
84
|
+
*
|
|
85
|
+
* ⚠ Only decrypts notes encrypted TO `viewPublicKey`. Notes sealed to a wallet
|
|
86
|
+
* Ed25519 key — every note written before the v2 format — will not open here.
|
|
87
|
+
*/
|
|
88
|
+
export function openCompactNoteWithViewKey(viewSecretKey, cipher) {
|
|
89
|
+
assertBytes(viewSecretKey, 32, "view secret key");
|
|
90
|
+
assertBytes(cipher.ephemeralPublicKey, 32, "ephemeral public key");
|
|
91
|
+
const sharedSecret = nacl.scalarMult(viewSecretKey, ed25519PublicKeyToX25519(cipher.ephemeralPublicKey));
|
|
92
|
+
if (nacl.hash(sharedSecret)[0] !== cipher.viewTag)
|
|
93
|
+
return null;
|
|
94
|
+
// walletSecretKey is unused once `sharedSecret` is supplied.
|
|
95
|
+
return decryptCompactNoteCipher(viewSecretKey, cipher.ephemeralPublicKey, cipher.compactBlob, { sharedSecret });
|
|
96
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Idl } from "@coral-xyz/anchor";
|
|
2
|
+
/** Protocol generations used to decode Veilo's historical on-chain data. */
|
|
3
|
+
export type PrivacyPoolIdlVersion = "current" | "legacy" | "legacy2";
|
|
4
|
+
export type VersionedPrivacyPoolIdl = {
|
|
5
|
+
version: PrivacyPoolIdlVersion;
|
|
6
|
+
idl: Idl;
|
|
7
|
+
};
|
|
8
|
+
/** Current IDL used for building new instructions. */
|
|
9
|
+
export declare const PRIVACY_POOL_CURRENT_IDL: Idl;
|
|
10
|
+
/** Original event shape without compact note recovery fields. */
|
|
11
|
+
export declare const PRIVACY_POOL_LEGACY_IDL: Idl;
|
|
12
|
+
/** Intermediate event shape with compact cipher fields but no view tag. */
|
|
13
|
+
export declare const PRIVACY_POOL_LEGACY2_IDL: Idl;
|
|
14
|
+
/**
|
|
15
|
+
* IDLs in the same newest-to-oldest fallback order used by the relayer indexer.
|
|
16
|
+
* All three target the same deployed program address.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PRIVACY_POOL_IDLS: readonly VersionedPrivacyPoolIdl[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import currentIdl from "./privacy_pool.js";
|
|
2
|
+
import legacyIdl from "./privacy_pool_legacy.js";
|
|
3
|
+
import legacy2Idl from "./privacy_pool_legacy2.js";
|
|
4
|
+
/** Current IDL used for building new instructions. */
|
|
5
|
+
export const PRIVACY_POOL_CURRENT_IDL = currentIdl;
|
|
6
|
+
/** Original event shape without compact note recovery fields. */
|
|
7
|
+
export const PRIVACY_POOL_LEGACY_IDL = legacyIdl;
|
|
8
|
+
/** Intermediate event shape with compact cipher fields but no view tag. */
|
|
9
|
+
export const PRIVACY_POOL_LEGACY2_IDL = legacy2Idl;
|
|
10
|
+
/**
|
|
11
|
+
* IDLs in the same newest-to-oldest fallback order used by the relayer indexer.
|
|
12
|
+
* All three target the same deployed program address.
|
|
13
|
+
*/
|
|
14
|
+
export const PRIVACY_POOL_IDLS = [
|
|
15
|
+
{ version: "current", idl: PRIVACY_POOL_CURRENT_IDL },
|
|
16
|
+
{ version: "legacy", idl: PRIVACY_POOL_LEGACY_IDL },
|
|
17
|
+
{ version: "legacy2", idl: PRIVACY_POOL_LEGACY2_IDL },
|
|
18
|
+
];
|