@veil-cash/sdk 0.6.1 → 0.6.2
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/README.md +5 -1
- package/SDK.md +20 -2
- package/dist/cli/index.cjs +257 -13
- package/dist/index.cjs +185 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -2
- package/dist/index.d.ts +84 -2
- package/dist/index.js +184 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/veil/SKILL.md +26 -8
- package/skills/veil/reference.md +23 -3
- package/src/cli/commands/subaccount.ts +82 -2
- package/src/cli/index.ts +1 -1
- package/src/index.ts +6 -0
- package/src/subaccount.ts +244 -5
- package/src/types.ts +56 -0
package/dist/index.d.cts
CHANGED
|
@@ -406,6 +406,23 @@ interface SubaccountBalances {
|
|
|
406
406
|
eth: SubaccountAssetBalance;
|
|
407
407
|
usdc: SubaccountAssetBalance;
|
|
408
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Private pool balance summary for a specific asset
|
|
411
|
+
*/
|
|
412
|
+
interface SubaccountPrivateBalanceStatus {
|
|
413
|
+
privateBalance: string;
|
|
414
|
+
privateBalanceWei: string;
|
|
415
|
+
utxoCount: number;
|
|
416
|
+
spentCount: number;
|
|
417
|
+
unspentCount: number;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Private pool balances for both supported assets
|
|
421
|
+
*/
|
|
422
|
+
interface SubaccountPrivateBalances {
|
|
423
|
+
eth: SubaccountPrivateBalanceStatus;
|
|
424
|
+
usdc: SubaccountPrivateBalanceStatus;
|
|
425
|
+
}
|
|
409
426
|
/**
|
|
410
427
|
* Queue status for a specific asset
|
|
411
428
|
*/
|
|
@@ -423,6 +440,7 @@ interface SubaccountStatusResult {
|
|
|
423
440
|
slot: SubaccountSlot;
|
|
424
441
|
deployed: boolean;
|
|
425
442
|
balances: SubaccountBalances;
|
|
443
|
+
privateBalances: SubaccountPrivateBalances;
|
|
426
444
|
queues: {
|
|
427
445
|
eth: SubaccountQueueStatus;
|
|
428
446
|
usdc: SubaccountQueueStatus;
|
|
@@ -453,6 +471,40 @@ interface SubaccountWithdrawTypedData {
|
|
|
453
471
|
deadline: bigint;
|
|
454
472
|
};
|
|
455
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Options for merging a subaccount's private balance back to the main wallet
|
|
476
|
+
*/
|
|
477
|
+
interface SubaccountMergeOptions {
|
|
478
|
+
/** Root private key (VEIL_KEY) */
|
|
479
|
+
rootPrivateKey: `0x${string}`;
|
|
480
|
+
/** Subaccount slot (0-2) */
|
|
481
|
+
slot: number;
|
|
482
|
+
/** Pool to merge in (default: 'eth') */
|
|
483
|
+
pool?: RelayPool;
|
|
484
|
+
/** Optional RPC URL */
|
|
485
|
+
rpcUrl?: string;
|
|
486
|
+
/** Optional relay URL */
|
|
487
|
+
relayUrl?: string;
|
|
488
|
+
/** Progress callback */
|
|
489
|
+
onProgress?: (stage: string, detail?: string) => void;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Result from merging a subaccount's balance to the main wallet
|
|
493
|
+
*/
|
|
494
|
+
interface SubaccountMergeResult {
|
|
495
|
+
/** Whether the merge was successful */
|
|
496
|
+
success: boolean;
|
|
497
|
+
/** Transaction hash */
|
|
498
|
+
transactionHash: string;
|
|
499
|
+
/** Block number of the transaction */
|
|
500
|
+
blockNumber: string;
|
|
501
|
+
/** Amount merged (human-readable) */
|
|
502
|
+
amount: string;
|
|
503
|
+
/** Subaccount slot that was merged */
|
|
504
|
+
slot: number;
|
|
505
|
+
/** Pool the merge was executed in */
|
|
506
|
+
pool: RelayPool;
|
|
507
|
+
}
|
|
456
508
|
/**
|
|
457
509
|
* Built recovery transaction and signing metadata
|
|
458
510
|
*/
|
|
@@ -2587,8 +2639,17 @@ declare function isSubaccountForwarderDeployed(options: {
|
|
|
2587
2639
|
forwarderAddress: `0x${string}`;
|
|
2588
2640
|
rpcUrl?: string;
|
|
2589
2641
|
}): Promise<boolean>;
|
|
2590
|
-
declare function deploySubaccountForwarder(options: SubaccountDeployRequest): Promise<SubaccountRelayResult
|
|
2642
|
+
declare function deploySubaccountForwarder(options: SubaccountDeployRequest): Promise<SubaccountRelayResult & {
|
|
2643
|
+
slot: SubaccountSlot;
|
|
2644
|
+
}>;
|
|
2591
2645
|
declare function sweepSubaccountForwarder(options: SubaccountSweepRequest): Promise<SubaccountRelayResult>;
|
|
2646
|
+
declare function getSubaccountPrivateBalance(options: {
|
|
2647
|
+
rootPrivateKey: `0x${string}`;
|
|
2648
|
+
slot: number;
|
|
2649
|
+
pool?: 'eth' | 'usdc';
|
|
2650
|
+
rpcUrl?: string;
|
|
2651
|
+
onProgress?: (stage: string, detail?: string) => void;
|
|
2652
|
+
}): Promise<PrivateBalanceResult>;
|
|
2592
2653
|
declare function getSubaccountStatus(options: {
|
|
2593
2654
|
rootPrivateKey: `0x${string}`;
|
|
2594
2655
|
slot: number;
|
|
@@ -2627,6 +2688,27 @@ declare function buildSubaccountRecoveryTx(options: {
|
|
|
2627
2688
|
deadline?: bigint | number;
|
|
2628
2689
|
rpcUrl?: string;
|
|
2629
2690
|
}): Promise<SubaccountRecoveryResult>;
|
|
2691
|
+
/**
|
|
2692
|
+
* Merge a subaccount's entire private balance back to the main wallet.
|
|
2693
|
+
*
|
|
2694
|
+
* Builds a ZK transfer proof that moves every unspent UTXO belonging to the
|
|
2695
|
+
* child keypair into a new UTXO encrypted to the parent (root) keypair,
|
|
2696
|
+
* then submits it via the relay.
|
|
2697
|
+
*
|
|
2698
|
+
* @param options - Merge options
|
|
2699
|
+
* @returns Merge result with transaction hash and amount
|
|
2700
|
+
*
|
|
2701
|
+
* @example
|
|
2702
|
+
* ```typescript
|
|
2703
|
+
* const result = await mergeSubaccount({
|
|
2704
|
+
* rootPrivateKey: process.env.VEIL_KEY as `0x${string}`,
|
|
2705
|
+
* slot: 0,
|
|
2706
|
+
* pool: 'eth',
|
|
2707
|
+
* });
|
|
2708
|
+
* console.log(`Merged ${result.amount} — tx: ${result.transactionHash}`);
|
|
2709
|
+
* ```
|
|
2710
|
+
*/
|
|
2711
|
+
declare function mergeSubaccount(options: SubaccountMergeOptions): Promise<SubaccountMergeResult>;
|
|
2630
2712
|
|
|
2631
2713
|
/**
|
|
2632
2714
|
* Crypto utilities for Veil SDK
|
|
@@ -2697,4 +2779,4 @@ declare function getExtDataHash(extData: ExtDataInput): bigint;
|
|
|
2697
2779
|
*/
|
|
2698
2780
|
declare function shuffle<T>(array: T[]): T[];
|
|
2699
2781
|
|
|
2700
|
-
export { ADDRESSES, type BuildTransferProofOptions, type BuildWithdrawProofOptions, CIRCUIT_CONFIG, type DepositTxOptions, ENTRY_ABI, ERC20_ABI, type EncryptedMessage, type ExtData, type ExtDataInput, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, type MessageSigner, type NetworkAddresses, POOL_ABI, POOL_CONFIG, type PendingDeposit, type PoolConfig, type PrepareTransactionParams, type PrivateBalanceResult, type ProgressCallback, type ProofArgs, type ProofBuildResult, type ProofInput, QUEUE_ABI, type QueueBalanceResult, type RegisterTxOptions, RelayError, type RelayErrorResponse, type RelayExtData, type RelayMetadata, type RelayPool, type RelayProofArgs, type RelayRequest, type RelayResponse, type RelayType, type SubaccountAsset, type SubaccountAssetBalance, type SubaccountBalances, type SubaccountDeployRequest, type SubaccountQueueStatus, type SubaccountRecoveryResult, type SubaccountRelayResult, type SubaccountSlot, type SubaccountStatusResult, type SubaccountSweepRequest, type SubaccountWithdrawTypedData, type SubmitRelayOptions, type Token, type TransactionData, type TransactionResult, type TransferResult, Utxo, type UtxoInfo, type UtxoParams, type UtxoSelectionResult, VEIL_SIGNED_MESSAGE, type WithdrawResult, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountStatus, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeUtxos, packEncryptedMessage, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, randomBN, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, withdraw };
|
|
2782
|
+
export { ADDRESSES, type BuildTransferProofOptions, type BuildWithdrawProofOptions, CIRCUIT_CONFIG, type DepositTxOptions, ENTRY_ABI, ERC20_ABI, type EncryptedMessage, type ExtData, type ExtDataInput, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, type MessageSigner, type NetworkAddresses, POOL_ABI, POOL_CONFIG, type PendingDeposit, type PoolConfig, type PrepareTransactionParams, type PrivateBalanceResult, type ProgressCallback, type ProofArgs, type ProofBuildResult, type ProofInput, QUEUE_ABI, type QueueBalanceResult, type RegisterTxOptions, RelayError, type RelayErrorResponse, type RelayExtData, type RelayMetadata, type RelayPool, type RelayProofArgs, type RelayRequest, type RelayResponse, type RelayType, type SubaccountAsset, type SubaccountAssetBalance, type SubaccountBalances, type SubaccountDeployRequest, type SubaccountMergeOptions, type SubaccountMergeResult, type SubaccountPrivateBalanceStatus, type SubaccountPrivateBalances, type SubaccountQueueStatus, type SubaccountRecoveryResult, type SubaccountRelayResult, type SubaccountSlot, type SubaccountStatusResult, type SubaccountSweepRequest, type SubaccountWithdrawTypedData, type SubmitRelayOptions, type Token, type TransactionData, type TransactionResult, type TransferResult, Utxo, type UtxoInfo, type UtxoParams, type UtxoSelectionResult, VEIL_SIGNED_MESSAGE, type WithdrawResult, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountPrivateBalance, getSubaccountStatus, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeSubaccount, mergeUtxos, packEncryptedMessage, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, randomBN, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, withdraw };
|
package/dist/index.d.ts
CHANGED
|
@@ -406,6 +406,23 @@ interface SubaccountBalances {
|
|
|
406
406
|
eth: SubaccountAssetBalance;
|
|
407
407
|
usdc: SubaccountAssetBalance;
|
|
408
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Private pool balance summary for a specific asset
|
|
411
|
+
*/
|
|
412
|
+
interface SubaccountPrivateBalanceStatus {
|
|
413
|
+
privateBalance: string;
|
|
414
|
+
privateBalanceWei: string;
|
|
415
|
+
utxoCount: number;
|
|
416
|
+
spentCount: number;
|
|
417
|
+
unspentCount: number;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Private pool balances for both supported assets
|
|
421
|
+
*/
|
|
422
|
+
interface SubaccountPrivateBalances {
|
|
423
|
+
eth: SubaccountPrivateBalanceStatus;
|
|
424
|
+
usdc: SubaccountPrivateBalanceStatus;
|
|
425
|
+
}
|
|
409
426
|
/**
|
|
410
427
|
* Queue status for a specific asset
|
|
411
428
|
*/
|
|
@@ -423,6 +440,7 @@ interface SubaccountStatusResult {
|
|
|
423
440
|
slot: SubaccountSlot;
|
|
424
441
|
deployed: boolean;
|
|
425
442
|
balances: SubaccountBalances;
|
|
443
|
+
privateBalances: SubaccountPrivateBalances;
|
|
426
444
|
queues: {
|
|
427
445
|
eth: SubaccountQueueStatus;
|
|
428
446
|
usdc: SubaccountQueueStatus;
|
|
@@ -453,6 +471,40 @@ interface SubaccountWithdrawTypedData {
|
|
|
453
471
|
deadline: bigint;
|
|
454
472
|
};
|
|
455
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Options for merging a subaccount's private balance back to the main wallet
|
|
476
|
+
*/
|
|
477
|
+
interface SubaccountMergeOptions {
|
|
478
|
+
/** Root private key (VEIL_KEY) */
|
|
479
|
+
rootPrivateKey: `0x${string}`;
|
|
480
|
+
/** Subaccount slot (0-2) */
|
|
481
|
+
slot: number;
|
|
482
|
+
/** Pool to merge in (default: 'eth') */
|
|
483
|
+
pool?: RelayPool;
|
|
484
|
+
/** Optional RPC URL */
|
|
485
|
+
rpcUrl?: string;
|
|
486
|
+
/** Optional relay URL */
|
|
487
|
+
relayUrl?: string;
|
|
488
|
+
/** Progress callback */
|
|
489
|
+
onProgress?: (stage: string, detail?: string) => void;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Result from merging a subaccount's balance to the main wallet
|
|
493
|
+
*/
|
|
494
|
+
interface SubaccountMergeResult {
|
|
495
|
+
/** Whether the merge was successful */
|
|
496
|
+
success: boolean;
|
|
497
|
+
/** Transaction hash */
|
|
498
|
+
transactionHash: string;
|
|
499
|
+
/** Block number of the transaction */
|
|
500
|
+
blockNumber: string;
|
|
501
|
+
/** Amount merged (human-readable) */
|
|
502
|
+
amount: string;
|
|
503
|
+
/** Subaccount slot that was merged */
|
|
504
|
+
slot: number;
|
|
505
|
+
/** Pool the merge was executed in */
|
|
506
|
+
pool: RelayPool;
|
|
507
|
+
}
|
|
456
508
|
/**
|
|
457
509
|
* Built recovery transaction and signing metadata
|
|
458
510
|
*/
|
|
@@ -2587,8 +2639,17 @@ declare function isSubaccountForwarderDeployed(options: {
|
|
|
2587
2639
|
forwarderAddress: `0x${string}`;
|
|
2588
2640
|
rpcUrl?: string;
|
|
2589
2641
|
}): Promise<boolean>;
|
|
2590
|
-
declare function deploySubaccountForwarder(options: SubaccountDeployRequest): Promise<SubaccountRelayResult
|
|
2642
|
+
declare function deploySubaccountForwarder(options: SubaccountDeployRequest): Promise<SubaccountRelayResult & {
|
|
2643
|
+
slot: SubaccountSlot;
|
|
2644
|
+
}>;
|
|
2591
2645
|
declare function sweepSubaccountForwarder(options: SubaccountSweepRequest): Promise<SubaccountRelayResult>;
|
|
2646
|
+
declare function getSubaccountPrivateBalance(options: {
|
|
2647
|
+
rootPrivateKey: `0x${string}`;
|
|
2648
|
+
slot: number;
|
|
2649
|
+
pool?: 'eth' | 'usdc';
|
|
2650
|
+
rpcUrl?: string;
|
|
2651
|
+
onProgress?: (stage: string, detail?: string) => void;
|
|
2652
|
+
}): Promise<PrivateBalanceResult>;
|
|
2592
2653
|
declare function getSubaccountStatus(options: {
|
|
2593
2654
|
rootPrivateKey: `0x${string}`;
|
|
2594
2655
|
slot: number;
|
|
@@ -2627,6 +2688,27 @@ declare function buildSubaccountRecoveryTx(options: {
|
|
|
2627
2688
|
deadline?: bigint | number;
|
|
2628
2689
|
rpcUrl?: string;
|
|
2629
2690
|
}): Promise<SubaccountRecoveryResult>;
|
|
2691
|
+
/**
|
|
2692
|
+
* Merge a subaccount's entire private balance back to the main wallet.
|
|
2693
|
+
*
|
|
2694
|
+
* Builds a ZK transfer proof that moves every unspent UTXO belonging to the
|
|
2695
|
+
* child keypair into a new UTXO encrypted to the parent (root) keypair,
|
|
2696
|
+
* then submits it via the relay.
|
|
2697
|
+
*
|
|
2698
|
+
* @param options - Merge options
|
|
2699
|
+
* @returns Merge result with transaction hash and amount
|
|
2700
|
+
*
|
|
2701
|
+
* @example
|
|
2702
|
+
* ```typescript
|
|
2703
|
+
* const result = await mergeSubaccount({
|
|
2704
|
+
* rootPrivateKey: process.env.VEIL_KEY as `0x${string}`,
|
|
2705
|
+
* slot: 0,
|
|
2706
|
+
* pool: 'eth',
|
|
2707
|
+
* });
|
|
2708
|
+
* console.log(`Merged ${result.amount} — tx: ${result.transactionHash}`);
|
|
2709
|
+
* ```
|
|
2710
|
+
*/
|
|
2711
|
+
declare function mergeSubaccount(options: SubaccountMergeOptions): Promise<SubaccountMergeResult>;
|
|
2630
2712
|
|
|
2631
2713
|
/**
|
|
2632
2714
|
* Crypto utilities for Veil SDK
|
|
@@ -2697,4 +2779,4 @@ declare function getExtDataHash(extData: ExtDataInput): bigint;
|
|
|
2697
2779
|
*/
|
|
2698
2780
|
declare function shuffle<T>(array: T[]): T[];
|
|
2699
2781
|
|
|
2700
|
-
export { ADDRESSES, type BuildTransferProofOptions, type BuildWithdrawProofOptions, CIRCUIT_CONFIG, type DepositTxOptions, ENTRY_ABI, ERC20_ABI, type EncryptedMessage, type ExtData, type ExtDataInput, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, type MessageSigner, type NetworkAddresses, POOL_ABI, POOL_CONFIG, type PendingDeposit, type PoolConfig, type PrepareTransactionParams, type PrivateBalanceResult, type ProgressCallback, type ProofArgs, type ProofBuildResult, type ProofInput, QUEUE_ABI, type QueueBalanceResult, type RegisterTxOptions, RelayError, type RelayErrorResponse, type RelayExtData, type RelayMetadata, type RelayPool, type RelayProofArgs, type RelayRequest, type RelayResponse, type RelayType, type SubaccountAsset, type SubaccountAssetBalance, type SubaccountBalances, type SubaccountDeployRequest, type SubaccountQueueStatus, type SubaccountRecoveryResult, type SubaccountRelayResult, type SubaccountSlot, type SubaccountStatusResult, type SubaccountSweepRequest, type SubaccountWithdrawTypedData, type SubmitRelayOptions, type Token, type TransactionData, type TransactionResult, type TransferResult, Utxo, type UtxoInfo, type UtxoParams, type UtxoSelectionResult, VEIL_SIGNED_MESSAGE, type WithdrawResult, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountStatus, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeUtxos, packEncryptedMessage, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, randomBN, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, withdraw };
|
|
2782
|
+
export { ADDRESSES, type BuildTransferProofOptions, type BuildWithdrawProofOptions, CIRCUIT_CONFIG, type DepositTxOptions, ENTRY_ABI, ERC20_ABI, type EncryptedMessage, type ExtData, type ExtDataInput, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, type MessageSigner, type NetworkAddresses, POOL_ABI, POOL_CONFIG, type PendingDeposit, type PoolConfig, type PrepareTransactionParams, type PrivateBalanceResult, type ProgressCallback, type ProofArgs, type ProofBuildResult, type ProofInput, QUEUE_ABI, type QueueBalanceResult, type RegisterTxOptions, RelayError, type RelayErrorResponse, type RelayExtData, type RelayMetadata, type RelayPool, type RelayProofArgs, type RelayRequest, type RelayResponse, type RelayType, type SubaccountAsset, type SubaccountAssetBalance, type SubaccountBalances, type SubaccountDeployRequest, type SubaccountMergeOptions, type SubaccountMergeResult, type SubaccountPrivateBalanceStatus, type SubaccountPrivateBalances, type SubaccountQueueStatus, type SubaccountRecoveryResult, type SubaccountRelayResult, type SubaccountSlot, type SubaccountStatusResult, type SubaccountSweepRequest, type SubaccountWithdrawTypedData, type SubmitRelayOptions, type Token, type TransactionData, type TransactionResult, type TransferResult, Utxo, type UtxoInfo, type UtxoParams, type UtxoSelectionResult, VEIL_SIGNED_MESSAGE, type WithdrawResult, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountPrivateBalance, getSubaccountStatus, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeSubaccount, mergeUtxos, packEncryptedMessage, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, randomBN, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, withdraw };
|
package/dist/index.js
CHANGED
|
@@ -1641,7 +1641,16 @@ async function postRelayJson(endpoint, body, relayUrl) {
|
|
|
1641
1641
|
},
|
|
1642
1642
|
body: JSON.stringify(body)
|
|
1643
1643
|
});
|
|
1644
|
-
const
|
|
1644
|
+
const text = await response.text();
|
|
1645
|
+
let data;
|
|
1646
|
+
try {
|
|
1647
|
+
data = JSON.parse(text);
|
|
1648
|
+
} catch {
|
|
1649
|
+
throw new RelayError(
|
|
1650
|
+
`Relay returned non-JSON response (HTTP ${response.status})`,
|
|
1651
|
+
response.status
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1645
1654
|
if (!response.ok) {
|
|
1646
1655
|
const errorData = data;
|
|
1647
1656
|
throw new RelayError(
|
|
@@ -2213,11 +2222,12 @@ function deriveSubaccountChildDepositKey(childPrivateKey) {
|
|
|
2213
2222
|
}
|
|
2214
2223
|
async function predictSubaccountForwarder(options) {
|
|
2215
2224
|
const publicClient = createBaseClient(options.rpcUrl);
|
|
2225
|
+
const depositKeyBytes = options.childDepositKey.startsWith("0x") ? options.childDepositKey : `0x${options.childDepositKey}`;
|
|
2216
2226
|
return publicClient.readContract({
|
|
2217
2227
|
abi: FORWARDER_FACTORY_ABI,
|
|
2218
2228
|
address: getForwarderFactoryAddress(),
|
|
2219
2229
|
functionName: "computeAddress",
|
|
2220
|
-
args: [options.salt,
|
|
2230
|
+
args: [options.salt, depositKeyBytes, options.childOwner]
|
|
2221
2231
|
});
|
|
2222
2232
|
}
|
|
2223
2233
|
async function deriveSubaccountSlot(options) {
|
|
@@ -2254,7 +2264,7 @@ async function deploySubaccountForwarder(options) {
|
|
|
2254
2264
|
slot: options.slot,
|
|
2255
2265
|
rpcUrl: options.rpcUrl
|
|
2256
2266
|
});
|
|
2257
|
-
|
|
2267
|
+
const result = await postRelayJson(
|
|
2258
2268
|
"/stealth/deploy",
|
|
2259
2269
|
{
|
|
2260
2270
|
salt: slot.salt,
|
|
@@ -2264,6 +2274,7 @@ async function deploySubaccountForwarder(options) {
|
|
|
2264
2274
|
},
|
|
2265
2275
|
options.relayUrl
|
|
2266
2276
|
);
|
|
2277
|
+
return { ...result, slot };
|
|
2267
2278
|
}
|
|
2268
2279
|
async function sweepSubaccountForwarder(options) {
|
|
2269
2280
|
const asset = normalizeAsset(options.asset);
|
|
@@ -2288,11 +2299,32 @@ function toQueueStatus(asset, result) {
|
|
|
2288
2299
|
pendingDeposits: result.pendingDeposits
|
|
2289
2300
|
};
|
|
2290
2301
|
}
|
|
2302
|
+
function toPrivateBalanceStatus(result) {
|
|
2303
|
+
return {
|
|
2304
|
+
privateBalance: result.privateBalance,
|
|
2305
|
+
privateBalanceWei: result.privateBalanceWei,
|
|
2306
|
+
utxoCount: result.utxoCount,
|
|
2307
|
+
spentCount: result.spentCount,
|
|
2308
|
+
unspentCount: result.unspentCount
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
async function getSubaccountPrivateBalance(options) {
|
|
2312
|
+
const normalizedSlot = normalizeSlot(options.slot);
|
|
2313
|
+
assertPrivateKey(options.rootPrivateKey, "rootPrivateKey");
|
|
2314
|
+
const childPrivateKey = deriveSubaccountChildPrivateKey(options.rootPrivateKey, normalizedSlot);
|
|
2315
|
+
const childKeypair = new Keypair(childPrivateKey);
|
|
2316
|
+
return getPrivateBalance({
|
|
2317
|
+
keypair: childKeypair,
|
|
2318
|
+
pool: options.pool,
|
|
2319
|
+
rpcUrl: options.rpcUrl,
|
|
2320
|
+
onProgress: options.onProgress
|
|
2321
|
+
});
|
|
2322
|
+
}
|
|
2291
2323
|
async function getSubaccountStatus(options) {
|
|
2292
2324
|
const slot = await deriveSubaccountSlot(options);
|
|
2293
2325
|
const publicClient = createBaseClient(options.rpcUrl);
|
|
2294
2326
|
const addresses = getAddresses();
|
|
2295
|
-
const [deployed, ethWei, usdcWei, ethQueue, usdcQueue] = await Promise.all([
|
|
2327
|
+
const [deployed, ethWei, usdcWei, ethQueue, usdcQueue, ethPrivate, usdcPrivate] = await Promise.all([
|
|
2296
2328
|
isSubaccountForwarderDeployed({
|
|
2297
2329
|
forwarderAddress: slot.forwarderAddress,
|
|
2298
2330
|
rpcUrl: options.rpcUrl
|
|
@@ -2313,6 +2345,18 @@ async function getSubaccountStatus(options) {
|
|
|
2313
2345
|
address: slot.forwarderAddress,
|
|
2314
2346
|
pool: "usdc",
|
|
2315
2347
|
rpcUrl: options.rpcUrl
|
|
2348
|
+
}),
|
|
2349
|
+
getSubaccountPrivateBalance({
|
|
2350
|
+
rootPrivateKey: options.rootPrivateKey,
|
|
2351
|
+
slot: options.slot,
|
|
2352
|
+
pool: "eth",
|
|
2353
|
+
rpcUrl: options.rpcUrl
|
|
2354
|
+
}),
|
|
2355
|
+
getSubaccountPrivateBalance({
|
|
2356
|
+
rootPrivateKey: options.rootPrivateKey,
|
|
2357
|
+
slot: options.slot,
|
|
2358
|
+
pool: "usdc",
|
|
2359
|
+
rpcUrl: options.rpcUrl
|
|
2316
2360
|
})
|
|
2317
2361
|
]);
|
|
2318
2362
|
return {
|
|
@@ -2328,6 +2372,10 @@ async function getSubaccountStatus(options) {
|
|
|
2328
2372
|
balanceWei: usdcWei.toString()
|
|
2329
2373
|
}
|
|
2330
2374
|
},
|
|
2375
|
+
privateBalances: {
|
|
2376
|
+
eth: toPrivateBalanceStatus(ethPrivate),
|
|
2377
|
+
usdc: toPrivateBalanceStatus(usdcPrivate)
|
|
2378
|
+
},
|
|
2331
2379
|
queues: {
|
|
2332
2380
|
eth: toQueueStatus("eth", ethQueue),
|
|
2333
2381
|
usdc: toQueueStatus("usdc", usdcQueue)
|
|
@@ -2474,7 +2522,138 @@ async function buildSubaccountRecoveryTx(options) {
|
|
|
2474
2522
|
signature
|
|
2475
2523
|
};
|
|
2476
2524
|
}
|
|
2525
|
+
async function mergeSubaccount(options) {
|
|
2526
|
+
const {
|
|
2527
|
+
rootPrivateKey,
|
|
2528
|
+
slot,
|
|
2529
|
+
pool = "eth",
|
|
2530
|
+
rpcUrl,
|
|
2531
|
+
relayUrl,
|
|
2532
|
+
onProgress
|
|
2533
|
+
} = options;
|
|
2534
|
+
const normalizedSlot = normalizeSlot(slot);
|
|
2535
|
+
assertPrivateKey(rootPrivateKey, "rootPrivateKey");
|
|
2536
|
+
const poolConfig = POOL_CONFIG[pool];
|
|
2537
|
+
const poolAddress = getPoolAddress(pool);
|
|
2538
|
+
const childPrivateKey = deriveSubaccountChildPrivateKey(rootPrivateKey, normalizedSlot);
|
|
2539
|
+
const childKeypair = new Keypair(childPrivateKey);
|
|
2540
|
+
const parentKeypair = new Keypair(rootPrivateKey);
|
|
2541
|
+
onProgress?.("Fetching subaccount balance...");
|
|
2542
|
+
const balanceResult = await getPrivateBalance({
|
|
2543
|
+
keypair: childKeypair,
|
|
2544
|
+
pool,
|
|
2545
|
+
rpcUrl,
|
|
2546
|
+
onProgress
|
|
2547
|
+
});
|
|
2548
|
+
const unspentUtxoInfos = balanceResult.utxos.filter((u) => !u.isSpent);
|
|
2549
|
+
if (unspentUtxoInfos.length === 0) {
|
|
2550
|
+
throw new Error("Subaccount has no unspent UTXOs to merge");
|
|
2551
|
+
}
|
|
2552
|
+
if (unspentUtxoInfos.length > 16) {
|
|
2553
|
+
throw new Error(
|
|
2554
|
+
`Subaccount has ${unspentUtxoInfos.length} unspent UTXOs which exceeds the 16-input circuit limit. Consolidate UTXOs on the subaccount first before merging.`
|
|
2555
|
+
);
|
|
2556
|
+
}
|
|
2557
|
+
onProgress?.("Preparing UTXOs...");
|
|
2558
|
+
const publicClient = createPublicClient({
|
|
2559
|
+
chain: base,
|
|
2560
|
+
transport: http(rpcUrl)
|
|
2561
|
+
});
|
|
2562
|
+
const utxos = [];
|
|
2563
|
+
for (const utxoInfo of unspentUtxoInfos) {
|
|
2564
|
+
const encryptedOutputs = await publicClient.readContract({
|
|
2565
|
+
address: poolAddress,
|
|
2566
|
+
abi: POOL_ABI,
|
|
2567
|
+
functionName: "getEncryptedOutputs",
|
|
2568
|
+
args: [BigInt(utxoInfo.index), BigInt(utxoInfo.index + 1)]
|
|
2569
|
+
});
|
|
2570
|
+
if (encryptedOutputs.length > 0) {
|
|
2571
|
+
try {
|
|
2572
|
+
const utxo = Utxo.decrypt(encryptedOutputs[0], childKeypair);
|
|
2573
|
+
utxo.index = utxoInfo.index;
|
|
2574
|
+
utxos.push(utxo);
|
|
2575
|
+
} catch {
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
if (utxos.length === 0) {
|
|
2580
|
+
throw new Error("Failed to decrypt subaccount UTXOs");
|
|
2581
|
+
}
|
|
2582
|
+
onProgress?.("Selecting UTXOs...");
|
|
2583
|
+
const amount = balanceResult.privateBalance;
|
|
2584
|
+
const { selectedUtxos, changeAmount } = selectUtxosForWithdraw(
|
|
2585
|
+
utxos,
|
|
2586
|
+
amount,
|
|
2587
|
+
poolConfig.decimals
|
|
2588
|
+
);
|
|
2589
|
+
const outputs = [];
|
|
2590
|
+
const mergeWei = parseUnits(amount, poolConfig.decimals);
|
|
2591
|
+
outputs.push(new Utxo({ amount: mergeWei, keypair: parentKeypair }));
|
|
2592
|
+
if (changeAmount > 0n) {
|
|
2593
|
+
outputs.push(new Utxo({ amount: changeAmount, keypair: parentKeypair }));
|
|
2594
|
+
}
|
|
2595
|
+
onProgress?.("Fetching commitments...");
|
|
2596
|
+
const nextIndex = await publicClient.readContract({
|
|
2597
|
+
address: poolAddress,
|
|
2598
|
+
abi: POOL_ABI,
|
|
2599
|
+
functionName: "nextIndex"
|
|
2600
|
+
});
|
|
2601
|
+
const BATCH_SIZE = 5e3;
|
|
2602
|
+
const commitments = [];
|
|
2603
|
+
const totalBatches = Math.ceil(nextIndex / BATCH_SIZE);
|
|
2604
|
+
for (let start = 0; start < nextIndex; start += BATCH_SIZE) {
|
|
2605
|
+
const end = Math.min(start + BATCH_SIZE, nextIndex);
|
|
2606
|
+
const batchNum = Math.floor(start / BATCH_SIZE) + 1;
|
|
2607
|
+
onProgress?.("Fetching commitments", `batch ${batchNum}/${totalBatches}`);
|
|
2608
|
+
const batch = await publicClient.readContract({
|
|
2609
|
+
address: poolAddress,
|
|
2610
|
+
abi: POOL_ABI,
|
|
2611
|
+
functionName: "getCommitments",
|
|
2612
|
+
args: [BigInt(start), BigInt(end)]
|
|
2613
|
+
});
|
|
2614
|
+
commitments.push(...batch.map((c) => c.toString()));
|
|
2615
|
+
}
|
|
2616
|
+
onProgress?.("Building ZK proof...");
|
|
2617
|
+
const result = await prepareTransaction({
|
|
2618
|
+
commitments,
|
|
2619
|
+
inputs: selectedUtxos,
|
|
2620
|
+
outputs,
|
|
2621
|
+
fee: 0,
|
|
2622
|
+
recipient: "0x0000000000000000000000000000000000000000",
|
|
2623
|
+
relayer: "0x0000000000000000000000000000000000000000",
|
|
2624
|
+
onProgress
|
|
2625
|
+
});
|
|
2626
|
+
onProgress?.("Submitting to relay...");
|
|
2627
|
+
const relayResult = await submitRelay({
|
|
2628
|
+
type: "transfer",
|
|
2629
|
+
pool,
|
|
2630
|
+
relayUrl,
|
|
2631
|
+
proofArgs: {
|
|
2632
|
+
proof: result.args.proof,
|
|
2633
|
+
root: result.args.root,
|
|
2634
|
+
inputNullifiers: result.args.inputNullifiers,
|
|
2635
|
+
outputCommitments: result.args.outputCommitments,
|
|
2636
|
+
publicAmount: result.args.publicAmount,
|
|
2637
|
+
extDataHash: result.args.extDataHash
|
|
2638
|
+
},
|
|
2639
|
+
extData: result.extData,
|
|
2640
|
+
metadata: {
|
|
2641
|
+
amount,
|
|
2642
|
+
recipient: "self",
|
|
2643
|
+
inputUtxoCount: selectedUtxos.length,
|
|
2644
|
+
outputUtxoCount: outputs.length
|
|
2645
|
+
}
|
|
2646
|
+
});
|
|
2647
|
+
return {
|
|
2648
|
+
success: relayResult.success,
|
|
2649
|
+
transactionHash: relayResult.transactionHash,
|
|
2650
|
+
blockNumber: relayResult.blockNumber,
|
|
2651
|
+
amount,
|
|
2652
|
+
slot: normalizedSlot,
|
|
2653
|
+
pool
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2477
2656
|
|
|
2478
|
-
export { ADDRESSES, CIRCUIT_CONFIG, ENTRY_ABI, ERC20_ABI, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, POOL_ABI, POOL_CONFIG, QUEUE_ABI, RelayError, Utxo, VEIL_SIGNED_MESSAGE, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountStatus, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeUtxos, packEncryptedMessage, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, randomBN, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, withdraw };
|
|
2657
|
+
export { ADDRESSES, CIRCUIT_CONFIG, ENTRY_ABI, ERC20_ABI, FIELD_SIZE, FORWARDER_ABI, FORWARDER_CONTRACT_VERSION, FORWARDER_FACTORY_ABI, Keypair, MAX_SUBACCOUNT_SLOTS, MERKLE_TREE_HEIGHT, POOL_ABI, POOL_CONFIG, QUEUE_ABI, RelayError, Utxo, VEIL_SIGNED_MESSAGE, buildApproveUSDCTx, buildChangeDepositKeyTx, buildDepositETHTx, buildDepositTx, buildDepositUSDCTx, buildMerkleTree, buildRegisterTx, buildSubaccountRecoveryTx, buildSubaccountWithdrawTypedData, buildTransferProof, buildWithdrawProof, checkRecipientRegistration, checkRelayHealth, deploySubaccountForwarder, deriveSubaccountChildDepositKey, deriveSubaccountChildOwner, deriveSubaccountChildPrivateKey, deriveSubaccountSalt, deriveSubaccountSlot, findNextSubaccountWithdrawNonce, getAddresses, getExtDataHash, getForwarderFactoryAddress, getMerklePath, getPoolAddress, getPrivateBalance, getQueueAddress, getQueueBalance, getRelayInfo, getRelayUrl, getSubaccountPrivateBalance, getSubaccountStatus, isSubaccountForwarderDeployed, isSubaccountWithdrawNonceUsed, mergeSubaccount, mergeUtxos, packEncryptedMessage, poseidonHash, poseidonHash2, predictSubaccountForwarder, prepareTransaction, prove, randomBN, selectCircuit, selectUtxosForWithdraw, shuffle, signSubaccountWithdraw, submitRelay, sweepSubaccountForwarder, toBuffer, toFixedHex, transfer, unpackEncryptedMessage, withdraw };
|
|
2479
2658
|
//# sourceMappingURL=index.js.map
|
|
2480
2659
|
//# sourceMappingURL=index.js.map
|