@auditable/privacy-pool-zk-sdk 0.1.0 → 0.6.1-rc.5

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,54 @@
1
+ import { Keypair } from '@stellar/stellar-sdk';
2
+ import { buildKytPassageAuthorization, derivePassageFromTransactContext, hashPublicSignalBytes, type InspectKytPassageRequest, type PublicLegContextInput } from './kyt-passage.js';
3
+ import { type OnboardingPayloadInput } from './kyt-onboarding.js';
4
+ export interface RegisterPassageParams {
5
+ kytRegistryId: string;
6
+ poolContract: string;
7
+ owner: string;
8
+ publicSignalsBytes: Buffer | string;
9
+ publicLegContext: PublicLegContextInput;
10
+ onboarding?: OnboardingPayloadInput | null;
11
+ signature: string;
12
+ expiresAtLedger: number;
13
+ source: Keypair;
14
+ networkPassphrase: string;
15
+ rpcUrl: string;
16
+ }
17
+ export interface SubmitKytTransactParams {
18
+ poolContract: string;
19
+ owner: string;
20
+ proofBytes: Buffer;
21
+ publicSignalsBytes: Buffer;
22
+ onboarding?: OnboardingPayloadInput | null;
23
+ source: Keypair;
24
+ networkPassphrase: string;
25
+ rpcUrl: string;
26
+ }
27
+ export interface SubmitWithKytPassageParams extends SubmitKytTransactParams {
28
+ kytRegistryId: string;
29
+ kytSubmitHelperId?: string;
30
+ inspectRequest: InspectKytPassageRequest;
31
+ publicLegContext: PublicLegContextInput;
32
+ inspectFn?: (request: InspectKytPassageRequest) => Promise<{
33
+ passageId: string;
34
+ signature: string;
35
+ expiresAtLedger: number;
36
+ }>;
37
+ }
38
+ export interface SubmitApprovedKytPassageParams extends SubmitKytTransactParams {
39
+ kytSubmitHelperId: string;
40
+ passageId: string;
41
+ signature: string;
42
+ expiresAtLedger: number;
43
+ }
44
+ export interface AtomicKytSubmitPlan {
45
+ atomic: boolean;
46
+ operations: Array<'helper.submit_with_passage' | 'register_passage' | 'pool.transact'>;
47
+ }
48
+ export declare function planKytSubmit(registerFirst: boolean, helperAvailable?: boolean): AtomicKytSubmitPlan;
49
+ export declare function registerKytPassage(params: RegisterPassageParams): Promise<string>;
50
+ export declare function submitPoolTransact(params: SubmitKytTransactParams): Promise<string>;
51
+ export declare function submitApprovedKytPassage(params: SubmitApprovedKytPassageParams): Promise<string>;
52
+ export declare function submitWithKytPassage(params: SubmitWithKytPassageParams): Promise<string>;
53
+ export declare function localSignKytPassageAuthorization(secretSeed: string, authorization: ReturnType<typeof buildKytPassageAuthorization>): string;
54
+ export { buildKytPassageAuthorization, derivePassageFromTransactContext, hashPublicSignalBytes };
@@ -0,0 +1,36 @@
1
+ import { xdr } from '@stellar/stellar-sdk';
2
+ export interface PlaintextNotePayload {
3
+ value: bigint;
4
+ asset_hi: Buffer;
5
+ asset_lo: Buffer;
6
+ nullifier: Buffer;
7
+ secret: Buffer;
8
+ deposited_ephemeral_scalar?: Buffer;
9
+ }
10
+ export type OptionalPrivateAddressRegistrationPayload = {
11
+ tag: 'None';
12
+ } | {
13
+ tag: 'Some';
14
+ values: readonly [
15
+ {
16
+ owner: string;
17
+ public_key_x: Buffer;
18
+ public_key_y: Buffer;
19
+ }
20
+ ];
21
+ };
22
+ export interface OnboardingPayloadInput {
23
+ owner: string;
24
+ temp_public_key_x: Buffer;
25
+ temp_public_key_y: Buffer;
26
+ encrypted_private_key: Buffer;
27
+ notes: PlaintextNotePayload[];
28
+ private_address_registration: OptionalPrivateAddressRegistrationPayload;
29
+ }
30
+ declare const ONBOARDING_ZERO_DOMAIN = "privacy-pool-onboarding-zero-v1";
31
+ /** Canonical `onboardingHash` matching `libs/kyt-passage/src/lib.rs::hash_onboarding`. */
32
+ export declare function hashOnboardingCanonical(onboarding: OnboardingPayloadInput | null | undefined): string;
33
+ export declare function onboardingToScVal(onboarding: OnboardingPayloadInput): xdr.ScVal;
34
+ export declare function onboardingOptionToScVal(onboarding: OnboardingPayloadInput | null | undefined): xdr.ScVal;
35
+ export declare function addressToScVal(address: string): xdr.ScVal;
36
+ export { ONBOARDING_ZERO_DOMAIN };
@@ -0,0 +1,71 @@
1
+ import { type OnboardingPayloadInput } from './kyt-onboarding.js';
2
+ export declare const KYT_PASSAGE_AUTH_DOMAIN = "privacy-pool-kyt-passage-v1";
3
+ export declare const PUBLIC_LEG_CONTEXT_DOMAIN = "privacy-pool-public-leg-context-v1";
4
+ export declare const PASSAGE_ID_DOMAIN = "privacy-pool-passage-id-v1";
5
+ export declare const ONBOARDING_ZERO_DOMAIN = "privacy-pool-onboarding-zero-v1";
6
+ export declare const NOTE_AUDIT_LEN = 9;
7
+ export declare const TOTAL_PUBLIC_SIGNALS = 79;
8
+ export interface PublicLegLayout {
9
+ publicNInputs: number;
10
+ publicNOutputs: number;
11
+ }
12
+ export interface PublicLegContextInput {
13
+ owner: string;
14
+ withdrawAddress: string;
15
+ publicDeposits: string[];
16
+ publicWithdrawals: string[];
17
+ publicDepositedAssets: [string, string][];
18
+ publicWithdrawnAssets: [string, string][];
19
+ }
20
+ export interface KytPassageDerivation {
21
+ publicSignalHash: string;
22
+ publicLegContextHash: string;
23
+ onboardingHash: string;
24
+ passageId: string;
25
+ }
26
+ export interface KytPassageAuthorization {
27
+ authorizationHash: string;
28
+ poolContract: string;
29
+ kytRegistry: string;
30
+ passageId: string;
31
+ expiresAtLedger: number;
32
+ }
33
+ /** Canonical zero-address sentinel for absent public-leg slots: `u32_be(0)` with no XDR bytes. */
34
+ export declare function zeroAddressSentinelBuffer(): Buffer;
35
+ export declare function addressToCanonicalXdr(address: string): Buffer;
36
+ export declare function hashPublicSignalBytes(publicSignalsBytes: Buffer | string): string;
37
+ export declare function hashPublicLegContext(layout: PublicLegLayout, input: PublicLegContextInput): string;
38
+ export declare function hashOnboarding(onboarding: OnboardingPayloadInput | null | undefined): string;
39
+ export declare function derivePassageId(owner: string, publicSignalHash: string, publicLegContextHash: string, onboardingHash: string): string;
40
+ export declare function buildKytPassageAuthorization(input: {
41
+ poolContract: string;
42
+ kytRegistry: string;
43
+ passageId: string;
44
+ expiresAtLedger: number;
45
+ }): KytPassageAuthorization;
46
+ export declare function derivePassageFromTransactContext(input: {
47
+ owner: string;
48
+ publicSignalsBytes: Buffer | string;
49
+ publicLegContext: PublicLegContextInput;
50
+ layout?: PublicLegLayout;
51
+ onboarding?: OnboardingPayloadInput | null;
52
+ }): KytPassageDerivation;
53
+ export declare function accountIdFromAddress(address: string): Buffer;
54
+ export interface InspectKytPassageRequest {
55
+ owner: string;
56
+ poolContract: string;
57
+ kytRegistry: string;
58
+ proofBytes: string;
59
+ publicSignalsBytes: string;
60
+ applicationIdsPlaintext: [string, string, string, string];
61
+ onboarding?: OnboardingPayloadInput | null;
62
+ nonce?: string;
63
+ }
64
+ export interface InspectKytPassageApproved {
65
+ status: 'approved';
66
+ passageId: string;
67
+ signature: string;
68
+ expiresAtLedger: number;
69
+ }
70
+ export declare function inspectKytPassage(backendUrl: string, request: InspectKytPassageRequest): Promise<InspectKytPassageApproved>;
71
+ export declare function signatureBase64ToBytes(signature: string): Buffer;
@@ -0,0 +1,42 @@
1
+ import type { DepositObject } from './withdrawal-transaction-input.js';
2
+ import type { EcdhSharedKeyFn } from './shared-secret.js';
3
+ export declare const NOTE_OUTPUT_LEN = 6;
4
+ export declare const OUTPUT_NOTE_TAG_DOMAIN = 3n;
5
+ export declare const STREAM_DOMAIN = 1n;
6
+ export declare const FR_SIZE = 32;
7
+ export type OutputNotePlaintext = {
8
+ value: string;
9
+ assetHi: string;
10
+ assetLo: string;
11
+ nullifier: string;
12
+ secret: string;
13
+ applicationId: string;
14
+ };
15
+ export type OutputNoteEncryption = {
16
+ ciphertext: [string, string, string, string, string, string];
17
+ tag: string;
18
+ };
19
+ export type DecryptedOutputNote = OutputNotePlaintext & {
20
+ commitmentHex: string;
21
+ commitmentMatches: boolean;
22
+ };
23
+ export type OutputNoteEventInput = {
24
+ recipientScalarHex: string;
25
+ commitmentHashHex: string;
26
+ createdEphemeralKey: readonly [string, string];
27
+ ciphertext: readonly string[];
28
+ tag: string;
29
+ };
30
+ export declare function secretFromDepositEphemeralScalarDecimal(ephemeralKeyScalarDecimal: string): Promise<string>;
31
+ export declare function encryptOutputNoteForDeposit(parameters: {
32
+ deposit: DepositObject;
33
+ ecdhShared: EcdhSharedKeyFn;
34
+ }): Promise<OutputNoteEncryption>;
35
+ export declare function buildOutputNoteEncryptionPublicInputs(parameters: {
36
+ deposits: [DepositObject, DepositObject];
37
+ ecdhShared: EcdhSharedKeyFn;
38
+ }): Promise<{
39
+ outputNoteCiphertexts: [OutputNoteEncryption['ciphertext'], OutputNoteEncryption['ciphertext']];
40
+ outputNoteTags: [string, string];
41
+ }>;
42
+ export declare function decryptOutputNoteEvent(input: OutputNoteEventInput): Promise<DecryptedOutputNote>;
package/dist/sdk.d.ts CHANGED
@@ -2,7 +2,8 @@ import { type DecodedDepositorSharedSecretPreimage, type DecodedEphemeralKey, ty
2
2
  import { type SharedSecret } from './shared-secret';
3
3
  import type { DecodedRecipientSharedSecretPreimage } from './stealth-address';
4
4
  import type { CoinData, GeneratedCoin, SDKOptions, StateFile, WithdrawMerkleWitness, WithdrawResult } from './types';
5
- import { type DepositSlot, type WithdrawalProofPublicParams, type WithdrawSlot } from './withdrawal-transaction-input';
5
+ import { type DepositSlot, type TransactionPublicLegParams, type WithdrawalProofPublicParams, type WithdrawSlot } from './withdrawal-transaction-input';
6
+ import { type TransactionAuditParams } from './transaction-audit';
6
7
  export declare class PrivacyPoolSDK {
7
8
  private wasm;
8
9
  private options;
@@ -32,29 +33,33 @@ export declare class PrivacyPoolSDK {
32
33
  /**
33
34
  * Generate a new coin with random nullifier, secret, and random shared-secret field elements (dev / self-contained tests).
34
35
  * @param amount Stroops encoded as `bigint` or integer `number` (WASM `u64`).
36
+ * @param assetHiDecimal / assetLoDecimal Decimal Fr strings for Stellar asset contract id (two limbs).
35
37
  */
36
- generateCoin(amount: bigint | number): GeneratedCoin;
38
+ generateCoin(amount: bigint | number, assetHiDecimal: string, assetLoDecimal: string, applicationIdDecimal?: string): GeneratedCoin;
37
39
  /**
38
40
  * Generate a coin with the same commitment shape as on-chain deposit: pass `ecdhSharedKey` output (hex x, y).
39
41
  * @param amount Stroops (`bigint` | `number`).
40
42
  */
41
- generateCoinWithSharedSecret(shared: SharedSecret, amount: bigint | number): GeneratedCoin;
43
+ generateCoinWithSharedSecret(shared: SharedSecret, amount: bigint | number, assetHiDecimal: string, assetLoDecimal: string, applicationIdDecimal?: string): GeneratedCoin;
42
44
  /**
43
45
  * Coin for a depositor `ephemeralKeyScalar` (32-byte hex): `coin.secret = Poseidon255(1)(scalar)` as in `deposit.circom`.
44
46
  * @param amount Stroops (`bigint` | `number`).
45
47
  */
46
- generateCoinFromDepositEphemeralScalarHex(scalarHex: string, amount: bigint | number): GeneratedCoin;
48
+ generateCoinFromDepositEphemeralScalarHex(scalarHex: string, amount: bigint | number, assetHiDecimal: string, assetLoDecimal: string, applicationIdDecimal?: string): GeneratedCoin;
47
49
  /**
48
50
  * Aligned deposit coin: `secret = Poseidon₁(scalar)` and ECDH shared key from hex coords (e.g. `ecdhSharedKey(scalar, recipient_x, recipient_y)`).
49
51
  * @param amount Stroops (`bigint` | `number`).
50
52
  */
51
- generateCoinForDepositWithSharedHex(scalarHex: string, sharedXHex: string, sharedYHex: string, amount: bigint | number): GeneratedCoin;
53
+ generateCoinForDepositWithSharedHex(scalarHex: string, sharedXHex: string, sharedYHex: string, amount: bigint | number, assetHiDecimal: string, assetLoDecimal: string, applicationIdDecimal?: string): GeneratedCoin;
52
54
  /**
53
55
  * Merkle root, path, and coin fields for the first withdraw leg (Rust LeanIMT + Poseidon).
54
56
  */
55
57
  buildWithdrawMerkleWitness(coin: CoinData, state: StateFile): WithdrawMerkleWitness;
56
58
  /**
57
59
  * Full `Transaction(20,2,2)` withdrawal proof: one real withdraw + dummies, using coin/state and depositor ECDH point (hex).
60
+ *
61
+ * Optional **partial public withdraw**: spend the full coin commitment `coin.value` (V), send `publicWithdrawStroops` (W) to the
62
+ * Stellar receiver, and re-deposit the remainder (V−W) as a new private note to `changeRecipientStealthAddress` (same circuit balance).
58
63
  */
59
64
  proveWithdrawal(coin: CoinData, state: StateFile, params: {
60
65
  withdrawAddressHi: string;
@@ -62,6 +67,12 @@ export declare class PrivacyPoolSDK {
62
67
  privKeyScalar: string;
63
68
  ephemeralXHex: string;
64
69
  ephemeralYHex: string;
70
+ /** If set, public leg amount W (stroops). Must satisfy 0 < W < V. Remainder (V−W) stays in the pool as a new commitment. */
71
+ publicWithdrawStroops?: bigint;
72
+ /** Required when `publicWithdrawStroops` is set: stealth recipient for the change note (typically same as deposit). */
73
+ changeRecipientStealthAddress?: string;
74
+ applicationId?: string;
75
+ audit?: TransactionAuditParams;
65
76
  }): Promise<WithdrawResult>;
66
77
  /**
67
78
  * Convert a snarkjs proof JSON to hex bytes for Soroban.
@@ -84,10 +95,11 @@ export declare class PrivacyPoolSDK {
84
95
  * `Transaction(20,2,2)` proof from high-level legs: maps to witness input (incl. `"dummy"` ECDH via WASM), then Groth16 → Soroban hex.
85
96
  *
86
97
  * @param publicParams Public inputs: `stateRoot`, `withdrawAddressHi` / `withdrawAddressLo`, `privKeyScalar` (decimal field strings).
98
+ * @param publicLegs Public token legs (`publicWithdrawnAssets`, `publicDepositedAssets`, `publicDeposits`, `publicWithdrawals`).
87
99
  * @param withdraws Exactly two withdraw slots (`WithdrawObject` or `"dummy"`).
88
100
  * @param deposits Exactly two deposit slots (`DepositObject` or `"dummy"`).
89
101
  */
90
- proveTransaction(publicParams: WithdrawalProofPublicParams, withdraws: [WithdrawSlot, WithdrawSlot], deposits: [DepositSlot, DepositSlot]): Promise<WithdrawResult>;
102
+ proveTransaction(publicParams: WithdrawalProofPublicParams, publicLegs: TransactionPublicLegParams, withdraws: [WithdrawSlot, WithdrawSlot], deposits: [DepositSlot, DepositSlot], audit: TransactionAuditParams): Promise<WithdrawResult>;
91
103
  /**
92
104
  * Calculate nullifier hash: Poseidon(nullifier)
93
105
  * @param nullifier Nullifier decimal string from coin data
@@ -0,0 +1,25 @@
1
+ import { type DepositObject, type DepositSlot, type WithdrawObject, type WithdrawSlot } from './withdrawal-transaction-input';
2
+ export declare const TRANSACTION_N_AUDIT_SLOTS = 4;
3
+ export declare const DEFAULT_APPLICATION_ID = "101";
4
+ /** BabyJub audit public key (decimal Fr) used in BDD / local demo when env is unset. */
5
+ export declare const DEMO_AUDIT_PUBLIC_KEY: AuditPublicKey;
6
+ export type AuditPublicKey = [string, string];
7
+ export interface TransactionAuditParams {
8
+ applicationId: string;
9
+ noteAuditPublicKeys: [
10
+ AuditPublicKey,
11
+ AuditPublicKey,
12
+ AuditPublicKey,
13
+ AuditPublicKey
14
+ ];
15
+ auditEphemeralScalars: [string, string, string, string];
16
+ }
17
+ export interface TransactionSlotApplicationIds {
18
+ inputApplicationIds: [string, string];
19
+ outputApplicationIds: [string, string];
20
+ }
21
+ export declare function buildUniformAuditParams(applicationId: string | undefined, auditPublicKey: AuditPublicKey): TransactionAuditParams;
22
+ export declare function resolveSlotApplicationIds(audit: TransactionAuditParams, withdrawSlots: [WithdrawSlot, WithdrawSlot], depositSlots: [DepositSlot, DepositSlot]): TransactionSlotApplicationIds;
23
+ export declare function withApplicationIdOnDeposit(deposit: DepositObject, applicationId: string): DepositObject;
24
+ export declare function withApplicationIdOnWithdraw(withdraw: WithdrawObject, applicationId: string): WithdrawObject;
25
+ export declare function resolveTransactionAuditParams(applicationId: string, auditPublicKey?: AuditPublicKey): TransactionAuditParams;
package/dist/types.d.ts CHANGED
@@ -3,10 +3,17 @@ export interface CoinData {
3
3
  nullifier: string;
4
4
  secret: string;
5
5
  commitment: string;
6
+ /** Decimal Fr strings for Stellar asset contract id (`asset[0]`, `asset[1]` in `commitment.circom`). */
7
+ asset_hi: string;
8
+ asset_lo: string;
9
+ /** Decimal Fr application id (per-note KYT slot); optional on legacy coins. */
10
+ application_id?: string;
6
11
  }
7
12
  export interface GeneratedCoin {
8
13
  coin: CoinData;
9
14
  commitment_hex: string;
15
+ /** 64-char lowercase hex (no `0x`), Fr big-endian for audit `precommitement`. */
16
+ precommitement_hex: string;
10
17
  }
11
18
  /** Pool Merkle tree depth (matches `coin::TREE_DEPTH` / `Transaction` circuit). */
12
19
  export declare const POOL_MERKLE_TREE_DEPTH = 20;
@@ -23,6 +30,8 @@ export interface WithdrawMerkleWitness {
23
30
  value: string;
24
31
  nullifier: string;
25
32
  secret: string;
33
+ /** `[asset_hi, asset_lo]` decimal Fr strings (Stellar asset contract id). */
34
+ withdrawnAsset: [string, string];
26
35
  stateRoot: string;
27
36
  stateIndex: string;
28
37
  /** Length is always {@link POOL_MERKLE_TREE_DEPTH}; each entry is a decimal field element. */
@@ -1,8 +1,15 @@
1
+ import type { TransactionAuditParams } from './transaction-audit';
1
2
  import type { WithdrawMerkleWitness } from './types';
2
- /** Matches `Transaction(20, 2, 2)` in `circuits/main.circom`. */
3
+ /** Matches `Transaction(20, 2, 2, publicNInputs, publicNOutputs, 4, 9)` in `circuits/main.circom`. */
3
4
  export declare const TRANSACTION_TREE_DEPTH = 20;
4
5
  export declare const TRANSACTION_N_INS = 2;
5
6
  export declare const TRANSACTION_N_OUTS = 2;
7
+ export declare const TRANSACTION_N_AUDIT_SLOTS = 4;
8
+ export declare const NOTE_AUDIT_LEN = 9;
9
+ export declare const NOTE_OUTPUT_LEN = 6;
10
+ /** Must match `Transaction(..., publicNInputs, publicNOutputs)` and contract `get_public_slot_config`. */
11
+ export declare const TRANSACTION_PUBLIC_N_INPUTS = 1;
12
+ export declare const TRANSACTION_PUBLIC_N_OUTPUTS = 1;
6
13
  /** BN254 scalar field modulus (ark `Fr`, circom signals). */
7
14
  export declare const BN254_SCALAR_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
8
15
  /**
@@ -20,11 +27,24 @@ export interface WithdrawalProofPublicParams {
20
27
  /** Decimal string, circom `privKeyScalar`. */
21
28
  privKeyScalar: string;
22
29
  }
30
+ /** Public accounting legs (`publicWithdrawnAssets`, `publicDepositedAssets`, `publicDeposits`, `publicWithdrawals`). */
31
+ export interface TransactionPublicLegParams {
32
+ publicWithdrawnAssets: Array<[string, string]>;
33
+ publicDepositedAssets: Array<[string, string]>;
34
+ publicDeposits: string[];
35
+ publicWithdrawals: string[];
36
+ }
37
+ /** All-zero public legs (private-only pool moves). */
38
+ export declare function zeroPublicLegs(): TransactionPublicLegParams;
23
39
  /** Real withdraw leg; coordinates are decimal field strings (same as `CoinData`). */
24
40
  export interface WithdrawObject {
25
41
  value: string;
26
42
  nullifier: string;
27
43
  secret: string;
44
+ /** Asset contract id as two decimal Fr strings (`asset[0]`, `asset[1]`). */
45
+ asset: [string, string];
46
+ /** BN254 Fr decimal; `0` for dummy slots. */
47
+ applicationId: string;
28
48
  /** Depositor ECDH point `[x, y]` as decimal strings. */
29
49
  ephemeralKeys: [string, string];
30
50
  stateSiblings: string[];
@@ -34,12 +54,16 @@ export interface DepositObject {
34
54
  value: string;
35
55
  nullifier: string;
36
56
  ephemeralKeyScalar: string;
57
+ /** Asset contract id as two decimal Fr strings. */
58
+ asset: [string, string];
59
+ /** BN254 Fr decimal; `0` for dummy slots. */
60
+ applicationId: string;
37
61
  /** Recipient public key `[x, y]` as decimal strings. */
38
62
  recipientPublicKeys: [string, string];
39
63
  }
40
64
  export type WithdrawSlot = WithdrawObject | 'dummy';
41
65
  export type DepositSlot = DepositObject | 'dummy';
42
- /** Witness calculator input for `circuits/main.circom` `Transaction(20,2,2)`. */
66
+ /** Witness calculator input for `circuits/main.circom` `Transaction(20,2,2,publicNInputs,publicNOutputs)`. */
43
67
  export interface TransactionWitnessInput {
44
68
  stateRoot: string;
45
69
  withdrawAddressHi: string;
@@ -48,13 +72,40 @@ export interface TransactionWitnessInput {
48
72
  withdrawnValues: [string, string];
49
73
  withdrawnNullifiers: [string, string];
50
74
  withdrawnSecrets: [string, string];
75
+ withdrawnAssets: [[string, string], [string, string]];
51
76
  ephemeralKeys: [[string, string], [string, string]];
52
77
  stateSiblings: [string[], string[]];
53
78
  stateIndex: [string, string];
54
79
  depositedValues: [string, string];
55
80
  depositedNullifiers: [string, string];
81
+ depositedAssets: [[string, string], [string, string]];
56
82
  depositedEphemeralKeyScalars: [string, string];
57
83
  depositedRecipientPublicKeys: [[string, string], [string, string]];
84
+ publicWithdrawnAssets: Array<[string, string]>;
85
+ publicDepositedAssets: Array<[string, string]>;
86
+ publicDeposits: string[];
87
+ publicWithdrawals: string[];
88
+ inputApplicationIds: [string, string];
89
+ outputApplicationIds: [string, string];
90
+ auditEphemeralScalars: [string, string, string, string];
91
+ noteAuditPublicKeys: [
92
+ [
93
+ string,
94
+ string
95
+ ],
96
+ [
97
+ string,
98
+ string
99
+ ],
100
+ [
101
+ string,
102
+ string
103
+ ],
104
+ [
105
+ string,
106
+ string
107
+ ]
108
+ ];
58
109
  }
59
110
  export interface WasmEcdhPointFns {
60
111
  ecdhEphemeralPublicKeyFromScalarHex(scalarHex: string): {
@@ -77,15 +128,20 @@ export declare function ed25519PubkeyPayloadHexToWithdrawFrDecimals(hex: string)
77
128
  hi: string;
78
129
  lo: string;
79
130
  };
131
+ /**
132
+ * Stellar contract id (`C…`) → two circom field decimals for `asset[0]`, `asset[1]` (same 32-byte split as accounts).
133
+ */
134
+ export declare function stellarContractAddressToAssetFrDecimals(address: string): [string, string];
80
135
  /** Uniform random `Fr` as decimal (32 random bytes, mod r). For Poseidon-only inputs (e.g. nullifiers). */
81
136
  export declare function randomFrDecimal(): string;
82
137
  /** Random scalar < 2^253 for BabyJub ECDH / `Num2Bits(253)` (uses {@link generateRandomScalarHex32}). */
83
138
  export declare function randomFrDecimal253(): string;
84
- export declare function buildTransactionWitnessInput(publicParams: WithdrawalProofPublicParams, withdrawSlots: [WithdrawSlot, WithdrawSlot], depositSlots: [DepositSlot, DepositSlot], wasm: WasmEcdhPointFns): TransactionWitnessInput;
139
+ export declare function resolveDepositsForWitness(depositSlots: [DepositSlot, DepositSlot], wasm: WasmEcdhPointFns): [DepositObject, DepositObject];
140
+ export declare function buildTransactionWitnessInput(publicParams: WithdrawalProofPublicParams, publicLegs: TransactionPublicLegParams, withdrawSlots: [WithdrawSlot, WithdrawSlot], depositSlots: [DepositSlot, DepositSlot], audit: TransactionAuditParams, wasm: WasmEcdhPointFns): TransactionWitnessInput;
85
141
  /** `stpl1…` stealth address → `[x, y]` as decimal field strings for `depositedRecipientPublicKeys`. */
86
142
  export declare function recipientPublicKeysDecimalFromStealthAddress(stealthAddress: string): [string, string];
87
143
  /** First withdraw leg: Merkle witness + depositor ECDH point coordinates (hex). */
88
144
  export declare function withdrawObjectFromMerkleWitness(witness: WithdrawMerkleWitness, depositorEphemeralHex: {
89
145
  x: string;
90
146
  y: string;
91
- }): WithdrawObject;
147
+ }, applicationId: string): WithdrawObject;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auditable/privacy-pool-zk-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.6.1-rc.5",
4
4
  "description": "Client SDK for Soroban Privacy Pools - coin generation, withdrawal proofs, and proof serialization",
5
5
  "main": "dist/index.mjs",
6
6
  "module": "dist/index.mjs",
@@ -35,10 +35,16 @@
35
35
  "build:wasm": "cd crate && wasm-pack build --target web --out-dir ../pkg",
36
36
  "build:ts": "rollup -c",
37
37
  "build": "rollup -c",
38
- "cli": "node dist/cli.js"
38
+ "cli": "node dist/cli.js",
39
+ "test:kyt": "node test/kyt-onboarding-hash.mjs && node test/kyt-flow-atomic.mjs && node test/kyt-public-leg-context.mjs && node test/kyt-passage-id-auth.mjs",
40
+ "test:output-note": "node test/output-note-encryption.mjs"
39
41
  },
40
42
  "dependencies": {
43
+ "@noble/hashes": "^2.2.0",
44
+ "@stellar/stellar-sdk": "^16.0.1",
41
45
  "bech32": "^2.0.0",
46
+ "circomlibjs": "^0.1.7",
47
+ "ffjavascript": "^0.3.0",
42
48
  "snarkjs": "^0.7.0"
43
49
  },
44
50
  "devDependencies": {
@@ -31,24 +31,25 @@ export function ecdhSharedKey(priv_hex: string, pub_x_hex: string, pub_y_hex: st
31
31
  /**
32
32
  * Generate a new coin with random nullifier, secret, and shared-secret field elements.
33
33
  * `amount` is stroops (u64); JS passes `bigint`.
34
- * Returns JSON: { coin: { value, nullifier, secret, commitment }, commitment_hex }
34
+ * `asset_hi_decimal` / `asset_lo_decimal` are decimal Fr strings for the Stellar asset contract id (two limbs).
35
+ * Returns JSON: { coin: { value, nullifier, secret, commitment, asset_hi, asset_lo }, commitment_hex, precommitement_hex }
35
36
  */
36
- export function generateCoin(amount: bigint): any;
37
+ export function generateCoin(amount: bigint, asset_hi_decimal: string, asset_lo_decimal: string, application_id_decimal: string): any;
37
38
 
38
39
  /**
39
40
  * `Poseidon₁(scalar)` secret + fixed ECDH shared coords (hex), matching an aligned deposit witness.
40
41
  */
41
- export function generateCoinForDepositWithSharedHex(scalar_hex: string, shared_x_hex: string, shared_y_hex: string, amount: bigint): any;
42
+ export function generateCoinForDepositWithSharedHex(scalar_hex: string, shared_x_hex: string, shared_y_hex: string, amount: bigint, asset_hi_decimal: string, asset_lo_decimal: string, application_id_decimal: string): any;
42
43
 
43
44
  /**
44
45
  * `secret` in coin = `Poseidon255(1)(scalar)` per `deposit.circom`; scalar is 32-byte hex (64 chars, optional `0x`).
45
46
  */
46
- export function generateCoinFromDepositEphemeralScalarHex(scalar_hex: string, amount: bigint): any;
47
+ export function generateCoinFromDepositEphemeralScalarHex(scalar_hex: string, amount: bigint, asset_hi_decimal: string, asset_lo_decimal: string, application_id_decimal: string): any;
47
48
 
48
49
  /**
49
50
  * Same as `generateCoin`, but commitment uses the given ECDH shared key (64-char hex coords from `ecdhSharedKey`); shared coords are not stored in `coin` JSON.
50
51
  */
51
- export function generateCoinWithSharedSecretHex(shared_x_hex: string, shared_y_hex: string, amount: bigint): any;
52
+ export function generateCoinWithSharedSecretHex(shared_x_hex: string, shared_y_hex: string, amount: bigint, asset_hi_decimal: string, asset_lo_decimal: string, application_id_decimal: string): any;
52
53
 
53
54
  /**
54
55
  * Convert snarkjs proof JSON to hex bytes for Soroban contract.
@@ -69,10 +70,10 @@ export interface InitOutput {
69
70
  readonly ecdhEphemeralPublicKey: (a: number, b: number, c: number) => void;
70
71
  readonly ecdhEphemeralPublicKeyFromScalarHex: (a: number, b: number, c: number) => void;
71
72
  readonly ecdhSharedKey: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
72
- readonly generateCoin: (a: bigint) => number;
73
- readonly generateCoinForDepositWithSharedHex: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: bigint) => void;
74
- readonly generateCoinFromDepositEphemeralScalarHex: (a: number, b: number, c: number, d: bigint) => void;
75
- readonly generateCoinWithSharedSecretHex: (a: number, b: number, c: number, d: number, e: number, f: bigint) => void;
73
+ readonly generateCoin: (a: number, b: bigint, c: number, d: number, e: number, f: number, g: number, h: number) => void;
74
+ readonly generateCoinForDepositWithSharedHex: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: bigint, i: number, j: number, k: number, l: number, m: number, n: number) => void;
75
+ readonly generateCoinFromDepositEphemeralScalarHex: (a: number, b: number, c: number, d: bigint, e: number, f: number, g: number, h: number, i: number, j: number) => void;
76
+ readonly generateCoinWithSharedSecretHex: (a: number, b: number, c: number, d: number, e: number, f: bigint, g: number, h: number, i: number, j: number, k: number, l: number) => void;
76
77
  readonly proofToHex: (a: number, b: number, c: number) => void;
77
78
  readonly publicToHex: (a: number, b: number, c: number) => void;
78
79
  readonly __wbindgen_export: (a: number, b: number) => number;