@opaquecash/disclosure 0.2.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/context.d.ts +20 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +37 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/prove.d.ts +48 -0
- package/dist/prove.d.ts.map +1 -0
- package/dist/prove.js +58 -0
- package/dist/prove.js.map +1 -0
- package/dist/schnorr.d.ts +28 -0
- package/dist/schnorr.d.ts.map +1 -0
- package/dist/schnorr.js +55 -0
- package/dist/schnorr.js.map +1 -0
- package/dist/shamir.d.ts +28 -0
- package/dist/shamir.d.ts.map +1 -0
- package/dist/shamir.js +93 -0
- package/dist/shamir.js.map +1 -0
- package/dist/tx.d.ts +204 -0
- package/dist/tx.d.ts.map +1 -0
- package/dist/tx.js +195 -0
- package/dist/tx.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure request contexts — spec/conditional-disclosure.md §5.
|
|
3
|
+
* `context` commits the proof and the custodian quorum signature to one exact
|
|
4
|
+
* request (policy, case, requester). Each chain's registry recomputes it on-chain,
|
|
5
|
+
* so these MUST match the deployed encodings byte-for-byte.
|
|
6
|
+
*/
|
|
7
|
+
import { type Address, type Hex } from "viem";
|
|
8
|
+
export declare const FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
9
|
+
/** keccak256("opaque/disclosure/v1") mod r — the nullifier domain tag (spec §7). */
|
|
10
|
+
export declare const DOMAIN_DISCLOSURE = 2892858644728810973983554811705195156385130922452064297470708309156017996001n;
|
|
11
|
+
/** Ethereum: `uint256(keccak256(abi.encode(policyId, caseId, requester))) % r`. */
|
|
12
|
+
export declare function computeContextEvm(policyId: bigint, caseId: Hex, requester: Address): bigint;
|
|
13
|
+
/**
|
|
14
|
+
* Solana: `keccak256(policy_pda ‖ case_id ‖ requester)` with the top 3 bits
|
|
15
|
+
* cleared (< 2^253 < r), matching the program and the pool's scope/context style.
|
|
16
|
+
*/
|
|
17
|
+
export declare function computeContextSolana(policy: Uint8Array, caseId: Uint8Array, requester: Uint8Array): bigint;
|
|
18
|
+
/** The 32-byte big-endian message the custodian quorum FROST-signs. */
|
|
19
|
+
export declare function contextToMessage(context: bigint): Uint8Array;
|
|
20
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAkC,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAE9E,eAAO,MAAM,KAAK,iFAC8D,CAAC;AAEjF,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,gFACiD,CAAC;AAEhF,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAW3F;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,UAAU,GACpB,MAAM,CAWR;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAG5D"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure request contexts — spec/conditional-disclosure.md §5.
|
|
3
|
+
* `context` commits the proof and the custodian quorum signature to one exact
|
|
4
|
+
* request (policy, case, requester). Each chain's registry recomputes it on-chain,
|
|
5
|
+
* so these MUST match the deployed encodings byte-for-byte.
|
|
6
|
+
*/
|
|
7
|
+
import { encodeAbiParameters, keccak256 } from "viem";
|
|
8
|
+
export const FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
9
|
+
/** keccak256("opaque/disclosure/v1") mod r — the nullifier domain tag (spec §7). */
|
|
10
|
+
export const DOMAIN_DISCLOSURE = 2892858644728810973983554811705195156385130922452064297470708309156017996001n;
|
|
11
|
+
/** Ethereum: `uint256(keccak256(abi.encode(policyId, caseId, requester))) % r`. */
|
|
12
|
+
export function computeContextEvm(policyId, caseId, requester) {
|
|
13
|
+
return (BigInt(keccak256(encodeAbiParameters([{ type: "uint256" }, { type: "bytes32" }, { type: "address" }], [policyId, caseId, requester]))) % FIELD);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Solana: `keccak256(policy_pda ‖ case_id ‖ requester)` with the top 3 bits
|
|
17
|
+
* cleared (< 2^253 < r), matching the program and the pool's scope/context style.
|
|
18
|
+
*/
|
|
19
|
+
export function computeContextSolana(policy, caseId, requester) {
|
|
20
|
+
if (policy.length !== 32 || caseId.length !== 32 || requester.length !== 32) {
|
|
21
|
+
throw new Error("policy, caseId, and requester must each be 32 bytes");
|
|
22
|
+
}
|
|
23
|
+
const joined = new Uint8Array(96);
|
|
24
|
+
joined.set(policy, 0);
|
|
25
|
+
joined.set(caseId, 32);
|
|
26
|
+
joined.set(requester, 64);
|
|
27
|
+
const digest = Buffer.from(keccak256(joined).slice(2), "hex");
|
|
28
|
+
digest[0] &= 0x1f;
|
|
29
|
+
return BigInt("0x" + digest.toString("hex"));
|
|
30
|
+
}
|
|
31
|
+
/** The 32-byte big-endian message the custodian quorum FROST-signs. */
|
|
32
|
+
export function contextToMessage(context) {
|
|
33
|
+
if (context < 0n || context >= FIELD)
|
|
34
|
+
throw new Error("context out of field");
|
|
35
|
+
return Uint8Array.from(Buffer.from(context.toString(16).padStart(64, "0"), "hex"));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAA0B,MAAM,MAAM,CAAC;AAE9E,MAAM,CAAC,MAAM,KAAK,GAChB,8EAA8E,CAAC;AAEjF,oFAAoF;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAC5B,6EAA6E,CAAC;AAEhF,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAW,EAAE,SAAkB;IACjF,OAAO,CACL,MAAM,CACJ,SAAS,CACP,mBAAmB,CACjB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAC/D,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAC9B,CACF,CACF,GAAG,KAAK,CACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkB,EAClB,MAAkB,EAClB,SAAqB;IAErB,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtB,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9D,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAClB,OAAO,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC9E,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACrF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@opaquecash/disclosure` — conditional disclosure / threshold viewing keys
|
|
3
|
+
* (spec/conditional-disclosure.md).
|
|
4
|
+
*
|
|
5
|
+
* Two surfaces:
|
|
6
|
+
* - **Escrow backstop**: {@link splitViewingKey} / {@link recoverViewingKey} —
|
|
7
|
+
* Shamir shares of the CSAP viewing key. Reconstruction reveals the FULL key;
|
|
8
|
+
* recovery only.
|
|
9
|
+
* - **Active disclosure**: {@link buildDisclosureWitness} +
|
|
10
|
+
* {@link generateDisclosureProof} (pool-scoped Groth16 proof) gated by a
|
|
11
|
+
* custodian FROST quorum's BIP-340 signature ({@link verifyQuorumSignature})
|
|
12
|
+
* over the request {@link computeContextEvm | context}, submitted via
|
|
13
|
+
* {@link buildDiscloseTx} / {@link buildDiscloseIx}.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
export { splitViewingKey, recoverViewingKey, parseShare, SHARE_SCHEME, type ParsedShare, } from "./shamir.js";
|
|
18
|
+
export { FIELD, DOMAIN_DISCLOSURE, computeContextEvm, computeContextSolana, contextToMessage, } from "./context.js";
|
|
19
|
+
export { liftEvenY, parseBip340, parseFrostSignature, verifyQuorumSignature, type QuorumSignature, type FrostSignatureFile, } from "./schnorr.js";
|
|
20
|
+
export { disclosureNullifier, buildDisclosureWitness, generateDisclosureProof, POOL_LEVELS, type DisclosureArtifacts, type BuildDisclosureWitnessParams, type DisclosureWitness, type DisclosureProof, } from "./prove.js";
|
|
21
|
+
export { opaqueDisclosureRegistryAbi, buildRegisterPolicyTx, buildDiscloseTx, policyPda, disclosureNullifierPda, buildRegisterPolicyIx, buildDiscloseIx, toSolanaProof, toSolidityProof, type EvmTxRequest, type SolanaProofBytes, type SolidityProof, } from "./tx.js";
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@opaquecash/disclosure` — conditional disclosure / threshold viewing keys
|
|
3
|
+
* (spec/conditional-disclosure.md).
|
|
4
|
+
*
|
|
5
|
+
* Two surfaces:
|
|
6
|
+
* - **Escrow backstop**: {@link splitViewingKey} / {@link recoverViewingKey} —
|
|
7
|
+
* Shamir shares of the CSAP viewing key. Reconstruction reveals the FULL key;
|
|
8
|
+
* recovery only.
|
|
9
|
+
* - **Active disclosure**: {@link buildDisclosureWitness} +
|
|
10
|
+
* {@link generateDisclosureProof} (pool-scoped Groth16 proof) gated by a
|
|
11
|
+
* custodian FROST quorum's BIP-340 signature ({@link verifyQuorumSignature})
|
|
12
|
+
* over the request {@link computeContextEvm | context}, submitted via
|
|
13
|
+
* {@link buildDiscloseTx} / {@link buildDiscloseIx}.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
export { splitViewingKey, recoverViewingKey, parseShare, SHARE_SCHEME, } from "./shamir.js";
|
|
18
|
+
export { FIELD, DOMAIN_DISCLOSURE, computeContextEvm, computeContextSolana, contextToMessage, } from "./context.js";
|
|
19
|
+
export { liftEvenY, parseBip340, parseFrostSignature, verifyQuorumSignature, } from "./schnorr.js";
|
|
20
|
+
export { disclosureNullifier, buildDisclosureWitness, generateDisclosureProof, POOL_LEVELS, } from "./prove.js";
|
|
21
|
+
export { opaqueDisclosureRegistryAbi, buildRegisterPolicyTx, buildDiscloseTx, policyPda, disclosureNullifierPda, buildRegisterPolicyIx, buildDiscloseIx, toSolanaProof, toSolidityProof, } from "./tx.js";
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,YAAY,GAEb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,GAKZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,eAAe,GAIhB,MAAM,SAAS,CAAC"}
|
package/dist/prove.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure witness assembly + Groth16 proof generation
|
|
3
|
+
* (spec/conditional-disclosure.md §4). The witness binds a pool note's openings,
|
|
4
|
+
* its state-tree inclusion path, the policy threshold, and the request `context`.
|
|
5
|
+
* Public-signal order matches the circuit:
|
|
6
|
+
* value, label, threshold, state_root, disclosure_nullifier, context.
|
|
7
|
+
*/
|
|
8
|
+
import { POOL_LEVELS, type PoolCrypto, type CommitmentNote } from "@opaquecash/privacy-pool";
|
|
9
|
+
/** Paths/URLs to the conditional_disclosure circuit artifacts. */
|
|
10
|
+
export interface DisclosureArtifacts {
|
|
11
|
+
wasmPath: string;
|
|
12
|
+
zkeyPath: string;
|
|
13
|
+
}
|
|
14
|
+
export interface BuildDisclosureWitnessParams {
|
|
15
|
+
/** The note being disclosed (its openings stay private). */
|
|
16
|
+
note: CommitmentNote;
|
|
17
|
+
/** The policy's qualification threshold; note.value must exceed it. */
|
|
18
|
+
threshold: bigint;
|
|
19
|
+
/** Ordered state-tree leaves (all commitments) and the note's leaf index. */
|
|
20
|
+
stateLeaves: bigint[];
|
|
21
|
+
stateIndex: number;
|
|
22
|
+
/** The request context (computeContextEvm / computeContextSolana). */
|
|
23
|
+
context: bigint;
|
|
24
|
+
}
|
|
25
|
+
export interface DisclosureWitness {
|
|
26
|
+
input: Record<string, string | string[] | number[]>;
|
|
27
|
+
/** Public values submitted to `disclose` alongside the proof. */
|
|
28
|
+
publics: {
|
|
29
|
+
value: bigint;
|
|
30
|
+
label: bigint;
|
|
31
|
+
threshold: bigint;
|
|
32
|
+
stateRoot: bigint;
|
|
33
|
+
disclosureNullifier: bigint;
|
|
34
|
+
context: bigint;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** disclosure_nullifier = Poseidon(nullifier, context, DOMAIN_DISCLOSURE) (spec §7). */
|
|
38
|
+
export declare function disclosureNullifier(crypto: PoolCrypto, nullifier: bigint, context: bigint): bigint;
|
|
39
|
+
/** Assemble the circuit input + public values for an on-chain `disclose` call. */
|
|
40
|
+
export declare function buildDisclosureWitness(crypto: PoolCrypto, p: BuildDisclosureWitnessParams): DisclosureWitness;
|
|
41
|
+
export interface DisclosureProof {
|
|
42
|
+
proof: unknown;
|
|
43
|
+
publicSignals: string[];
|
|
44
|
+
}
|
|
45
|
+
/** Generate the Groth16 proof (snarkjs; Node paths or browser URLs). */
|
|
46
|
+
export declare function generateDisclosureProof(witness: DisclosureWitness, artifacts: DisclosureArtifacts): Promise<DisclosureProof>;
|
|
47
|
+
export { POOL_LEVELS };
|
|
48
|
+
//# sourceMappingURL=prove.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../src/prove.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAEL,WAAW,EACX,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAGlC,kEAAkE;AAClE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,4BAA4B;IAC3C,4DAA4D;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACpD,iEAAiE;IACjE,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,EAClB,CAAC,EAAE,4BAA4B,GAC9B,iBAAiB,CAyCnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wEAAwE;AACxE,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAO1B;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/prove.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure witness assembly + Groth16 proof generation
|
|
3
|
+
* (spec/conditional-disclosure.md §4). The witness binds a pool note's openings,
|
|
4
|
+
* its state-tree inclusion path, the policy threshold, and the request `context`.
|
|
5
|
+
* Public-signal order matches the circuit:
|
|
6
|
+
* value, label, threshold, state_root, disclosure_nullifier, context.
|
|
7
|
+
*/
|
|
8
|
+
// @ts-expect-error snarkjs is untyped
|
|
9
|
+
import * as snarkjs from "snarkjs";
|
|
10
|
+
import { PoolMerkleTree, POOL_LEVELS, } from "@opaquecash/privacy-pool";
|
|
11
|
+
import { DOMAIN_DISCLOSURE } from "./context.js";
|
|
12
|
+
/** disclosure_nullifier = Poseidon(nullifier, context, DOMAIN_DISCLOSURE) (spec §7). */
|
|
13
|
+
export function disclosureNullifier(crypto, nullifier, context) {
|
|
14
|
+
return crypto.hash([nullifier, context, DOMAIN_DISCLOSURE]);
|
|
15
|
+
}
|
|
16
|
+
/** Assemble the circuit input + public values for an on-chain `disclose` call. */
|
|
17
|
+
export function buildDisclosureWitness(crypto, p) {
|
|
18
|
+
if (p.note.value <= p.threshold) {
|
|
19
|
+
throw new Error(`note does not qualify: value ${p.note.value} <= threshold ${p.threshold} ` +
|
|
20
|
+
"(the circuit would be unsatisfiable)");
|
|
21
|
+
}
|
|
22
|
+
const commitment = crypto.commitment(p.note.value, p.note.label, crypto.precommitment(p.note.nullifier, p.note.secret));
|
|
23
|
+
if (p.stateLeaves[p.stateIndex] !== commitment) {
|
|
24
|
+
throw new Error("stateLeaves[stateIndex] is not the note's commitment");
|
|
25
|
+
}
|
|
26
|
+
const tree = new PoolMerkleTree(crypto, p.stateLeaves);
|
|
27
|
+
const path = tree.proof(p.stateIndex);
|
|
28
|
+
const nullifier = disclosureNullifier(crypto, p.note.nullifier, p.context);
|
|
29
|
+
return {
|
|
30
|
+
input: {
|
|
31
|
+
nullifier: p.note.nullifier.toString(),
|
|
32
|
+
secret: p.note.secret.toString(),
|
|
33
|
+
state_siblings: path.siblings.map(String),
|
|
34
|
+
state_index: path.pathIndices,
|
|
35
|
+
value: p.note.value.toString(),
|
|
36
|
+
label: p.note.label.toString(),
|
|
37
|
+
threshold: p.threshold.toString(),
|
|
38
|
+
state_root: tree.root().toString(),
|
|
39
|
+
disclosure_nullifier: nullifier.toString(),
|
|
40
|
+
context: p.context.toString(),
|
|
41
|
+
},
|
|
42
|
+
publics: {
|
|
43
|
+
value: p.note.value,
|
|
44
|
+
label: p.note.label,
|
|
45
|
+
threshold: p.threshold,
|
|
46
|
+
stateRoot: tree.root(),
|
|
47
|
+
disclosureNullifier: nullifier,
|
|
48
|
+
context: p.context,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Generate the Groth16 proof (snarkjs; Node paths or browser URLs). */
|
|
53
|
+
export async function generateDisclosureProof(witness, artifacts) {
|
|
54
|
+
const { proof, publicSignals } = await snarkjs.groth16.fullProve(witness.input, artifacts.wasmPath, artifacts.zkeyPath);
|
|
55
|
+
return { proof, publicSignals };
|
|
56
|
+
}
|
|
57
|
+
export { POOL_LEVELS };
|
|
58
|
+
//# sourceMappingURL=prove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../src/prove.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** The SchnorrSig tuple submitted on-chain (R as a full even-Y point). */
|
|
2
|
+
export interface QuorumSignature {
|
|
3
|
+
rx: bigint;
|
|
4
|
+
ry: bigint;
|
|
5
|
+
s: bigint;
|
|
6
|
+
}
|
|
7
|
+
/** The custodian CLI's `signature.json` shape (frost-custodian aggregate). */
|
|
8
|
+
export interface FrostSignatureFile {
|
|
9
|
+
rx: string;
|
|
10
|
+
ry: string;
|
|
11
|
+
s: string;
|
|
12
|
+
bip340: string;
|
|
13
|
+
message: string;
|
|
14
|
+
group_key_x: string;
|
|
15
|
+
}
|
|
16
|
+
/** Even-Y lift of an x coordinate (p ≡ 3 mod 4 → sqrt = ^((p+1)/4)). */
|
|
17
|
+
export declare function liftEvenY(x: bigint): bigint;
|
|
18
|
+
/** Parse a 64-byte BIP-340 signature (Rx ‖ s) into the on-chain tuple. */
|
|
19
|
+
export declare function parseBip340(signature: Uint8Array): QuorumSignature;
|
|
20
|
+
/** Parse the custodian CLI's aggregate output. */
|
|
21
|
+
export declare function parseFrostSignature(file: FrostSignatureFile): QuorumSignature;
|
|
22
|
+
/**
|
|
23
|
+
* Verify a quorum signature over a 32-byte message against the x-only group key —
|
|
24
|
+
* the same check both registries perform, so a submission that passes here passes
|
|
25
|
+
* on-chain.
|
|
26
|
+
*/
|
|
27
|
+
export declare function verifyQuorumSignature(groupKeyX: bigint, message: Uint8Array, sig: QuorumSignature): boolean;
|
|
28
|
+
//# sourceMappingURL=schnorr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schnorr.d.ts","sourceRoot":"","sources":["../src/schnorr.ts"],"names":[],"mappings":"AAUA,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;CACX;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAaD,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3C;AAID,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,eAAe,CAKlE;AAED,kDAAkD;AAClD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAWT"}
|
package/dist/schnorr.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BIP-340 quorum-signature helpers — spec/conditional-disclosure.md §5.
|
|
3
|
+
* A FROST(secp256k1, Taproot) aggregate from the custodian ceremony is a standard
|
|
4
|
+
* BIP-340 Schnorr signature; this module verifies one client-side (mirroring the
|
|
5
|
+
* on-chain checks) and converts it into the (rx, ry, s) tuple both registries take.
|
|
6
|
+
*/
|
|
7
|
+
import { schnorr } from "@noble/curves/secp256k1";
|
|
8
|
+
const SECP_P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
|
|
9
|
+
function modpow(base, exp, mod) {
|
|
10
|
+
let r = 1n;
|
|
11
|
+
base %= mod;
|
|
12
|
+
while (exp > 0n) {
|
|
13
|
+
if (exp & 1n)
|
|
14
|
+
r = (r * base) % mod;
|
|
15
|
+
base = (base * base) % mod;
|
|
16
|
+
exp >>= 1n;
|
|
17
|
+
}
|
|
18
|
+
return r;
|
|
19
|
+
}
|
|
20
|
+
/** Even-Y lift of an x coordinate (p ≡ 3 mod 4 → sqrt = ^((p+1)/4)). */
|
|
21
|
+
export function liftEvenY(x) {
|
|
22
|
+
const y = modpow((x * x * x + 7n) % SECP_P, (SECP_P + 1n) / 4n, SECP_P);
|
|
23
|
+
if ((y * y) % SECP_P !== (x * x * x + 7n) % SECP_P)
|
|
24
|
+
throw new Error("x is not on the curve");
|
|
25
|
+
return y % 2n === 0n ? y : SECP_P - y;
|
|
26
|
+
}
|
|
27
|
+
const to32 = (x) => Uint8Array.from(Buffer.from(x.toString(16).padStart(64, "0"), "hex"));
|
|
28
|
+
/** Parse a 64-byte BIP-340 signature (Rx ‖ s) into the on-chain tuple. */
|
|
29
|
+
export function parseBip340(signature) {
|
|
30
|
+
if (signature.length !== 64)
|
|
31
|
+
throw new Error("BIP-340 signature must be 64 bytes");
|
|
32
|
+
const rx = BigInt("0x" + Buffer.from(signature.slice(0, 32)).toString("hex"));
|
|
33
|
+
const s = BigInt("0x" + Buffer.from(signature.slice(32)).toString("hex"));
|
|
34
|
+
return { rx, ry: liftEvenY(rx), s };
|
|
35
|
+
}
|
|
36
|
+
/** Parse the custodian CLI's aggregate output. */
|
|
37
|
+
export function parseFrostSignature(file) {
|
|
38
|
+
return parseBip340(Uint8Array.from(Buffer.from(file.bip340, "hex")));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Verify a quorum signature over a 32-byte message against the x-only group key —
|
|
42
|
+
* the same check both registries perform, so a submission that passes here passes
|
|
43
|
+
* on-chain.
|
|
44
|
+
*/
|
|
45
|
+
export function verifyQuorumSignature(groupKeyX, message, sig) {
|
|
46
|
+
if (message.length !== 32)
|
|
47
|
+
throw new Error("message must be 32 bytes (the context)");
|
|
48
|
+
try {
|
|
49
|
+
return schnorr.verify(new Uint8Array([...to32(sig.rx), ...to32(sig.s)]), message, to32(groupKeyX));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=schnorr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schnorr.js","sourceRoot":"","sources":["../src/schnorr.ts"],"names":[],"mappings":"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"}
|
package/dist/shamir.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const SHARE_SCHEME = "shamir-gf256-v1";
|
|
2
|
+
export interface ParsedShare {
|
|
3
|
+
/** Envelope version (currently 1). */
|
|
4
|
+
version: number;
|
|
5
|
+
/** Recovery threshold m. */
|
|
6
|
+
threshold: number;
|
|
7
|
+
/** Total shares issued n. */
|
|
8
|
+
total: number;
|
|
9
|
+
/** 1-based custodian index this share was issued to. */
|
|
10
|
+
index: number;
|
|
11
|
+
/** The raw GF(256) share. */
|
|
12
|
+
share: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Split a 32-byte viewing key into `custodians` shares, any `threshold` of
|
|
16
|
+
* which recover it. Returns base64 envelope strings, ordered by custodian
|
|
17
|
+
* index (1-based).
|
|
18
|
+
*/
|
|
19
|
+
export declare function splitViewingKey(viewingKey: Uint8Array, threshold: number, custodians: number): Promise<string[]>;
|
|
20
|
+
/** Decode and validate a single share envelope. */
|
|
21
|
+
export declare function parseShare(encoded: string): ParsedShare;
|
|
22
|
+
/**
|
|
23
|
+
* Recover the viewing key from `>= threshold` envelope shares. Rejects shares
|
|
24
|
+
* from different splits (mismatched m/n), duplicate custodian indices, and
|
|
25
|
+
* share sets below the recorded threshold.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recoverViewingKey(shares: string[]): Promise<Uint8Array>;
|
|
28
|
+
//# sourceMappingURL=shamir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shamir.d.ts","sourceRoot":"","sources":["../src/shamir.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,YAAY,oBAAoB,CAAC;AAM9C,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,KAAK,EAAE,UAAU,CAAC;CACnB;AAKD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBnB;AAED,mDAAmD;AACnD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAQvD;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAqB7E"}
|
package/dist/shamir.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shamir viewing-key escrow — spec/conditional-disclosure.md §2.
|
|
3
|
+
*
|
|
4
|
+
* Splits the 32-byte CSAP viewing-key scalar into n shares with threshold m
|
|
5
|
+
* over GF(256) (audited `shamir-secret-sharing`). Each share is wrapped in the
|
|
6
|
+
* versioned envelope `base64(0x01 ‖ m ‖ n ‖ index ‖ raw_share)` so recovery can
|
|
7
|
+
* enforce the threshold and reject mixed share sets — the underlying scheme
|
|
8
|
+
* silently returns garbage when combined below threshold.
|
|
9
|
+
*
|
|
10
|
+
* NORMATIVE WARNING (spec §2): combining m shares reconstructs the FULL viewing
|
|
11
|
+
* key and reveals the owner's entire incoming-payment history to the combiner.
|
|
12
|
+
* This is the recovery backstop, not the disclosure path; active disclosure is
|
|
13
|
+
* the FROST-gated proof flow in prove.ts/tx.ts.
|
|
14
|
+
*/
|
|
15
|
+
import { split as gf256Split, combine as gf256Combine } from "shamir-secret-sharing";
|
|
16
|
+
export const SHARE_SCHEME = "shamir-gf256-v1";
|
|
17
|
+
const SHARE_VERSION = 0x01;
|
|
18
|
+
const VIEWING_KEY_LENGTH = 32;
|
|
19
|
+
/** envelope = version ‖ m ‖ n ‖ index */
|
|
20
|
+
const ENVELOPE_HEADER_LENGTH = 4;
|
|
21
|
+
const toBase64 = (bytes) => Buffer.from(bytes).toString("base64");
|
|
22
|
+
const fromBase64 = (s) => new Uint8Array(Buffer.from(s, "base64"));
|
|
23
|
+
/**
|
|
24
|
+
* Split a 32-byte viewing key into `custodians` shares, any `threshold` of
|
|
25
|
+
* which recover it. Returns base64 envelope strings, ordered by custodian
|
|
26
|
+
* index (1-based).
|
|
27
|
+
*/
|
|
28
|
+
export async function splitViewingKey(viewingKey, threshold, custodians) {
|
|
29
|
+
if (viewingKey.length !== VIEWING_KEY_LENGTH) {
|
|
30
|
+
throw new Error(`viewing key must be ${VIEWING_KEY_LENGTH} bytes, got ${viewingKey.length}`);
|
|
31
|
+
}
|
|
32
|
+
if (!Number.isInteger(threshold) || !Number.isInteger(custodians)) {
|
|
33
|
+
throw new Error("threshold and custodians must be integers");
|
|
34
|
+
}
|
|
35
|
+
if (threshold < 2)
|
|
36
|
+
throw new Error("threshold must be at least 2 (1 would be no escrow)");
|
|
37
|
+
if (custodians < threshold)
|
|
38
|
+
throw new Error("custodians must be >= threshold");
|
|
39
|
+
if (custodians > 255)
|
|
40
|
+
throw new Error("at most 255 custodians");
|
|
41
|
+
const raw = await gf256Split(viewingKey, custodians, threshold);
|
|
42
|
+
return raw.map((share, i) => {
|
|
43
|
+
const envelope = new Uint8Array(ENVELOPE_HEADER_LENGTH + share.length);
|
|
44
|
+
envelope[0] = SHARE_VERSION;
|
|
45
|
+
envelope[1] = threshold;
|
|
46
|
+
envelope[2] = custodians;
|
|
47
|
+
envelope[3] = i + 1;
|
|
48
|
+
envelope.set(share, ENVELOPE_HEADER_LENGTH);
|
|
49
|
+
return toBase64(envelope);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/** Decode and validate a single share envelope. */
|
|
53
|
+
export function parseShare(encoded) {
|
|
54
|
+
const bytes = fromBase64(encoded);
|
|
55
|
+
if (bytes.length <= ENVELOPE_HEADER_LENGTH)
|
|
56
|
+
throw new Error("share envelope too short");
|
|
57
|
+
const [version, threshold, total, index] = bytes;
|
|
58
|
+
if (version !== SHARE_VERSION)
|
|
59
|
+
throw new Error(`unsupported share version ${version}`);
|
|
60
|
+
if (threshold < 2 || total < threshold)
|
|
61
|
+
throw new Error("corrupt share envelope (threshold/total)");
|
|
62
|
+
if (index < 1 || index > total)
|
|
63
|
+
throw new Error("corrupt share envelope (index)");
|
|
64
|
+
return { version, threshold, total, index, share: bytes.slice(ENVELOPE_HEADER_LENGTH) };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Recover the viewing key from `>= threshold` envelope shares. Rejects shares
|
|
68
|
+
* from different splits (mismatched m/n), duplicate custodian indices, and
|
|
69
|
+
* share sets below the recorded threshold.
|
|
70
|
+
*/
|
|
71
|
+
export async function recoverViewingKey(shares) {
|
|
72
|
+
if (shares.length === 0)
|
|
73
|
+
throw new Error("no shares provided");
|
|
74
|
+
const parsed = shares.map(parseShare);
|
|
75
|
+
const { threshold, total } = parsed[0];
|
|
76
|
+
for (const p of parsed) {
|
|
77
|
+
if (p.threshold !== threshold || p.total !== total) {
|
|
78
|
+
throw new Error("shares are from different splits (threshold/total mismatch)");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const indices = new Set(parsed.map((p) => p.index));
|
|
82
|
+
if (indices.size !== parsed.length)
|
|
83
|
+
throw new Error("duplicate share indices");
|
|
84
|
+
if (parsed.length < threshold) {
|
|
85
|
+
throw new Error(`need ${threshold} shares to recover, got ${parsed.length}`);
|
|
86
|
+
}
|
|
87
|
+
const key = await gf256Combine(parsed.map((p) => p.share));
|
|
88
|
+
if (key.length !== VIEWING_KEY_LENGTH) {
|
|
89
|
+
throw new Error(`recovered ${key.length} bytes, expected ${VIEWING_KEY_LENGTH}`);
|
|
90
|
+
}
|
|
91
|
+
return key;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=shamir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shamir.js","sourceRoot":"","sources":["../src/shamir.ts"],"names":[],"mappings":"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"}
|
package/dist/tx.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure transaction builders — spec/conditional-disclosure.md §6.
|
|
3
|
+
* Ethereum: calldata for OpaqueDisclosureRegistry. Solana: raw instructions for the
|
|
4
|
+
* conditional-disclosure program (no IDL dependency; matches the program's borsh
|
|
5
|
+
* layout exactly).
|
|
6
|
+
*/
|
|
7
|
+
import { type Address, type Hex } from "viem";
|
|
8
|
+
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
9
|
+
import { toSolidityProof, type SolidityProof } from "@opaquecash/privacy-pool";
|
|
10
|
+
import type { QuorumSignature } from "./schnorr.js";
|
|
11
|
+
export declare const opaqueDisclosureRegistryAbi: readonly [{
|
|
12
|
+
readonly type: "function";
|
|
13
|
+
readonly name: "registerPolicy";
|
|
14
|
+
readonly stateMutability: "nonpayable";
|
|
15
|
+
readonly inputs: readonly [{
|
|
16
|
+
readonly name: "pool";
|
|
17
|
+
readonly type: "address";
|
|
18
|
+
}, {
|
|
19
|
+
readonly name: "groupKeyX";
|
|
20
|
+
readonly type: "uint256";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "threshold";
|
|
23
|
+
readonly type: "uint128";
|
|
24
|
+
}, {
|
|
25
|
+
readonly name: "m";
|
|
26
|
+
readonly type: "uint8";
|
|
27
|
+
}, {
|
|
28
|
+
readonly name: "n";
|
|
29
|
+
readonly type: "uint8";
|
|
30
|
+
}];
|
|
31
|
+
readonly outputs: readonly [{
|
|
32
|
+
readonly name: "policyId";
|
|
33
|
+
readonly type: "uint256";
|
|
34
|
+
}];
|
|
35
|
+
}, {
|
|
36
|
+
readonly type: "function";
|
|
37
|
+
readonly name: "disclose";
|
|
38
|
+
readonly stateMutability: "nonpayable";
|
|
39
|
+
readonly inputs: readonly [{
|
|
40
|
+
readonly name: "a";
|
|
41
|
+
readonly type: "uint256[2]";
|
|
42
|
+
}, {
|
|
43
|
+
readonly name: "b";
|
|
44
|
+
readonly type: "uint256[2][2]";
|
|
45
|
+
}, {
|
|
46
|
+
readonly name: "c";
|
|
47
|
+
readonly type: "uint256[2]";
|
|
48
|
+
}, {
|
|
49
|
+
readonly name: "signals";
|
|
50
|
+
readonly type: "uint256[6]";
|
|
51
|
+
}, {
|
|
52
|
+
readonly name: "policyId";
|
|
53
|
+
readonly type: "uint256";
|
|
54
|
+
}, {
|
|
55
|
+
readonly name: "caseId";
|
|
56
|
+
readonly type: "bytes32";
|
|
57
|
+
}, {
|
|
58
|
+
readonly name: "sig";
|
|
59
|
+
readonly type: "tuple";
|
|
60
|
+
readonly components: readonly [{
|
|
61
|
+
readonly name: "rx";
|
|
62
|
+
readonly type: "uint256";
|
|
63
|
+
}, {
|
|
64
|
+
readonly name: "ry";
|
|
65
|
+
readonly type: "uint256";
|
|
66
|
+
}, {
|
|
67
|
+
readonly name: "s";
|
|
68
|
+
readonly type: "uint256";
|
|
69
|
+
}];
|
|
70
|
+
}];
|
|
71
|
+
readonly outputs: readonly [];
|
|
72
|
+
}, {
|
|
73
|
+
readonly type: "function";
|
|
74
|
+
readonly name: "context";
|
|
75
|
+
readonly stateMutability: "pure";
|
|
76
|
+
readonly inputs: readonly [{
|
|
77
|
+
readonly name: "policyId";
|
|
78
|
+
readonly type: "uint256";
|
|
79
|
+
}, {
|
|
80
|
+
readonly name: "caseId";
|
|
81
|
+
readonly type: "bytes32";
|
|
82
|
+
}, {
|
|
83
|
+
readonly name: "requester";
|
|
84
|
+
readonly type: "address";
|
|
85
|
+
}];
|
|
86
|
+
readonly outputs: readonly [{
|
|
87
|
+
readonly type: "uint256";
|
|
88
|
+
}];
|
|
89
|
+
}, {
|
|
90
|
+
readonly type: "function";
|
|
91
|
+
readonly name: "policies";
|
|
92
|
+
readonly stateMutability: "view";
|
|
93
|
+
readonly inputs: readonly [{
|
|
94
|
+
readonly type: "uint256";
|
|
95
|
+
}];
|
|
96
|
+
readonly outputs: readonly [{
|
|
97
|
+
readonly name: "pool";
|
|
98
|
+
readonly type: "address";
|
|
99
|
+
}, {
|
|
100
|
+
readonly name: "groupKeyX";
|
|
101
|
+
readonly type: "uint256";
|
|
102
|
+
}, {
|
|
103
|
+
readonly name: "threshold";
|
|
104
|
+
readonly type: "uint128";
|
|
105
|
+
}, {
|
|
106
|
+
readonly name: "m";
|
|
107
|
+
readonly type: "uint8";
|
|
108
|
+
}, {
|
|
109
|
+
readonly name: "n";
|
|
110
|
+
readonly type: "uint8";
|
|
111
|
+
}];
|
|
112
|
+
}, {
|
|
113
|
+
readonly type: "function";
|
|
114
|
+
readonly name: "nullifierConsumed";
|
|
115
|
+
readonly stateMutability: "view";
|
|
116
|
+
readonly inputs: readonly [{
|
|
117
|
+
readonly type: "bytes32";
|
|
118
|
+
}];
|
|
119
|
+
readonly outputs: readonly [{
|
|
120
|
+
readonly type: "bool";
|
|
121
|
+
}];
|
|
122
|
+
}, {
|
|
123
|
+
readonly type: "event";
|
|
124
|
+
readonly name: "Disclosure";
|
|
125
|
+
readonly inputs: readonly [{
|
|
126
|
+
readonly name: "policyId";
|
|
127
|
+
readonly type: "uint256";
|
|
128
|
+
readonly indexed: true;
|
|
129
|
+
}, {
|
|
130
|
+
readonly name: "caseId";
|
|
131
|
+
readonly type: "bytes32";
|
|
132
|
+
readonly indexed: true;
|
|
133
|
+
}, {
|
|
134
|
+
readonly name: "requester";
|
|
135
|
+
readonly type: "address";
|
|
136
|
+
readonly indexed: true;
|
|
137
|
+
}, {
|
|
138
|
+
readonly name: "label";
|
|
139
|
+
readonly type: "uint256";
|
|
140
|
+
readonly indexed: false;
|
|
141
|
+
}, {
|
|
142
|
+
readonly name: "value";
|
|
143
|
+
readonly type: "uint256";
|
|
144
|
+
readonly indexed: false;
|
|
145
|
+
}, {
|
|
146
|
+
readonly name: "disclosureNullifier";
|
|
147
|
+
readonly type: "bytes32";
|
|
148
|
+
readonly indexed: false;
|
|
149
|
+
}];
|
|
150
|
+
}];
|
|
151
|
+
export interface EvmTxRequest {
|
|
152
|
+
to: Address;
|
|
153
|
+
data: Hex;
|
|
154
|
+
}
|
|
155
|
+
export declare function buildRegisterPolicyTx(registry: Address, p: {
|
|
156
|
+
pool: Address;
|
|
157
|
+
groupKeyX: bigint;
|
|
158
|
+
threshold: bigint;
|
|
159
|
+
m: number;
|
|
160
|
+
n: number;
|
|
161
|
+
}): EvmTxRequest;
|
|
162
|
+
export declare function buildDiscloseTx(registry: Address, p: {
|
|
163
|
+
proof: SolidityProof;
|
|
164
|
+
signals: [bigint, bigint, bigint, bigint, bigint, bigint];
|
|
165
|
+
policyId: bigint;
|
|
166
|
+
caseId: Hex;
|
|
167
|
+
sig: QuorumSignature;
|
|
168
|
+
}): EvmTxRequest;
|
|
169
|
+
export declare function policyPda(program: PublicKey, groupKeyX: bigint): PublicKey;
|
|
170
|
+
export declare function disclosureNullifierPda(program: PublicKey, nullifier: bigint): PublicKey;
|
|
171
|
+
export declare function buildRegisterPolicyIx(program: PublicKey, p: {
|
|
172
|
+
pool: PublicKey;
|
|
173
|
+
groupKeyX: bigint;
|
|
174
|
+
threshold: bigint;
|
|
175
|
+
m: number;
|
|
176
|
+
n: number;
|
|
177
|
+
payer: PublicKey;
|
|
178
|
+
}): TransactionInstruction;
|
|
179
|
+
/** Groth16 proof in the program's byte encoding (negated-A handled on-chain). */
|
|
180
|
+
export interface SolanaProofBytes {
|
|
181
|
+
a: Uint8Array;
|
|
182
|
+
b: Uint8Array;
|
|
183
|
+
c: Uint8Array;
|
|
184
|
+
}
|
|
185
|
+
/** snarkjs proof object → the program's G1/G2 byte encoding. */
|
|
186
|
+
export declare function toSolanaProof(proof: {
|
|
187
|
+
pi_a: string[];
|
|
188
|
+
pi_b: string[][];
|
|
189
|
+
pi_c: string[];
|
|
190
|
+
}): SolanaProofBytes;
|
|
191
|
+
export declare function buildDiscloseIx(program: PublicKey, p: {
|
|
192
|
+
pool: PublicKey;
|
|
193
|
+
groupKeyX: bigint;
|
|
194
|
+
proof: SolanaProofBytes;
|
|
195
|
+
value: bigint;
|
|
196
|
+
label: bigint;
|
|
197
|
+
stateRoot: bigint;
|
|
198
|
+
disclosureNullifier: bigint;
|
|
199
|
+
caseId: Uint8Array;
|
|
200
|
+
sig: QuorumSignature;
|
|
201
|
+
requester: PublicKey;
|
|
202
|
+
}): TransactionInstruction;
|
|
203
|
+
export { toSolidityProof, type SolidityProof };
|
|
204
|
+
//# sourceMappingURL=tx.d.ts.map
|
package/dist/tx.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../src/tx.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAsB,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,SAAS,EAAiB,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgF9B,CAAC;AAEX,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;CACX;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EACjB,CAAC,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E,YAAY,CASd;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,CAAC,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC;IACZ,GAAG,EAAE,eAAe,CAAC;CACtB,GACA,YAAY,CAiBd;AAaD,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAK1E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAKvF;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,EAClB,CAAC,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACnG,sBAAsB,CAgBxB;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,CAAC,EAAE,UAAU,CAAC;IACd,CAAC,EAAE,UAAU,CAAC;IACd,CAAC,EAAE,UAAU,CAAC;CACf;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,gBAAgB,CAUnB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,EAClB,CAAC,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,eAAe,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;CACtB,GACA,sBAAsB,CA8BxB;AAED,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,CAAC"}
|
package/dist/tx.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure transaction builders — spec/conditional-disclosure.md §6.
|
|
3
|
+
* Ethereum: calldata for OpaqueDisclosureRegistry. Solana: raw instructions for the
|
|
4
|
+
* conditional-disclosure program (no IDL dependency; matches the program's borsh
|
|
5
|
+
* layout exactly).
|
|
6
|
+
*/
|
|
7
|
+
import { encodeFunctionData } from "viem";
|
|
8
|
+
import { PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js";
|
|
9
|
+
import { toSolidityProof } from "@opaquecash/privacy-pool";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
export const opaqueDisclosureRegistryAbi = [
|
|
12
|
+
{
|
|
13
|
+
type: "function",
|
|
14
|
+
name: "registerPolicy",
|
|
15
|
+
stateMutability: "nonpayable",
|
|
16
|
+
inputs: [
|
|
17
|
+
{ name: "pool", type: "address" },
|
|
18
|
+
{ name: "groupKeyX", type: "uint256" },
|
|
19
|
+
{ name: "threshold", type: "uint128" },
|
|
20
|
+
{ name: "m", type: "uint8" },
|
|
21
|
+
{ name: "n", type: "uint8" },
|
|
22
|
+
],
|
|
23
|
+
outputs: [{ name: "policyId", type: "uint256" }],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: "function",
|
|
27
|
+
name: "disclose",
|
|
28
|
+
stateMutability: "nonpayable",
|
|
29
|
+
inputs: [
|
|
30
|
+
{ name: "a", type: "uint256[2]" },
|
|
31
|
+
{ name: "b", type: "uint256[2][2]" },
|
|
32
|
+
{ name: "c", type: "uint256[2]" },
|
|
33
|
+
{ name: "signals", type: "uint256[6]" },
|
|
34
|
+
{ name: "policyId", type: "uint256" },
|
|
35
|
+
{ name: "caseId", type: "bytes32" },
|
|
36
|
+
{
|
|
37
|
+
name: "sig",
|
|
38
|
+
type: "tuple",
|
|
39
|
+
components: [
|
|
40
|
+
{ name: "rx", type: "uint256" },
|
|
41
|
+
{ name: "ry", type: "uint256" },
|
|
42
|
+
{ name: "s", type: "uint256" },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
outputs: [],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
type: "function",
|
|
50
|
+
name: "context",
|
|
51
|
+
stateMutability: "pure",
|
|
52
|
+
inputs: [
|
|
53
|
+
{ name: "policyId", type: "uint256" },
|
|
54
|
+
{ name: "caseId", type: "bytes32" },
|
|
55
|
+
{ name: "requester", type: "address" },
|
|
56
|
+
],
|
|
57
|
+
outputs: [{ type: "uint256" }],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: "function",
|
|
61
|
+
name: "policies",
|
|
62
|
+
stateMutability: "view",
|
|
63
|
+
inputs: [{ type: "uint256" }],
|
|
64
|
+
outputs: [
|
|
65
|
+
{ name: "pool", type: "address" },
|
|
66
|
+
{ name: "groupKeyX", type: "uint256" },
|
|
67
|
+
{ name: "threshold", type: "uint128" },
|
|
68
|
+
{ name: "m", type: "uint8" },
|
|
69
|
+
{ name: "n", type: "uint8" },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
type: "function",
|
|
74
|
+
name: "nullifierConsumed",
|
|
75
|
+
stateMutability: "view",
|
|
76
|
+
inputs: [{ type: "bytes32" }],
|
|
77
|
+
outputs: [{ type: "bool" }],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: "event",
|
|
81
|
+
name: "Disclosure",
|
|
82
|
+
inputs: [
|
|
83
|
+
{ name: "policyId", type: "uint256", indexed: true },
|
|
84
|
+
{ name: "caseId", type: "bytes32", indexed: true },
|
|
85
|
+
{ name: "requester", type: "address", indexed: true },
|
|
86
|
+
{ name: "label", type: "uint256", indexed: false },
|
|
87
|
+
{ name: "value", type: "uint256", indexed: false },
|
|
88
|
+
{ name: "disclosureNullifier", type: "bytes32", indexed: false },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
export function buildRegisterPolicyTx(registry, p) {
|
|
93
|
+
return {
|
|
94
|
+
to: registry,
|
|
95
|
+
data: encodeFunctionData({
|
|
96
|
+
abi: opaqueDisclosureRegistryAbi,
|
|
97
|
+
functionName: "registerPolicy",
|
|
98
|
+
args: [p.pool, p.groupKeyX, p.threshold, p.m, p.n],
|
|
99
|
+
}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function buildDiscloseTx(registry, p) {
|
|
103
|
+
return {
|
|
104
|
+
to: registry,
|
|
105
|
+
data: encodeFunctionData({
|
|
106
|
+
abi: opaqueDisclosureRegistryAbi,
|
|
107
|
+
functionName: "disclose",
|
|
108
|
+
args: [
|
|
109
|
+
p.proof.a,
|
|
110
|
+
p.proof.b,
|
|
111
|
+
p.proof.c,
|
|
112
|
+
p.signals,
|
|
113
|
+
p.policyId,
|
|
114
|
+
p.caseId,
|
|
115
|
+
{ rx: p.sig.rx, ry: p.sig.ry, s: p.sig.s },
|
|
116
|
+
],
|
|
117
|
+
}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// ----------------------------------------------------------------- Solana
|
|
121
|
+
const disc = (name) => createHash("sha256").update(`global:${name}`).digest().subarray(0, 8);
|
|
122
|
+
const be32 = (x) => Buffer.from(x.toString(16).padStart(64, "0"), "hex");
|
|
123
|
+
const u64le = (n) => {
|
|
124
|
+
const b = Buffer.alloc(8);
|
|
125
|
+
b.writeBigUInt64LE(n);
|
|
126
|
+
return b;
|
|
127
|
+
};
|
|
128
|
+
export function policyPda(program, groupKeyX) {
|
|
129
|
+
return PublicKey.findProgramAddressSync([Buffer.from("policy"), be32(groupKeyX)], program)[0];
|
|
130
|
+
}
|
|
131
|
+
export function disclosureNullifierPda(program, nullifier) {
|
|
132
|
+
return PublicKey.findProgramAddressSync([Buffer.from("nullifier"), be32(nullifier)], program)[0];
|
|
133
|
+
}
|
|
134
|
+
export function buildRegisterPolicyIx(program, p) {
|
|
135
|
+
return new TransactionInstruction({
|
|
136
|
+
programId: program,
|
|
137
|
+
keys: [
|
|
138
|
+
{ pubkey: policyPda(program, p.groupKeyX), isSigner: false, isWritable: true },
|
|
139
|
+
{ pubkey: p.pool, isSigner: false, isWritable: false },
|
|
140
|
+
{ pubkey: p.payer, isSigner: true, isWritable: true },
|
|
141
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
142
|
+
],
|
|
143
|
+
data: Buffer.concat([
|
|
144
|
+
disc("register_policy"),
|
|
145
|
+
be32(p.groupKeyX),
|
|
146
|
+
u64le(p.threshold),
|
|
147
|
+
Buffer.from([p.m, p.n]),
|
|
148
|
+
]),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/** snarkjs proof object → the program's G1/G2 byte encoding. */
|
|
152
|
+
export function toSolanaProof(proof) {
|
|
153
|
+
const g1 = (p) => Buffer.concat([be32(BigInt(p[0])), be32(BigInt(p[1]))]);
|
|
154
|
+
const g2 = (p) => Buffer.concat([
|
|
155
|
+
be32(BigInt(p[0][1])),
|
|
156
|
+
be32(BigInt(p[0][0])),
|
|
157
|
+
be32(BigInt(p[1][1])),
|
|
158
|
+
be32(BigInt(p[1][0])),
|
|
159
|
+
]);
|
|
160
|
+
return { a: g1(proof.pi_a), b: g2(proof.pi_b), c: g1(proof.pi_c) };
|
|
161
|
+
}
|
|
162
|
+
export function buildDiscloseIx(program, p) {
|
|
163
|
+
if (p.caseId.length !== 32)
|
|
164
|
+
throw new Error("caseId must be 32 bytes");
|
|
165
|
+
return new TransactionInstruction({
|
|
166
|
+
programId: program,
|
|
167
|
+
keys: [
|
|
168
|
+
{ pubkey: policyPda(program, p.groupKeyX), isSigner: false, isWritable: false },
|
|
169
|
+
{ pubkey: p.pool, isSigner: false, isWritable: false },
|
|
170
|
+
{
|
|
171
|
+
pubkey: disclosureNullifierPda(program, p.disclosureNullifier),
|
|
172
|
+
isSigner: false,
|
|
173
|
+
isWritable: true,
|
|
174
|
+
},
|
|
175
|
+
{ pubkey: p.requester, isSigner: true, isWritable: true },
|
|
176
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
177
|
+
],
|
|
178
|
+
data: Buffer.concat([
|
|
179
|
+
disc("disclose"),
|
|
180
|
+
p.proof.a,
|
|
181
|
+
p.proof.b,
|
|
182
|
+
p.proof.c,
|
|
183
|
+
u64le(p.value),
|
|
184
|
+
be32(p.label),
|
|
185
|
+
be32(p.stateRoot),
|
|
186
|
+
be32(p.disclosureNullifier),
|
|
187
|
+
p.caseId,
|
|
188
|
+
be32(p.sig.rx),
|
|
189
|
+
be32(p.sig.ry),
|
|
190
|
+
be32(p.sig.s),
|
|
191
|
+
]),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
export { toSolidityProof };
|
|
195
|
+
//# sourceMappingURL=tx.js.map
|
package/dist/tx.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx.js","sourceRoot":"","sources":["../src/tx.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opaquecash/disclosure",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Conditional disclosure client: Shamir viewing-key escrow, disclosure witness + Groth16 proof generation, BIP-340 quorum-signature helpers, and disclose tx building (spec/conditional-disclosure.md)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"clean": "rm -rf dist"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@noble/curves": "^1.6.0",
|
|
23
|
+
"@solana/web3.js": "^1.98.4",
|
|
24
|
+
"@opaquecash/deployments": "0.2.0",
|
|
25
|
+
"@opaquecash/privacy-pool": "0.2.0",
|
|
26
|
+
"shamir-secret-sharing": "^0.0.4",
|
|
27
|
+
"snarkjs": "^0.7.5",
|
|
28
|
+
"viem": "^2.21.0"
|
|
29
|
+
},
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/opaquecash/sdk.git",
|
|
35
|
+
"directory": "packages/disclosure"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://docs.opaque.cash",
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
}
|
|
41
|
+
}
|