@opaquecash/opaque 0.1.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.
@@ -0,0 +1,30 @@
1
+ import type { Address } from "viem";
2
+ import type { TrackedToken } from "@opaquecash/stealth-balance";
3
+ /** Sentinel for native ETH in balance aggregation (not a contract). */
4
+ export declare const NATIVE_TOKEN_ADDRESS: Address;
5
+ /**
6
+ * Contract bundle for one chain (Opaque deployments).
7
+ */
8
+ export interface OpaqueChainDeployment {
9
+ chainId: number;
10
+ name: string;
11
+ stealthMetaAddressRegistry: Address;
12
+ stealthAddressAnnouncer: Address;
13
+ /** Optional PSR verifier; omitted if not deployed. */
14
+ opaqueReputationVerifier?: Address;
15
+ /** Default tokens merged with `OpaqueClientConfig.trackedTokens`. */
16
+ defaultTrackedTokens: TrackedToken[];
17
+ }
18
+ /**
19
+ * Chain IDs with bundled Opaque contract addresses.
20
+ */
21
+ export declare function getSupportedChainIds(): number[];
22
+ /**
23
+ * Resolve deployment metadata for a chain, or `undefined` if unknown.
24
+ */
25
+ export declare function getChainDeployment(chainId: number): OpaqueChainDeployment | undefined;
26
+ /**
27
+ * Require a known deployment or throw.
28
+ */
29
+ export declare function requireChainDeployment(chainId: number): OpaqueChainDeployment;
30
+ //# sourceMappingURL=chains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,EACiB,OAAO,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B,EAAE,OAAO,CAAC;IACpC,uBAAuB,EAAE,OAAO,CAAC;IACjC,sDAAsD;IACtD,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,qEAAqE;IACrE,oBAAoB,EAAE,YAAY,EAAE,CAAC;CACtC;AAkCD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GACd,qBAAqB,GAAG,SAAS,CAEnC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAQ7E"}
package/dist/chains.js ADDED
@@ -0,0 +1,52 @@
1
+ /** Sentinel for native ETH in balance aggregation (not a contract). */
2
+ export const NATIVE_TOKEN_ADDRESS = "0x0000000000000000000000000000000000000000";
3
+ const sepolia = {
4
+ chainId: 11155111,
5
+ name: "Sepolia",
6
+ stealthMetaAddressRegistry: "0x77425e04163d608B876c7f50E34A378624A12067",
7
+ stealthAddressAnnouncer: "0x840f72249A8bF6F10b0eB64412E315efBD730865",
8
+ opaqueReputationVerifier: "0x30B750Ae9851e104F8dbB4B8082b1a07a34885B0",
9
+ defaultTrackedTokens: [
10
+ {
11
+ address: NATIVE_TOKEN_ADDRESS,
12
+ symbol: "ETH",
13
+ decimals: 18,
14
+ },
15
+ {
16
+ address: "0x73197e8303904862d543f9706E8422F634D713cb",
17
+ symbol: "USDC",
18
+ decimals: 6,
19
+ },
20
+ {
21
+ address: "0x6Ff8Afb2aA9eB5A89Ce86c44DD460bD17C92f644",
22
+ symbol: "USDT",
23
+ decimals: 6,
24
+ },
25
+ ],
26
+ };
27
+ const DEPLOYMENTS = {
28
+ 11155111: sepolia,
29
+ };
30
+ /**
31
+ * Chain IDs with bundled Opaque contract addresses.
32
+ */
33
+ export function getSupportedChainIds() {
34
+ return Object.keys(DEPLOYMENTS).map(Number);
35
+ }
36
+ /**
37
+ * Resolve deployment metadata for a chain, or `undefined` if unknown.
38
+ */
39
+ export function getChainDeployment(chainId) {
40
+ return DEPLOYMENTS[chainId];
41
+ }
42
+ /**
43
+ * Require a known deployment or throw.
44
+ */
45
+ export function requireChainDeployment(chainId) {
46
+ const d = DEPLOYMENTS[chainId];
47
+ if (!d) {
48
+ throw new Error(`Opaque: unsupported chainId ${chainId}. Supported: ${getSupportedChainIds().join(", ")}`);
49
+ }
50
+ return d;
51
+ }
52
+ //# sourceMappingURL=chains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAGA,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAC/B,4CAAuD,CAAC;AAgB1D,MAAM,OAAO,GAA0B;IACrC,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,0BAA0B,EACxB,4CAAuD;IACzD,uBAAuB,EACrB,4CAAuD;IACzD,wBAAwB,EACtB,4CAAuD;IACzD,oBAAoB,EAAE;QACpB;YACE,OAAO,EAAE,oBAAoB;YAC7B,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,EAAE;SACb;QACD;YACE,OAAO,EAAE,4CAAuD;YAChE,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,CAAC;SACZ;QACD;YACE,OAAO,EAAE,4CAAuD;YAChE,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,CAAC;SACZ;KACF;CACF,CAAC;AAEF,MAAM,WAAW,GAA0C;IACzD,QAAQ,EAAE,OAAO;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe;IAEf,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CACb,+BAA+B,OAAO,gBAAgB,oBAAoB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,267 @@
1
+ import { type Account, type Address, type Chain, type Hex, type Transport, type WalletClient } from "viem";
2
+ import { buildActionScope, externalNullifierFromScope, type ProofData } from "@opaquecash/psr-core";
3
+ import type { DiscoveredTrait } from "@opaquecash/psr-core";
4
+ import { type VerifyReputationArgs } from "@opaquecash/psr-chain";
5
+ import { type ArtifactPaths, type ProofProgressCallback } from "@opaquecash/psr-prover";
6
+ import { type TrackedToken } from "@opaquecash/stealth-balance";
7
+ import { type OpaqueChainDeployment } from "./chains.js";
8
+ import type { IndexerAnnouncement, OwnedStealthOutput, TokenBalanceSummary } from "./types/indexer.js";
9
+ /**
10
+ * Configuration for {@link OpaqueClient.create}.
11
+ */
12
+ export interface OpaqueClientConfig {
13
+ /** EVM chain id (must be in {@link getSupportedChainIds} unless you override all contracts). */
14
+ chainId: number;
15
+ /** HTTP(S) RPC URL for reads (balances, optional registry view). */
16
+ rpcUrl: string;
17
+ /**
18
+ * Wallet signature used as HKDF entropy (`opaque-cash-v1`) for viewing + spending keys.
19
+ * Never sent on-chain by the SDK.
20
+ */
21
+ walletSignature: Hex;
22
+ /**
23
+ * The externally owned account that signs / registers (used as registrant context in docs;
24
+ * you still pass the same address to your wallet when sending txs).
25
+ */
26
+ ethereumAddress: Address;
27
+ /** Dynamic import URL for wasm-pack `cryptography.js`. */
28
+ wasmModuleSpecifier: string;
29
+ /**
30
+ * Extra ERC-20s (and native) to aggregate. Merged with chain defaults; native uses
31
+ * {@link NATIVE_TOKEN_ADDRESS}.
32
+ */
33
+ trackedTokens?: TrackedToken[];
34
+ /** Override registry / announcer / verifier for custom deployments. */
35
+ contracts?: Partial<{
36
+ stealthMetaAddressRegistry: Address;
37
+ stealthAddressAnnouncer: Address;
38
+ opaqueReputationVerifier: Address;
39
+ }>;
40
+ }
41
+ /**
42
+ * Result of preparing a stealth send (ephemeral material + announce fields).
43
+ */
44
+ export interface PrepareStealthSendResult {
45
+ schemeId: bigint;
46
+ stealthAddress: Address;
47
+ viewTag: number;
48
+ /** 33-byte compressed ephemeral public key. */
49
+ ephemeralPublicKey: Uint8Array;
50
+ /** 32-byte ephemeral private key — store securely if you need ghost / later announce. */
51
+ ephemeralPrivateKey: Uint8Array;
52
+ /** Metadata bytes for `announce` (view tag byte; extend with WASM for PSR). */
53
+ metadata: Uint8Array;
54
+ }
55
+ /**
56
+ * Result of {@link OpaqueClient.prepareGhostReceive} — same shape as {@link PrepareStealthSendResult},
57
+ * keyed to your own meta-address for receive-without-prior-announcement flows.
58
+ */
59
+ export type PrepareGhostReceiveResult = PrepareStealthSendResult;
60
+ /**
61
+ * Calldata-ready request for `StealthAddressAnnouncer.announce` (developer submits via wallet).
62
+ */
63
+ export interface AnnounceTransactionRequest {
64
+ to: Address;
65
+ data: Hex;
66
+ chainId: number;
67
+ summary: {
68
+ schemeId: bigint;
69
+ stealthAddress: Address;
70
+ ephemeralPublicKey: Hex;
71
+ metadata: Hex;
72
+ };
73
+ }
74
+ /**
75
+ * Calldata-ready request for `StealthMetaAddressRegistry.registerKeys`.
76
+ */
77
+ export interface RegisterMetaAddressTransactionRequest {
78
+ to: Address;
79
+ data: Hex;
80
+ chainId: number;
81
+ metaAddressHex: Hex;
82
+ }
83
+ /**
84
+ * Result of {@link OpaqueClient.resolveRecipientMetaAddress}: registry lookup for a normal EOA.
85
+ */
86
+ export interface ResolveRecipientMetaResult {
87
+ /**
88
+ * Checksummed address you looked up (the would-be recipient).
89
+ * When `registered` is false, use this as the plain receiver identity — there is no meta-address yet.
90
+ */
91
+ recipientAddress: Address;
92
+ /** True when `stealthMetaAddressOf` returned a 66-byte meta-address for EIP-5564 scheme 1. */
93
+ registered: boolean;
94
+ /**
95
+ * 66-byte stealth meta-address (`0x` + 132 hex) for {@link prepareStealthSend}.
96
+ * Omitted when `registered` is false.
97
+ */
98
+ metaAddressHex?: Hex;
99
+ }
100
+ export declare class OpaqueClient {
101
+ private readonly config;
102
+ private readonly deployment;
103
+ private readonly registry;
104
+ private readonly announcer;
105
+ private readonly reputationVerifier?;
106
+ private readonly tokens;
107
+ private readonly viewingKey;
108
+ private readonly spendingKey;
109
+ private readonly spendPubKey;
110
+ private readonly metaAddressHex;
111
+ private readonly publicClient;
112
+ private readonly wasm;
113
+ private constructor();
114
+ /**
115
+ * Construct a client: loads WASM, derives keys from `walletSignature`, wires RPC + addresses.
116
+ */
117
+ static create(config: OpaqueClientConfig): Promise<OpaqueClient>;
118
+ /** Chain id from configuration. */
119
+ getChainId(): number;
120
+ /** Connected Ethereum address (from config). */
121
+ getEthereumAddress(): Address;
122
+ /** 66-byte meta-address hex for registry / sharing. */
123
+ getMetaAddressHex(): Hex;
124
+ /** Resolved contract addresses for the active chain. */
125
+ getContracts(): {
126
+ stealthMetaAddressRegistry: Address;
127
+ stealthAddressAnnouncer: Address;
128
+ opaqueReputationVerifier?: Address;
129
+ };
130
+ /**
131
+ * Look up a recipient’s stealth meta-address on `StealthMetaAddressRegistry` using this client’s
132
+ * `rpcUrl` and configured registry (scheme id {@link EIP5564_SCHEME_SECP256K1}).
133
+ *
134
+ * When the account has not registered, `registered` is false and `metaAddressHex` is omitted —
135
+ * `recipientAddress` is still the checksummed address you passed in so you can show “not on Opaque yet”.
136
+ *
137
+ * @param recipientAddress - Normal Ethereum address of the intended recipient.
138
+ */
139
+ resolveRecipientMetaAddress(recipientAddress: Address): Promise<ResolveRecipientMetaResult>;
140
+ /**
141
+ * Encode `registerKeys` for the user's meta-address (they submit with `ethereumAddress`).
142
+ */
143
+ buildRegisterMetaAddressTransaction(): RegisterMetaAddressTransactionRequest;
144
+ /**
145
+ * Derive a one-time stealth address for sending to a recipient meta-address.
146
+ */
147
+ prepareStealthSend(recipientMetaAddressHex: Hex): PrepareStealthSendResult;
148
+ /**
149
+ * Manual “ghost” receive: derive a one-time stealth address for **this** wallet’s meta-address
150
+ * without any on-chain announcement yet. Cryptographically this is {@link prepareStealthSend}
151
+ * with {@link getMetaAddressHex}; you must persist `ephemeralPrivateKey` (and optionally the
152
+ * full prep) securely to sweep funds or to announce later.
153
+ */
154
+ prepareGhostReceive(): PrepareGhostReceiveResult;
155
+ /**
156
+ * Build `announce` calldata after you only have the stored 32-byte ephemeral secret from
157
+ * {@link prepareGhostReceive} (or any prior {@link prepareStealthSend} to your meta-address).
158
+ * Recomputes stealth address and pubkey material deterministically. If you still have the full
159
+ * {@link PrepareStealthSendResult} object, {@link buildAnnounceTransactionRequest} is enough.
160
+ */
161
+ buildAnnounceTransactionRequestForGhost(ephemeralPrivateKey: Uint8Array): AnnounceTransactionRequest;
162
+ /**
163
+ * Build calldata for `announce` so the developer can prompt the user to broadcast.
164
+ */
165
+ buildAnnounceTransactionRequest(send: PrepareStealthSendResult): AnnounceTransactionRequest;
166
+ /**
167
+ * Filter indexer announcements down to outputs owned by this user (WASM scan).
168
+ */
169
+ filterOwnedAnnouncements(rows: IndexerAnnouncement[]): Promise<OwnedStealthOutput[]>;
170
+ /**
171
+ * Reconstruct the 32-byte secp256k1 private key that controls `output`’s one-time stealth address.
172
+ * Uses the same WASM path as the on-chain scanner (`reconstruct_signing_key_wasm`).
173
+ *
174
+ * You supply gas, nonce, and broadcast: build a viem `PrivateKeyAccount` (or ethers wallet) from
175
+ * the returned bytes and sign a transfer **from** `output.stealthAddress`. Never log or persist
176
+ * the result beyond what your threat model allows.
177
+ */
178
+ getStealthSignerPrivateKey(output: Pick<OwnedStealthOutput, "ephemeralPublicKey">): Uint8Array;
179
+ /**
180
+ * Same as {@link getStealthSignerPrivateKey} when you only have the 32-byte ephemeral **private**
181
+ * key from {@link prepareGhostReceive} / {@link prepareStealthSend} (e.g. ghost storage) instead
182
+ * of an indexer row with `ephemeralPublicKey`.
183
+ */
184
+ getStealthSignerPrivateKeyFromEphemeralPrivateKey(ephemeralPrivateKey: Uint8Array): Uint8Array;
185
+ /**
186
+ * Owned outputs + balances summed per tracked token (uses `rpcUrl` from config).
187
+ */
188
+ getBalancesFromAnnouncements(rows: IndexerAnnouncement[]): Promise<TokenBalanceSummary[]>;
189
+ /**
190
+ * PSR: map owned attestation markers to {@link DiscoveredTrait} list.
191
+ */
192
+ discoverTraits(rows: IndexerAnnouncement[]): Promise<DiscoveredTrait[]>;
193
+ /**
194
+ * PSR: same as {@link discoverTraits} — alias for reputation-focused call sites.
195
+ */
196
+ getReputationTraitsFromAnnouncements(rows: IndexerAnnouncement[]): Promise<DiscoveredTrait[]>;
197
+ /**
198
+ * Encode `announce` metadata for a PSR attestation (view tag byte + `0xA7` + u64 `attestationId`).
199
+ * Canonical encoding matches WASM/Rust; use with {@link prepareReputationAssignment}.
200
+ */
201
+ encodeReputationMetadata(viewTag: number, attestationId: bigint): Uint8Array;
202
+ /**
203
+ * Issuer flow: derive one-time stealth material for the recipient and embed `attestationId` in metadata.
204
+ */
205
+ prepareReputationAssignment(recipientMetaAddressHex: Hex, attestationId: bigint): PrepareStealthSendResult;
206
+ /**
207
+ * Issuer flow: calldata for `StealthAddressAnnouncer.announce` with PSR metadata (no asset transfer).
208
+ */
209
+ buildAssignReputationTransaction(recipientMetaAddressHex: Hex, attestationId: bigint): AnnounceTransactionRequest;
210
+ /**
211
+ * JSON array string for {@link generateReputationProof} when passing `attestationsJson` (WASM Merkle witness).
212
+ */
213
+ announcementsJsonForReputationWitness(rows: IndexerAnnouncement[]): string;
214
+ /**
215
+ * One-time stealth signing key for a {@link DiscoveredTrait} (requires `ephemeralPubkey` from the scan).
216
+ */
217
+ getStealthSignerPrivateKeyForReputationTrait(trait: DiscoveredTrait): Uint8Array;
218
+ /**
219
+ * Groth16 proof bundle for `OpaqueReputationVerifier` (requires `snarkjs`).
220
+ * When `artifacts` is omitted, wasm/zkey are loaded from the default hosted paths on opaque.cash
221
+ * (same as the Opaque frontend `/circuits/...` assets).
222
+ */
223
+ generateReputationProof(params: {
224
+ trait: DiscoveredTrait;
225
+ stealthPrivKeyBytes: Uint8Array;
226
+ externalNullifier: string;
227
+ attestationsJson?: string;
228
+ artifacts?: ArtifactPaths;
229
+ onProgress?: ProofProgressCallback;
230
+ }): Promise<ProofData>;
231
+ /** Latest non-expired Merkle root from `OpaqueReputationVerifier.rootHistory`. */
232
+ fetchLatestValidReputationRoot(): Promise<Hex>;
233
+ /** Whether the verifier currently accepts this root (exists and not past expiry). */
234
+ isReputationRootValid(root: Hex): Promise<boolean>;
235
+ /** Full root history with per-entry validity (newest index last). */
236
+ fetchReputationRootHistory(): Promise<Array<{
237
+ index: number;
238
+ root: Hex;
239
+ valid: boolean;
240
+ }>>;
241
+ /** On-chain view helper: verify proof without spending nullifier. */
242
+ verifyReputationProofView(args: VerifyReputationArgs): Promise<boolean>;
243
+ /** Simulate `verifyReputation` for gas / revert checks. */
244
+ simulateReputationVerification<TTransport extends Transport, TChain extends Chain, TAccount extends Account | undefined>(wallet: WalletClient<TTransport, TChain, TAccount>, args: VerifyReputationArgs): Promise<void>;
245
+ /** Broadcast `verifyReputation` (consumes nullifier when successful). */
246
+ submitReputationVerification<TTransport extends Transport, TChain extends Chain, TAccount extends Account | undefined>(wallet: WalletClient<TTransport, TChain, TAccount>, args: VerifyReputationArgs): Promise<Hex>;
247
+ private getReputationVerifierAddress;
248
+ /**
249
+ * Deterministic scope string for reputation actions (`chainId:module:actionId`).
250
+ * Same as {@link buildActionScope} in `@opaquecash/psr-core`.
251
+ */
252
+ static buildReputationActionScope: typeof buildActionScope;
253
+ /**
254
+ * Map a scope string to the circuit `externalNullifier` scalar (keccak, uint256).
255
+ * Same as {@link externalNullifierFromScope} in `@opaquecash/psr-core`.
256
+ */
257
+ static reputationExternalNullifierFromScope: typeof externalNullifierFromScope;
258
+ /**
259
+ * Chain IDs that ship with bundled contract addresses in this SDK version.
260
+ */
261
+ static supportedChainIds(): number[];
262
+ /**
263
+ * Read bundled deployment metadata (contracts, default tokens) for a chain.
264
+ */
265
+ static chainDeployment(chainId: number): OpaqueChainDeployment | undefined;
266
+ }
267
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,GAAG,EAER,KAAK,SAAS,EACd,KAAK,YAAY,EAMlB,MAAM,MAAM,CAAC;AAcd,OAAO,EAEL,gBAAgB,EAChB,0BAA0B,EAC1B,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAC;AAUrC,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,aAAa,CAAC;AAKrB,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAY5B;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gGAAgG;IAChG,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,eAAe,EAAE,GAAG,CAAC;IACrB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,CAAC;QAClB,0BAA0B,EAAE,OAAO,CAAC;QACpC,uBAAuB,EAAE,OAAO,CAAC;QACjC,wBAAwB,EAAE,OAAO,CAAC;KACnC,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,kBAAkB,EAAE,UAAU,CAAC;IAC/B,yFAAyF;IACzF,mBAAmB,EAAE,UAAU,CAAC;IAChC,+EAA+E;IAC/E,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,wBAAwB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,GAAG,CAAC;QACxB,QAAQ,EAAE,GAAG,CAAC;KACf,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qCAAqC;IACpD,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,GAAG,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8FAA8F;IAC9F,UAAU,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,cAAc,CAAC,EAAE,GAAG,CAAC;CACtB;AAUD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAU;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IAEzC,OAAO;IAmCP;;OAEG;WACU,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC;IA0BtE,mCAAmC;IACnC,UAAU,IAAI,MAAM;IAIpB,gDAAgD;IAChD,kBAAkB,IAAI,OAAO;IAI7B,uDAAuD;IACvD,iBAAiB,IAAI,GAAG;IAIxB,wDAAwD;IACxD,YAAY,IAAI;QACd,0BAA0B,EAAE,OAAO,CAAC;QACpC,uBAAuB,EAAE,OAAO,CAAC;QACjC,wBAAwB,CAAC,EAAE,OAAO,CAAC;KACpC;IAQD;;;;;;;;OAQG;IACG,2BAA2B,CAC/B,gBAAgB,EAAE,OAAO,GACxB,OAAO,CAAC,0BAA0B,CAAC;IAsBtC;;OAEG;IACH,mCAAmC,IAAI,qCAAqC;IAe5E;;OAEG;IACH,kBAAkB,CAAC,uBAAuB,EAAE,GAAG,GAAG,wBAAwB;IAY1E;;;;;OAKG;IACH,mBAAmB,IAAI,yBAAyB;IAIhD;;;;;OAKG;IACH,uCAAuC,CACrC,mBAAmB,EAAE,UAAU,GAC9B,0BAA0B;IAe7B;;OAEG;IACH,+BAA+B,CAC7B,IAAI,EAAE,wBAAwB,GAC7B,0BAA0B;IAqB7B;;OAEG;IACG,wBAAwB,CAC5B,IAAI,EAAE,mBAAmB,EAAE,GAC1B,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA+BhC;;;;;;;OAOG;IACH,0BAA0B,CACxB,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,GACrD,UAAU;IAeb;;;;OAIG;IACH,iDAAiD,CAC/C,mBAAmB,EAAE,UAAU,GAC9B,UAAU;IAWb;;OAEG;IACG,4BAA4B,CAChC,IAAI,EAAE,mBAAmB,EAAE,GAC1B,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAmCjC;;OAEG;IACG,cAAc,CAClB,IAAI,EAAE,mBAAmB,EAAE,GAC1B,OAAO,CAAC,eAAe,EAAE,CAAC;IAa7B;;OAEG;IACG,oCAAoC,CACxC,IAAI,EAAE,mBAAmB,EAAE,GAC1B,OAAO,CAAC,eAAe,EAAE,CAAC;IAI7B;;;OAGG;IACH,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,UAAU;IAS5E;;OAEG;IACH,2BAA2B,CACzB,uBAAuB,EAAE,GAAG,EAC5B,aAAa,EAAE,MAAM,GACpB,wBAAwB;IAM3B;;OAEG;IACH,gCAAgC,CAC9B,uBAAuB,EAAE,GAAG,EAC5B,aAAa,EAAE,MAAM,GACpB,0BAA0B;IAM7B;;OAEG;IACH,qCAAqC,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,MAAM;IAI1E;;OAEG;IACH,4CAA4C,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU;IAYhF;;;;OAIG;IACG,uBAAuB,CAAC,MAAM,EAAE;QACpC,KAAK,EAAE,eAAe,CAAC;QACvB,mBAAmB,EAAE,UAAU,CAAC;QAChC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,SAAS,CAAC,EAAE,aAAa,CAAC;QAC1B,UAAU,CAAC,EAAE,qBAAqB,CAAC;KACpC,GAAG,OAAO,CAAC,SAAS,CAAC;IAatB,kFAAkF;IAC5E,8BAA8B,IAAI,OAAO,CAAC,GAAG,CAAC;IAOpD,qFAAqF;IAC/E,qBAAqB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAQxD,qEAAqE;IAC/D,0BAA0B,IAAI,OAAO,CACzC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CACpD;IAOD,qEAAqE;IAC/D,yBAAyB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ7E,2DAA2D;IACrD,8BAA8B,CAClC,UAAU,SAAS,SAAS,EAC5B,MAAM,SAAS,KAAK,EACpB,QAAQ,SAAS,OAAO,GAAG,SAAS,EAEpC,MAAM,EAAE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAClD,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;IAShB,yEAAyE;IACnE,4BAA4B,CAChC,UAAU,SAAS,SAAS,EAC5B,MAAM,SAAS,KAAK,EACpB,QAAQ,SAAS,OAAO,GAAG,SAAS,EAEpC,MAAM,EAAE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAClD,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,GAAG,CAAC;IASf,OAAO,CAAC,4BAA4B;IASpC;;;OAGG;IACH,MAAM,CAAC,0BAA0B,0BAAoB;IAErD;;;OAGG;IACH,MAAM,CAAC,oCAAoC,oCAA8B;IAEzE;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,MAAM,EAAE;IAIpC;;OAEG;IACH,MAAM,CAAC,eAAe,CACpB,OAAO,EAAE,MAAM,GACd,qBAAqB,GAAG,SAAS;CAGrC"}
package/dist/client.js ADDED
@@ -0,0 +1,438 @@
1
+ import { createPublicClient, http, encodeFunctionData, getAddress, hexToBytes, } from "viem";
2
+ import { EIP5564_SCHEME_SECP256K1 } from "@opaquecash/stealth-core";
3
+ import { stealthMetaAddressRegistryAbi, stealthAddressAnnouncerAbi, getStealthMetaAddress as readRegistryMetaAddress, } from "@opaquecash/stealth-chain";
4
+ import { encodeAttestationMetadata, initStealthWasm, reconstructSigningKey, scanAttestationsJson, } from "@opaquecash/stealth-wasm";
5
+ import { attestationsToDiscoveredTraits, buildActionScope, externalNullifierFromScope, } from "@opaquecash/psr-core";
6
+ import { fetchLatestValidRoot, fetchRootHistory, isRootValid, simulateVerifyReputation, submitVerifyReputation, verifyReputationView, } from "@opaquecash/psr-chain";
7
+ import { ensureBufferPolyfill, generateReputationProof as runGenerateReputationProof, } from "@opaquecash/psr-prover";
8
+ import { aggregateBalancesByToken, } from "@opaquecash/stealth-balance";
9
+ import { deriveKeysFromSignature, keysToStealthMetaAddress, stealthMetaAddressToHex, computeStealthAddressAndViewTag, recomputeStealthSendFromEphemeralPrivateKey, ephemeralPrivateKeyToCompressedPublicKey, } from "./crypto/dksap.js";
10
+ import { getChainDeployment as getChainDeploymentInfo, getSupportedChainIds, requireChainDeployment, NATIVE_TOKEN_ADDRESS, } from "./chains.js";
11
+ import { indexerAnnouncementsToScannerJson, } from "./indexer/normalize.js";
12
+ const ERC20_BALANCE_ABI = [
13
+ {
14
+ type: "function",
15
+ name: "balanceOf",
16
+ stateMutability: "view",
17
+ inputs: [{ name: "account", type: "address" }],
18
+ outputs: [{ type: "uint256" }],
19
+ },
20
+ ];
21
+ export class OpaqueClient {
22
+ config;
23
+ deployment;
24
+ registry;
25
+ announcer;
26
+ reputationVerifier;
27
+ tokens;
28
+ viewingKey;
29
+ spendingKey;
30
+ spendPubKey;
31
+ metaAddressHex;
32
+ publicClient;
33
+ wasm;
34
+ constructor(config, deployment, wasm, keys) {
35
+ this.config = config;
36
+ this.deployment = deployment;
37
+ this.registry =
38
+ config.contracts?.stealthMetaAddressRegistry ??
39
+ deployment.stealthMetaAddressRegistry;
40
+ this.announcer =
41
+ config.contracts?.stealthAddressAnnouncer ??
42
+ deployment.stealthAddressAnnouncer;
43
+ this.reputationVerifier =
44
+ config.contracts?.opaqueReputationVerifier ??
45
+ deployment.opaqueReputationVerifier;
46
+ const baseTokens = deployment.defaultTrackedTokens;
47
+ const extra = config.trackedTokens ?? [];
48
+ this.tokens = mergeTrackedTokens(baseTokens, extra);
49
+ this.viewingKey = keys.viewingKey;
50
+ this.spendingKey = keys.spendingKey;
51
+ this.spendPubKey = keys.spendPubKey;
52
+ this.metaAddressHex = keys.metaAddressHex;
53
+ this.publicClient = createPublicClient({
54
+ transport: http(config.rpcUrl),
55
+ });
56
+ this.wasm = wasm;
57
+ }
58
+ /**
59
+ * Construct a client: loads WASM, derives keys from `walletSignature`, wires RPC + addresses.
60
+ */
61
+ static async create(config) {
62
+ const deployment = requireChainDeployment(config.chainId);
63
+ const wasm = await initStealthWasm({
64
+ moduleSpecifier: config.wasmModuleSpecifier,
65
+ });
66
+ const { viewingKey, spendingKey } = deriveKeysFromSignature(config.walletSignature);
67
+ const { S, metaAddress } = keysToStealthMetaAddress(viewingKey, spendingKey);
68
+ const metaAddressHex = stealthMetaAddressToHex(metaAddress);
69
+ return new OpaqueClient(config, deployment, wasm, {
70
+ viewingKey,
71
+ spendingKey,
72
+ spendPubKey: S,
73
+ metaAddressHex,
74
+ });
75
+ }
76
+ /** Chain id from configuration. */
77
+ getChainId() {
78
+ return this.config.chainId;
79
+ }
80
+ /** Connected Ethereum address (from config). */
81
+ getEthereumAddress() {
82
+ return this.config.ethereumAddress;
83
+ }
84
+ /** 66-byte meta-address hex for registry / sharing. */
85
+ getMetaAddressHex() {
86
+ return this.metaAddressHex;
87
+ }
88
+ /** Resolved contract addresses for the active chain. */
89
+ getContracts() {
90
+ return {
91
+ stealthMetaAddressRegistry: this.registry,
92
+ stealthAddressAnnouncer: this.announcer,
93
+ opaqueReputationVerifier: this.reputationVerifier,
94
+ };
95
+ }
96
+ /**
97
+ * Look up a recipient’s stealth meta-address on `StealthMetaAddressRegistry` using this client’s
98
+ * `rpcUrl` and configured registry (scheme id {@link EIP5564_SCHEME_SECP256K1}).
99
+ *
100
+ * When the account has not registered, `registered` is false and `metaAddressHex` is omitted —
101
+ * `recipientAddress` is still the checksummed address you passed in so you can show “not on Opaque yet”.
102
+ *
103
+ * @param recipientAddress - Normal Ethereum address of the intended recipient.
104
+ */
105
+ async resolveRecipientMetaAddress(recipientAddress) {
106
+ const recipient = getAddress(recipientAddress);
107
+ const schemeId = BigInt(EIP5564_SCHEME_SECP256K1);
108
+ const bytes = await readRegistryMetaAddress(this.publicClient, {
109
+ registryAddress: this.registry,
110
+ registrant: recipient,
111
+ schemeId,
112
+ });
113
+ const byteLen = hexPayloadByteLength(bytes);
114
+ if (byteLen < 66) {
115
+ return {
116
+ recipientAddress: recipient,
117
+ registered: false,
118
+ };
119
+ }
120
+ return {
121
+ recipientAddress: recipient,
122
+ registered: true,
123
+ metaAddressHex: bytes,
124
+ };
125
+ }
126
+ /**
127
+ * Encode `registerKeys` for the user's meta-address (they submit with `ethereumAddress`).
128
+ */
129
+ buildRegisterMetaAddressTransaction() {
130
+ const schemeId = BigInt(EIP5564_SCHEME_SECP256K1);
131
+ const data = encodeFunctionData({
132
+ abi: stealthMetaAddressRegistryAbi,
133
+ functionName: "registerKeys",
134
+ args: [schemeId, this.metaAddressHex],
135
+ });
136
+ return {
137
+ to: this.registry,
138
+ data,
139
+ chainId: this.config.chainId,
140
+ metaAddressHex: this.metaAddressHex,
141
+ };
142
+ }
143
+ /**
144
+ * Derive a one-time stealth address for sending to a recipient meta-address.
145
+ */
146
+ prepareStealthSend(recipientMetaAddressHex) {
147
+ const r = computeStealthAddressAndViewTag(recipientMetaAddressHex);
148
+ return {
149
+ schemeId: BigInt(EIP5564_SCHEME_SECP256K1),
150
+ stealthAddress: r.stealthAddress,
151
+ viewTag: r.viewTag,
152
+ ephemeralPublicKey: r.ephemeralPubKey,
153
+ ephemeralPrivateKey: r.ephemeralPriv,
154
+ metadata: r.metadata,
155
+ };
156
+ }
157
+ /**
158
+ * Manual “ghost” receive: derive a one-time stealth address for **this** wallet’s meta-address
159
+ * without any on-chain announcement yet. Cryptographically this is {@link prepareStealthSend}
160
+ * with {@link getMetaAddressHex}; you must persist `ephemeralPrivateKey` (and optionally the
161
+ * full prep) securely to sweep funds or to announce later.
162
+ */
163
+ prepareGhostReceive() {
164
+ return this.prepareStealthSend(this.metaAddressHex);
165
+ }
166
+ /**
167
+ * Build `announce` calldata after you only have the stored 32-byte ephemeral secret from
168
+ * {@link prepareGhostReceive} (or any prior {@link prepareStealthSend} to your meta-address).
169
+ * Recomputes stealth address and pubkey material deterministically. If you still have the full
170
+ * {@link PrepareStealthSendResult} object, {@link buildAnnounceTransactionRequest} is enough.
171
+ */
172
+ buildAnnounceTransactionRequestForGhost(ephemeralPrivateKey) {
173
+ const r = recomputeStealthSendFromEphemeralPrivateKey(this.metaAddressHex, ephemeralPrivateKey);
174
+ return this.buildAnnounceTransactionRequest({
175
+ schemeId: BigInt(EIP5564_SCHEME_SECP256K1),
176
+ stealthAddress: r.stealthAddress,
177
+ viewTag: r.viewTag,
178
+ ephemeralPublicKey: r.ephemeralPubKey,
179
+ ephemeralPrivateKey: r.ephemeralPriv,
180
+ metadata: r.metadata,
181
+ });
182
+ }
183
+ /**
184
+ * Build calldata for `announce` so the developer can prompt the user to broadcast.
185
+ */
186
+ buildAnnounceTransactionRequest(send) {
187
+ const ephemeralHex = (`0x${bytesToHex(send.ephemeralPublicKey)}`);
188
+ const metadataHex = (`0x${bytesToHex(send.metadata)}`);
189
+ const data = encodeFunctionData({
190
+ abi: stealthAddressAnnouncerAbi,
191
+ functionName: "announce",
192
+ args: [send.schemeId, send.stealthAddress, ephemeralHex, metadataHex],
193
+ });
194
+ return {
195
+ to: this.announcer,
196
+ data,
197
+ chainId: this.config.chainId,
198
+ summary: {
199
+ schemeId: send.schemeId,
200
+ stealthAddress: send.stealthAddress,
201
+ ephemeralPublicKey: ephemeralHex,
202
+ metadata: metadataHex,
203
+ },
204
+ };
205
+ }
206
+ /**
207
+ * Filter indexer announcements down to outputs owned by this user (WASM scan).
208
+ */
209
+ async filterOwnedAnnouncements(rows) {
210
+ if (rows.length === 0)
211
+ return [];
212
+ const json = indexerAnnouncementsToScannerJson(rows);
213
+ const out = scanAttestationsJson(this.wasm, json, this.viewingKey, this.spendPubKey);
214
+ const list = JSON.parse(out);
215
+ const owned = [];
216
+ for (const att of list) {
217
+ const row = rows.find((r) => r.transactionHash.toLowerCase() === att.tx_hash.toLowerCase() &&
218
+ r.stealthAddress.toLowerCase() === att.stealth_address.toLowerCase());
219
+ const epk = (`0x${att.ephemeral_pubkey.map((b) => b.toString(16).padStart(2, "0")).join("")}`);
220
+ owned.push({
221
+ stealthAddress: getAddress(att.stealth_address),
222
+ transactionHash: att.tx_hash,
223
+ blockNumber: att.block_number,
224
+ logIndex: row?.logIndex ?? 0,
225
+ viewTag: row?.viewTag ?? 0,
226
+ ephemeralPublicKey: epk,
227
+ attestationId: att.attestation_id,
228
+ });
229
+ }
230
+ return owned;
231
+ }
232
+ /**
233
+ * Reconstruct the 32-byte secp256k1 private key that controls `output`’s one-time stealth address.
234
+ * Uses the same WASM path as the on-chain scanner (`reconstruct_signing_key_wasm`).
235
+ *
236
+ * You supply gas, nonce, and broadcast: build a viem `PrivateKeyAccount` (or ethers wallet) from
237
+ * the returned bytes and sign a transfer **from** `output.stealthAddress`. Never log or persist
238
+ * the result beyond what your threat model allows.
239
+ */
240
+ getStealthSignerPrivateKey(output) {
241
+ const ephemeralPubkeyBytes = hexToBytes(output.ephemeralPublicKey);
242
+ if (ephemeralPubkeyBytes.length !== 33) {
243
+ throw new Error("Opaque: ephemeralPublicKey must be 33-byte compressed secp256k1 hex");
244
+ }
245
+ return reconstructSigningKey(this.wasm, this.spendingKey, this.viewingKey, ephemeralPubkeyBytes);
246
+ }
247
+ /**
248
+ * Same as {@link getStealthSignerPrivateKey} when you only have the 32-byte ephemeral **private**
249
+ * key from {@link prepareGhostReceive} / {@link prepareStealthSend} (e.g. ghost storage) instead
250
+ * of an indexer row with `ephemeralPublicKey`.
251
+ */
252
+ getStealthSignerPrivateKeyFromEphemeralPrivateKey(ephemeralPrivateKey) {
253
+ const ephemeralPubkeyBytes = ephemeralPrivateKeyToCompressedPublicKey(ephemeralPrivateKey);
254
+ return reconstructSigningKey(this.wasm, this.spendingKey, this.viewingKey, ephemeralPubkeyBytes);
255
+ }
256
+ /**
257
+ * Owned outputs + balances summed per tracked token (uses `rpcUrl` from config).
258
+ */
259
+ async getBalancesFromAnnouncements(rows) {
260
+ const owned = await this.filterOwnedAnnouncements(rows);
261
+ const unique = [...new Map(owned.map((o) => [o.stealthAddress, o])).values()];
262
+ const outputs = [];
263
+ for (const o of unique) {
264
+ const balances = {};
265
+ for (const t of this.tokens) {
266
+ if (t.address.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase()) {
267
+ const wei = await this.publicClient.getBalance({
268
+ address: o.stealthAddress,
269
+ });
270
+ balances[NATIVE_TOKEN_ADDRESS] = wei;
271
+ }
272
+ else {
273
+ const bal = await this.publicClient.readContract({
274
+ address: t.address,
275
+ abi: ERC20_BALANCE_ABI,
276
+ functionName: "balanceOf",
277
+ args: [o.stealthAddress],
278
+ });
279
+ balances[t.address] = bal;
280
+ }
281
+ }
282
+ outputs.push({ stealthAddress: o.stealthAddress, balances });
283
+ }
284
+ const totals = aggregateBalancesByToken(outputs);
285
+ return this.tokens.map((t) => ({
286
+ tokenAddress: t.address,
287
+ symbol: t.symbol,
288
+ decimals: t.decimals,
289
+ totalRaw: totals.get(t.address.toLowerCase()) ?? 0n,
290
+ }));
291
+ }
292
+ /**
293
+ * PSR: map owned attestation markers to {@link DiscoveredTrait} list.
294
+ */
295
+ async discoverTraits(rows) {
296
+ if (rows.length === 0)
297
+ return [];
298
+ const json = indexerAnnouncementsToScannerJson(rows);
299
+ const out = scanAttestationsJson(this.wasm, json, this.viewingKey, this.spendPubKey);
300
+ const list = JSON.parse(out);
301
+ return attestationsToDiscoveredTraits(list);
302
+ }
303
+ /**
304
+ * PSR: same as {@link discoverTraits} — alias for reputation-focused call sites.
305
+ */
306
+ async getReputationTraitsFromAnnouncements(rows) {
307
+ return this.discoverTraits(rows);
308
+ }
309
+ /**
310
+ * Encode `announce` metadata for a PSR attestation (view tag byte + `0xA7` + u64 `attestationId`).
311
+ * Canonical encoding matches WASM/Rust; use with {@link prepareReputationAssignment}.
312
+ */
313
+ encodeReputationMetadata(viewTag, attestationId) {
314
+ const hex = encodeAttestationMetadata(this.wasm, viewTag, attestationId);
315
+ return hexToBytes(hex);
316
+ }
317
+ /**
318
+ * Issuer flow: derive one-time stealth material for the recipient and embed `attestationId` in metadata.
319
+ */
320
+ prepareReputationAssignment(recipientMetaAddressHex, attestationId) {
321
+ const prep = this.prepareStealthSend(recipientMetaAddressHex);
322
+ const metadata = this.encodeReputationMetadata(prep.viewTag, attestationId);
323
+ return { ...prep, metadata };
324
+ }
325
+ /**
326
+ * Issuer flow: calldata for `StealthAddressAnnouncer.announce` with PSR metadata (no asset transfer).
327
+ */
328
+ buildAssignReputationTransaction(recipientMetaAddressHex, attestationId) {
329
+ return this.buildAnnounceTransactionRequest(this.prepareReputationAssignment(recipientMetaAddressHex, attestationId));
330
+ }
331
+ /**
332
+ * JSON array string for {@link generateReputationProof} when passing `attestationsJson` (WASM Merkle witness).
333
+ */
334
+ announcementsJsonForReputationWitness(rows) {
335
+ return indexerAnnouncementsToScannerJson(rows);
336
+ }
337
+ /**
338
+ * One-time stealth signing key for a {@link DiscoveredTrait} (requires `ephemeralPubkey` from the scan).
339
+ */
340
+ getStealthSignerPrivateKeyForReputationTrait(trait) {
341
+ if (!trait.ephemeralPubkey?.length) {
342
+ throw new Error("Opaque: DiscoveredTrait.ephemeralPubkey is required (use discoverTraits / getReputationTraitsFromAnnouncements)");
343
+ }
344
+ const ephemeralPublicKey = (`0x${trait.ephemeralPubkey
345
+ .map((b) => b.toString(16).padStart(2, "0"))
346
+ .join("")}`);
347
+ return this.getStealthSignerPrivateKey({ ephemeralPublicKey });
348
+ }
349
+ /**
350
+ * Groth16 proof bundle for `OpaqueReputationVerifier` (requires `snarkjs`).
351
+ * When `artifacts` is omitted, wasm/zkey are loaded from the default hosted paths on opaque.cash
352
+ * (same as the Opaque frontend `/circuits/...` assets).
353
+ */
354
+ async generateReputationProof(params) {
355
+ await ensureBufferPolyfill();
356
+ return runGenerateReputationProof({
357
+ wasm: this.wasm,
358
+ trait: params.trait,
359
+ stealthPrivKeyBytes: params.stealthPrivKeyBytes,
360
+ externalNullifier: params.externalNullifier,
361
+ attestationsJson: params.attestationsJson,
362
+ artifacts: params.artifacts,
363
+ onProgress: params.onProgress,
364
+ });
365
+ }
366
+ /** Latest non-expired Merkle root from `OpaqueReputationVerifier.rootHistory`. */
367
+ async fetchLatestValidReputationRoot() {
368
+ return fetchLatestValidRoot(this.publicClient, this.getReputationVerifierAddress());
369
+ }
370
+ /** Whether the verifier currently accepts this root (exists and not past expiry). */
371
+ async isReputationRootValid(root) {
372
+ return isRootValid(this.publicClient, this.getReputationVerifierAddress(), root);
373
+ }
374
+ /** Full root history with per-entry validity (newest index last). */
375
+ async fetchReputationRootHistory() {
376
+ return fetchRootHistory(this.publicClient, this.getReputationVerifierAddress());
377
+ }
378
+ /** On-chain view helper: verify proof without spending nullifier. */
379
+ async verifyReputationProofView(args) {
380
+ return verifyReputationView(this.publicClient, this.getReputationVerifierAddress(), args);
381
+ }
382
+ /** Simulate `verifyReputation` for gas / revert checks. */
383
+ async simulateReputationVerification(wallet, args) {
384
+ return simulateVerifyReputation(this.publicClient, wallet, this.getReputationVerifierAddress(), args);
385
+ }
386
+ /** Broadcast `verifyReputation` (consumes nullifier when successful). */
387
+ async submitReputationVerification(wallet, args) {
388
+ return submitVerifyReputation(this.publicClient, wallet, this.getReputationVerifierAddress(), args);
389
+ }
390
+ getReputationVerifierAddress() {
391
+ if (!this.reputationVerifier) {
392
+ throw new Error("Opaque: opaqueReputationVerifier is not configured for this chain. Set contracts.opaqueReputationVerifier in OpaqueClient.create or use a bundled deployment.");
393
+ }
394
+ return this.reputationVerifier;
395
+ }
396
+ /**
397
+ * Deterministic scope string for reputation actions (`chainId:module:actionId`).
398
+ * Same as {@link buildActionScope} in `@opaquecash/psr-core`.
399
+ */
400
+ static buildReputationActionScope = buildActionScope;
401
+ /**
402
+ * Map a scope string to the circuit `externalNullifier` scalar (keccak, uint256).
403
+ * Same as {@link externalNullifierFromScope} in `@opaquecash/psr-core`.
404
+ */
405
+ static reputationExternalNullifierFromScope = externalNullifierFromScope;
406
+ /**
407
+ * Chain IDs that ship with bundled contract addresses in this SDK version.
408
+ */
409
+ static supportedChainIds() {
410
+ return getSupportedChainIds();
411
+ }
412
+ /**
413
+ * Read bundled deployment metadata (contracts, default tokens) for a chain.
414
+ */
415
+ static chainDeployment(chainId) {
416
+ return getChainDeploymentInfo(chainId);
417
+ }
418
+ }
419
+ function bytesToHex(b) {
420
+ return Array.from(b)
421
+ .map((x) => x.toString(16).padStart(2, "0"))
422
+ .join("");
423
+ }
424
+ function hexPayloadByteLength(h) {
425
+ const s = h.startsWith("0x") ? h.slice(2) : h;
426
+ return s.length / 2;
427
+ }
428
+ function mergeTrackedTokens(base, extra) {
429
+ const map = new Map();
430
+ for (const t of base) {
431
+ map.set(t.address.toLowerCase(), t);
432
+ }
433
+ for (const t of extra) {
434
+ map.set(t.address.toLowerCase(), t);
435
+ }
436
+ return [...map.values()];
437
+ }
438
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * EIP-5564 sender/receiver key material — matches Opaque wallet derivation (`opaque-cash-v1` HKDF).
3
+ */
4
+ import type { Hex } from "viem";
5
+ import { type Address } from "viem";
6
+ export declare function deriveKeysFromSignature(signatureHex: Hex): {
7
+ viewingKey: Uint8Array;
8
+ spendingKey: Uint8Array;
9
+ };
10
+ export declare function keysToStealthMetaAddress(viewingKey: Uint8Array, spendingKey: Uint8Array): {
11
+ V: Uint8Array;
12
+ S: Uint8Array;
13
+ metaAddress: Uint8Array;
14
+ };
15
+ export declare function stealthMetaAddressToHex(metaAddress: Uint8Array): Hex;
16
+ export declare function parseStealthMetaAddress(metaHex: Hex): {
17
+ viewPubKey: Uint8Array;
18
+ spendPubKey: Uint8Array;
19
+ };
20
+ export declare function computeStealthAddressAndViewTag(recipientMetaAddressHex: Hex): {
21
+ ephemeralPriv: Uint8Array;
22
+ ephemeralPubKey: Uint8Array;
23
+ stealthAddress: Address;
24
+ viewTag: number;
25
+ metadata: Uint8Array;
26
+ };
27
+ /**
28
+ * Re-derive stealth material from a fixed 32-byte ephemeral secret (manual “ghost” receive).
29
+ * Must match {@link computeStealthAddressAndViewTag} for the same meta-address and scalar.
30
+ */
31
+ /** 33-byte compressed secp256k1 pubkey for a 32-byte ephemeral secret (sender ghost material). */
32
+ export declare function ephemeralPrivateKeyToCompressedPublicKey(ephemeralPrivateKey: Uint8Array): Uint8Array;
33
+ export declare function recomputeStealthSendFromEphemeralPrivateKey(recipientMetaAddressHex: Hex, ephemeralPrivateKey: Uint8Array): {
34
+ ephemeralPriv: Uint8Array;
35
+ ephemeralPubKey: Uint8Array;
36
+ stealthAddress: Address;
37
+ viewTag: number;
38
+ metadata: Uint8Array;
39
+ };
40
+ //# sourceMappingURL=dksap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dksap.d.ts","sourceRoot":"","sources":["../../src/crypto/dksap.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAKhD,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,GAAG,GAAG;IAC1D,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,UAAU,CAAC;CACzB,CAWA;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,UAAU,GACtB;IAAE,CAAC,EAAE,UAAU,CAAC;IAAC,CAAC,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,UAAU,CAAA;CAAE,CAO3D;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,UAAU,GAAG,GAAG,CAEpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,GAAG,GAAG;IACrD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,UAAU,CAAC;CACzB,CAaA;AAuCD,wBAAgB,+BAA+B,CAAC,uBAAuB,EAAE,GAAG,GAAG;IAC7E,aAAa,EAAE,UAAU,CAAC;IAC1B,eAAe,EAAE,UAAU,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAiBA;AAED;;;GAGG;AACH,kGAAkG;AAClG,wBAAgB,wCAAwC,CACtD,mBAAmB,EAAE,UAAU,GAC9B,UAAU,CAKZ;AAED,wBAAgB,2CAA2C,CACzD,uBAAuB,EAAE,GAAG,EAC5B,mBAAmB,EAAE,UAAU,GAC9B;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,eAAe,EAAE,UAAU,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAoBA"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * EIP-5564 sender/receiver key material — matches Opaque wallet derivation (`opaque-cash-v1` HKDF).
3
+ */
4
+ import { secp256k1 } from "@noble/curves/secp256k1";
5
+ import { keccak_256 } from "@noble/hashes/sha3";
6
+ import { hkdf } from "@noble/hashes/hkdf";
7
+ import { sha256 } from "@noble/hashes/sha2";
8
+ import { getAddress } from "viem";
9
+ const CURVE = secp256k1;
10
+ const DOMAIN = "opaque-cash-v1";
11
+ export function deriveKeysFromSignature(signatureHex) {
12
+ const sigBytes = typeof signatureHex === "string"
13
+ ? signatureHex.startsWith("0x")
14
+ ? signatureHex.slice(2)
15
+ : signatureHex
16
+ : signatureHex;
17
+ const sig = typeof sigBytes === "string" ? hexToBytes(sigBytes) : sigBytes;
18
+ const okm = hkdf(sha256, sig, undefined, DOMAIN, 64);
19
+ return { viewingKey: okm.slice(0, 32), spendingKey: okm.slice(32, 64) };
20
+ }
21
+ export function keysToStealthMetaAddress(viewingKey, spendingKey) {
22
+ const V = CURVE.getPublicKey(viewingKey, true);
23
+ const S = CURVE.getPublicKey(spendingKey, true);
24
+ const metaAddress = new Uint8Array(V.length + S.length);
25
+ metaAddress.set(V, 0);
26
+ metaAddress.set(S, V.length);
27
+ return { V, S, metaAddress };
28
+ }
29
+ export function stealthMetaAddressToHex(metaAddress) {
30
+ return (`0x${bytesToHex(metaAddress)}`);
31
+ }
32
+ export function parseStealthMetaAddress(metaHex) {
33
+ const raw = typeof metaHex === "string" && metaHex.startsWith("0x")
34
+ ? metaHex.slice(2)
35
+ : metaHex;
36
+ const bytes = hexToBytes(raw);
37
+ if (bytes.length < 66) {
38
+ throw new Error("Invalid stealth meta-address: expected 66 bytes");
39
+ }
40
+ return {
41
+ viewPubKey: bytes.slice(0, 33),
42
+ spendPubKey: bytes.slice(33, 66),
43
+ };
44
+ }
45
+ function sharedSecretSender(ephemeralPriv, viewPubKey) {
46
+ const P = CURVE.ProjectivePoint.fromHex(viewPubKey);
47
+ const scalar = bytesToBigInt(ephemeralPriv) % CURVE.CURVE.n;
48
+ if (scalar === 0n)
49
+ throw new Error("Invalid ephemeral key");
50
+ return P.multiply(scalar).toRawBytes(true);
51
+ }
52
+ function hashSharedSecret(sharedSecret) {
53
+ const sH = keccak_256(sharedSecret);
54
+ return { sH, viewTag: sH[0] };
55
+ }
56
+ function stealthPointAndAddress(spendPubKey, sH) {
57
+ const n = CURVE.CURVE.n;
58
+ const sHBig = bytesToBigInt(sH);
59
+ const sHMod = sHBig % n;
60
+ if (sHMod === 0n)
61
+ throw new Error("Invalid scalar from hash");
62
+ const S_h = CURVE.ProjectivePoint.BASE.multiply(sHMod);
63
+ const P_spend = CURVE.ProjectivePoint.fromHex(spendPubKey);
64
+ const P_stealth = P_spend.add(S_h);
65
+ const uncompressed = P_stealth.toRawBytes(false);
66
+ const hash = keccak_256(uncompressed.slice(1));
67
+ const addr = getAddress((`0x${bytesToHex(hash.slice(12))}`));
68
+ return { stealthAddress: addr };
69
+ }
70
+ export function computeStealthAddressAndViewTag(recipientMetaAddressHex) {
71
+ const { viewPubKey, spendPubKey } = parseStealthMetaAddress(recipientMetaAddressHex);
72
+ const ephemeralPriv = CURVE.utils.randomPrivateKey();
73
+ const ephemeralPubKey = CURVE.getPublicKey(ephemeralPriv, true);
74
+ const shared = sharedSecretSender(ephemeralPriv, viewPubKey);
75
+ const { sH, viewTag } = hashSharedSecret(shared);
76
+ const { stealthAddress } = stealthPointAndAddress(spendPubKey, sH);
77
+ const metadata = new Uint8Array(1);
78
+ metadata[0] = viewTag;
79
+ return {
80
+ ephemeralPriv,
81
+ ephemeralPubKey,
82
+ stealthAddress,
83
+ viewTag,
84
+ metadata,
85
+ };
86
+ }
87
+ /**
88
+ * Re-derive stealth material from a fixed 32-byte ephemeral secret (manual “ghost” receive).
89
+ * Must match {@link computeStealthAddressAndViewTag} for the same meta-address and scalar.
90
+ */
91
+ /** 33-byte compressed secp256k1 pubkey for a 32-byte ephemeral secret (sender ghost material). */
92
+ export function ephemeralPrivateKeyToCompressedPublicKey(ephemeralPrivateKey) {
93
+ if (ephemeralPrivateKey.length !== 32) {
94
+ throw new Error("Ephemeral private key must be 32 bytes.");
95
+ }
96
+ return CURVE.getPublicKey(ephemeralPrivateKey, true);
97
+ }
98
+ export function recomputeStealthSendFromEphemeralPrivateKey(recipientMetaAddressHex, ephemeralPrivateKey) {
99
+ if (ephemeralPrivateKey.length !== 32) {
100
+ throw new Error("Ephemeral private key must be 32 bytes.");
101
+ }
102
+ const { viewPubKey, spendPubKey } = parseStealthMetaAddress(recipientMetaAddressHex);
103
+ const ephemeralPriv = ephemeralPrivateKey;
104
+ const ephemeralPubKey = CURVE.getPublicKey(ephemeralPriv, true);
105
+ const shared = sharedSecretSender(ephemeralPriv, viewPubKey);
106
+ const { sH, viewTag } = hashSharedSecret(shared);
107
+ const { stealthAddress } = stealthPointAndAddress(spendPubKey, sH);
108
+ const metadata = new Uint8Array(1);
109
+ metadata[0] = viewTag;
110
+ return {
111
+ ephemeralPriv,
112
+ ephemeralPubKey,
113
+ stealthAddress,
114
+ viewTag,
115
+ metadata,
116
+ };
117
+ }
118
+ function hexToBytes(hex) {
119
+ const h = hex.startsWith("0x") ? hex.slice(2) : hex;
120
+ if (h.length % 2)
121
+ throw new Error("Invalid hex length");
122
+ const out = new Uint8Array(h.length / 2);
123
+ for (let i = 0; i < out.length; i++) {
124
+ out[i] = Number.parseInt(h.slice(i * 2, i * 2 + 2), 16);
125
+ }
126
+ return out;
127
+ }
128
+ function bytesToHex(b) {
129
+ return Array.from(b)
130
+ .map((x) => x.toString(16).padStart(2, "0"))
131
+ .join("");
132
+ }
133
+ function bytesToBigInt(b) {
134
+ let x = 0n;
135
+ for (let i = 0; i < b.length; i++)
136
+ x = (x << 8n) | BigInt(b[i]);
137
+ return x;
138
+ }
139
+ //# sourceMappingURL=dksap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dksap.js","sourceRoot":"","sources":["../../src/crypto/dksap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `@opaquecash/opaque` — unified Opaque SDK client.
3
+ *
4
+ * Initialize once with chain, RPC, wallet signature, and WASM URL; then prepare txs,
5
+ * filter indexer announcements, aggregate balances, reconstruct one-time spend keys, and discover PSR traits.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { OpaqueClient, type OpaqueClientConfig, type PrepareStealthSendResult, type PrepareGhostReceiveResult, type AnnounceTransactionRequest, type RegisterMetaAddressTransactionRequest, type ResolveRecipientMetaResult, } from "./client.js";
10
+ export type { VerifyReputationArgs } from "@opaquecash/psr-chain";
11
+ export type { ArtifactPaths, ProofProgressCallback, } from "@opaquecash/psr-prover";
12
+ export { DEFAULT_REPUTATION_ARTIFACT_PATHS, DEFAULT_REPUTATION_ARTIFACTS_ORIGIN, } from "@opaquecash/psr-prover";
13
+ export type { ProofData } from "@opaquecash/psr-core";
14
+ export { buildActionScope, externalNullifierFromScope } from "@opaquecash/psr-core";
15
+ export type { IndexerAnnouncement, OwnedStealthOutput, TokenBalanceSummary, } from "./types/indexer.js";
16
+ export { getSupportedChainIds, getChainDeployment, requireChainDeployment, NATIVE_TOKEN_ADDRESS, type OpaqueChainDeployment, } from "./chains.js";
17
+ export { indexerAnnouncementToScannerRecord, indexerAnnouncementsToScannerJson, } from "./indexer/normalize.js";
18
+ export { deriveKeysFromSignature, computeStealthAddressAndViewTag, recomputeStealthSendFromEphemeralPrivateKey, ephemeralPrivateKeyToCompressedPublicKey, stealthMetaAddressToHex, keysToStealthMetaAddress, parseStealthMetaAddress, } from "./crypto/dksap.js";
19
+ export { EIP5564_SCHEME_SECP256K1 } from "@opaquecash/stealth-core";
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,qCAAqC,EAC1C,KAAK,0BAA0B,GAChC,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EACV,aAAa,EACb,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEpF,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,2CAA2C,EAC3C,wCAAwC,EACxC,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `@opaquecash/opaque` — unified Opaque SDK client.
3
+ *
4
+ * Initialize once with chain, RPC, wallet signature, and WASM URL; then prepare txs,
5
+ * filter indexer announcements, aggregate balances, reconstruct one-time spend keys, and discover PSR traits.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { OpaqueClient, } from "./client.js";
10
+ export { DEFAULT_REPUTATION_ARTIFACT_PATHS, DEFAULT_REPUTATION_ARTIFACTS_ORIGIN, } from "@opaquecash/psr-prover";
11
+ export { buildActionScope, externalNullifierFromScope } from "@opaquecash/psr-core";
12
+ export { getSupportedChainIds, getChainDeployment, requireChainDeployment, NATIVE_TOKEN_ADDRESS, } from "./chains.js";
13
+ export { indexerAnnouncementToScannerRecord, indexerAnnouncementsToScannerJson, } from "./indexer/normalize.js";
14
+ export { deriveKeysFromSignature, computeStealthAddressAndViewTag, recomputeStealthSendFromEphemeralPrivateKey, ephemeralPrivateKeyToCompressedPublicKey, stealthMetaAddressToHex, keysToStealthMetaAddress, parseStealthMetaAddress, } from "./crypto/dksap.js";
15
+ export { EIP5564_SCHEME_SECP256K1 } from "@opaquecash/stealth-core";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,YAAY,GAOb,MAAM,aAAa,CAAC;AAOrB,OAAO,EACL,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAQpF,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GAErB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,2CAA2C,EAC3C,wCAAwC,EACxC,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { AnnouncementJsonRecord } from "@opaquecash/stealth-core";
2
+ import type { IndexerAnnouncement } from "../types/indexer.js";
3
+ /**
4
+ * Map a subgraph/indexer row into the JSON record expected by `scan_attestations_wasm`.
5
+ */
6
+ export declare function indexerAnnouncementToScannerRecord(row: IndexerAnnouncement): AnnouncementJsonRecord;
7
+ /**
8
+ * Batch-normalize indexer rows for WASM or playground inspection.
9
+ */
10
+ export declare function indexerAnnouncementsToScannerJson(rows: IndexerAnnouncement[]): string;
11
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/indexer/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAW/D;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,GAAG,EAAE,mBAAmB,GACvB,sBAAsB,CAexB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,mBAAmB,EAAE,GAC1B,MAAM,CAER"}
@@ -0,0 +1,32 @@
1
+ function hexToBytes(h) {
2
+ const s = h.startsWith("0x") ? h.slice(2) : h;
3
+ const out = [];
4
+ for (let i = 0; i < s.length; i += 2) {
5
+ out.push(Number.parseInt(s.slice(i, i + 2), 16));
6
+ }
7
+ return out;
8
+ }
9
+ /**
10
+ * Map a subgraph/indexer row into the JSON record expected by `scan_attestations_wasm`.
11
+ */
12
+ export function indexerAnnouncementToScannerRecord(row) {
13
+ const bn = Number.parseInt(row.blockNumber, 10);
14
+ if (!Number.isFinite(bn)) {
15
+ throw new Error(`Invalid blockNumber on announcement ${row.transactionHash}: ${row.blockNumber}`);
16
+ }
17
+ return {
18
+ stealthAddress: row.stealthAddress,
19
+ viewTag: row.viewTag,
20
+ ephemeralPubKey: hexToBytes(row.etherealPublicKey),
21
+ metadata: hexToBytes(row.metadata),
22
+ txHash: row.transactionHash,
23
+ blockNumber: bn,
24
+ };
25
+ }
26
+ /**
27
+ * Batch-normalize indexer rows for WASM or playground inspection.
28
+ */
29
+ export function indexerAnnouncementsToScannerJson(rows) {
30
+ return JSON.stringify(rows.map(indexerAnnouncementToScannerRecord));
31
+ }
32
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/indexer/normalize.ts"],"names":[],"mappings":"AAIA,SAAS,UAAU,CAAC,CAAM;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kCAAkC,CAChD,GAAwB;IAExB,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,uCAAuC,GAAG,CAAC,eAAe,KAAK,GAAG,CAAC,WAAW,EAAE,CACjF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,eAAe,EAAE,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAClD,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClC,MAAM,EAAE,GAAG,CAAC,eAAe;QAC3B,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iCAAiC,CAC/C,IAA2B;IAE3B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { Address, Hex } from "viem";
2
+ /**
3
+ * Announcement row shape from a typical Graph subgraph (field names preserved).
4
+ *
5
+ * `etherealPublicKey` is the **ephemeral** secp256k1 public key (33-byte compressed hex),
6
+ * as commonly returned by indexers despite the name.
7
+ */
8
+ export interface IndexerAnnouncement {
9
+ __typename?: string;
10
+ id?: string;
11
+ blockNumber: string;
12
+ etherealPublicKey: Hex;
13
+ logIndex: number;
14
+ metadata: Hex;
15
+ stealthAddress: Address;
16
+ transactionHash: Hex;
17
+ viewTag: number;
18
+ }
19
+ /**
20
+ * One output the recipient owns (from WASM `scan_attestations` + normalized context).
21
+ */
22
+ export interface OwnedStealthOutput {
23
+ stealthAddress: Address;
24
+ transactionHash: Hex;
25
+ blockNumber: number;
26
+ logIndex: number;
27
+ viewTag: number;
28
+ ephemeralPublicKey: Hex;
29
+ /** Present when announcement carried PSR attestation metadata. */
30
+ attestationId?: number;
31
+ }
32
+ /**
33
+ * Aggregated balance for a single tracked asset across all owned stealth addresses.
34
+ */
35
+ export interface TokenBalanceSummary {
36
+ /** `0x0000…0000` denotes native ETH when using {@link NATIVE_TOKEN_ADDRESS}. */
37
+ tokenAddress: Address;
38
+ symbol: string;
39
+ decimals: number;
40
+ /** Sum of raw units (wei for ETH, base units for ERC-20). */
41
+ totalRaw: bigint;
42
+ }
43
+ //# sourceMappingURL=indexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../../src/types/indexer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,GAAG,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,GAAG,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,GAAG,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,GAAG,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,GAAG,CAAC;IACxB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=indexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/types/indexer.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@opaquecash/opaque",
3
+ "version": "0.1.0",
4
+ "description": "Unified Opaque SDK client: config, indexer announcements, announce payloads, balances, traits",
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": ["dist", "API.md", "README.md"],
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.json",
17
+ "clean": "rm -rf dist"
18
+ },
19
+ "dependencies": {
20
+ "@noble/curves": "^1.6.0",
21
+ "@noble/hashes": "^1.5.0",
22
+ "@opaquecash/psr-chain": "0.1.0",
23
+ "@opaquecash/psr-core": "0.1.0",
24
+ "@opaquecash/psr-prover": "0.1.0",
25
+ "@opaquecash/stealth-balance": "0.1.0",
26
+ "@opaquecash/stealth-chain": "0.1.0",
27
+ "@opaquecash/stealth-core": "0.1.0",
28
+ "@opaquecash/stealth-wasm": "0.1.0",
29
+ "viem": "^2.21.0"
30
+ },
31
+ "sideEffects": false
32
+ }