@permissionless-technologies/upp-sdk 0.3.6 → 0.4.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/dist/{asp-ZA3RGN7G.js → asp-72WUGTQE.js} +3 -3
- package/dist/asp-72WUGTQE.js.map +1 -0
- package/dist/{asp-TXSAFFD3.cjs → asp-CUE3NMBN.cjs} +14 -14
- package/dist/asp-CUE3NMBN.cjs.map +1 -0
- package/dist/{chunk-KXPZUBPI.cjs → chunk-23B5XSS4.cjs} +12 -12
- package/dist/{chunk-KXPZUBPI.cjs.map → chunk-23B5XSS4.cjs.map} +1 -1
- package/dist/{chunk-SQKBT2SH.cjs → chunk-2G22R7AJ.cjs} +18 -7
- package/dist/chunk-2G22R7AJ.cjs.map +1 -0
- package/dist/chunk-5QSSX3KR.js +64 -0
- package/dist/chunk-5QSSX3KR.js.map +1 -0
- package/dist/{chunk-P37MRZ73.js → chunk-6IEYWJVS.js} +8 -8
- package/dist/chunk-6IEYWJVS.js.map +1 -0
- package/dist/{chunk-5V5HSN6Y.js → chunk-6TFDBBAQ.js} +3 -3
- package/dist/{chunk-5V5HSN6Y.js.map → chunk-6TFDBBAQ.js.map} +1 -1
- package/dist/{chunk-ZKZV6OI3.cjs → chunk-7BNJV2ZS.cjs} +21 -21
- package/dist/{chunk-ZKZV6OI3.cjs.map → chunk-7BNJV2ZS.cjs.map} +1 -1
- package/dist/{chunk-XBNYAAMU.js → chunk-7T4CUE6E.js} +3 -3
- package/dist/{chunk-XBNYAAMU.js.map → chunk-7T4CUE6E.js.map} +1 -1
- package/dist/{chunk-OD2SDC4L.js → chunk-CEJN5ZE5.js} +3 -3
- package/dist/{chunk-OD2SDC4L.js.map → chunk-CEJN5ZE5.js.map} +1 -1
- package/dist/{chunk-2JQISXBD.js → chunk-DTEAFJG7.js} +8 -8
- package/dist/{chunk-2JQISXBD.js.map → chunk-DTEAFJG7.js.map} +1 -1
- package/dist/chunk-EHGH6TAW.js +100 -0
- package/dist/chunk-EHGH6TAW.js.map +1 -0
- package/dist/{chunk-ZU6J7KMY.js → chunk-GPF72JFR.js} +3 -3
- package/dist/{chunk-ZU6J7KMY.js.map → chunk-GPF72JFR.js.map} +1 -1
- package/dist/chunk-HEHXSV47.cjs +77 -0
- package/dist/chunk-HEHXSV47.cjs.map +1 -0
- package/dist/chunk-I5EKGD4P.cjs +113 -0
- package/dist/chunk-I5EKGD4P.cjs.map +1 -0
- package/dist/{chunk-EUP7MBAH.cjs → chunk-IIUKM5VE.cjs} +7 -7
- package/dist/{chunk-EUP7MBAH.cjs.map → chunk-IIUKM5VE.cjs.map} +1 -1
- package/dist/{chunk-CWSUBAV3.js → chunk-OBBSIPEK.js} +30 -35
- package/dist/chunk-OBBSIPEK.js.map +1 -0
- package/dist/{chunk-FVT2XRRL.cjs → chunk-Q2E432UK.cjs} +41 -46
- package/dist/chunk-Q2E432UK.cjs.map +1 -0
- package/dist/{chunk-QKI4QWLT.js → chunk-RNUG3EFC.js} +6 -6
- package/dist/{chunk-QKI4QWLT.js.map → chunk-RNUG3EFC.js.map} +1 -1
- package/dist/{chunk-3YZSIYJC.cjs → chunk-SWTNJPK5.cjs} +11 -11
- package/dist/{chunk-3YZSIYJC.cjs.map → chunk-SWTNJPK5.cjs.map} +1 -1
- package/dist/{chunk-BH24DZ5S.cjs → chunk-U3YFYMWF.cjs} +5 -5
- package/dist/{chunk-BH24DZ5S.cjs.map → chunk-U3YFYMWF.cjs.map} +1 -1
- package/dist/{chunk-3HQ7A6ZM.cjs → chunk-UFEDJJSH.cjs} +5 -5
- package/dist/{chunk-3HQ7A6ZM.cjs.map → chunk-UFEDJJSH.cjs.map} +1 -1
- package/dist/{chunk-W77GRBO4.js → chunk-UQIM2KT3.js} +3 -3
- package/dist/{chunk-W77GRBO4.js.map → chunk-UQIM2KT3.js.map} +1 -1
- package/dist/{chunk-SJDPDHSD.cjs → chunk-UTAJSERA.cjs} +4 -4
- package/dist/{chunk-SJDPDHSD.cjs.map → chunk-UTAJSERA.cjs.map} +1 -1
- package/dist/{chunk-NI62M3W3.cjs → chunk-UYE2JASE.cjs} +2 -2
- package/dist/{chunk-NI62M3W3.cjs.map → chunk-UYE2JASE.cjs.map} +1 -1
- package/dist/{chunk-S4B7GYLN.js → chunk-W3HLIKC2.js} +18 -8
- package/dist/chunk-W3HLIKC2.js.map +1 -0
- package/dist/{chunk-NDM5EJEV.cjs → chunk-XVIICZKW.cjs} +7 -7
- package/dist/chunk-XVIICZKW.cjs.map +1 -0
- package/dist/{chunk-7Q4RSSHM.js → chunk-ZTVXII74.js} +2 -2
- package/dist/{chunk-7Q4RSSHM.js.map → chunk-ZTVXII74.js.map} +1 -1
- package/dist/core/index.cjs +85 -85
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +10 -10
- package/dist/{index-B45-okum.d.cts → index-BgPdYxFS.d.cts} +18 -18
- package/dist/{index-o-Ds3YAq.d.cts → index-CL4vb3ej.d.cts} +1 -1
- package/dist/{index-BIcvNMPt.d.ts → index-CtcXgof_.d.ts} +18 -18
- package/dist/{index-DwAJBoU7.d.ts → index-D6nvfm59.d.ts} +1 -1
- package/dist/index.cjs +265 -266
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +29 -30
- package/dist/index.js.map +1 -1
- package/dist/indexer/index.cjs +6 -6
- package/dist/indexer/index.d.cts +5 -5
- package/dist/indexer/index.d.ts +5 -5
- package/dist/indexer/index.js +1 -1
- package/dist/keys/index.cjs +18 -18
- package/dist/keys/index.js +4 -4
- package/dist/merkle-DZHEOPH3.cjs +30 -0
- package/dist/{merkle-HGDC6OB4.cjs.map → merkle-DZHEOPH3.cjs.map} +1 -1
- package/dist/merkle-IF2RMWCF.js +5 -0
- package/dist/{merkle-7KS2EHRF.js.map → merkle-IF2RMWCF.js.map} +1 -1
- package/dist/poseidon-ACM7E2OH.js +7 -0
- package/dist/{poseidon-UHTJLWQM.js.map → poseidon-ACM7E2OH.js.map} +1 -1
- package/dist/poseidon-PUSGUIVZ.cjs +61 -0
- package/dist/{poseidon-WHJSZSNP.cjs.map → poseidon-PUSGUIVZ.cjs.map} +1 -1
- package/dist/proof-JME3IZTX.js +4 -0
- package/dist/{proof-C4YBP6RY.js.map → proof-JME3IZTX.js.map} +1 -1
- package/dist/proof-XR6XE5PJ.cjs +49 -0
- package/dist/{proof-5OECB3RQ.cjs.map → proof-XR6XE5PJ.cjs.map} +1 -1
- package/dist/react/index.cjs +47 -51
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +20 -24
- package/dist/react/index.js.map +1 -1
- package/dist/{transfer-BzyernBd.d.cts → transfer-D111ihqN.d.cts} +108 -56
- package/dist/{transfer-sqS6mJko.d.ts → transfer-DvIXqHCr.d.ts} +108 -56
- package/dist/transfer-MQMGSXTH.js +8 -0
- package/dist/{transfer-F6YOQTUL.js.map → transfer-MQMGSXTH.js.map} +1 -1
- package/dist/transfer-PB6D5VCW.cjs +37 -0
- package/dist/{transfer-42C4DXYA.cjs.map → transfer-PB6D5VCW.cjs.map} +1 -1
- package/dist/utils/index.cjs +60 -61
- package/dist/utils/index.d.cts +37 -14
- package/dist/utils/index.d.ts +37 -14
- package/dist/utils/index.js +6 -7
- package/package.json +4 -2
- package/src/contracts/interfaces/IUniversalPrivatePool.sol +10 -8
- package/src/contracts/interfaces/IVerifiers.sol +16 -52
- package/src/deployments/11155111.json +15 -12
- package/dist/asp-TXSAFFD3.cjs.map +0 -1
- package/dist/asp-ZA3RGN7G.js.map +0 -1
- package/dist/babyjubjub-2MGQVCKB.js +0 -5
- package/dist/babyjubjub-2MGQVCKB.js.map +0 -1
- package/dist/babyjubjub-MWZLJOVZ.cjs +0 -66
- package/dist/babyjubjub-MWZLJOVZ.cjs.map +0 -1
- package/dist/chunk-CWSUBAV3.js.map +0 -1
- package/dist/chunk-FVT2XRRL.cjs.map +0 -1
- package/dist/chunk-JWNXBALH.cjs +0 -57
- package/dist/chunk-JWNXBALH.cjs.map +0 -1
- package/dist/chunk-NDM5EJEV.cjs.map +0 -1
- package/dist/chunk-P37MRZ73.js.map +0 -1
- package/dist/chunk-PTDVGWHU.cjs +0 -10
- package/dist/chunk-PTDVGWHU.cjs.map +0 -1
- package/dist/chunk-S4B7GYLN.js.map +0 -1
- package/dist/chunk-SQKBT2SH.cjs.map +0 -1
- package/dist/chunk-TSF6HEVS.cjs +0 -201
- package/dist/chunk-TSF6HEVS.cjs.map +0 -1
- package/dist/chunk-UAVWYXDN.js +0 -8
- package/dist/chunk-UAVWYXDN.js.map +0 -1
- package/dist/chunk-V23OSL25.js +0 -48
- package/dist/chunk-V23OSL25.js.map +0 -1
- package/dist/chunk-YOWDERVC.js +0 -186
- package/dist/chunk-YOWDERVC.js.map +0 -1
- package/dist/merkle-7KS2EHRF.js +0 -5
- package/dist/merkle-HGDC6OB4.cjs +0 -30
- package/dist/poseidon-UHTJLWQM.js +0 -7
- package/dist/poseidon-WHJSZSNP.cjs +0 -45
- package/dist/proof-5OECB3RQ.cjs +0 -45
- package/dist/proof-C4YBP6RY.js +0 -4
- package/dist/transfer-42C4DXYA.cjs +0 -37
- package/dist/transfer-F6YOQTUL.js +0 -8
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ASP_TREE_DEPTH, DEMO_ASP_ID, DEMO_ASP_NAME, buildASPTree, computeMultiOriginASPRoot, computeSingleOriginASPRoot, createDemoASPRoot, generateASPProof, generateMultiOriginASPProof, generateSingleOriginASPProof, verifyASPProof } from './chunk-
|
|
1
|
+
export { ASP_TREE_DEPTH, DEMO_ASP_ID, DEMO_ASP_NAME, buildASPTree, computeMultiOriginASPRoot, computeSingleOriginASPRoot, createDemoASPRoot, generateASPProof, generateMultiOriginASPProof, generateSingleOriginASPProof, verifyASPProof } from './chunk-6IEYWJVS.js';
|
|
2
2
|
import './chunk-Z6ZWNWWR.js';
|
|
3
|
-
//# sourceMappingURL=asp-
|
|
4
|
-
//# sourceMappingURL=asp-
|
|
3
|
+
//# sourceMappingURL=asp-72WUGTQE.js.map
|
|
4
|
+
//# sourceMappingURL=asp-72WUGTQE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"asp-72WUGTQE.js"}
|
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkXVIICZKW_cjs = require('./chunk-XVIICZKW.cjs');
|
|
4
4
|
require('./chunk-G7VZBCD6.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "ASP_TREE_DEPTH", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkXVIICZKW_cjs.ASP_TREE_DEPTH; }
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, "DEMO_ASP_ID", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkXVIICZKW_cjs.DEMO_ASP_ID; }
|
|
15
15
|
});
|
|
16
16
|
Object.defineProperty(exports, "DEMO_ASP_NAME", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkXVIICZKW_cjs.DEMO_ASP_NAME; }
|
|
19
19
|
});
|
|
20
20
|
Object.defineProperty(exports, "buildASPTree", {
|
|
21
21
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
22
|
+
get: function () { return chunkXVIICZKW_cjs.buildASPTree; }
|
|
23
23
|
});
|
|
24
24
|
Object.defineProperty(exports, "computeMultiOriginASPRoot", {
|
|
25
25
|
enumerable: true,
|
|
26
|
-
get: function () { return
|
|
26
|
+
get: function () { return chunkXVIICZKW_cjs.computeMultiOriginASPRoot; }
|
|
27
27
|
});
|
|
28
28
|
Object.defineProperty(exports, "computeSingleOriginASPRoot", {
|
|
29
29
|
enumerable: true,
|
|
30
|
-
get: function () { return
|
|
30
|
+
get: function () { return chunkXVIICZKW_cjs.computeSingleOriginASPRoot; }
|
|
31
31
|
});
|
|
32
32
|
Object.defineProperty(exports, "createDemoASPRoot", {
|
|
33
33
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
34
|
+
get: function () { return chunkXVIICZKW_cjs.createDemoASPRoot; }
|
|
35
35
|
});
|
|
36
36
|
Object.defineProperty(exports, "generateASPProof", {
|
|
37
37
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
38
|
+
get: function () { return chunkXVIICZKW_cjs.generateASPProof; }
|
|
39
39
|
});
|
|
40
40
|
Object.defineProperty(exports, "generateMultiOriginASPProof", {
|
|
41
41
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
42
|
+
get: function () { return chunkXVIICZKW_cjs.generateMultiOriginASPProof; }
|
|
43
43
|
});
|
|
44
44
|
Object.defineProperty(exports, "generateSingleOriginASPProof", {
|
|
45
45
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
46
|
+
get: function () { return chunkXVIICZKW_cjs.generateSingleOriginASPProof; }
|
|
47
47
|
});
|
|
48
48
|
Object.defineProperty(exports, "verifyASPProof", {
|
|
49
49
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
50
|
+
get: function () { return chunkXVIICZKW_cjs.verifyASPProof; }
|
|
51
51
|
});
|
|
52
|
-
//# sourceMappingURL=asp-
|
|
53
|
-
//# sourceMappingURL=asp-
|
|
52
|
+
//# sourceMappingURL=asp-CUE3NMBN.cjs.map
|
|
53
|
+
//# sourceMappingURL=asp-CUE3NMBN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"asp-CUE3NMBN.cjs"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUFEDJJSH_cjs = require('./chunk-UFEDJJSH.cjs');
|
|
4
4
|
var chunkG7VZBCD6_cjs = require('./chunk-G7VZBCD6.cjs');
|
|
5
5
|
var bech32 = require('bech32');
|
|
6
6
|
var viem = require('viem');
|
|
@@ -33,10 +33,10 @@ function encodeStealthAddress(ownerHash, viewingHash, chainId = 0) {
|
|
|
33
33
|
data[offset++] = chainId >> 16 & 255;
|
|
34
34
|
data[offset++] = chainId >> 8 & 255;
|
|
35
35
|
data[offset++] = chainId & 255;
|
|
36
|
-
const ownerBytes =
|
|
36
|
+
const ownerBytes = chunkUFEDJJSH_cjs.bigintToBytes(ownerHash, 32);
|
|
37
37
|
data.set(ownerBytes, offset);
|
|
38
38
|
offset += 32;
|
|
39
|
-
const viewingBytes =
|
|
39
|
+
const viewingBytes = chunkUFEDJJSH_cjs.bigintToBytes(viewingHash, 32);
|
|
40
40
|
data.set(viewingBytes, offset);
|
|
41
41
|
const words = bech32.bech32m.toWords(data);
|
|
42
42
|
return bech32.bech32m.encode(exports.STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT);
|
|
@@ -53,9 +53,9 @@ function decodeStealthAddress(address) {
|
|
|
53
53
|
throw new Error(`Unsupported address version: ${version}. Expected v${exports.ADDRESS_VERSION} (hash-based).`);
|
|
54
54
|
}
|
|
55
55
|
const chainId = data[offset++] << 24 | data[offset++] << 16 | data[offset++] << 8 | data[offset++];
|
|
56
|
-
const ownerHash =
|
|
56
|
+
const ownerHash = chunkUFEDJJSH_cjs.bytesToBigint(data.slice(offset, offset + 32));
|
|
57
57
|
offset += 32;
|
|
58
|
-
const viewingHash =
|
|
58
|
+
const viewingHash = chunkUFEDJJSH_cjs.bytesToBigint(data.slice(offset, offset + 32));
|
|
59
59
|
return {
|
|
60
60
|
version,
|
|
61
61
|
chainId,
|
|
@@ -75,7 +75,7 @@ function generateStealthAddress(keys, chainId = 0) {
|
|
|
75
75
|
return encodeStealthAddress(keys.ownerHash, keys.viewingHash, chainId);
|
|
76
76
|
}
|
|
77
77
|
async function createOneTimeKeys(_recipientOwnerHash, selfSecret) {
|
|
78
|
-
const { poseidon } = await import('./poseidon-
|
|
78
|
+
const { poseidon } = await import('./poseidon-PUSGUIVZ.cjs');
|
|
79
79
|
if (selfSecret !== void 0) {
|
|
80
80
|
const ownerHash2 = await poseidon([selfSecret]);
|
|
81
81
|
return {
|
|
@@ -83,7 +83,7 @@ async function createOneTimeKeys(_recipientOwnerHash, selfSecret) {
|
|
|
83
83
|
ownerHash: ownerHash2
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
|
-
const oneTimeSecret =
|
|
86
|
+
const oneTimeSecret = chunkUFEDJJSH_cjs.randomFieldElement();
|
|
87
87
|
const ownerHash = await poseidon([oneTimeSecret]);
|
|
88
88
|
return {
|
|
89
89
|
oneTimeSecret,
|
|
@@ -91,12 +91,12 @@ async function createOneTimeKeys(_recipientOwnerHash, selfSecret) {
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
async function verifyOwnership(secret, expectedOwnerHash) {
|
|
94
|
-
const { poseidon } = await import('./poseidon-
|
|
94
|
+
const { poseidon } = await import('./poseidon-PUSGUIVZ.cjs');
|
|
95
95
|
const computedHash = await poseidon([secret]);
|
|
96
96
|
return computedHash === expectedOwnerHash;
|
|
97
97
|
}
|
|
98
98
|
async function computeNoteEncryptionKey(viewingSecret, nonce) {
|
|
99
|
-
const { poseidon } = await import('./poseidon-
|
|
99
|
+
const { poseidon } = await import('./poseidon-PUSGUIVZ.cjs');
|
|
100
100
|
if (nonce !== void 0) {
|
|
101
101
|
return poseidon([viewingSecret, nonce]);
|
|
102
102
|
}
|
|
@@ -181,7 +181,7 @@ function detectAddressType(address) {
|
|
|
181
181
|
exports.STEALTH_ADDRESS_PREFIX = void 0; exports.ADDRESS_VERSION = void 0; var BECH32M_LIMIT; exports.STARK_STEALTH_ADDRESS_PREFIX = void 0; exports.STARK_ADDRESS_VERSION = void 0;
|
|
182
182
|
var init_stealth = chunkG7VZBCD6_cjs.__esm({
|
|
183
183
|
"src/core/stealth.ts"() {
|
|
184
|
-
|
|
184
|
+
chunkUFEDJJSH_cjs.init_crypto();
|
|
185
185
|
exports.STEALTH_ADDRESS_PREFIX = "0zk";
|
|
186
186
|
exports.ADDRESS_VERSION = 2;
|
|
187
187
|
BECH32M_LIMIT = 1023;
|
|
@@ -611,5 +611,5 @@ exports.removeCancelSecret = removeCancelSecret;
|
|
|
611
611
|
exports.stealth_exports = stealth_exports;
|
|
612
612
|
exports.storeCancelSecret = storeCancelSecret;
|
|
613
613
|
exports.verifyOwnership = verifyOwnership;
|
|
614
|
-
//# sourceMappingURL=chunk-
|
|
615
|
-
//# sourceMappingURL=chunk-
|
|
614
|
+
//# sourceMappingURL=chunk-23B5XSS4.cjs.map
|
|
615
|
+
//# sourceMappingURL=chunk-23B5XSS4.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/stealth.ts","../src/core/swap.ts","../src/core/account.ts","../src/core/note-store.ts"],"names":["__export","ADDRESS_VERSION","STARK_ADDRESS_VERSION","STARK_STEALTH_ADDRESS_PREFIX","STEALTH_ADDRESS_PREFIX","bigintToBytes","bech32m","bytesToBigint","ownerHash","randomFieldElement","__esm","init_crypto","keccak256","encodeAbiParameters","parseAbiParameters","toHex","getAddress"],"mappings":"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","file":"chunk-KXPZUBPI.cjs","sourcesContent":["/**\n * Stealth Address Utilities (Post-Quantum, Hash-Based)\n *\n * Implements stealth addresses using Poseidon hashes with bech32m encoding.\n * No BabyJubJub curve operations — ownership is proven via hash preimage.\n *\n * Address Format (bech32m):\n * 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * Key Flow (self-shield):\n * 1. User derives ownerHash = Poseidon(spendingSecret)\n * 2. Commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n * 3. Encrypt note with key derived from viewingSecret\n *\n * Key Flow (send to others, future):\n * 1. Decode recipient's stealth address (ownerHash, viewingHash)\n * 2. Generate per-note secret and derive ownerHash for the note\n * 3. Encrypt note so recipient's viewingSecret can decrypt\n */\n\nimport { bech32m } from 'bech32'\nimport {\n randomFieldElement,\n bigintToBytes,\n bytesToBigint,\n} from '../utils/crypto.js'\nimport type { MasterKeys, StarkMasterKeys, OneTimeKeys } from '../keys/types.js'\nimport type { M31Digest } from '../utils/keccak-m31.js'\n\n/**\n * Stealth address prefix\n */\nexport const STEALTH_ADDRESS_PREFIX = '0zk'\n\n/**\n * Address version (v2 = hash-based, post-quantum)\n */\nexport const ADDRESS_VERSION = 2\n\n/**\n * Maximum length for bech32m encoding\n */\nconst BECH32M_LIMIT = 1023\n\n/**\n * Encode a stealth address in bech32m format\n *\n * Format: 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * @param ownerHash - Owner hash = Poseidon(spendingSecret)\n * @param viewingHash - Viewing hash = Poseidon(viewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n * @returns bech32m encoded stealth address\n */\nexport function encodeStealthAddress(\n ownerHash: bigint,\n viewingHash: bigint,\n chainId: number = 0\n): string {\n // Build data buffer: version (1 byte) + chainId (4 bytes) + 2 * 32 bytes = 69 bytes\n const data = new Uint8Array(1 + 4 + 32 * 2)\n let offset = 0\n\n // Version\n data[offset++] = ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash (32 bytes)\n const ownerBytes = bigintToBytes(ownerHash, 32)\n data.set(ownerBytes, offset)\n offset += 32\n\n // Viewing hash (32 bytes)\n const viewingBytes = bigintToBytes(viewingHash, 32)\n data.set(viewingBytes, offset)\n\n // Convert to 5-bit words for bech32m\n const words = bech32m.toWords(data)\n\n // Encode with prefix\n return bech32m.encode(STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a bech32m stealth address\n *\n * @param address - bech32m encoded stealth address\n * @returns Decoded hash values\n */\nexport function decodeStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: bigint\n viewingHash: bigint\n} {\n // Decode bech32m\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n // Verify prefix\n if (decoded.prefix !== STEALTH_ADDRESS_PREFIX) {\n throw new Error(`Invalid stealth address prefix: expected '${STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`)\n }\n\n // Convert from 5-bit words back to bytes\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n\n // Parse version\n let offset = 0\n const version = data[offset++]!\n\n if (version !== ADDRESS_VERSION) {\n throw new Error(`Unsupported address version: ${version}. Expected v${ADDRESS_VERSION} (hash-based).`)\n }\n\n // Parse chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Parse owner hash (32 bytes)\n const ownerHash = bytesToBigint(data.slice(offset, offset + 32))\n offset += 32\n\n // Parse viewing hash (32 bytes)\n const viewingHash = bytesToBigint(data.slice(offset, offset + 32))\n\n return {\n version,\n chainId,\n ownerHash,\n viewingHash,\n }\n}\n\n/**\n * Validate a stealth address format\n */\nexport function isValidStealthAddress(address: string): boolean {\n try {\n decodeStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate stealth address from master keys\n */\nexport function generateStealthAddress(keys: MasterKeys, chainId: number = 0): string {\n return encodeStealthAddress(keys.ownerHash, keys.viewingHash, chainId)\n}\n\n/**\n * Create one-time keys for a transaction (hash-based)\n *\n * For self-shield: the user uses their own spendingSecret directly\n * as the ownerSecret, producing ownerHash = Poseidon(spendingSecret).\n *\n * For sending to others (future): generate a random oneTimeSecret\n * and derive ownerHash = Poseidon(oneTimeSecret).\n *\n * @param recipientOwnerHash - Recipient's owner hash (for verification)\n * @param selfSecret - If self-shield, the user's spending secret\n * @returns One-time keys for the note\n */\nexport async function createOneTimeKeys(\n _recipientOwnerHash?: bigint,\n selfSecret?: bigint,\n): Promise<OneTimeKeys> {\n const { poseidon } = await import('../utils/poseidon.js')\n\n if (selfSecret !== undefined) {\n // Self-shield: use own spending secret\n const ownerHash = await poseidon([selfSecret])\n return {\n oneTimeSecret: selfSecret,\n ownerHash,\n }\n }\n\n // Generate random one-time secret for the note\n const oneTimeSecret = randomFieldElement()\n const ownerHash = await poseidon([oneTimeSecret])\n\n return {\n oneTimeSecret,\n ownerHash,\n }\n}\n\n/**\n * Verify ownership of a note by checking hash preimage\n *\n * @param secret - Claimed spending secret\n * @param expectedOwnerHash - Owner hash from the note commitment\n * @returns True if the secret hashes to the expected owner hash\n */\nexport async function verifyOwnership(\n secret: bigint,\n expectedOwnerHash: bigint\n): Promise<boolean> {\n const { poseidon } = await import('../utils/poseidon.js')\n const computedHash = await poseidon([secret])\n return computedHash === expectedOwnerHash\n}\n\n/**\n * Compute shared secret for note encryption/decryption (hash-based)\n *\n * For self-shield: just uses the viewing secret directly.\n * For sending to others (future): use Poseidon(viewingSecret, recipientViewingHash)\n *\n * @param viewingSecret - Sender's or recipient's viewing secret\n * @param nonce - Optional nonce for key derivation\n * @returns Encryption key as bigint\n */\nexport async function computeNoteEncryptionKey(\n viewingSecret: bigint,\n nonce?: bigint\n): Promise<bigint> {\n const { poseidon } = await import('../utils/poseidon.js')\n if (nonce !== undefined) {\n return poseidon([viewingSecret, nonce])\n }\n return poseidon([viewingSecret])\n}\n\n// =========================================================================\n// STARK Stealth Addresses (0zs prefix, M31/Keccak-based)\n// =========================================================================\n\n/**\n * STARK stealth address prefix\n */\nexport const STARK_STEALTH_ADDRESS_PREFIX = '0zs'\n\n/**\n * STARK address version (v1 = M31/Keccak)\n */\nexport const STARK_ADDRESS_VERSION = 1\n\n/**\n * Encode a STARK stealth address in bech32m format\n *\n * Format: 0zs1<version><chainId><ownerHash[0..3]><viewingHash[0..3]>\n *\n * Each M31 element is encoded as 4 bytes (little-endian).\n * Total data: 1 (version) + 4 (chainId) + 16 (ownerHash) + 16 (viewingHash) = 37 bytes.\n *\n * @param ownerHash - 4 M31 elements: keccak_m31(starkSecret)\n * @param viewingHash - 4 M31 elements: keccak_m31(starkViewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n */\nexport function encodeStarkStealthAddress(\n ownerHash: M31Digest,\n viewingHash: M31Digest,\n chainId: number = 0\n): string {\n const data = new Uint8Array(1 + 4 + 16 + 16) // 37 bytes\n let offset = 0\n\n // Version\n data[offset++] = STARK_ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(ownerHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n // Viewing hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(viewingHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n const words = bech32m.toWords(data)\n return bech32m.encode(STARK_STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a STARK stealth address (0zs prefix)\n */\nexport function decodeStarkStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: M31Digest\n viewingHash: M31Digest\n} {\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n if (decoded.prefix !== STARK_STEALTH_ADDRESS_PREFIX) {\n throw new Error(\n `Invalid STARK stealth address prefix: expected '${STARK_STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`\n )\n }\n\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n let offset = 0\n\n const version = data[offset++]!\n if (version !== STARK_ADDRESS_VERSION) {\n throw new Error(\n `Unsupported STARK address version: ${version}. Expected v${STARK_ADDRESS_VERSION}.`\n )\n }\n\n // Chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Owner hash: 4 M31 LE uint32s\n const ownerHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n ownerHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n // Viewing hash: 4 M31 LE uint32s\n const viewingHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n viewingHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n return {\n version,\n chainId,\n ownerHash: ownerHash as unknown as M31Digest,\n viewingHash: viewingHash as unknown as M31Digest,\n }\n}\n\n/**\n * Validate a STARK stealth address format\n */\nexport function isValidStarkStealthAddress(address: string): boolean {\n try {\n decodeStarkStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate a STARK stealth address from STARK master keys\n */\nexport function generateStarkStealthAddress(\n keys: StarkMasterKeys,\n chainId: number = 0\n): string {\n return encodeStarkStealthAddress(keys.starkOwnerHash, keys.starkViewingHash, chainId)\n}\n\n/**\n * Detect whether an address is SNARK (0zk) or STARK (0zs)\n */\nexport function detectAddressType(address: string): 'snark' | 'stark' | 'unknown' {\n if (address.startsWith(STEALTH_ADDRESS_PREFIX + '1')) return 'snark'\n if (address.startsWith(STARK_STEALTH_ADDRESS_PREFIX + '1')) return 'stark'\n return 'unknown'\n}\n","/**\n * Swap Module\n *\n * Core logic for building and interacting with the UPP in-pool swap order book.\n * Framework-agnostic (no React). Reuses withdraw verifier for proofs.\n */\n\nimport { type Address, type Hex, encodeAbiParameters, keccak256, parseAbiParameters, toHex } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Swap order as stored on-chain\n */\nexport interface SwapOrder {\n /** Order ID (= maker's nullifier) */\n orderId: Hex\n /** Token being sold */\n sellToken: Address\n /** Original total sell amount */\n sellAmount: bigint\n /** Remaining sell amount (decremented on each fill) */\n remainingSellAmount: bigint\n /** Token the maker wants to receive */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Accumulated buy token amount from fills */\n accumulatedBuyAmount: bigint\n /** Maker's ASP ID (public, filterable by takers) */\n makerAspId: bigint\n /** Required filler ASP (0 = any) */\n requiredFillerAspId: bigint\n /** Block number after which order expires */\n expiry: bigint\n /** Whether the maker has claimed */\n claimed: boolean\n /** Whether the order was cancelled */\n cancelled: boolean\n}\n\n/**\n * Parameters to place a swap order\n */\nexport interface SwapOrderParams {\n /** Token to sell */\n sellToken: Address\n /** Amount to sell */\n sellAmount: bigint\n /** Token to buy */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Required filler ASP (0n = accept any) */\n requiredFillerAspId?: bigint\n /** Number of blocks until expiry (from current block) */\n expiryBlocks: bigint\n}\n\n/**\n * Parameters to fill a swap order\n */\nexport interface SwapFillParams {\n /** The order to fill */\n orderId: Hex\n /** How much sellToken the filler wants (≤ remaining) */\n takeAmount: bigint\n}\n\n/**\n * Swap order from event log\n */\nexport interface SwapOrderEvent {\n orderId: Hex\n sellToken: Address\n buyToken: Address\n sellAmount: bigint\n rate: bigint\n makerAspId: bigint\n requiredFillerAspId: bigint\n expiry: bigint\n blockNumber: bigint\n /** On-chain remaining sell amount (populated by useSwapOrderBook) */\n remainingSellAmount?: bigint\n /** Whether the order has been claimed */\n claimed?: boolean\n /** Whether the order has been cancelled */\n cancelled?: boolean\n}\n\n/**\n * Swap fill from event log\n */\nexport interface SwapFillEvent {\n orderId: Hex\n fillerNullifier: Hex\n takeAmount: bigint\n giveAmount: bigint\n fillerAspId: bigint\n blockNumber: bigint\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** 1e18 fixed-point precision for swap rates */\nexport const RATE_PRECISION = 10n ** 18n\n\n// ============================================================================\n// Event ABIs (for indexing swap events)\n// ============================================================================\n\nexport const SWAP_ORDER_PLACED_EVENT = {\n type: 'event',\n name: 'SwapOrderPlaced',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'sellToken', type: 'address', indexed: true },\n { name: 'buyToken', type: 'address', indexed: true },\n { name: 'sellAmount', type: 'uint256', indexed: false },\n { name: 'rate', type: 'uint256', indexed: false },\n { name: 'makerAspId', type: 'uint256', indexed: false },\n { name: 'requiredFillerAspId', type: 'uint256', indexed: false },\n { name: 'expiry', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_FILLED_EVENT = {\n type: 'event',\n name: 'SwapOrderFilled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'fillerNullifier', type: 'bytes32', indexed: true },\n { name: 'takeAmount', type: 'uint256', indexed: false },\n { name: 'giveAmount', type: 'uint256', indexed: false },\n { name: 'fillerAspId', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CLAIMED_EVENT = {\n type: 'event',\n name: 'SwapOrderClaimed',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'accumulatedBuyAmount', type: 'uint256', indexed: false },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CANCELLED_EVENT = {\n type: 'event',\n name: 'SwapOrderCancelled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_EVENTS_ABI = [\n SWAP_ORDER_PLACED_EVENT,\n SWAP_ORDER_FILLED_EVENT,\n SWAP_ORDER_CLAIMED_EVENT,\n SWAP_ORDER_CANCELLED_EVENT,\n] as const\n\n// ============================================================================\n// Rate Calculations\n// ============================================================================\n\n/**\n * Compute the giveAmount (buyToken) for a given takeAmount (sellToken) at a rate.\n * giveAmount = (takeAmount * rate) / 1e18\n */\nexport function computeGiveAmount(takeAmount: bigint, rate: bigint): bigint {\n return (takeAmount * rate) / RATE_PRECISION\n}\n\n/**\n * Compute the maximum takeAmount for a given giveAmount and rate.\n * takeAmount = (giveAmount * 1e18) / rate\n */\nexport function computeTakeAmount(giveAmount: bigint, rate: bigint): bigint {\n if (rate === 0n) throw new Error('Rate cannot be zero')\n return (giveAmount * RATE_PRECISION) / rate\n}\n\n/**\n * Compute rate from a desired trade: I want `buyAmount` of buyToken for `sellAmount` of sellToken.\n * rate = (buyAmount * 1e18) / sellAmount\n */\nexport function computeRate(sellAmount: bigint, buyAmount: bigint): bigint {\n if (sellAmount === 0n) throw new Error('Sell amount cannot be zero')\n return (buyAmount * RATE_PRECISION) / sellAmount\n}\n\n/**\n * Format a rate for human display.\n * Returns a string like \"0.0005\" for rate = 500000000000000n (0.0005e18)\n */\nexport function formatRate(rate: bigint, decimals: number = 6): string {\n const whole = rate / RATE_PRECISION\n const frac = rate % RATE_PRECISION\n const fracStr = frac.toString().padStart(18, '0').slice(0, decimals)\n return `${whole}.${fracStr}`\n}\n\n// ============================================================================\n// Cancel Key Management\n// ============================================================================\n\n/**\n * Generate a cancel key hash from a secret.\n * The secret should be a random 32-byte value stored by the maker.\n */\nexport function computeCancelKeyHash(cancelSecret: Hex): Hex {\n return keccak256(encodeAbiParameters(\n parseAbiParameters('bytes32'),\n [cancelSecret]\n ))\n}\n\n/**\n * Generate a random cancel secret.\n */\nexport function generateCancelSecret(): Hex {\n const bytes = new Uint8Array(32)\n crypto.getRandomValues(bytes)\n return toHex(bytes)\n}\n\n// ============================================================================\n// Order Filtering\n// ============================================================================\n\n/**\n * Filter orders by ASP: only show orders from makers on acceptable ASPs.\n */\nexport function filterOrdersByASP(\n orders: SwapOrderEvent[],\n acceptableAspIds: bigint[]\n): SwapOrderEvent[] {\n const aspSet = new Set(acceptableAspIds.map(id => id.toString()))\n return orders.filter(o => aspSet.has(o.makerAspId.toString()))\n}\n\n/**\n * Filter orders by token pair.\n */\nexport function filterOrdersByTokenPair(\n orders: SwapOrderEvent[],\n sellToken: Address,\n buyToken: Address\n): SwapOrderEvent[] {\n const sell = sellToken.toLowerCase()\n const buy = buyToken.toLowerCase()\n return orders.filter(\n o => o.sellToken.toLowerCase() === sell && o.buyToken.toLowerCase() === buy\n )\n}\n\n/**\n * Check if a filler's ASP is accepted by an order.\n */\nexport function isFillerASPAccepted(order: SwapOrder | SwapOrderEvent, fillerAspId: bigint): boolean {\n const required = 'requiredFillerAspId' in order ? order.requiredFillerAspId : 0n\n return required === 0n || required === fillerAspId\n}\n\n// ============================================================================\n// Cancel Secret Persistence (localStorage)\n// ============================================================================\n\nconst CANCEL_SECRET_PREFIX = 'upp_swap_cancel_'\n\nfunction cancelKey(account: string, orderId: Hex): string {\n return `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_${orderId}`\n}\n\n/**\n * Store a cancel secret in localStorage, scoped by wallet address.\n * Must be called after placing a swap order.\n */\nexport function storeCancelSecret(orderId: Hex, cancelSecret: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.setItem(cancelKey(account, orderId), cancelSecret)\n }\n // Also store unscoped for backward compat\n localStorage.setItem(`${CANCEL_SECRET_PREFIX}${orderId}`, cancelSecret)\n}\n\n/**\n * Retrieve a cancel secret from localStorage.\n * Returns null if not found (e.g. order was placed by someone else).\n */\nexport function getCancelSecret(orderId: Hex, account?: string): Hex | null {\n if (typeof localStorage === 'undefined') return null\n if (account) {\n const scoped = localStorage.getItem(cancelKey(account, orderId))\n if (scoped) return scoped as Hex\n }\n // Fall back to unscoped key\n return localStorage.getItem(`${CANCEL_SECRET_PREFIX}${orderId}`) as Hex | null\n}\n\n/**\n * Remove a cancel secret from localStorage (after claim or cancel).\n */\nexport function removeCancelSecret(orderId: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.removeItem(cancelKey(account, orderId))\n }\n localStorage.removeItem(`${CANCEL_SECRET_PREFIX}${orderId}`)\n}\n\n/**\n * Get all order IDs for a specific wallet address.\n * Falls back to all cancel secrets if no account provided (backward compat).\n */\nexport function getOwnOrderIds(account?: string): Hex[] {\n if (typeof localStorage === 'undefined') return []\n const prefix = account\n ? `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_`\n : CANCEL_SECRET_PREFIX\n const ids: Hex[] = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(prefix)) {\n ids.push(key.slice(prefix.length) as Hex)\n }\n }\n return ids\n}\n\n// ============================================================================\n// Order Status Helpers\n// ============================================================================\n\n/**\n * Check if an order is still active (not claimed, not cancelled, not expired).\n */\nexport function isOrderActive(order: SwapOrder, currentBlock: bigint): boolean {\n return !order.claimed && !order.cancelled && currentBlock <= order.expiry && order.remainingSellAmount > 0n\n}\n\n/**\n * Compute the total buyToken amount the maker would receive for a full fill.\n */\nexport function computeTotalBuyAmount(sellAmount: bigint, rate: bigint): bigint {\n return computeGiveAmount(sellAmount, rate)\n}\n\n/**\n * Compute fill percentage (0-100) for display.\n */\nexport function computeFillPercentage(order: SwapOrder): number {\n if (order.sellAmount === 0n) return 0\n const filled = order.sellAmount - order.remainingSellAmount\n return Number((filled * 10000n) / order.sellAmount) / 100\n}\n","/**\n * Account Adapter — Pluggable account creation and persistence\n *\n * Abstracts how master keys are derived/loaded/stored.\n * The SDK doesn't care if keys come from a wallet signature,\n * seed phrase, hardware wallet, or external KMS.\n *\n * Persistence is handled via StorageAdapter (IndexedDB, localStorage, etc.)\n */\n\nimport type { MasterKeys, StarkMasterKeys } from '../keys/types.js'\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { toHex } from 'viem'\n\n// ============================================================================\n// Interface\n// ============================================================================\n\n/**\n * Account adapter interface — pluggable key source.\n *\n * Implement this to bring your own key derivation:\n * - StorableAccountAdapter: persists keys via StorageAdapter (built-in)\n * - DirectAccountAdapter: pre-derived keys, no persistence (built-in, for testing)\n * - Custom: seed phrase, hardware wallet, external KMS\n */\nexport interface IAccountAdapter {\n /** Load persisted keys (returns null if no saved account) */\n load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null>\n /** Save keys to storage */\n save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void>\n /** Clear persisted keys */\n clear(): Promise<void>\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\ninterface SerializedAccount {\n version: 3\n spendingSecret: string\n ownerHash: string\n viewingSecret: string\n viewingHash: string\n starkSecret?: string[]\n starkOwnerHash?: string[]\n starkViewingSecret?: string[]\n starkViewingHash?: string[]\n}\n\nfunction serializeAccount(keys: MasterKeys, starkKeys?: StarkMasterKeys): SerializedAccount {\n return {\n version: 3,\n spendingSecret: toHex(keys.spendingSecret, { size: 32 }),\n ownerHash: toHex(keys.ownerHash, { size: 32 }),\n viewingSecret: toHex(keys.viewingSecret, { size: 32 }),\n viewingHash: toHex(keys.viewingHash, { size: 32 }),\n ...(starkKeys ? {\n starkSecret: starkKeys.starkSecret.map(v => v.toString()),\n starkOwnerHash: starkKeys.starkOwnerHash.map(v => v.toString()),\n starkViewingSecret: starkKeys.starkViewingSecret.map(v => v.toString()),\n starkViewingHash: starkKeys.starkViewingHash.map(v => v.toString()),\n } : {}),\n }\n}\n\nfunction deserializeAccount(data: SerializedAccount): { keys: MasterKeys; starkKeys?: StarkMasterKeys } {\n if (data.version !== 3 || !data.spendingSecret) {\n throw new Error('Invalid or outdated account data')\n }\n\n const keys: MasterKeys = {\n spendingSecret: BigInt(data.spendingSecret),\n ownerHash: BigInt(data.ownerHash),\n viewingSecret: BigInt(data.viewingSecret),\n viewingHash: BigInt(data.viewingHash),\n }\n\n let starkKeys: StarkMasterKeys | undefined\n if (data.starkSecret) {\n starkKeys = {\n starkSecret: data.starkSecret.map(s => BigInt(s)) as any,\n starkOwnerHash: data.starkOwnerHash!.map(s => BigInt(s)) as any,\n starkViewingSecret: data.starkViewingSecret!.map(s => BigInt(s)) as any,\n starkViewingHash: data.starkViewingHash!.map(s => BigInt(s)) as any,\n }\n }\n\n return { keys, starkKeys }\n}\n\n// ============================================================================\n// StorableAccountAdapter — persists via StorageAdapter\n// ============================================================================\n\n/**\n * Account adapter that persists keys via a pluggable StorageAdapter.\n *\n * Works with IndexedDB, localStorage, memory, Redis, Postgres — anything\n * that implements StorageAdapter.\n *\n * @example\n * ```ts\n * const storage = createAutoAdapter('upp_account')\n * const adapter = new StorableAccountAdapter(storage, ethAddress)\n * const saved = await adapter.load()\n * if (!saved) {\n * const keys = await deriveKeysFromSignature(sig)\n * await adapter.save(keys, starkKeys)\n * }\n * ```\n */\nexport class StorableAccountAdapter implements IAccountAdapter {\n private storageKey: string\n\n constructor(\n private storage: StorageAdapter,\n ethAddress: string,\n ) {\n this.storageKey = `account_${ethAddress.toLowerCase()}`\n }\n\n async load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null> {\n const data = await this.storage.get<SerializedAccount>(this.storageKey)\n if (!data) return null\n try {\n return deserializeAccount(data)\n } catch {\n // Corrupt or outdated — clear it\n await this.storage.delete(this.storageKey)\n return null\n }\n }\n\n async save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void> {\n const serialized = serializeAccount(keys, starkKeys)\n await this.storage.set(this.storageKey, serialized)\n }\n\n async clear(): Promise<void> {\n await this.storage.delete(this.storageKey)\n }\n}\n\n// ============================================================================\n// DirectAccountAdapter — no persistence (testing, KMS)\n// ============================================================================\n\n/**\n * Direct account adapter — accepts pre-derived keys, no persistence.\n *\n * @example\n * ```ts\n * const adapter = new DirectAccountAdapter(masterKeys, starkKeys)\n * ```\n */\nexport class DirectAccountAdapter implements IAccountAdapter {\n constructor(\n private keys: MasterKeys,\n private starkKeys?: StarkMasterKeys,\n ) {}\n\n async load() {\n return { keys: this.keys, starkKeys: this.starkKeys }\n }\n\n async save(): Promise<void> {\n // No-op — keys are in memory only\n }\n\n async clear(): Promise<void> {\n // No-op\n }\n}\n","/**\n * NoteStore — Single source of truth for note state\n *\n * Framework-agnostic. Uses StorageAdapter for persistence.\n * Handles deduplication, status management, balance calculation.\n *\n * Usage:\n * const store = new NoteStore(createMemoryAdapter())\n * await store.load()\n * store.addNote(note) // returns false if duplicate\n * store.getBalance() // sum of unspent notes\n */\n\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { getAddress } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type NoteStatus = 'pending' | 'confirmed' | 'spent'\nexport type ProofSystem = 'snark' | 'stark'\n\nexport interface ShieldedNote {\n amount: bigint\n blinding: bigint\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\n/** Serialized format for storage (bigints as strings) */\ninterface SerializedNote {\n amount: string\n blinding: string\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\nexport interface INoteStore {\n getNotes(): ShieldedNote[]\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[]\n getBalance(token?: string, proofSystem?: ProofSystem): bigint\n addNote(note: ShieldedNote): boolean\n addNotes(notes: ShieldedNote[]): number\n markSpent(commitment: string): void\n unmarkSpent(commitment: string): void\n updateLeafIndex(commitment: string, leafIndex: number): void\n load(): Promise<void>\n persist(): Promise<void>\n clear(): Promise<void>\n onChange(callback: () => void): () => void\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport class NoteStore implements INoteStore {\n private notes: ShieldedNote[] = []\n private commitmentSet = new Set<string>()\n private listeners = new Set<() => void>()\n private dirty = false\n\n constructor(\n private storage: StorageAdapter,\n private storageKey: string = 'notes',\n ) {}\n\n // ---------- Queries ----------\n\n getNotes(): ShieldedNote[] {\n return [...this.notes]\n }\n\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[] {\n let result = this.notes.filter(n => n.status !== 'spent')\n if (proofSystem) {\n result = result.filter(n => (n.proofSystem ?? 'snark') === proofSystem)\n }\n return result\n }\n\n getBalance(token?: string, proofSystem?: ProofSystem): bigint {\n let notes = this.getUnspentNotes(proofSystem)\n if (token) {\n const normalized = token.toLowerCase()\n notes = notes.filter(n => n.token.toLowerCase() === normalized)\n }\n return notes.reduce((sum, n) => sum + n.amount, 0n)\n }\n\n // ---------- Mutations ----------\n\n /**\n * Add a note. Returns false if duplicate (by commitment).\n * Normalizes token and origin addresses.\n */\n addNote(note: ShieldedNote): boolean {\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) return false\n\n // Normalize addresses\n const normalized: ShieldedNote = {\n ...note,\n commitment: note.commitment.toLowerCase(),\n origin: safeGetAddress(note.origin),\n token: safeGetAddress(note.token),\n }\n\n this.notes.push(normalized)\n this.commitmentSet.add(key)\n this.dirty = true\n this.notify()\n return true\n }\n\n /**\n * Add multiple notes. Returns count of actually added (non-duplicate).\n */\n addNotes(notes: ShieldedNote[]): number {\n let added = 0\n for (const note of notes) {\n if (this.addNote(note)) added++\n }\n return added\n }\n\n /**\n * Mark a note as spent (optimistic — syncNotes reconciles via nullifier check).\n */\n markSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status !== 'spent') {\n note.status = 'spent'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Un-mark a note as spent (reconciliation: nullifier not found on-chain).\n */\n unmarkSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status === 'spent') {\n note.status = 'confirmed'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Update the leafIndex for a note (e.g., after confirming on-chain).\n */\n updateLeafIndex(commitment: string, leafIndex: number): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.leafIndex !== leafIndex) {\n note.leafIndex = leafIndex\n this.dirty = true\n this.notify()\n }\n }\n\n // ---------- Persistence ----------\n\n async load(): Promise<void> {\n const serialized = await this.storage.get<SerializedNote[]>(this.storageKey)\n if (!serialized || !Array.isArray(serialized)) {\n this.notes = []\n this.commitmentSet.clear()\n return\n }\n\n // Deduplicate on load — prevents persisted duplicates from propagating\n this.notes = []\n this.commitmentSet.clear()\n let deduped = 0\n for (const s of serialized) {\n const note = deserializeNote(s)\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) { deduped++; continue }\n this.commitmentSet.add(key)\n this.notes.push(note)\n }\n if (deduped > 0) {\n console.log(`[NoteStore] Removed ${deduped} duplicate notes on load`)\n this.dirty = true // will persist the cleaned version\n } else {\n this.dirty = false\n }\n }\n\n async persist(): Promise<void> {\n if (!this.dirty) return\n const serialized = this.notes.map(serializeNote)\n await this.storage.set(this.storageKey, serialized)\n this.dirty = false\n }\n\n async clear(): Promise<void> {\n this.notes = []\n this.commitmentSet.clear()\n this.dirty = false\n await this.storage.delete(this.storageKey)\n this.notify()\n }\n\n // ---------- Events ----------\n\n onChange(callback: () => void): () => void {\n this.listeners.add(callback)\n return () => this.listeners.delete(callback)\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener()\n }\n }\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\nfunction serializeNote(note: ShieldedNote): SerializedNote {\n return {\n ...note,\n amount: note.amount.toString(),\n blinding: note.blinding.toString(),\n }\n}\n\nfunction deserializeNote(s: SerializedNote): ShieldedNote {\n return {\n ...s,\n amount: BigInt(s.amount),\n blinding: BigInt(s.blinding),\n proofSystem: s.proofSystem ?? 'snark',\n }\n}\n\nfunction safeGetAddress(addr: string): string {\n try {\n return getAddress(addr)\n } catch {\n return addr // return as-is if not a valid address (e.g., bigint-encoded origin)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/stealth.ts","../src/core/swap.ts","../src/core/account.ts","../src/core/note-store.ts"],"names":["__export","ADDRESS_VERSION","STARK_ADDRESS_VERSION","STARK_STEALTH_ADDRESS_PREFIX","STEALTH_ADDRESS_PREFIX","bigintToBytes","bech32m","bytesToBigint","ownerHash","randomFieldElement","__esm","init_crypto","keccak256","encodeAbiParameters","parseAbiParameters","toHex","getAddress"],"mappings":"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","file":"chunk-23B5XSS4.cjs","sourcesContent":["/**\n * Stealth Address Utilities (Post-Quantum, Hash-Based)\n *\n * Implements stealth addresses using Poseidon hashes with bech32m encoding.\n * No BabyJubJub curve operations — ownership is proven via hash preimage.\n *\n * Address Format (bech32m):\n * 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * Key Flow (self-shield):\n * 1. User derives ownerHash = Poseidon(spendingSecret)\n * 2. Commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n * 3. Encrypt note with key derived from viewingSecret\n *\n * Key Flow (send to others, future):\n * 1. Decode recipient's stealth address (ownerHash, viewingHash)\n * 2. Generate per-note secret and derive ownerHash for the note\n * 3. Encrypt note so recipient's viewingSecret can decrypt\n */\n\nimport { bech32m } from 'bech32'\nimport {\n randomFieldElement,\n bigintToBytes,\n bytesToBigint,\n} from '../utils/crypto.js'\nimport type { MasterKeys, StarkMasterKeys, OneTimeKeys } from '../keys/types.js'\nimport type { M31Digest } from '../utils/keccak-m31.js'\n\n/**\n * Stealth address prefix\n */\nexport const STEALTH_ADDRESS_PREFIX = '0zk'\n\n/**\n * Address version (v2 = hash-based, post-quantum)\n */\nexport const ADDRESS_VERSION = 2\n\n/**\n * Maximum length for bech32m encoding\n */\nconst BECH32M_LIMIT = 1023\n\n/**\n * Encode a stealth address in bech32m format\n *\n * Format: 0zk1<version><chainId><ownerHash><viewingHash>\n *\n * @param ownerHash - Owner hash = Poseidon(spendingSecret)\n * @param viewingHash - Viewing hash = Poseidon(viewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n * @returns bech32m encoded stealth address\n */\nexport function encodeStealthAddress(\n ownerHash: bigint,\n viewingHash: bigint,\n chainId: number = 0\n): string {\n // Build data buffer: version (1 byte) + chainId (4 bytes) + 2 * 32 bytes = 69 bytes\n const data = new Uint8Array(1 + 4 + 32 * 2)\n let offset = 0\n\n // Version\n data[offset++] = ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash (32 bytes)\n const ownerBytes = bigintToBytes(ownerHash, 32)\n data.set(ownerBytes, offset)\n offset += 32\n\n // Viewing hash (32 bytes)\n const viewingBytes = bigintToBytes(viewingHash, 32)\n data.set(viewingBytes, offset)\n\n // Convert to 5-bit words for bech32m\n const words = bech32m.toWords(data)\n\n // Encode with prefix\n return bech32m.encode(STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a bech32m stealth address\n *\n * @param address - bech32m encoded stealth address\n * @returns Decoded hash values\n */\nexport function decodeStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: bigint\n viewingHash: bigint\n} {\n // Decode bech32m\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n // Verify prefix\n if (decoded.prefix !== STEALTH_ADDRESS_PREFIX) {\n throw new Error(`Invalid stealth address prefix: expected '${STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`)\n }\n\n // Convert from 5-bit words back to bytes\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n\n // Parse version\n let offset = 0\n const version = data[offset++]!\n\n if (version !== ADDRESS_VERSION) {\n throw new Error(`Unsupported address version: ${version}. Expected v${ADDRESS_VERSION} (hash-based).`)\n }\n\n // Parse chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Parse owner hash (32 bytes)\n const ownerHash = bytesToBigint(data.slice(offset, offset + 32))\n offset += 32\n\n // Parse viewing hash (32 bytes)\n const viewingHash = bytesToBigint(data.slice(offset, offset + 32))\n\n return {\n version,\n chainId,\n ownerHash,\n viewingHash,\n }\n}\n\n/**\n * Validate a stealth address format\n */\nexport function isValidStealthAddress(address: string): boolean {\n try {\n decodeStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate stealth address from master keys\n */\nexport function generateStealthAddress(keys: MasterKeys, chainId: number = 0): string {\n return encodeStealthAddress(keys.ownerHash, keys.viewingHash, chainId)\n}\n\n/**\n * Create one-time keys for a transaction (hash-based)\n *\n * For self-shield: the user uses their own spendingSecret directly\n * as the ownerSecret, producing ownerHash = Poseidon(spendingSecret).\n *\n * For sending to others (future): generate a random oneTimeSecret\n * and derive ownerHash = Poseidon(oneTimeSecret).\n *\n * @param recipientOwnerHash - Recipient's owner hash (for verification)\n * @param selfSecret - If self-shield, the user's spending secret\n * @returns One-time keys for the note\n */\nexport async function createOneTimeKeys(\n _recipientOwnerHash?: bigint,\n selfSecret?: bigint,\n): Promise<OneTimeKeys> {\n const { poseidon } = await import('../utils/poseidon.js')\n\n if (selfSecret !== undefined) {\n // Self-shield: use own spending secret\n const ownerHash = await poseidon([selfSecret])\n return {\n oneTimeSecret: selfSecret,\n ownerHash,\n }\n }\n\n // Generate random one-time secret for the note\n const oneTimeSecret = randomFieldElement()\n const ownerHash = await poseidon([oneTimeSecret])\n\n return {\n oneTimeSecret,\n ownerHash,\n }\n}\n\n/**\n * Verify ownership of a note by checking hash preimage\n *\n * @param secret - Claimed spending secret\n * @param expectedOwnerHash - Owner hash from the note commitment\n * @returns True if the secret hashes to the expected owner hash\n */\nexport async function verifyOwnership(\n secret: bigint,\n expectedOwnerHash: bigint\n): Promise<boolean> {\n const { poseidon } = await import('../utils/poseidon.js')\n const computedHash = await poseidon([secret])\n return computedHash === expectedOwnerHash\n}\n\n/**\n * Compute shared secret for note encryption/decryption (hash-based)\n *\n * For self-shield: just uses the viewing secret directly.\n * For sending to others (future): use Poseidon(viewingSecret, recipientViewingHash)\n *\n * @param viewingSecret - Sender's or recipient's viewing secret\n * @param nonce - Optional nonce for key derivation\n * @returns Encryption key as bigint\n */\nexport async function computeNoteEncryptionKey(\n viewingSecret: bigint,\n nonce?: bigint\n): Promise<bigint> {\n const { poseidon } = await import('../utils/poseidon.js')\n if (nonce !== undefined) {\n return poseidon([viewingSecret, nonce])\n }\n return poseidon([viewingSecret])\n}\n\n// =========================================================================\n// STARK Stealth Addresses (0zs prefix, M31/Keccak-based)\n// =========================================================================\n\n/**\n * STARK stealth address prefix\n */\nexport const STARK_STEALTH_ADDRESS_PREFIX = '0zs'\n\n/**\n * STARK address version (v1 = M31/Keccak)\n */\nexport const STARK_ADDRESS_VERSION = 1\n\n/**\n * Encode a STARK stealth address in bech32m format\n *\n * Format: 0zs1<version><chainId><ownerHash[0..3]><viewingHash[0..3]>\n *\n * Each M31 element is encoded as 4 bytes (little-endian).\n * Total data: 1 (version) + 4 (chainId) + 16 (ownerHash) + 16 (viewingHash) = 37 bytes.\n *\n * @param ownerHash - 4 M31 elements: keccak_m31(starkSecret)\n * @param viewingHash - 4 M31 elements: keccak_m31(starkViewingSecret)\n * @param chainId - Optional chain ID (0 = any chain)\n */\nexport function encodeStarkStealthAddress(\n ownerHash: M31Digest,\n viewingHash: M31Digest,\n chainId: number = 0\n): string {\n const data = new Uint8Array(1 + 4 + 16 + 16) // 37 bytes\n let offset = 0\n\n // Version\n data[offset++] = STARK_ADDRESS_VERSION\n\n // Chain ID (4 bytes, big-endian)\n data[offset++] = (chainId >> 24) & 0xff\n data[offset++] = (chainId >> 16) & 0xff\n data[offset++] = (chainId >> 8) & 0xff\n data[offset++] = chainId & 0xff\n\n // Owner hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(ownerHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n // Viewing hash: 4 M31 elements, each 4 bytes LE\n for (let i = 0; i < 4; i++) {\n const val = Number(viewingHash[i]!)\n data[offset++] = val & 0xff\n data[offset++] = (val >> 8) & 0xff\n data[offset++] = (val >> 16) & 0xff\n data[offset++] = (val >> 24) & 0xff\n }\n\n const words = bech32m.toWords(data)\n return bech32m.encode(STARK_STEALTH_ADDRESS_PREFIX, words, BECH32M_LIMIT)\n}\n\n/**\n * Decode a STARK stealth address (0zs prefix)\n */\nexport function decodeStarkStealthAddress(address: string): {\n version: number\n chainId: number\n ownerHash: M31Digest\n viewingHash: M31Digest\n} {\n const decoded = bech32m.decode(address, BECH32M_LIMIT)\n\n if (decoded.prefix !== STARK_STEALTH_ADDRESS_PREFIX) {\n throw new Error(\n `Invalid STARK stealth address prefix: expected '${STARK_STEALTH_ADDRESS_PREFIX}', got '${decoded.prefix}'`\n )\n }\n\n const data = new Uint8Array(bech32m.fromWords(decoded.words))\n let offset = 0\n\n const version = data[offset++]!\n if (version !== STARK_ADDRESS_VERSION) {\n throw new Error(\n `Unsupported STARK address version: ${version}. Expected v${STARK_ADDRESS_VERSION}.`\n )\n }\n\n // Chain ID\n const chainId =\n (data[offset++]! << 24) |\n (data[offset++]! << 16) |\n (data[offset++]! << 8) |\n data[offset++]!\n\n // Owner hash: 4 M31 LE uint32s\n const ownerHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n ownerHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n // Viewing hash: 4 M31 LE uint32s\n const viewingHash: bigint[] = []\n for (let i = 0; i < 4; i++) {\n const val =\n data[offset]! |\n (data[offset + 1]! << 8) |\n (data[offset + 2]! << 16) |\n (data[offset + 3]! << 24)\n viewingHash.push(BigInt(val >>> 0))\n offset += 4\n }\n\n return {\n version,\n chainId,\n ownerHash: ownerHash as unknown as M31Digest,\n viewingHash: viewingHash as unknown as M31Digest,\n }\n}\n\n/**\n * Validate a STARK stealth address format\n */\nexport function isValidStarkStealthAddress(address: string): boolean {\n try {\n decodeStarkStealthAddress(address)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Generate a STARK stealth address from STARK master keys\n */\nexport function generateStarkStealthAddress(\n keys: StarkMasterKeys,\n chainId: number = 0\n): string {\n return encodeStarkStealthAddress(keys.starkOwnerHash, keys.starkViewingHash, chainId)\n}\n\n/**\n * Detect whether an address is SNARK (0zk) or STARK (0zs)\n */\nexport function detectAddressType(address: string): 'snark' | 'stark' | 'unknown' {\n if (address.startsWith(STEALTH_ADDRESS_PREFIX + '1')) return 'snark'\n if (address.startsWith(STARK_STEALTH_ADDRESS_PREFIX + '1')) return 'stark'\n return 'unknown'\n}\n","/**\n * Swap Module\n *\n * Core logic for building and interacting with the UPP in-pool swap order book.\n * Framework-agnostic (no React). Reuses withdraw verifier for proofs.\n */\n\nimport { type Address, type Hex, encodeAbiParameters, keccak256, parseAbiParameters, toHex } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Swap order as stored on-chain\n */\nexport interface SwapOrder {\n /** Order ID (= maker's nullifier) */\n orderId: Hex\n /** Token being sold */\n sellToken: Address\n /** Original total sell amount */\n sellAmount: bigint\n /** Remaining sell amount (decremented on each fill) */\n remainingSellAmount: bigint\n /** Token the maker wants to receive */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Accumulated buy token amount from fills */\n accumulatedBuyAmount: bigint\n /** Maker's ASP ID (public, filterable by takers) */\n makerAspId: bigint\n /** Required filler ASP (0 = any) */\n requiredFillerAspId: bigint\n /** Block number after which order expires */\n expiry: bigint\n /** Whether the maker has claimed */\n claimed: boolean\n /** Whether the order was cancelled */\n cancelled: boolean\n}\n\n/**\n * Parameters to place a swap order\n */\nexport interface SwapOrderParams {\n /** Token to sell */\n sellToken: Address\n /** Amount to sell */\n sellAmount: bigint\n /** Token to buy */\n buyToken: Address\n /** Price: buyToken per sellToken (1e18 fixed-point) */\n rate: bigint\n /** Required filler ASP (0n = accept any) */\n requiredFillerAspId?: bigint\n /** Number of blocks until expiry (from current block) */\n expiryBlocks: bigint\n}\n\n/**\n * Parameters to fill a swap order\n */\nexport interface SwapFillParams {\n /** The order to fill */\n orderId: Hex\n /** How much sellToken the filler wants (≤ remaining) */\n takeAmount: bigint\n}\n\n/**\n * Swap order from event log\n */\nexport interface SwapOrderEvent {\n orderId: Hex\n sellToken: Address\n buyToken: Address\n sellAmount: bigint\n rate: bigint\n makerAspId: bigint\n requiredFillerAspId: bigint\n expiry: bigint\n blockNumber: bigint\n /** On-chain remaining sell amount (populated by useSwapOrderBook) */\n remainingSellAmount?: bigint\n /** Whether the order has been claimed */\n claimed?: boolean\n /** Whether the order has been cancelled */\n cancelled?: boolean\n}\n\n/**\n * Swap fill from event log\n */\nexport interface SwapFillEvent {\n orderId: Hex\n fillerNullifier: Hex\n takeAmount: bigint\n giveAmount: bigint\n fillerAspId: bigint\n blockNumber: bigint\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** 1e18 fixed-point precision for swap rates */\nexport const RATE_PRECISION = 10n ** 18n\n\n// ============================================================================\n// Event ABIs (for indexing swap events)\n// ============================================================================\n\nexport const SWAP_ORDER_PLACED_EVENT = {\n type: 'event',\n name: 'SwapOrderPlaced',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'sellToken', type: 'address', indexed: true },\n { name: 'buyToken', type: 'address', indexed: true },\n { name: 'sellAmount', type: 'uint256', indexed: false },\n { name: 'rate', type: 'uint256', indexed: false },\n { name: 'makerAspId', type: 'uint256', indexed: false },\n { name: 'requiredFillerAspId', type: 'uint256', indexed: false },\n { name: 'expiry', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_FILLED_EVENT = {\n type: 'event',\n name: 'SwapOrderFilled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'fillerNullifier', type: 'bytes32', indexed: true },\n { name: 'takeAmount', type: 'uint256', indexed: false },\n { name: 'giveAmount', type: 'uint256', indexed: false },\n { name: 'fillerAspId', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CLAIMED_EVENT = {\n type: 'event',\n name: 'SwapOrderClaimed',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'accumulatedBuyAmount', type: 'uint256', indexed: false },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_ORDER_CANCELLED_EVENT = {\n type: 'event',\n name: 'SwapOrderCancelled',\n inputs: [\n { name: 'orderId', type: 'bytes32', indexed: true },\n { name: 'refundedSellAmount', type: 'uint256', indexed: false },\n ],\n} as const\n\nexport const SWAP_EVENTS_ABI = [\n SWAP_ORDER_PLACED_EVENT,\n SWAP_ORDER_FILLED_EVENT,\n SWAP_ORDER_CLAIMED_EVENT,\n SWAP_ORDER_CANCELLED_EVENT,\n] as const\n\n// ============================================================================\n// Rate Calculations\n// ============================================================================\n\n/**\n * Compute the giveAmount (buyToken) for a given takeAmount (sellToken) at a rate.\n * giveAmount = (takeAmount * rate) / 1e18\n */\nexport function computeGiveAmount(takeAmount: bigint, rate: bigint): bigint {\n return (takeAmount * rate) / RATE_PRECISION\n}\n\n/**\n * Compute the maximum takeAmount for a given giveAmount and rate.\n * takeAmount = (giveAmount * 1e18) / rate\n */\nexport function computeTakeAmount(giveAmount: bigint, rate: bigint): bigint {\n if (rate === 0n) throw new Error('Rate cannot be zero')\n return (giveAmount * RATE_PRECISION) / rate\n}\n\n/**\n * Compute rate from a desired trade: I want `buyAmount` of buyToken for `sellAmount` of sellToken.\n * rate = (buyAmount * 1e18) / sellAmount\n */\nexport function computeRate(sellAmount: bigint, buyAmount: bigint): bigint {\n if (sellAmount === 0n) throw new Error('Sell amount cannot be zero')\n return (buyAmount * RATE_PRECISION) / sellAmount\n}\n\n/**\n * Format a rate for human display.\n * Returns a string like \"0.0005\" for rate = 500000000000000n (0.0005e18)\n */\nexport function formatRate(rate: bigint, decimals: number = 6): string {\n const whole = rate / RATE_PRECISION\n const frac = rate % RATE_PRECISION\n const fracStr = frac.toString().padStart(18, '0').slice(0, decimals)\n return `${whole}.${fracStr}`\n}\n\n// ============================================================================\n// Cancel Key Management\n// ============================================================================\n\n/**\n * Generate a cancel key hash from a secret.\n * The secret should be a random 32-byte value stored by the maker.\n */\nexport function computeCancelKeyHash(cancelSecret: Hex): Hex {\n return keccak256(encodeAbiParameters(\n parseAbiParameters('bytes32'),\n [cancelSecret]\n ))\n}\n\n/**\n * Generate a random cancel secret.\n */\nexport function generateCancelSecret(): Hex {\n const bytes = new Uint8Array(32)\n crypto.getRandomValues(bytes)\n return toHex(bytes)\n}\n\n// ============================================================================\n// Order Filtering\n// ============================================================================\n\n/**\n * Filter orders by ASP: only show orders from makers on acceptable ASPs.\n */\nexport function filterOrdersByASP(\n orders: SwapOrderEvent[],\n acceptableAspIds: bigint[]\n): SwapOrderEvent[] {\n const aspSet = new Set(acceptableAspIds.map(id => id.toString()))\n return orders.filter(o => aspSet.has(o.makerAspId.toString()))\n}\n\n/**\n * Filter orders by token pair.\n */\nexport function filterOrdersByTokenPair(\n orders: SwapOrderEvent[],\n sellToken: Address,\n buyToken: Address\n): SwapOrderEvent[] {\n const sell = sellToken.toLowerCase()\n const buy = buyToken.toLowerCase()\n return orders.filter(\n o => o.sellToken.toLowerCase() === sell && o.buyToken.toLowerCase() === buy\n )\n}\n\n/**\n * Check if a filler's ASP is accepted by an order.\n */\nexport function isFillerASPAccepted(order: SwapOrder | SwapOrderEvent, fillerAspId: bigint): boolean {\n const required = 'requiredFillerAspId' in order ? order.requiredFillerAspId : 0n\n return required === 0n || required === fillerAspId\n}\n\n// ============================================================================\n// Cancel Secret Persistence (localStorage)\n// ============================================================================\n\nconst CANCEL_SECRET_PREFIX = 'upp_swap_cancel_'\n\nfunction cancelKey(account: string, orderId: Hex): string {\n return `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_${orderId}`\n}\n\n/**\n * Store a cancel secret in localStorage, scoped by wallet address.\n * Must be called after placing a swap order.\n */\nexport function storeCancelSecret(orderId: Hex, cancelSecret: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.setItem(cancelKey(account, orderId), cancelSecret)\n }\n // Also store unscoped for backward compat\n localStorage.setItem(`${CANCEL_SECRET_PREFIX}${orderId}`, cancelSecret)\n}\n\n/**\n * Retrieve a cancel secret from localStorage.\n * Returns null if not found (e.g. order was placed by someone else).\n */\nexport function getCancelSecret(orderId: Hex, account?: string): Hex | null {\n if (typeof localStorage === 'undefined') return null\n if (account) {\n const scoped = localStorage.getItem(cancelKey(account, orderId))\n if (scoped) return scoped as Hex\n }\n // Fall back to unscoped key\n return localStorage.getItem(`${CANCEL_SECRET_PREFIX}${orderId}`) as Hex | null\n}\n\n/**\n * Remove a cancel secret from localStorage (after claim or cancel).\n */\nexport function removeCancelSecret(orderId: Hex, account?: string): void {\n if (typeof localStorage === 'undefined') return\n if (account) {\n localStorage.removeItem(cancelKey(account, orderId))\n }\n localStorage.removeItem(`${CANCEL_SECRET_PREFIX}${orderId}`)\n}\n\n/**\n * Get all order IDs for a specific wallet address.\n * Falls back to all cancel secrets if no account provided (backward compat).\n */\nexport function getOwnOrderIds(account?: string): Hex[] {\n if (typeof localStorage === 'undefined') return []\n const prefix = account\n ? `${CANCEL_SECRET_PREFIX}${account.toLowerCase()}_`\n : CANCEL_SECRET_PREFIX\n const ids: Hex[] = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(prefix)) {\n ids.push(key.slice(prefix.length) as Hex)\n }\n }\n return ids\n}\n\n// ============================================================================\n// Order Status Helpers\n// ============================================================================\n\n/**\n * Check if an order is still active (not claimed, not cancelled, not expired).\n */\nexport function isOrderActive(order: SwapOrder, currentBlock: bigint): boolean {\n return !order.claimed && !order.cancelled && currentBlock <= order.expiry && order.remainingSellAmount > 0n\n}\n\n/**\n * Compute the total buyToken amount the maker would receive for a full fill.\n */\nexport function computeTotalBuyAmount(sellAmount: bigint, rate: bigint): bigint {\n return computeGiveAmount(sellAmount, rate)\n}\n\n/**\n * Compute fill percentage (0-100) for display.\n */\nexport function computeFillPercentage(order: SwapOrder): number {\n if (order.sellAmount === 0n) return 0\n const filled = order.sellAmount - order.remainingSellAmount\n return Number((filled * 10000n) / order.sellAmount) / 100\n}\n","/**\n * Account Adapter — Pluggable account creation and persistence\n *\n * Abstracts how master keys are derived/loaded/stored.\n * The SDK doesn't care if keys come from a wallet signature,\n * seed phrase, hardware wallet, or external KMS.\n *\n * Persistence is handled via StorageAdapter (IndexedDB, localStorage, etc.)\n */\n\nimport type { MasterKeys, StarkMasterKeys } from '../keys/types.js'\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { toHex } from 'viem'\n\n// ============================================================================\n// Interface\n// ============================================================================\n\n/**\n * Account adapter interface — pluggable key source.\n *\n * Implement this to bring your own key derivation:\n * - StorableAccountAdapter: persists keys via StorageAdapter (built-in)\n * - DirectAccountAdapter: pre-derived keys, no persistence (built-in, for testing)\n * - Custom: seed phrase, hardware wallet, external KMS\n */\nexport interface IAccountAdapter {\n /** Load persisted keys (returns null if no saved account) */\n load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null>\n /** Save keys to storage */\n save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void>\n /** Clear persisted keys */\n clear(): Promise<void>\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\ninterface SerializedAccount {\n version: 3\n spendingSecret: string\n ownerHash: string\n viewingSecret: string\n viewingHash: string\n starkSecret?: string[]\n starkOwnerHash?: string[]\n starkViewingSecret?: string[]\n starkViewingHash?: string[]\n}\n\nfunction serializeAccount(keys: MasterKeys, starkKeys?: StarkMasterKeys): SerializedAccount {\n return {\n version: 3,\n spendingSecret: toHex(keys.spendingSecret, { size: 32 }),\n ownerHash: toHex(keys.ownerHash, { size: 32 }),\n viewingSecret: toHex(keys.viewingSecret, { size: 32 }),\n viewingHash: toHex(keys.viewingHash, { size: 32 }),\n ...(starkKeys ? {\n starkSecret: starkKeys.starkSecret.map(v => v.toString()),\n starkOwnerHash: starkKeys.starkOwnerHash.map(v => v.toString()),\n starkViewingSecret: starkKeys.starkViewingSecret.map(v => v.toString()),\n starkViewingHash: starkKeys.starkViewingHash.map(v => v.toString()),\n } : {}),\n }\n}\n\nfunction deserializeAccount(data: SerializedAccount): { keys: MasterKeys; starkKeys?: StarkMasterKeys } {\n if (data.version !== 3 || !data.spendingSecret) {\n throw new Error('Invalid or outdated account data')\n }\n\n const keys: MasterKeys = {\n spendingSecret: BigInt(data.spendingSecret),\n ownerHash: BigInt(data.ownerHash),\n viewingSecret: BigInt(data.viewingSecret),\n viewingHash: BigInt(data.viewingHash),\n }\n\n let starkKeys: StarkMasterKeys | undefined\n if (data.starkSecret) {\n starkKeys = {\n starkSecret: data.starkSecret.map(s => BigInt(s)) as any,\n starkOwnerHash: data.starkOwnerHash!.map(s => BigInt(s)) as any,\n starkViewingSecret: data.starkViewingSecret!.map(s => BigInt(s)) as any,\n starkViewingHash: data.starkViewingHash!.map(s => BigInt(s)) as any,\n }\n }\n\n return { keys, starkKeys }\n}\n\n// ============================================================================\n// StorableAccountAdapter — persists via StorageAdapter\n// ============================================================================\n\n/**\n * Account adapter that persists keys via a pluggable StorageAdapter.\n *\n * Works with IndexedDB, localStorage, memory, Redis, Postgres — anything\n * that implements StorageAdapter.\n *\n * @example\n * ```ts\n * const storage = createAutoAdapter('upp_account')\n * const adapter = new StorableAccountAdapter(storage, ethAddress)\n * const saved = await adapter.load()\n * if (!saved) {\n * const keys = await deriveKeysFromSignature(sig)\n * await adapter.save(keys, starkKeys)\n * }\n * ```\n */\nexport class StorableAccountAdapter implements IAccountAdapter {\n private storageKey: string\n\n constructor(\n private storage: StorageAdapter,\n ethAddress: string,\n ) {\n this.storageKey = `account_${ethAddress.toLowerCase()}`\n }\n\n async load(): Promise<{ keys: MasterKeys; starkKeys?: StarkMasterKeys } | null> {\n const data = await this.storage.get<SerializedAccount>(this.storageKey)\n if (!data) return null\n try {\n return deserializeAccount(data)\n } catch {\n // Corrupt or outdated — clear it\n await this.storage.delete(this.storageKey)\n return null\n }\n }\n\n async save(keys: MasterKeys, starkKeys?: StarkMasterKeys): Promise<void> {\n const serialized = serializeAccount(keys, starkKeys)\n await this.storage.set(this.storageKey, serialized)\n }\n\n async clear(): Promise<void> {\n await this.storage.delete(this.storageKey)\n }\n}\n\n// ============================================================================\n// DirectAccountAdapter — no persistence (testing, KMS)\n// ============================================================================\n\n/**\n * Direct account adapter — accepts pre-derived keys, no persistence.\n *\n * @example\n * ```ts\n * const adapter = new DirectAccountAdapter(masterKeys, starkKeys)\n * ```\n */\nexport class DirectAccountAdapter implements IAccountAdapter {\n constructor(\n private keys: MasterKeys,\n private starkKeys?: StarkMasterKeys,\n ) {}\n\n async load() {\n return { keys: this.keys, starkKeys: this.starkKeys }\n }\n\n async save(): Promise<void> {\n // No-op — keys are in memory only\n }\n\n async clear(): Promise<void> {\n // No-op\n }\n}\n","/**\n * NoteStore — Single source of truth for note state\n *\n * Framework-agnostic. Uses StorageAdapter for persistence.\n * Handles deduplication, status management, balance calculation.\n *\n * Usage:\n * const store = new NoteStore(createMemoryAdapter())\n * await store.load()\n * store.addNote(note) // returns false if duplicate\n * store.getBalance() // sum of unspent notes\n */\n\nimport type { StorageAdapter } from '../indexer/types.js'\nimport { getAddress } from 'viem'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type NoteStatus = 'pending' | 'confirmed' | 'spent'\nexport type ProofSystem = 'snark' | 'stark'\n\nexport interface ShieldedNote {\n amount: bigint\n blinding: bigint\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\n/** Serialized format for storage (bigints as strings) */\ninterface SerializedNote {\n amount: string\n blinding: string\n commitment: string\n ownerSecret: string\n ownerHash: string\n leafIndex: number\n origin: string\n token: string\n txHash?: string\n status: NoteStatus\n timestamp: number\n proofSystem?: ProofSystem\n}\n\nexport interface INoteStore {\n getNotes(): ShieldedNote[]\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[]\n getBalance(token?: string, proofSystem?: ProofSystem): bigint\n addNote(note: ShieldedNote): boolean\n addNotes(notes: ShieldedNote[]): number\n markSpent(commitment: string): void\n unmarkSpent(commitment: string): void\n updateLeafIndex(commitment: string, leafIndex: number): void\n load(): Promise<void>\n persist(): Promise<void>\n clear(): Promise<void>\n onChange(callback: () => void): () => void\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nexport class NoteStore implements INoteStore {\n private notes: ShieldedNote[] = []\n private commitmentSet = new Set<string>()\n private listeners = new Set<() => void>()\n private dirty = false\n\n constructor(\n private storage: StorageAdapter,\n private storageKey: string = 'notes',\n ) {}\n\n // ---------- Queries ----------\n\n getNotes(): ShieldedNote[] {\n return [...this.notes]\n }\n\n getUnspentNotes(proofSystem?: ProofSystem): ShieldedNote[] {\n let result = this.notes.filter(n => n.status !== 'spent')\n if (proofSystem) {\n result = result.filter(n => (n.proofSystem ?? 'snark') === proofSystem)\n }\n return result\n }\n\n getBalance(token?: string, proofSystem?: ProofSystem): bigint {\n let notes = this.getUnspentNotes(proofSystem)\n if (token) {\n const normalized = token.toLowerCase()\n notes = notes.filter(n => n.token.toLowerCase() === normalized)\n }\n return notes.reduce((sum, n) => sum + n.amount, 0n)\n }\n\n // ---------- Mutations ----------\n\n /**\n * Add a note. Returns false if duplicate (by commitment).\n * Normalizes token and origin addresses.\n */\n addNote(note: ShieldedNote): boolean {\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) return false\n\n // Normalize addresses\n const normalized: ShieldedNote = {\n ...note,\n commitment: note.commitment.toLowerCase(),\n origin: safeGetAddress(note.origin),\n token: safeGetAddress(note.token),\n }\n\n this.notes.push(normalized)\n this.commitmentSet.add(key)\n this.dirty = true\n this.notify()\n return true\n }\n\n /**\n * Add multiple notes. Returns count of actually added (non-duplicate).\n */\n addNotes(notes: ShieldedNote[]): number {\n let added = 0\n for (const note of notes) {\n if (this.addNote(note)) added++\n }\n return added\n }\n\n /**\n * Mark a note as spent (optimistic — syncNotes reconciles via nullifier check).\n */\n markSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status !== 'spent') {\n note.status = 'spent'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Un-mark a note as spent (reconciliation: nullifier not found on-chain).\n */\n unmarkSpent(commitment: string): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.status === 'spent') {\n note.status = 'confirmed'\n this.dirty = true\n this.notify()\n }\n }\n\n /**\n * Update the leafIndex for a note (e.g., after confirming on-chain).\n */\n updateLeafIndex(commitment: string, leafIndex: number): void {\n const key = commitment.toLowerCase()\n const note = this.notes.find(n => n.commitment.toLowerCase() === key)\n if (note && note.leafIndex !== leafIndex) {\n note.leafIndex = leafIndex\n this.dirty = true\n this.notify()\n }\n }\n\n // ---------- Persistence ----------\n\n async load(): Promise<void> {\n const serialized = await this.storage.get<SerializedNote[]>(this.storageKey)\n if (!serialized || !Array.isArray(serialized)) {\n this.notes = []\n this.commitmentSet.clear()\n return\n }\n\n // Deduplicate on load — prevents persisted duplicates from propagating\n this.notes = []\n this.commitmentSet.clear()\n let deduped = 0\n for (const s of serialized) {\n const note = deserializeNote(s)\n const key = note.commitment.toLowerCase()\n if (this.commitmentSet.has(key)) { deduped++; continue }\n this.commitmentSet.add(key)\n this.notes.push(note)\n }\n if (deduped > 0) {\n console.log(`[NoteStore] Removed ${deduped} duplicate notes on load`)\n this.dirty = true // will persist the cleaned version\n } else {\n this.dirty = false\n }\n }\n\n async persist(): Promise<void> {\n if (!this.dirty) return\n const serialized = this.notes.map(serializeNote)\n await this.storage.set(this.storageKey, serialized)\n this.dirty = false\n }\n\n async clear(): Promise<void> {\n this.notes = []\n this.commitmentSet.clear()\n this.dirty = false\n await this.storage.delete(this.storageKey)\n this.notify()\n }\n\n // ---------- Events ----------\n\n onChange(callback: () => void): () => void {\n this.listeners.add(callback)\n return () => this.listeners.delete(callback)\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener()\n }\n }\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\nfunction serializeNote(note: ShieldedNote): SerializedNote {\n return {\n ...note,\n amount: note.amount.toString(),\n blinding: note.blinding.toString(),\n }\n}\n\nfunction deserializeNote(s: SerializedNote): ShieldedNote {\n return {\n ...s,\n amount: BigInt(s.amount),\n blinding: BigInt(s.blinding),\n proofSystem: s.proofSystem ?? 'snark',\n }\n}\n\nfunction safeGetAddress(addr: string): string {\n try {\n return getAddress(addr)\n } catch {\n return addr // return as-is if not a valid address (e.g., bigint-encoded origin)\n }\n}\n"]}
|
|
@@ -58,18 +58,16 @@ async function generateUPPProof(circuitType, inputs, baseUrl = "/circuits/") {
|
|
|
58
58
|
const artifacts = getUPPCircuitArtifacts(circuitType, baseUrl);
|
|
59
59
|
if (circuitType === "transfer") {
|
|
60
60
|
const i = inputs;
|
|
61
|
-
console.log("[generateUPPProof] === CIRCUIT INPUTS ===");
|
|
61
|
+
console.log("[generateUPPProof] === PLONK CIRCUIT INPUTS ===");
|
|
62
62
|
console.log(` circuitType: ${circuitType}`);
|
|
63
63
|
console.log(` stateRoot: ${i.stateRoot}`);
|
|
64
64
|
console.log(` aspRoot: ${i.aspRoot}`);
|
|
65
65
|
console.log(` inputOrigin: ${i.inputOrigin}`);
|
|
66
|
-
console.log(` aspRoot === inputOrigin: ${i.aspRoot === i.inputOrigin}`);
|
|
67
66
|
console.log(` aspPathElements[0..2]: ${i.aspPathElements?.slice(0, 3).join(", ")}`);
|
|
68
|
-
console.log(` aspPathIndices[0..2]: ${i.aspPathIndices?.slice(0, 3).join(", ")}`);
|
|
69
67
|
console.log(` artifacts.wasm: ${artifacts.wasm}`);
|
|
70
68
|
console.log(` artifacts.zkey: ${artifacts.zkey}`);
|
|
71
69
|
}
|
|
72
|
-
const result = await snarkjs2.
|
|
70
|
+
const result = await snarkjs2.plonk.fullProve(inputs, artifacts.wasm, artifacts.zkey);
|
|
73
71
|
return {
|
|
74
72
|
proof: {
|
|
75
73
|
proof: result.proof,
|
|
@@ -96,13 +94,25 @@ async function generateStealthProof(circuit, inputs, baseUrl = "/circuits/") {
|
|
|
96
94
|
async function verifyProof(_circuitType, _proof) {
|
|
97
95
|
throw new Error("Not implemented");
|
|
98
96
|
}
|
|
97
|
+
async function formatPlonkProofForContract(proof) {
|
|
98
|
+
const snarkjs2 = await loadSnarkjs();
|
|
99
|
+
const calldata = await snarkjs2.plonk.exportSolidityCallData(
|
|
100
|
+
proof.proof,
|
|
101
|
+
proof.publicSignals
|
|
102
|
+
);
|
|
103
|
+
const [proofHex, signalsStr] = calldata.split(',["');
|
|
104
|
+
const signals = signalsStr ? signalsStr.replace('"]', "").split('","').map((s) => BigInt(s)) : proof.publicSignals.map((s) => BigInt(s));
|
|
105
|
+
return {
|
|
106
|
+
proofBytes: proofHex,
|
|
107
|
+
publicSignals: signals
|
|
108
|
+
};
|
|
109
|
+
}
|
|
99
110
|
function formatProofForContract(proof) {
|
|
100
111
|
const { pi_a, pi_b, pi_c } = proof.proof;
|
|
101
112
|
return {
|
|
102
113
|
a: [BigInt(pi_a[0]), BigInt(pi_a[1])],
|
|
103
114
|
b: [
|
|
104
115
|
[BigInt(pi_b[0][1]), BigInt(pi_b[0][0])],
|
|
105
|
-
// Note: reversed for Solidity
|
|
106
116
|
[BigInt(pi_b[1][1]), BigInt(pi_b[1][0])]
|
|
107
117
|
],
|
|
108
118
|
c: [BigInt(pi_c[0]), BigInt(pi_c[1])]
|
|
@@ -111,6 +121,7 @@ function formatProofForContract(proof) {
|
|
|
111
121
|
|
|
112
122
|
exports.ASP_TREE_DEPTH = ASP_TREE_DEPTH;
|
|
113
123
|
exports.STATE_TREE_DEPTH = STATE_TREE_DEPTH;
|
|
124
|
+
exports.formatPlonkProofForContract = formatPlonkProofForContract;
|
|
114
125
|
exports.formatProofForContract = formatProofForContract;
|
|
115
126
|
exports.generateProof = generateProof;
|
|
116
127
|
exports.generateStealthProof = generateStealthProof;
|
|
@@ -118,5 +129,5 @@ exports.generateUPPProof = generateUPPProof;
|
|
|
118
129
|
exports.getStealthCircuitArtifacts = getStealthCircuitArtifacts;
|
|
119
130
|
exports.getUPPCircuitArtifacts = getUPPCircuitArtifacts;
|
|
120
131
|
exports.verifyProof = verifyProof;
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
122
|
-
//# sourceMappingURL=chunk-
|
|
132
|
+
//# sourceMappingURL=chunk-2G22R7AJ.cjs.map
|
|
133
|
+
//# sourceMappingURL=chunk-2G22R7AJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/proof.ts"],"names":["snarkjs"],"mappings":"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","file":"chunk-2G22R7AJ.cjs","sourcesContent":["/**\n * ZK Proof Generation and Verification (BLS12-381 PLONK)\n *\n * Uses snarkjs for PLONK proof generation over the BLS12-381 curve.\n * PLONK provides a universal trusted setup (no per-circuit ceremony).\n */\n\nimport type { Proof } from './types.js'\n\n// Lazy-loaded snarkjs reference\nlet snarkjs: any = null\n\n/**\n * Load snarkjs dynamically\n */\nasync function loadSnarkjs(): Promise<any> {\n if (snarkjs) return snarkjs\n snarkjs = await import('snarkjs')\n return snarkjs\n}\n\n// ============================================================================\n// UPP Circuit Constants\n// ============================================================================\n\n/** State tree depth (32 levels = ~4B notes) */\nexport const STATE_TREE_DEPTH = 32\n\n/** ASP tree depth (20 levels = ~1M addresses) */\nexport const ASP_TREE_DEPTH = 20\n\n// ============================================================================\n// UPP Circuit Types\n// ============================================================================\n\n/**\n * Circuit types available in UPP (full protocol)\n */\nexport type UPPCircuitType = 'transfer' | 'merge' | 'withdraw' | 'joinsplit' | 'merge_transfer_2x2' | 'merge_transfer_4x2'\n\n/**\n * @deprecated Use UPPCircuitType instead\n */\nexport type CircuitType = 'shield' | 'transfer' | 'merge' | 'withdraw'\n\n/**\n * @deprecated Stealth circuits are being replaced by UPP circuits\n */\nexport type StealthCircuitType = '1x2' | '2x2'\n\n/**\n * Input signals for UPP transfer circuit (1-in-2-out, BLS12-381 PLONK)\n *\n * Matches transfer.circom: Transfer(32, 20)\n * Public: stateRoot, aspRoot, nullifier, outputCommitment1, outputCommitment2, token\n *\n * Note: Uses hash-based ownership (ownerHash) instead of BabyJubJub pubkeys.\n */\nexport interface UPPTransferCircuitInputs {\n // Public inputs\n stateRoot: string\n aspRoot: string\n nullifier: string\n outputCommitment1: string\n outputCommitment2: string\n token: string\n\n // Private inputs - Input Note\n inputAmount: string\n inputOneTimeSecret: string\n inputBlinding: string\n inputOrigin: string\n inputLeafIndex: string\n inputPathElements: string[] // 32 elements\n inputPathIndices: string[] // 32 elements\n\n // Private inputs - ASP Membership Proof\n aspPathElements: string[] // 20 elements\n aspPathIndices: string[] // 20 elements\n\n // Private inputs - Output Notes (hash-based ownership)\n outputAmount1: string\n outputOwnerHash1: string\n outputBlinding1: string\n\n outputAmount2: string\n outputOwnerHash2: string\n outputBlinding2: string\n}\n\n/**\n * Input signals for UPP withdraw circuit (BLS12-381 PLONK)\n *\n * Matches withdraw.circom with optional ASP check (ragequit support)\n */\nexport interface UPPWithdrawCircuitInputs {\n // Public inputs\n stateRoot: string\n aspRoot: string\n nullifier: string\n amount: string\n recipient: string\n token: string\n isRagequit: string // '0' or '1'\n\n // Private inputs - Input Note\n inputAmount: string\n inputOneTimeSecret: string\n inputBlinding: string\n inputOrigin: string\n inputLeafIndex: string\n inputPathElements: string[] // 32 elements\n inputPathIndices: string[] // 32 elements\n\n // Private inputs - ASP Membership Proof (can be zeros if ragequit)\n aspPathElements: string[] // 20 elements\n aspPathIndices: string[] // 20 elements\n}\n\n/**\n * Input signals for UPP merge circuit (2-in-1-out, BLS12-381 PLONK)\n */\nexport interface UPPMergeCircuitInputs {\n // Public inputs\n stateRoot: string\n nullifier1: string\n nullifier2: string\n outputCommitment: string\n merger: string\n token: string\n\n // Private inputs - Input Note 1\n inputAmount1: string\n inputOneTimeSecret1: string\n inputBlinding1: string\n inputOrigin1: string\n inputLeafIndex1: string\n inputPathElements1: string[]\n inputPathIndices1: string[]\n\n // Private inputs - Input Note 2\n inputAmount2: string\n inputOneTimeSecret2: string\n inputBlinding2: string\n inputOrigin2: string\n inputLeafIndex2: string\n inputPathElements2: string[]\n inputPathIndices2: string[]\n\n // Private inputs - Output Note\n outputAmount: string\n outputOwnerHash: string\n outputBlinding: string\n}\n\n/**\n * Input signals for UPP joinsplit circuit (4-in-2-out, BLS12-381 PLONK)\n */\nexport interface UPPJoinSplitCircuitInputs {\n // Public inputs\n stateRoot: string\n aspRoot: string\n nullifier1: string\n nullifier2: string\n nullifier3: string\n nullifier4: string\n outputCommitment1: string\n outputCommitment2: string\n token: string\n\n // Private inputs - 4 Input Notes\n inputAmount1: string; inputOneTimeSecret1: string; inputBlinding1: string\n inputOrigin1: string; inputLeafIndex1: string\n inputPathElements1: string[]; inputPathIndices1: string[]\n\n inputAmount2: string; inputOneTimeSecret2: string; inputBlinding2: string\n inputOrigin2: string; inputLeafIndex2: string\n inputPathElements2: string[]; inputPathIndices2: string[]\n\n inputAmount3: string; inputOneTimeSecret3: string; inputBlinding3: string\n inputOrigin3: string; inputLeafIndex3: string\n inputPathElements3: string[]; inputPathIndices3: string[]\n\n inputAmount4: string; inputOneTimeSecret4: string; inputBlinding4: string\n inputOrigin4: string; inputLeafIndex4: string\n inputPathElements4: string[]; inputPathIndices4: string[]\n\n // Private inputs - ASP Membership Proof\n aspPathElements: string[]\n aspPathIndices: string[]\n\n // Private inputs - Output Notes\n outputAmount1: string; outputOwnerHash1: string; outputBlinding1: string\n outputAmount2: string; outputOwnerHash2: string; outputBlinding2: string\n}\n\n/**\n * @deprecated Use UPPTransferCircuitInputs instead\n */\nexport interface TransferCircuitInputs {\n stateRoot: bigint\n aspRoot: bigint\n nullifier: bigint\n outputCommitment1: bigint\n outputCommitment2: bigint\n token: bigint\n amount: bigint\n blinding: bigint\n origin: bigint\n statePathElements: bigint[]\n statePathIndices: bigint\n aspPathElements: bigint[]\n outAmount1: bigint\n outBlinding1: bigint\n outOrigin1: bigint\n outAmount2: bigint\n outBlinding2: bigint\n outOrigin2: bigint\n}\n\n/**\n * Input signals for shield circuit\n */\nexport interface ShieldCircuitInputs {\n commitment: bigint\n token: bigint\n amount: bigint\n blinding: bigint\n origin: bigint\n}\n\n/**\n * Input signals for merge circuit\n */\nexport interface MergeCircuitInputs {\n stateRoot: bigint\n nullifier1: bigint\n nullifier2: bigint\n outputCommitment: bigint\n newOrigin: bigint\n token: bigint\n amount1: bigint\n blinding1: bigint\n origin1: bigint\n token1: bigint\n pathElements1: bigint[]\n pathIndices1: bigint\n amount2: bigint\n blinding2: bigint\n origin2: bigint\n token2: bigint\n pathElements2: bigint[]\n pathIndices2: bigint\n outputAmount: bigint\n outputBlinding: bigint\n}\n\n/**\n * Input signals for withdraw circuit\n */\nexport interface WithdrawCircuitInputs {\n stateRoot: bigint\n aspRoot: bigint\n nullifier: bigint\n withdrawAmount: bigint\n recipient: bigint\n token: bigint\n isRagequit: bigint\n amount: bigint\n blinding: bigint\n origin: bigint\n statePathElements: bigint[]\n statePathIndices: bigint\n aspPathElements: bigint[]\n}\n\n/**\n * Circuit inputs union type\n */\nexport type CircuitInputs =\n | ShieldCircuitInputs\n | TransferCircuitInputs\n | MergeCircuitInputs\n | WithdrawCircuitInputs\n\n// ============================================================================\n// Stealth Circuit Types (deprecated)\n// ============================================================================\n\n/**\n * @deprecated\n */\nexport interface Stealth1x2CircuitInputs {\n root: string; nullifierHash: string; publicAmount: string\n recipient: string; extDataHash: string\n inputAmount: string; inputOneTimeSecret: string; inputBlinding: string\n inputLeafIndex: string; inputPathElements: string[]; inputPathIndices: string[]\n outputAmount1: string; outputPubkeyX1: string; outputPubkeyY1: string; outputBlinding1: string\n outputAmount2: string; outputPubkeyX2: string; outputPubkeyY2: string; outputBlinding2: string\n}\n\n/**\n * @deprecated\n */\nexport interface Stealth2x2CircuitInputs {\n root: string; nullifierHash1: string; nullifierHash2: string\n publicAmount: string; recipient: string; extDataHash: string\n inputAmount1: string; inputOneTimeSecret1: string; inputBlinding1: string\n inputLeafIndex1: string; inputPathElements1: string[]; inputPathIndices1: string[]\n inputAmount2: string; inputOneTimeSecret2: string; inputBlinding2: string\n inputLeafIndex2: string; inputPathElements2: string[]; inputPathIndices2: string[]\n outputAmount1: string; outputPubkeyX1: string; outputPubkeyY1: string; outputBlinding1: string\n outputAmount2: string; outputPubkeyX2: string; outputPubkeyY2: string; outputBlinding2: string\n}\n\n/** @deprecated */\nexport type StealthCircuitInputs = Stealth1x2CircuitInputs | Stealth2x2CircuitInputs\n\n/**\n * Circuit artifact paths\n */\nexport interface CircuitArtifacts {\n wasm: string\n zkey: string\n}\n\n/**\n * Get circuit artifacts for a UPP circuit\n *\n * @param circuit - UPP circuit type\n * @param baseUrl - Base URL for circuit files (default: '/circuits/')\n */\nexport function getUPPCircuitArtifacts(\n circuit: UPPCircuitType,\n baseUrl: string = '/circuits/'\n): CircuitArtifacts {\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`\n\n const circuitMap: Record<UPPCircuitType, CircuitArtifacts> = {\n transfer: {\n wasm: `${base}transfer.wasm`,\n zkey: `${base}transfer.zkey`,\n },\n merge: {\n wasm: `${base}merge.wasm`,\n zkey: `${base}merge.zkey`,\n },\n withdraw: {\n wasm: `${base}withdraw.wasm`,\n zkey: `${base}withdraw.zkey`,\n },\n joinsplit: {\n wasm: `${base}joinsplit.wasm`,\n zkey: `${base}joinsplit.zkey`,\n },\n merge_transfer_2x2: {\n wasm: `${base}merge_transfer_2x2.wasm`,\n zkey: `${base}merge_transfer_2x2.zkey`,\n },\n merge_transfer_4x2: {\n wasm: `${base}merge_transfer_4x2.wasm`,\n zkey: `${base}merge_transfer_4x2.zkey`,\n },\n }\n\n return circuitMap[circuit]\n}\n\n/**\n * @deprecated Use getUPPCircuitArtifacts instead\n */\nexport function getStealthCircuitArtifacts(\n circuit: StealthCircuitType,\n baseUrl: string = '/circuits/'\n): CircuitArtifacts {\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`\n\n const circuitMap: Record<StealthCircuitType, CircuitArtifacts> = {\n '1x2': {\n wasm: `${base}shielded_stealth.wasm`,\n zkey: `${base}shielded_stealth_final.zkey`,\n },\n '2x2': {\n wasm: `${base}stealth_2x2.wasm`,\n zkey: `${base}stealth_2x2_final.zkey`,\n },\n }\n\n return circuitMap[circuit]\n}\n\n/**\n * UPP circuit inputs union type\n */\nexport type UPPCircuitInputs =\n | UPPTransferCircuitInputs\n | UPPWithdrawCircuitInputs\n | UPPMergeCircuitInputs\n | UPPJoinSplitCircuitInputs\n\n/**\n * Generate a ZK proof for a UPP circuit (BLS12-381 PLONK)\n *\n * @param circuitType - Which UPP circuit to use\n * @param inputs - Circuit input signals\n * @param baseUrl - Base URL for circuit artifacts (default: '/circuits/')\n * @returns Generated proof and public signals\n *\n * @example\n * ```ts\n * const { proof, publicSignals } = await generateUPPProof('transfer', {\n * stateRoot: String(currentRoot),\n * aspRoot: String(aspRoot),\n * // ... other inputs\n * })\n * ```\n */\nexport async function generateUPPProof(\n circuitType: UPPCircuitType,\n inputs: UPPCircuitInputs,\n baseUrl: string = '/circuits/'\n): Promise<ProofResult> {\n const snarkjs = await loadSnarkjs()\n const artifacts = getUPPCircuitArtifacts(circuitType, baseUrl)\n\n // Debug: log key circuit inputs\n if (circuitType === 'transfer') {\n const i = inputs as UPPTransferCircuitInputs\n console.log('[generateUPPProof] === PLONK CIRCUIT INPUTS ===')\n console.log(` circuitType: ${circuitType}`)\n console.log(` stateRoot: ${i.stateRoot}`)\n console.log(` aspRoot: ${i.aspRoot}`)\n console.log(` inputOrigin: ${i.inputOrigin}`)\n console.log(` aspPathElements[0..2]: ${i.aspPathElements?.slice(0, 3).join(', ')}`)\n console.log(` artifacts.wasm: ${artifacts.wasm}`)\n console.log(` artifacts.zkey: ${artifacts.zkey}`)\n }\n\n // Use PLONK prover (not Groth16)\n const result = await snarkjs.plonk.fullProve(inputs, artifacts.wasm, artifacts.zkey)\n\n return {\n proof: {\n proof: result.proof,\n publicSignals: result.publicSignals,\n },\n publicSignals: result.publicSignals,\n }\n}\n\n/**\n * @deprecated Use generateUPPProof instead\n */\nexport async function generateProof(\n _circuitType: CircuitType,\n _inputs: CircuitInputs\n): Promise<Proof> {\n throw new Error('Deprecated: Use generateUPPProof instead')\n}\n\n/**\n * Result from proof generation\n */\nexport interface ProofResult {\n proof: Proof\n publicSignals: string[]\n}\n\n/**\n * @deprecated Stealth circuits use old Groth16 format\n */\nexport async function generateStealthProof(\n circuit: StealthCircuitType,\n inputs: StealthCircuitInputs,\n baseUrl: string = '/circuits/'\n): Promise<ProofResult> {\n const snarkjs = await loadSnarkjs()\n const artifacts = getStealthCircuitArtifacts(circuit, baseUrl)\n\n const result = await snarkjs.groth16.fullProve(inputs, artifacts.wasm, artifacts.zkey)\n\n return {\n proof: {\n proof: result.proof,\n publicSignals: result.publicSignals,\n },\n publicSignals: result.publicSignals,\n }\n}\n\n/**\n * Verify a ZK proof\n */\nexport async function verifyProof(\n _circuitType: CircuitType,\n _proof: Proof\n): Promise<boolean> {\n throw new Error('Not implemented')\n}\n\n/**\n * Format PLONK proof for on-chain verification\n *\n * PLONK proofs use a different format than Groth16:\n * - Groth16: uint256[8] (pi_a, pi_b, pi_c)\n * - PLONK: bytes (encoded proof with commitments and evaluations)\n *\n * Use snarkjs.plonk.exportSolidityCallData() for the exact encoding.\n */\nexport async function formatPlonkProofForContract(proof: Proof): Promise<{\n proofBytes: `0x${string}`\n publicSignals: bigint[]\n}> {\n const snarkjs = await loadSnarkjs()\n const calldata = await snarkjs.plonk.exportSolidityCallData(\n proof.proof,\n proof.publicSignals\n )\n\n // snarkjs returns a comma-separated string: \"0xproof,[sig1,sig2,...]\"\n const [proofHex, signalsStr] = calldata.split(',[\"')\n const signals = signalsStr\n ? signalsStr.replace('\"]', '').split('\",\"').map((s: string) => BigInt(s))\n : proof.publicSignals.map((s: string) => BigInt(s))\n\n return {\n proofBytes: proofHex as `0x${string}`,\n publicSignals: signals,\n }\n}\n\n/**\n * @deprecated Use formatPlonkProofForContract for PLONK proofs.\n *\n * Format Groth16 proof for on-chain verification (old format).\n */\nexport function formatProofForContract(proof: Proof): {\n a: [bigint, bigint]\n b: [[bigint, bigint], [bigint, bigint]]\n c: [bigint, bigint]\n} {\n const { pi_a, pi_b, pi_c } = proof.proof\n\n return {\n a: [BigInt(pi_a[0]), BigInt(pi_a[1])],\n b: [\n [BigInt(pi_b[0][1]), BigInt(pi_b[0][0])],\n [BigInt(pi_b[1][1]), BigInt(pi_b[1][0])],\n ],\n c: [BigInt(pi_c[0]), BigInt(pi_c[1])],\n }\n}\n"]}
|