@veilo/sdk-core 0.4.0 → 0.5.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/LICENSE +15 -0
- package/README.md +286 -1298
- package/dist/cjs/accounts/admin.d.ts +84 -0
- package/dist/cjs/accounts/admin.js +208 -0
- package/dist/cjs/accounts/errors.d.ts +6 -0
- package/dist/cjs/accounts/errors.js +98 -0
- package/dist/cjs/accounts/index.d.ts +4 -0
- package/dist/cjs/accounts/index.js +20 -0
- package/dist/cjs/accounts/pdas.d.ts +23 -0
- package/dist/cjs/accounts/pdas.js +44 -0
- package/dist/cjs/accounts/queries.d.ts +41 -0
- package/dist/cjs/accounts/queries.js +95 -0
- package/dist/cjs/client.d.ts +2 -407
- package/dist/cjs/client.js +6 -938
- package/dist/cjs/cloak/client.d.ts +28 -0
- package/dist/cjs/cloak/client.js +68 -0
- package/dist/cjs/cloak/errors.d.ts +13 -0
- package/dist/cjs/cloak/errors.js +25 -0
- package/dist/cjs/cloak/helpers.d.ts +6 -0
- package/dist/cjs/cloak/helpers.js +35 -0
- package/dist/cjs/cloak/index.d.ts +6 -0
- package/dist/cjs/cloak/index.js +24 -0
- package/dist/cjs/cloak/polling.d.ts +7 -0
- package/dist/cjs/cloak/polling.js +66 -0
- package/dist/cjs/cloak/transport.d.ts +15 -0
- package/dist/cjs/cloak/transport.js +119 -0
- package/dist/cjs/cloak/types.d.ts +188 -0
- package/dist/cjs/cloak/types.js +5 -0
- package/dist/cjs/cloak.d.ts +1 -0
- package/dist/cjs/cloak.js +18 -0
- package/dist/cjs/compactNote.d.ts +21 -0
- package/dist/cjs/compactNote.js +31 -7
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/notes/encryption.d.ts +41 -0
- package/dist/cjs/notes/encryption.js +75 -0
- package/dist/cjs/notes/index.d.ts +5 -0
- package/dist/cjs/notes/index.js +21 -0
- package/dist/cjs/notes/mailbox.d.ts +70 -0
- package/dist/cjs/notes/mailbox.js +164 -0
- package/dist/cjs/notes/model.d.ts +91 -0
- package/dist/cjs/notes/model.js +109 -0
- package/dist/cjs/notes/nullifier.d.ts +27 -0
- package/dist/cjs/notes/nullifier.js +45 -0
- package/dist/cjs/notes/recovery.d.ts +10 -0
- package/dist/cjs/notes/recovery.js +31 -0
- package/dist/cjs/proof.d.ts +1 -183
- package/dist/cjs/proof.js +16 -290
- package/dist/cjs/proofs/encoding.d.ts +17 -0
- package/dist/cjs/proofs/encoding.js +72 -0
- package/dist/cjs/proofs/formatting.d.ts +6 -0
- package/dist/cjs/proofs/formatting.js +34 -0
- package/dist/cjs/proofs/index.d.ts +5 -0
- package/dist/cjs/proofs/index.js +21 -0
- package/dist/cjs/proofs/swap.d.ts +87 -0
- package/dist/cjs/proofs/swap.js +144 -0
- package/dist/cjs/proofs/transaction.d.ts +28 -0
- package/dist/cjs/proofs/transaction.js +110 -0
- package/dist/cjs/proofs/types.d.ts +70 -0
- package/dist/cjs/prover.d.ts +4 -1
- package/dist/cjs/prover.js +12 -2
- package/dist/cjs/relayer/client.d.ts +61 -0
- package/dist/cjs/relayer/client.js +151 -0
- package/dist/cjs/relayer/crypto.d.ts +5 -0
- package/dist/cjs/relayer/crypto.js +26 -0
- package/dist/cjs/relayer/encoding.d.ts +2 -0
- package/dist/cjs/relayer/encoding.js +23 -0
- package/dist/cjs/relayer/errors.d.ts +7 -0
- package/dist/cjs/relayer/errors.js +17 -0
- package/dist/cjs/relayer/index.d.ts +3 -0
- package/dist/cjs/relayer/index.js +19 -0
- package/dist/cjs/relayer/transport.d.ts +17 -0
- package/dist/cjs/relayer/transport.js +63 -0
- package/dist/{src/relayer.d.ts → cjs/relayer/types.d.ts} +44 -86
- package/dist/cjs/relayer/types.js +5 -0
- package/dist/cjs/relayer.d.ts +1 -318
- package/dist/cjs/relayer.js +15 -254
- package/dist/cjs/shield/alt.js +8 -8
- package/dist/cjs/shield/errors.js +2 -2
- package/dist/cjs/shield/finalize.js +2 -2
- package/dist/cjs/shield/ix.d.ts +1 -1
- package/dist/cjs/shield/owner.js +9 -8
- package/dist/cjs/shield/ports.js +3 -3
- package/dist/cjs/shield/preflight.js +3 -3
- package/dist/cjs/shield/shield.js +20 -19
- package/dist/cjs/shield/types.d.ts +1 -1
- package/dist/cjs/transactions/deposit.d.ts +94 -0
- package/dist/cjs/transactions/deposit.js +234 -0
- package/dist/cjs/transactions/index.d.ts +7 -0
- package/dist/cjs/transactions/index.js +26 -0
- package/dist/cjs/transactions/swap.d.ts +71 -0
- package/dist/cjs/transactions/swap.js +184 -0
- package/dist/cjs/transactions/transact.d.ts +34 -0
- package/dist/cjs/transactions/transact.js +146 -0
- package/dist/cjs/transactions/transfer.d.ts +51 -0
- package/dist/cjs/transactions/transfer.js +106 -0
- package/dist/cjs/transactions/withdraw.d.ts +52 -0
- package/dist/cjs/transactions/withdraw.js +104 -0
- package/dist/cjs/utxo.d.ts +1 -235
- package/dist/cjs/utxo.js +15 -404
- package/dist/esm/accounts/admin.d.ts +84 -0
- package/dist/esm/accounts/admin.js +165 -0
- package/dist/esm/accounts/errors.d.ts +6 -0
- package/dist/esm/accounts/errors.js +95 -0
- package/dist/esm/accounts/index.d.ts +4 -0
- package/dist/esm/accounts/index.js +4 -0
- package/dist/esm/accounts/pdas.d.ts +23 -0
- package/dist/esm/accounts/pdas.js +38 -0
- package/dist/esm/accounts/queries.d.ts +41 -0
- package/dist/esm/accounts/queries.js +88 -0
- package/dist/esm/client.d.ts +2 -407
- package/dist/esm/client.js +3 -891
- package/dist/esm/cloak/client.d.ts +28 -0
- package/dist/esm/cloak/client.js +64 -0
- package/dist/esm/cloak/errors.d.ts +13 -0
- package/dist/esm/cloak/errors.js +21 -0
- package/dist/esm/cloak/helpers.d.ts +6 -0
- package/dist/esm/cloak/helpers.js +31 -0
- package/dist/esm/cloak/index.d.ts +6 -0
- package/dist/esm/cloak/index.js +6 -0
- package/dist/esm/cloak/polling.d.ts +7 -0
- package/dist/esm/cloak/polling.js +63 -0
- package/dist/esm/cloak/transport.d.ts +15 -0
- package/dist/esm/cloak/transport.js +115 -0
- package/dist/esm/cloak/types.d.ts +188 -0
- package/dist/esm/cloak/types.js +4 -0
- package/dist/esm/cloak.d.ts +1 -0
- package/dist/esm/cloak.js +2 -0
- package/dist/esm/compactNote.d.ts +21 -0
- package/dist/esm/compactNote.js +24 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/notes/encryption.d.ts +41 -0
- package/dist/esm/notes/encryption.js +67 -0
- package/dist/esm/notes/index.d.ts +5 -0
- package/dist/esm/notes/index.js +5 -0
- package/dist/esm/notes/mailbox.d.ts +70 -0
- package/dist/esm/notes/mailbox.js +154 -0
- package/dist/esm/notes/model.d.ts +91 -0
- package/dist/esm/notes/model.js +99 -0
- package/dist/esm/notes/nullifier.d.ts +27 -0
- package/dist/esm/notes/nullifier.js +40 -0
- package/dist/esm/notes/recovery.d.ts +10 -0
- package/dist/esm/notes/recovery.js +28 -0
- package/dist/esm/proof.d.ts +1 -183
- package/dist/esm/proof.js +2 -281
- package/dist/esm/proofs/encoding.d.ts +17 -0
- package/dist/esm/proofs/encoding.js +68 -0
- package/dist/esm/proofs/formatting.d.ts +6 -0
- package/dist/esm/proofs/formatting.js +31 -0
- package/dist/esm/proofs/index.d.ts +5 -0
- package/dist/esm/proofs/index.js +5 -0
- package/dist/esm/proofs/swap.d.ts +87 -0
- package/dist/esm/proofs/swap.js +138 -0
- package/dist/esm/proofs/transaction.d.ts +28 -0
- package/dist/esm/proofs/transaction.js +105 -0
- package/dist/esm/proofs/types.d.ts +70 -0
- package/dist/esm/proofs/types.js +1 -0
- package/dist/esm/prover.d.ts +4 -1
- package/dist/esm/prover.js +10 -1
- package/dist/esm/relayer/client.d.ts +61 -0
- package/dist/esm/relayer/client.js +144 -0
- package/dist/esm/relayer/crypto.d.ts +5 -0
- package/dist/esm/relayer/crypto.js +20 -0
- package/dist/esm/relayer/encoding.d.ts +2 -0
- package/dist/esm/relayer/encoding.js +19 -0
- package/dist/esm/relayer/errors.d.ts +7 -0
- package/dist/esm/relayer/errors.js +13 -0
- package/dist/esm/relayer/index.d.ts +3 -0
- package/dist/esm/relayer/index.js +3 -0
- package/dist/esm/relayer/transport.d.ts +17 -0
- package/dist/esm/relayer/transport.js +59 -0
- package/dist/esm/relayer/types.d.ts +276 -0
- package/dist/esm/relayer/types.js +4 -0
- package/dist/esm/relayer.d.ts +1 -318
- package/dist/esm/relayer.js +2 -249
- package/dist/esm/shield/alt.js +1 -1
- package/dist/esm/shield/errors.js +1 -1
- package/dist/esm/shield/finalize.js +1 -1
- package/dist/esm/shield/ix.d.ts +1 -1
- package/dist/esm/shield/owner.js +2 -1
- package/dist/esm/shield/ports.js +1 -1
- package/dist/esm/shield/preflight.js +1 -1
- package/dist/esm/shield/shield.js +4 -3
- package/dist/esm/shield/types.d.ts +1 -1
- package/dist/esm/transactions/deposit.d.ts +94 -0
- package/dist/esm/transactions/deposit.js +198 -0
- package/dist/esm/transactions/index.d.ts +7 -0
- package/dist/esm/transactions/index.js +7 -0
- package/dist/esm/transactions/swap.d.ts +71 -0
- package/dist/esm/transactions/swap.js +144 -0
- package/dist/esm/transactions/transact.d.ts +34 -0
- package/dist/esm/transactions/transact.js +110 -0
- package/dist/esm/transactions/transfer.d.ts +51 -0
- package/dist/esm/transactions/transfer.js +103 -0
- package/dist/esm/transactions/withdraw.d.ts +52 -0
- package/dist/esm/transactions/withdraw.js +101 -0
- package/dist/esm/utxo.d.ts +1 -235
- package/dist/esm/utxo.js +2 -382
- package/package.json +54 -16
- package/SHIELD_INTEGRATION.md +0 -143
- package/config.d.ts +0 -2
- package/config.js +0 -4
- package/dist/src/client.d.ts +0 -407
- package/dist/src/client.js +0 -951
- package/dist/src/compactNote.d.ts +0 -107
- package/dist/src/compactNote.js +0 -167
- package/dist/src/config.d.ts +0 -82
- package/dist/src/config.js +0 -57
- package/dist/src/events.d.ts +0 -77
- package/dist/src/events.js +0 -167
- package/dist/src/idl/privacy_pool.d.ts +0 -5
- package/dist/src/idl/privacy_pool.js +0 -15218
- package/dist/src/index.d.ts +0 -16
- package/dist/src/index.js +0 -67
- package/dist/src/merkle.d.ts +0 -77
- package/dist/src/merkle.js +0 -156
- package/dist/src/poseidon.d.ts +0 -29
- package/dist/src/poseidon.js +0 -100
- package/dist/src/program.d.ts +0 -37
- package/dist/src/program.js +0 -61
- package/dist/src/proof.d.ts +0 -183
- package/dist/src/proof.js +0 -292
- package/dist/src/prover.d.ts +0 -54
- package/dist/src/prover.js +0 -112
- package/dist/src/random.d.ts +0 -16
- package/dist/src/random.js +0 -28
- package/dist/src/relayer.js +0 -257
- package/dist/src/retry.d.ts +0 -32
- package/dist/src/retry.js +0 -75
- package/dist/src/shield/alt.d.ts +0 -87
- package/dist/src/shield/alt.js +0 -194
- package/dist/src/shield/computeBudget.d.ts +0 -61
- package/dist/src/shield/computeBudget.js +0 -64
- package/dist/src/shield/errors.d.ts +0 -58
- package/dist/src/shield/errors.js +0 -121
- package/dist/src/shield/finalize.d.ts +0 -45
- package/dist/src/shield/finalize.js +0 -119
- package/dist/src/shield/index.d.ts +0 -35
- package/dist/src/shield/index.js +0 -68
- package/dist/src/shield/ix.d.ts +0 -54
- package/dist/src/shield/ix.js +0 -119
- package/dist/src/shield/owner.d.ts +0 -36
- package/dist/src/shield/owner.js +0 -126
- package/dist/src/shield/ports.d.ts +0 -43
- package/dist/src/shield/ports.js +0 -153
- package/dist/src/shield/preflight.d.ts +0 -30
- package/dist/src/shield/preflight.js +0 -154
- package/dist/src/shield/shield.d.ts +0 -68
- package/dist/src/shield/shield.js +0 -499
- package/dist/src/shield/types.d.ts +0 -202
- package/dist/src/utxo.d.ts +0 -235
- package/dist/src/utxo.js +0 -407
- package/dist/tests/compact-note.test.d.ts +0 -1
- package/dist/tests/compact-note.test.js +0 -173
- package/dist/tests/config.test.d.ts +0 -1
- package/dist/tests/config.test.js +0 -102
- package/dist/tests/edge-cases.test.d.ts +0 -1
- package/dist/tests/edge-cases.test.js +0 -220
- package/dist/tests/encryption.test.d.ts +0 -1
- package/dist/tests/encryption.test.js +0 -215
- package/dist/tests/events.test.d.ts +0 -1
- package/dist/tests/events.test.js +0 -78
- package/dist/tests/multi-tree.test.d.ts +0 -1
- package/dist/tests/multi-tree.test.js +0 -405
- package/dist/tests/pda.test.d.ts +0 -1
- package/dist/tests/pda.test.js +0 -229
- package/dist/tests/poseidon-builder-parity.test.d.ts +0 -1
- package/dist/tests/poseidon-builder-parity.test.js +0 -72
- package/dist/tests/poseidon.test.d.ts +0 -1
- package/dist/tests/poseidon.test.js +0 -142
- package/dist/tests/proof.test.d.ts +0 -1
- package/dist/tests/proof.test.js +0 -296
- package/dist/tests/relayer.test.d.ts +0 -1
- package/dist/tests/relayer.test.js +0 -271
- package/dist/tests/sdk.integration.test.d.ts +0 -1
- package/dist/tests/sdk.integration.test.js +0 -330
- package/dist/tests/shield-owner.test.d.ts +0 -1
- package/dist/tests/shield-owner.test.js +0 -89
- package/dist/tests/shield-preflight.test.d.ts +0 -1
- package/dist/tests/shield-preflight.test.js +0 -87
- package/dist/tests/shield-realproof.test.d.ts +0 -1
- package/dist/tests/shield-realproof.test.js +0 -272
- package/dist/tests/shield.test.d.ts +0 -1
- package/dist/tests/shield.test.js +0 -403
- package/dist/tests/utxo.test.d.ts +0 -1
- package/dist/tests/utxo.test.js +0 -140
- package/poseidon.d.ts +0 -2
- package/poseidon.js +0 -4
- package/proof.d.ts +0 -2
- package/proof.js +0 -4
- package/prover.d.ts +0 -2
- package/prover.js +0 -4
- package/shield.d.ts +0 -2
- package/shield.js +0 -4
- /package/dist/{src/shield → cjs/proofs}/types.js +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.transact = transact;
|
|
37
|
+
const anchor = __importStar(require("@coral-xyz/anchor"));
|
|
38
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
39
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
40
|
+
const transaction_js_1 = require("../proofs/transaction.js");
|
|
41
|
+
const config_js_1 = require("../config.js");
|
|
42
|
+
const retry_js_1 = require("../retry.js");
|
|
43
|
+
const pdas_js_1 = require("../accounts/pdas.js");
|
|
44
|
+
// Anchor is CJS and does not expose BN as a detectable Node ESM named export.
|
|
45
|
+
const { BN } = anchor;
|
|
46
|
+
// -----------------------------------------------------------------------------
|
|
47
|
+
// Main Transaction Instruction
|
|
48
|
+
// -----------------------------------------------------------------------------
|
|
49
|
+
/**
|
|
50
|
+
* Execute a transaction on the privacy pool.
|
|
51
|
+
* This is the low-level function that calls the on-chain `transact` instruction.
|
|
52
|
+
*
|
|
53
|
+
* @param publicAmount - Positive for deposits, negative for withdrawals, 0 for transfers
|
|
54
|
+
* @param inputTreeId - The tree ID where input UTXOs are located
|
|
55
|
+
* @param outputTreeId - The tree ID where output commitments will be inserted
|
|
56
|
+
*/
|
|
57
|
+
async function transact(params) {
|
|
58
|
+
const { program, relayer, recipient, mintAddress, root, inputTreeId, outputTreeId, publicAmount, inputNullifiers, outputCommitments, extData, proof, deadline = BigInt(Math.floor(Date.now() / 1000) + 600), noteCiphers = null, vaultTokenAccount, userTokenAccount, recipientTokenAccount, relayerTokenAccount, } = params;
|
|
59
|
+
if (!recipient.equals(extData.recipient)) {
|
|
60
|
+
throw new Error("recipient account must match extData.recipient");
|
|
61
|
+
}
|
|
62
|
+
if (!relayer.publicKey.equals(extData.relayer)) {
|
|
63
|
+
throw new Error("relayer account must match extData.relayer");
|
|
64
|
+
}
|
|
65
|
+
if (deadline <= 0n) {
|
|
66
|
+
throw new Error("deadline must be a positive Unix timestamp");
|
|
67
|
+
}
|
|
68
|
+
if (publicAmount === 0n && (extData.fee !== 0n || extData.refund !== 0n)) {
|
|
69
|
+
throw new Error("Private transfers require extData fee and refund to be zero");
|
|
70
|
+
}
|
|
71
|
+
const { config, vault, nullifiers } = (0, pdas_js_1.getPoolPdas)(program.programId, mintAddress);
|
|
72
|
+
const globalConfig = (0, pdas_js_1.getGlobalConfigPda)(program.programId);
|
|
73
|
+
const inputTree = (0, pdas_js_1.getNoteTreePda)(program.programId, mintAddress, inputTreeId);
|
|
74
|
+
const outputTree = (0, pdas_js_1.getNoteTreePda)(program.programId, mintAddress, outputTreeId);
|
|
75
|
+
// Nullifier markers are global (no tree_id) to prevent cross-tree double-spend
|
|
76
|
+
const nullifierMarker0 = (0, pdas_js_1.getNullifierMarkerPda)(program.programId, mintAddress, inputNullifiers[0]);
|
|
77
|
+
const nullifierMarker1 = (0, pdas_js_1.getNullifierMarkerPda)(program.programId, mintAddress, inputNullifiers[1]);
|
|
78
|
+
const extDataHash = (0, transaction_js_1.computeExtDataHash)(extData);
|
|
79
|
+
const isNativeSol = mintAddress.equals(config_js_1.NATIVE_SOL_MINT);
|
|
80
|
+
// For SPL tokens, resolve token accounts
|
|
81
|
+
let vaultTA = vaultTokenAccount;
|
|
82
|
+
let userTA = userTokenAccount;
|
|
83
|
+
let recipientTA = recipientTokenAccount;
|
|
84
|
+
let relayerTA = relayerTokenAccount;
|
|
85
|
+
if (!isNativeSol) {
|
|
86
|
+
if (!vaultTA) {
|
|
87
|
+
vaultTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, vault, true);
|
|
88
|
+
}
|
|
89
|
+
if (!userTA) {
|
|
90
|
+
userTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, relayer.publicKey);
|
|
91
|
+
}
|
|
92
|
+
if (!recipientTA) {
|
|
93
|
+
recipientTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, recipient);
|
|
94
|
+
}
|
|
95
|
+
if (!relayerTA) {
|
|
96
|
+
relayerTA = await (0, spl_token_1.getAssociatedTokenAddress)(mintAddress, relayer.publicKey);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
vaultTA ?? (vaultTA = relayer.publicKey);
|
|
101
|
+
userTA ?? (userTA = relayer.publicKey);
|
|
102
|
+
recipientTA ?? (recipientTA = relayer.publicKey);
|
|
103
|
+
relayerTA ?? (relayerTA = relayer.publicKey);
|
|
104
|
+
}
|
|
105
|
+
const tx = program.methods
|
|
106
|
+
.transact(Array.from(root), inputTreeId, outputTreeId, new BN(publicAmount.toString()), Array.from(extDataHash), mintAddress, Array.from(inputNullifiers[0]), Array.from(inputNullifiers[1]), Array.from(outputCommitments[0]), Array.from(outputCommitments[1]), new BN(deadline.toString()), {
|
|
107
|
+
recipient: extData.recipient,
|
|
108
|
+
relayer: extData.relayer,
|
|
109
|
+
fee: new BN(extData.fee.toString()),
|
|
110
|
+
refund: new BN(extData.refund.toString()),
|
|
111
|
+
claimant: extData.claimant,
|
|
112
|
+
}, {
|
|
113
|
+
proofA: proof.proofA,
|
|
114
|
+
proofB: proof.proofB,
|
|
115
|
+
proofC: proof.proofC,
|
|
116
|
+
}, noteCiphers
|
|
117
|
+
? {
|
|
118
|
+
note0EphemeralKey: Array.from(noteCiphers.note0EphemeralKey),
|
|
119
|
+
note0Encrypted: Array.from(noteCiphers.note0Encrypted),
|
|
120
|
+
note0ViewTag: noteCiphers.note0ViewTag,
|
|
121
|
+
note1EphemeralKey: Array.from(noteCiphers.note1EphemeralKey),
|
|
122
|
+
note1Encrypted: Array.from(noteCiphers.note1Encrypted),
|
|
123
|
+
note1ViewTag: noteCiphers.note1ViewTag,
|
|
124
|
+
}
|
|
125
|
+
: null)
|
|
126
|
+
.accountsStrict({
|
|
127
|
+
config,
|
|
128
|
+
globalConfig,
|
|
129
|
+
vault,
|
|
130
|
+
inputTree,
|
|
131
|
+
outputTree,
|
|
132
|
+
nullifiers,
|
|
133
|
+
nullifierMarker0,
|
|
134
|
+
nullifierMarker1,
|
|
135
|
+
relayer: relayer.publicKey,
|
|
136
|
+
recipient,
|
|
137
|
+
vaultTokenAccount: vaultTA,
|
|
138
|
+
userTokenAccount: userTA,
|
|
139
|
+
recipientTokenAccount: recipientTA,
|
|
140
|
+
relayerTokenAccount: relayerTA,
|
|
141
|
+
tokenProgram: isNativeSol ? web3_js_1.SystemProgram.programId : spl_token_1.TOKEN_PROGRAM_ID,
|
|
142
|
+
systemProgram: web3_js_1.SystemProgram.programId,
|
|
143
|
+
})
|
|
144
|
+
.signers([relayer]);
|
|
145
|
+
return (0, retry_js_1.withRpcRetry)(() => tx.rpc());
|
|
146
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Program, Idl } from "@coral-xyz/anchor";
|
|
2
|
+
import { Keypair, PublicKey } from "@solana/web3.js";
|
|
3
|
+
import type { TransactionProofBuilder } from "../proofs/types.js";
|
|
4
|
+
import type { InputUTXO, SerializedUTXO } from "../notes/model.js";
|
|
5
|
+
import { MerkleTree } from "../merkle.js";
|
|
6
|
+
import { type NoteCiphers } from "../compactNote.js";
|
|
7
|
+
export type TransferResult = {
|
|
8
|
+
/** Output UTXOs created by the transfer */
|
|
9
|
+
outputUTXOs: [SerializedUTXO, SerializedUTXO];
|
|
10
|
+
/** Leaf indices where the UTXOs were inserted */
|
|
11
|
+
leafIndices: [number, number];
|
|
12
|
+
/** New Merkle root after insertion */
|
|
13
|
+
root: Uint8Array;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Execute a private transfer within the pool.
|
|
17
|
+
*
|
|
18
|
+
* For transfers, the publicAmount is 0 (no funds enter or leave the pool).
|
|
19
|
+
* Input amounts must equal output amounts.
|
|
20
|
+
*
|
|
21
|
+
* @param inputUTXOs - The UTXOs being spent
|
|
22
|
+
* @param outputPubkeys - UTXO public keys for the recipients
|
|
23
|
+
* @param outputAmounts - Amounts for each output (must sum to input total)
|
|
24
|
+
* @param inputTreeId - The tree ID where input UTXOs are located
|
|
25
|
+
* @param outputTreeId - The tree ID where output commitments will be inserted
|
|
26
|
+
*/
|
|
27
|
+
export declare function privateTransfer<T extends Idl>(params: {
|
|
28
|
+
program: Program<T>;
|
|
29
|
+
relayer: Keypair;
|
|
30
|
+
mintAddress: PublicKey;
|
|
31
|
+
inputUTXOs: [InputUTXO, InputUTXO];
|
|
32
|
+
outputPubkeys: [bigint, bigint];
|
|
33
|
+
outputAmounts: [bigint, bigint];
|
|
34
|
+
root: Uint8Array;
|
|
35
|
+
inputTreeId: number;
|
|
36
|
+
outputTreeId: number;
|
|
37
|
+
tree: MerkleTree;
|
|
38
|
+
proofBuilder: TransactionProofBuilder;
|
|
39
|
+
/** Must be zero: the program rejects fees on publicAmount=0 transfers. */
|
|
40
|
+
fee?: bigint;
|
|
41
|
+
deadline?: bigint;
|
|
42
|
+
/** Public recipient account committed in ExtData (no funds are sent to it). */
|
|
43
|
+
externalRecipient?: PublicKey;
|
|
44
|
+
/** Wallet keys used to encrypt output notes for on-chain recovery. */
|
|
45
|
+
noteRecipientWallets?: [
|
|
46
|
+
PublicKey | Uint8Array | null,
|
|
47
|
+
PublicKey | Uint8Array | null
|
|
48
|
+
];
|
|
49
|
+
/** Prebuilt note ciphers. Takes precedence over noteRecipientWallets. */
|
|
50
|
+
noteCiphers?: NoteCiphers | null;
|
|
51
|
+
}): Promise<TransferResult>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.privateTransfer = privateTransfer;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const transaction_js_1 = require("../proofs/transaction.js");
|
|
6
|
+
const encoding_js_1 = require("../proofs/encoding.js");
|
|
7
|
+
const model_js_1 = require("../notes/model.js");
|
|
8
|
+
const transact_js_1 = require("./transact.js");
|
|
9
|
+
const poseidon_js_1 = require("../poseidon.js");
|
|
10
|
+
const compactNote_js_1 = require("../compactNote.js");
|
|
11
|
+
/**
|
|
12
|
+
* Execute a private transfer within the pool.
|
|
13
|
+
*
|
|
14
|
+
* For transfers, the publicAmount is 0 (no funds enter or leave the pool).
|
|
15
|
+
* Input amounts must equal output amounts.
|
|
16
|
+
*
|
|
17
|
+
* @param inputUTXOs - The UTXOs being spent
|
|
18
|
+
* @param outputPubkeys - UTXO public keys for the recipients
|
|
19
|
+
* @param outputAmounts - Amounts for each output (must sum to input total)
|
|
20
|
+
* @param inputTreeId - The tree ID where input UTXOs are located
|
|
21
|
+
* @param outputTreeId - The tree ID where output commitments will be inserted
|
|
22
|
+
*/
|
|
23
|
+
async function privateTransfer(params) {
|
|
24
|
+
const { program, relayer, mintAddress, inputUTXOs, outputPubkeys, outputAmounts, root, inputTreeId, outputTreeId, tree, proofBuilder, fee = 0n, deadline = BigInt(Math.floor(Date.now() / 1000) + 600), externalRecipient = web3_js_1.Keypair.generate().publicKey, noteRecipientWallets, noteCiphers, } = params;
|
|
25
|
+
if (fee !== 0n) {
|
|
26
|
+
throw new Error("Private transact transfers require fee=0; represent any relayer fee in the output amounts");
|
|
27
|
+
}
|
|
28
|
+
const totalInput = inputUTXOs[0].amount + inputUTXOs[1].amount;
|
|
29
|
+
const totalOutput = outputAmounts[0] + outputAmounts[1];
|
|
30
|
+
if (totalInput !== totalOutput) {
|
|
31
|
+
throw new Error(`Balance mismatch: inputs=${totalInput}, outputs=${totalOutput}`);
|
|
32
|
+
}
|
|
33
|
+
const outputUTXO0 = (0, model_js_1.createUTXO)({
|
|
34
|
+
amount: outputAmounts[0],
|
|
35
|
+
pubkey: outputPubkeys[0],
|
|
36
|
+
mintAddress,
|
|
37
|
+
});
|
|
38
|
+
const outputUTXO1 = (0, model_js_1.createUTXO)({
|
|
39
|
+
amount: outputAmounts[1],
|
|
40
|
+
pubkey: outputPubkeys[1],
|
|
41
|
+
mintAddress,
|
|
42
|
+
});
|
|
43
|
+
const outputUTXOs = [
|
|
44
|
+
outputUTXO0,
|
|
45
|
+
outputUTXO1,
|
|
46
|
+
];
|
|
47
|
+
const extData = {
|
|
48
|
+
recipient: externalRecipient,
|
|
49
|
+
relayer: relayer.publicKey,
|
|
50
|
+
fee: 0n,
|
|
51
|
+
refund: 0n,
|
|
52
|
+
claimant: web3_js_1.SystemProgram.programId,
|
|
53
|
+
};
|
|
54
|
+
// publicAmount is 0 for transfers
|
|
55
|
+
const publicAmount = 0n;
|
|
56
|
+
const circuitInputs = (0, transaction_js_1.prepareTransactionInputs)({
|
|
57
|
+
inputUTXOs,
|
|
58
|
+
outputUTXOs,
|
|
59
|
+
root,
|
|
60
|
+
publicAmount,
|
|
61
|
+
extData,
|
|
62
|
+
mintAddress,
|
|
63
|
+
});
|
|
64
|
+
const rawProof = await proofBuilder(circuitInputs);
|
|
65
|
+
const proof = (0, encoding_js_1.encodeSnarkjsProofToTransactionProof)(rawProof);
|
|
66
|
+
const walletBytes = (wallet) => wallet instanceof web3_js_1.PublicKey ? wallet.toBytes() : wallet;
|
|
67
|
+
const transferNoteCiphers = noteCiphers ??
|
|
68
|
+
(noteRecipientWallets
|
|
69
|
+
? (0, compactNote_js_1.createNoteCiphers)(noteRecipientWallets[0]
|
|
70
|
+
? {
|
|
71
|
+
recipientWalletPubkey: walletBytes(noteRecipientWallets[0]),
|
|
72
|
+
blinding: (0, poseidon_js_1.bigIntToBytesBE)(outputUTXOs[0].blinding),
|
|
73
|
+
amount: outputUTXOs[0].amount,
|
|
74
|
+
}
|
|
75
|
+
: null, noteRecipientWallets[1]
|
|
76
|
+
? {
|
|
77
|
+
recipientWalletPubkey: walletBytes(noteRecipientWallets[1]),
|
|
78
|
+
blinding: (0, poseidon_js_1.bigIntToBytesBE)(outputUTXOs[1].blinding),
|
|
79
|
+
amount: outputUTXOs[1].amount,
|
|
80
|
+
}
|
|
81
|
+
: null)
|
|
82
|
+
: null);
|
|
83
|
+
await (0, transact_js_1.transact)({
|
|
84
|
+
program,
|
|
85
|
+
relayer,
|
|
86
|
+
recipient: externalRecipient,
|
|
87
|
+
mintAddress,
|
|
88
|
+
root,
|
|
89
|
+
inputTreeId,
|
|
90
|
+
outputTreeId,
|
|
91
|
+
publicAmount,
|
|
92
|
+
inputNullifiers: circuitInputs.inputNullifiers,
|
|
93
|
+
outputCommitments: circuitInputs.outputCommitments,
|
|
94
|
+
extData,
|
|
95
|
+
proof,
|
|
96
|
+
deadline,
|
|
97
|
+
noteCiphers: transferNoteCiphers,
|
|
98
|
+
});
|
|
99
|
+
const { index: outIdx0 } = tree.insert(outputUTXOs[0].commitment);
|
|
100
|
+
const { index: outIdx1, root: newRoot } = tree.insert(outputUTXOs[1].commitment);
|
|
101
|
+
return {
|
|
102
|
+
outputUTXOs,
|
|
103
|
+
leafIndices: [outIdx0, outIdx1],
|
|
104
|
+
root: newRoot,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Program, Idl } from "@coral-xyz/anchor";
|
|
2
|
+
import { Keypair, PublicKey } from "@solana/web3.js";
|
|
3
|
+
import type { TransactionProofBuilder } from "../proofs/types.js";
|
|
4
|
+
import type { InputUTXO, SerializedUTXO } from "../notes/model.js";
|
|
5
|
+
import { MerkleTree } from "../merkle.js";
|
|
6
|
+
import { type NoteCiphers } from "../compactNote.js";
|
|
7
|
+
export type WithdrawResult = {
|
|
8
|
+
/** Change UTXO (remaining balance) */
|
|
9
|
+
changeUTXO: SerializedUTXO;
|
|
10
|
+
/** Leaf index of the change UTXO */
|
|
11
|
+
leafIndex: number;
|
|
12
|
+
/** New Merkle root after insertion */
|
|
13
|
+
root: Uint8Array;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Withdraw funds from the privacy pool.
|
|
17
|
+
*
|
|
18
|
+
* For withdrawals, we spend input UTXOs and create change output UTXOs.
|
|
19
|
+
* The publicAmount is negative (funds flowing out).
|
|
20
|
+
*
|
|
21
|
+
* @param withdrawAmount - Amount to withdraw in lamports/token units
|
|
22
|
+
* @param inputUTXOs - The UTXOs being spent
|
|
23
|
+
* @param changePubkey - UTXO public key for the change output
|
|
24
|
+
* @param inputTreeId - The tree ID where input UTXOs are located
|
|
25
|
+
* @param outputTreeId - The tree ID where change outputs will be inserted
|
|
26
|
+
*/
|
|
27
|
+
export declare function withdraw<T extends Idl>(params: {
|
|
28
|
+
program: Program<T>;
|
|
29
|
+
relayer: Keypair;
|
|
30
|
+
recipient: PublicKey;
|
|
31
|
+
mintAddress: PublicKey;
|
|
32
|
+
inputUTXOs: [InputUTXO, InputUTXO];
|
|
33
|
+
changePubkey: bigint;
|
|
34
|
+
withdrawAmount: bigint;
|
|
35
|
+
fee: bigint;
|
|
36
|
+
refund: bigint;
|
|
37
|
+
root: Uint8Array;
|
|
38
|
+
inputTreeId: number;
|
|
39
|
+
outputTreeId: number;
|
|
40
|
+
tree: MerkleTree;
|
|
41
|
+
proofBuilder: TransactionProofBuilder;
|
|
42
|
+
/** When true, the fee is debited in addition to withdrawAmount. */
|
|
43
|
+
feeOnTop?: boolean;
|
|
44
|
+
deadline?: bigint;
|
|
45
|
+
/** Solana wallet key used to encrypt the change note for chain recovery. */
|
|
46
|
+
changeNoteRecipientWallet?: PublicKey | Uint8Array;
|
|
47
|
+
/** Prebuilt recovery payload. Takes precedence over changeNoteRecipientWallet. */
|
|
48
|
+
noteCiphers?: NoteCiphers | null;
|
|
49
|
+
}): Promise<WithdrawResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Result of a private transfer operation.
|
|
52
|
+
*/
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withdraw = withdraw;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const transaction_js_1 = require("../proofs/transaction.js");
|
|
6
|
+
const encoding_js_1 = require("../proofs/encoding.js");
|
|
7
|
+
const model_js_1 = require("../notes/model.js");
|
|
8
|
+
const transact_js_1 = require("./transact.js");
|
|
9
|
+
const poseidon_js_1 = require("../poseidon.js");
|
|
10
|
+
const compactNote_js_1 = require("../compactNote.js");
|
|
11
|
+
/**
|
|
12
|
+
* Withdraw funds from the privacy pool.
|
|
13
|
+
*
|
|
14
|
+
* For withdrawals, we spend input UTXOs and create change output UTXOs.
|
|
15
|
+
* The publicAmount is negative (funds flowing out).
|
|
16
|
+
*
|
|
17
|
+
* @param withdrawAmount - Amount to withdraw in lamports/token units
|
|
18
|
+
* @param inputUTXOs - The UTXOs being spent
|
|
19
|
+
* @param changePubkey - UTXO public key for the change output
|
|
20
|
+
* @param inputTreeId - The tree ID where input UTXOs are located
|
|
21
|
+
* @param outputTreeId - The tree ID where change outputs will be inserted
|
|
22
|
+
*/
|
|
23
|
+
async function withdraw(params) {
|
|
24
|
+
const { program, relayer, recipient, mintAddress, inputUTXOs, changePubkey, withdrawAmount, fee, refund, root, inputTreeId, outputTreeId, tree, proofBuilder, feeOnTop = false, deadline = BigInt(Math.floor(Date.now() / 1000) + 600), changeNoteRecipientWallet, noteCiphers, } = params;
|
|
25
|
+
const totalInput = inputUTXOs[0].amount + inputUTXOs[1].amount;
|
|
26
|
+
const outflowAmount = feeOnTop ? withdrawAmount + fee : withdrawAmount;
|
|
27
|
+
const changeAmount = totalInput - outflowAmount;
|
|
28
|
+
if (withdrawAmount <= 0n) {
|
|
29
|
+
throw new Error("Withdrawal amount must be positive");
|
|
30
|
+
}
|
|
31
|
+
if (fee < 0n || refund < 0n || fee + refund > outflowAmount) {
|
|
32
|
+
throw new Error("Withdrawal fee and refund must fit within the public outflow");
|
|
33
|
+
}
|
|
34
|
+
if (changeAmount < 0n) {
|
|
35
|
+
throw new Error("Insufficient input balance for withdrawal");
|
|
36
|
+
}
|
|
37
|
+
const changeUTXO = (0, model_js_1.createUTXO)({
|
|
38
|
+
amount: changeAmount,
|
|
39
|
+
pubkey: changePubkey,
|
|
40
|
+
mintAddress,
|
|
41
|
+
});
|
|
42
|
+
const zeroUTXO = (0, model_js_1.createUTXO)({
|
|
43
|
+
amount: 0n,
|
|
44
|
+
pubkey: (0, model_js_1.generateKeypair)().publicKey,
|
|
45
|
+
mintAddress,
|
|
46
|
+
});
|
|
47
|
+
const outputUTXOs = [changeUTXO, zeroUTXO];
|
|
48
|
+
const extData = {
|
|
49
|
+
recipient,
|
|
50
|
+
relayer: relayer.publicKey,
|
|
51
|
+
fee,
|
|
52
|
+
refund,
|
|
53
|
+
claimant: web3_js_1.SystemProgram.programId,
|
|
54
|
+
};
|
|
55
|
+
// publicAmount is negative for withdrawals
|
|
56
|
+
const publicAmount = -outflowAmount;
|
|
57
|
+
const circuitInputs = (0, transaction_js_1.prepareTransactionInputs)({
|
|
58
|
+
inputUTXOs,
|
|
59
|
+
outputUTXOs,
|
|
60
|
+
root,
|
|
61
|
+
publicAmount,
|
|
62
|
+
extData,
|
|
63
|
+
mintAddress,
|
|
64
|
+
});
|
|
65
|
+
const rawProof = await proofBuilder(circuitInputs);
|
|
66
|
+
const proof = (0, encoding_js_1.encodeSnarkjsProofToTransactionProof)(rawProof);
|
|
67
|
+
const withdrawNoteCiphers = noteCiphers !== undefined
|
|
68
|
+
? noteCiphers
|
|
69
|
+
: changeNoteRecipientWallet && changeAmount > 0n
|
|
70
|
+
? (0, compactNote_js_1.createNoteCiphers)({
|
|
71
|
+
recipientWalletPubkey: changeNoteRecipientWallet instanceof web3_js_1.PublicKey
|
|
72
|
+
? changeNoteRecipientWallet.toBytes()
|
|
73
|
+
: changeNoteRecipientWallet,
|
|
74
|
+
blinding: (0, poseidon_js_1.bigIntToBytesBE)(changeUTXO.blinding),
|
|
75
|
+
amount: changeAmount,
|
|
76
|
+
}, null)
|
|
77
|
+
: null;
|
|
78
|
+
await (0, transact_js_1.transact)({
|
|
79
|
+
program,
|
|
80
|
+
relayer,
|
|
81
|
+
recipient,
|
|
82
|
+
mintAddress,
|
|
83
|
+
root,
|
|
84
|
+
inputTreeId,
|
|
85
|
+
outputTreeId,
|
|
86
|
+
publicAmount,
|
|
87
|
+
inputNullifiers: circuitInputs.inputNullifiers,
|
|
88
|
+
outputCommitments: circuitInputs.outputCommitments,
|
|
89
|
+
extData,
|
|
90
|
+
proof,
|
|
91
|
+
deadline,
|
|
92
|
+
noteCiphers: withdrawNoteCiphers,
|
|
93
|
+
});
|
|
94
|
+
const { index: changeIdx } = tree.insert(changeUTXO.commitment);
|
|
95
|
+
const { root: newRoot } = tree.insert(zeroUTXO.commitment);
|
|
96
|
+
return {
|
|
97
|
+
changeUTXO,
|
|
98
|
+
leafIndex: changeIdx,
|
|
99
|
+
root: newRoot,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Result of a private transfer operation.
|
|
104
|
+
*/
|