@sip-protocol/sdk 0.7.3 → 0.7.4
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 +21 -0
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +47556 -19603
- package/dist/browser.mjs +628 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
- package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48396 -19623
- package/dist/index.mjs +537 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +54 -21
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +252 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +47 -6
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +186 -33
- package/src/chains/solana/providers/index.ts +31 -0
- package/src/chains/solana/providers/interface.ts +61 -18
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +338 -67
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +83 -66
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +57 -6
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +23 -0
- package/src/compliance/range-sas.ts +398 -33
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +686 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +254 -4
- package/src/privacy-backends/interface.ts +649 -6
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash.ts +13 -17
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +414 -2
- package/src/privacy-backends/router.ts +283 -3
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +3 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +110 -29
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-2XIVXWHA.mjs +0 -1930
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-7RFRWDCW.mjs +0 -1504
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-F6F73W35.mjs +0 -16166
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-OFDBEIEK.mjs +0 -16166
- package/dist/chunk-SF7YSLF5.mjs +0 -1515
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/chunk-WWUSGOXE.mjs +0 -17129
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-B71aXVzk.d.ts +0 -13264
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-pOIIuwfV.d.mts +0 -13264
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-4O4K45VU.mjs +0 -46
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-NDABAZ6P.mjs +0 -56
- package/dist/solana-Q4NAVBTS.mjs +0 -46
- package/dist/solana-ZYO63LY5.mjs +0 -46
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ethereum Stealth Transfer Builder
|
|
3
|
+
*
|
|
4
|
+
* High-level transfer orchestration that combines stealth address generation,
|
|
5
|
+
* announcement building, gas estimation, and transaction preparation.
|
|
6
|
+
*
|
|
7
|
+
* @module chains/ethereum/transfer
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { HexString, StealthMetaAddress } from '@sip-protocol/types'
|
|
11
|
+
import { EthereumPrivacyAdapter } from './privacy-adapter'
|
|
12
|
+
import { EthereumRpcClient } from './rpc'
|
|
13
|
+
import {
|
|
14
|
+
estimateEthTransferGas,
|
|
15
|
+
estimateTokenTransferGas,
|
|
16
|
+
type DetailedGasEstimate,
|
|
17
|
+
} from './gas-estimation'
|
|
18
|
+
import type { EthereumNetwork } from './constants'
|
|
19
|
+
|
|
20
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Prepared transaction ready for signing
|
|
24
|
+
*/
|
|
25
|
+
export interface PreparedTransaction {
|
|
26
|
+
/**
|
|
27
|
+
* Target address
|
|
28
|
+
*/
|
|
29
|
+
to: HexString
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Value in wei
|
|
33
|
+
*/
|
|
34
|
+
value: bigint
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Call data (if contract call)
|
|
38
|
+
*/
|
|
39
|
+
data?: HexString
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Nonce
|
|
43
|
+
*/
|
|
44
|
+
nonce: number
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Gas limit
|
|
48
|
+
*/
|
|
49
|
+
gasLimit: bigint
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Chain ID
|
|
53
|
+
*/
|
|
54
|
+
chainId: number
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* EIP-1559: Max priority fee per gas
|
|
58
|
+
*/
|
|
59
|
+
maxPriorityFeePerGas: bigint
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* EIP-1559: Max fee per gas
|
|
63
|
+
*/
|
|
64
|
+
maxFeePerGas: bigint
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Transaction type (2 = EIP-1559)
|
|
68
|
+
*/
|
|
69
|
+
type: 2
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Prepared stealth transfer bundle
|
|
74
|
+
*/
|
|
75
|
+
export interface PreparedStealthTransfer {
|
|
76
|
+
/**
|
|
77
|
+
* ETH/token transfer transaction
|
|
78
|
+
*/
|
|
79
|
+
transferTx: PreparedTransaction
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Announcement transaction
|
|
83
|
+
*/
|
|
84
|
+
announcementTx: PreparedTransaction
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Stealth address receiving funds
|
|
88
|
+
*/
|
|
89
|
+
stealthAddress: HexString
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Ephemeral public key for recipient
|
|
93
|
+
*/
|
|
94
|
+
ephemeralPublicKey: HexString
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* View tag for efficient scanning
|
|
98
|
+
*/
|
|
99
|
+
viewTag: number
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Amount commitment (if hiding amounts)
|
|
103
|
+
*/
|
|
104
|
+
amountCommitment?: HexString
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Blinding factor (if hiding amounts)
|
|
108
|
+
*/
|
|
109
|
+
blindingFactor?: HexString
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Gas estimate breakdown
|
|
113
|
+
*/
|
|
114
|
+
gasEstimate: DetailedGasEstimate
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Total cost estimate (gas + value)
|
|
118
|
+
*/
|
|
119
|
+
totalCostWei: bigint
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Transfer execution result
|
|
124
|
+
*/
|
|
125
|
+
export interface TransferResult {
|
|
126
|
+
/**
|
|
127
|
+
* Transfer transaction hash
|
|
128
|
+
*/
|
|
129
|
+
transferTxHash: HexString
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Announcement transaction hash
|
|
133
|
+
*/
|
|
134
|
+
announcementTxHash: HexString
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Stealth address funds were sent to
|
|
138
|
+
*/
|
|
139
|
+
stealthAddress: HexString
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Amount transferred
|
|
143
|
+
*/
|
|
144
|
+
amount: bigint
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Token address (if ERC-20)
|
|
148
|
+
*/
|
|
149
|
+
tokenAddress?: HexString
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Ephemeral public key
|
|
153
|
+
*/
|
|
154
|
+
ephemeralPublicKey: HexString
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* View tag
|
|
158
|
+
*/
|
|
159
|
+
viewTag: number
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Claim build result
|
|
164
|
+
*/
|
|
165
|
+
export interface PreparedClaim {
|
|
166
|
+
/**
|
|
167
|
+
* Claim transaction
|
|
168
|
+
*/
|
|
169
|
+
claimTx: PreparedTransaction
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Stealth address to claim from
|
|
173
|
+
*/
|
|
174
|
+
stealthAddress: HexString
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Derived private key for stealth address
|
|
178
|
+
*/
|
|
179
|
+
stealthPrivateKey: HexString
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Destination address
|
|
183
|
+
*/
|
|
184
|
+
destinationAddress: HexString
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Amount being claimed
|
|
188
|
+
*/
|
|
189
|
+
amount: bigint
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Token address (if ERC-20)
|
|
193
|
+
*/
|
|
194
|
+
tokenAddress?: HexString
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ─── Transfer Builder Class ──────────────────────────────────────────────────
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Ethereum Stealth Transfer Builder
|
|
201
|
+
*
|
|
202
|
+
* Orchestrates the complete flow for privacy transfers:
|
|
203
|
+
* 1. Generate stealth address from recipient's meta-address
|
|
204
|
+
* 2. Build transfer and announcement transactions
|
|
205
|
+
* 3. Estimate gas and prepare for signing
|
|
206
|
+
* 4. Track submissions and confirmations
|
|
207
|
+
*
|
|
208
|
+
* @example Complete flow
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const builder = new StealthTransferBuilder('mainnet', {
|
|
211
|
+
* rpcUrl: 'https://eth.llamarpc.com',
|
|
212
|
+
* })
|
|
213
|
+
*
|
|
214
|
+
* // Prepare transfer
|
|
215
|
+
* const prepared = await builder.prepareEthTransfer({
|
|
216
|
+
* from: senderAddress,
|
|
217
|
+
* recipient: recipientMetaAddress,
|
|
218
|
+
* amount: toWei(1), // 1 ETH
|
|
219
|
+
* })
|
|
220
|
+
*
|
|
221
|
+
* // Sign transactions (with your wallet)
|
|
222
|
+
* const signedTransfer = await wallet.signTransaction(prepared.transferTx)
|
|
223
|
+
* const signedAnnouncement = await wallet.signTransaction(prepared.announcementTx)
|
|
224
|
+
*
|
|
225
|
+
* // Submit
|
|
226
|
+
* const result = await builder.submitTransfer({
|
|
227
|
+
* signedTransferTx: signedTransfer,
|
|
228
|
+
* signedAnnouncementTx: signedAnnouncement,
|
|
229
|
+
* })
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export class StealthTransferBuilder {
|
|
233
|
+
private adapter: EthereumPrivacyAdapter
|
|
234
|
+
private rpc: EthereumRpcClient
|
|
235
|
+
private network: EthereumNetwork
|
|
236
|
+
private chainId: number
|
|
237
|
+
|
|
238
|
+
constructor(
|
|
239
|
+
network: EthereumNetwork = 'mainnet',
|
|
240
|
+
options?: {
|
|
241
|
+
rpcUrl?: string
|
|
242
|
+
announcerAddress?: HexString
|
|
243
|
+
}
|
|
244
|
+
) {
|
|
245
|
+
this.network = network
|
|
246
|
+
this.adapter = new EthereumPrivacyAdapter({
|
|
247
|
+
network,
|
|
248
|
+
announcerAddress: options?.announcerAddress,
|
|
249
|
+
})
|
|
250
|
+
this.rpc = new EthereumRpcClient(network, { rpcUrl: options?.rpcUrl })
|
|
251
|
+
this.chainId = this.rpc.getChainId()
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ─── ETH Transfer Methods ────────────────────────────────────────────────────
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Prepare an ETH stealth transfer
|
|
258
|
+
*
|
|
259
|
+
* Generates stealth address, builds transactions, estimates gas.
|
|
260
|
+
*
|
|
261
|
+
* @param params - Transfer parameters
|
|
262
|
+
* @returns Prepared transactions ready for signing
|
|
263
|
+
*/
|
|
264
|
+
async prepareEthTransfer(params: {
|
|
265
|
+
from: HexString
|
|
266
|
+
recipient: StealthMetaAddress | string
|
|
267
|
+
amount: bigint
|
|
268
|
+
memo?: string
|
|
269
|
+
}): Promise<PreparedStealthTransfer> {
|
|
270
|
+
// Build shielded transfer
|
|
271
|
+
const build = this.adapter.buildShieldedTransfer({
|
|
272
|
+
recipient: params.recipient,
|
|
273
|
+
amount: params.amount,
|
|
274
|
+
memo: params.memo,
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
// Get fee data and nonces
|
|
278
|
+
const [feeData, nonce] = await Promise.all([
|
|
279
|
+
this.rpc.getFeeData(),
|
|
280
|
+
this.rpc.getNextNonce(params.from),
|
|
281
|
+
])
|
|
282
|
+
|
|
283
|
+
// Reserve nonces for both transactions
|
|
284
|
+
const transferNonce = nonce
|
|
285
|
+
const announcementNonce = nonce + 1
|
|
286
|
+
|
|
287
|
+
// Get gas estimate
|
|
288
|
+
const gasEstimate = estimateEthTransferGas(this.network)
|
|
289
|
+
|
|
290
|
+
// Prepare transfer transaction
|
|
291
|
+
const transferTx: PreparedTransaction = {
|
|
292
|
+
to: build.stealthEthAddress,
|
|
293
|
+
value: params.amount,
|
|
294
|
+
nonce: transferNonce,
|
|
295
|
+
gasLimit: gasEstimate.breakdown.transferGas,
|
|
296
|
+
chainId: this.chainId,
|
|
297
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
|
298
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
299
|
+
type: 2,
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Prepare announcement transaction
|
|
303
|
+
const announcementTx: PreparedTransaction = {
|
|
304
|
+
to: build.announcementTx.to,
|
|
305
|
+
value: 0n,
|
|
306
|
+
data: build.announcementTx.data,
|
|
307
|
+
nonce: announcementNonce,
|
|
308
|
+
gasLimit: gasEstimate.breakdown.announcementGas,
|
|
309
|
+
chainId: this.chainId,
|
|
310
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
|
311
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
312
|
+
type: 2,
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Calculate total cost
|
|
316
|
+
const totalGasCost = gasEstimate.estimatedCostWei
|
|
317
|
+
const totalCostWei = params.amount + totalGasCost
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
transferTx,
|
|
321
|
+
announcementTx,
|
|
322
|
+
stealthAddress: build.stealthEthAddress,
|
|
323
|
+
ephemeralPublicKey: build.ephemeralPublicKey,
|
|
324
|
+
viewTag: build.viewTag,
|
|
325
|
+
amountCommitment: build.amountCommitment,
|
|
326
|
+
blindingFactor: build.blindingFactor,
|
|
327
|
+
gasEstimate,
|
|
328
|
+
totalCostWei,
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// ─── Token Transfer Methods ──────────────────────────────────────────────────
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Prepare an ERC-20 token stealth transfer
|
|
336
|
+
*
|
|
337
|
+
* @param params - Transfer parameters
|
|
338
|
+
* @returns Prepared transactions ready for signing
|
|
339
|
+
*/
|
|
340
|
+
async prepareTokenTransfer(params: {
|
|
341
|
+
from: HexString
|
|
342
|
+
recipient: StealthMetaAddress | string
|
|
343
|
+
amount: bigint
|
|
344
|
+
tokenContract: HexString
|
|
345
|
+
decimals?: number
|
|
346
|
+
memo?: string
|
|
347
|
+
}): Promise<PreparedStealthTransfer & { tokenTransferData: HexString }> {
|
|
348
|
+
// Build shielded token transfer
|
|
349
|
+
const build = this.adapter.buildShieldedTokenTransfer({
|
|
350
|
+
recipient: params.recipient,
|
|
351
|
+
amount: params.amount,
|
|
352
|
+
tokenContract: params.tokenContract,
|
|
353
|
+
decimals: params.decimals,
|
|
354
|
+
memo: params.memo,
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
// Get fee data and nonces
|
|
358
|
+
const [feeData, nonce] = await Promise.all([
|
|
359
|
+
this.rpc.getFeeData(),
|
|
360
|
+
this.rpc.getNextNonce(params.from),
|
|
361
|
+
])
|
|
362
|
+
|
|
363
|
+
// Reserve nonces
|
|
364
|
+
const transferNonce = nonce
|
|
365
|
+
const announcementNonce = nonce + 1
|
|
366
|
+
|
|
367
|
+
// Get gas estimate (without approval - caller handles that)
|
|
368
|
+
const gasEstimate = estimateTokenTransferGas(this.network, false)
|
|
369
|
+
|
|
370
|
+
// Prepare transfer transaction
|
|
371
|
+
const transferTx: PreparedTransaction = {
|
|
372
|
+
to: params.tokenContract,
|
|
373
|
+
value: 0n,
|
|
374
|
+
data: build.tokenTransferData,
|
|
375
|
+
nonce: transferNonce,
|
|
376
|
+
gasLimit: gasEstimate.breakdown.transferGas,
|
|
377
|
+
chainId: this.chainId,
|
|
378
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
|
379
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
380
|
+
type: 2,
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Prepare announcement transaction
|
|
384
|
+
const announcementTx: PreparedTransaction = {
|
|
385
|
+
to: build.announcementTx.to,
|
|
386
|
+
value: 0n,
|
|
387
|
+
data: build.announcementTx.data,
|
|
388
|
+
nonce: announcementNonce,
|
|
389
|
+
gasLimit: gasEstimate.breakdown.announcementGas,
|
|
390
|
+
chainId: this.chainId,
|
|
391
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
|
392
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
393
|
+
type: 2,
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
transferTx,
|
|
398
|
+
announcementTx,
|
|
399
|
+
stealthAddress: build.stealthEthAddress,
|
|
400
|
+
ephemeralPublicKey: build.ephemeralPublicKey,
|
|
401
|
+
viewTag: build.viewTag,
|
|
402
|
+
amountCommitment: build.amountCommitment,
|
|
403
|
+
blindingFactor: build.blindingFactor,
|
|
404
|
+
gasEstimate,
|
|
405
|
+
totalCostWei: gasEstimate.estimatedCostWei,
|
|
406
|
+
tokenTransferData: build.tokenTransferData,
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// ─── Submit Methods ──────────────────────────────────────────────────────────
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Submit signed transfer transactions
|
|
414
|
+
*
|
|
415
|
+
* Submits both transfer and announcement, waits for confirmations.
|
|
416
|
+
*
|
|
417
|
+
* @param params - Signed transaction data
|
|
418
|
+
* @returns Submission result
|
|
419
|
+
*/
|
|
420
|
+
async submitTransfer(params: {
|
|
421
|
+
signedTransferTx: HexString
|
|
422
|
+
signedAnnouncementTx: HexString
|
|
423
|
+
stealthAddress: HexString
|
|
424
|
+
ephemeralPublicKey: HexString
|
|
425
|
+
viewTag: number
|
|
426
|
+
amount: bigint
|
|
427
|
+
tokenAddress?: HexString
|
|
428
|
+
waitForConfirmation?: boolean
|
|
429
|
+
}): Promise<TransferResult> {
|
|
430
|
+
// Submit transfer first
|
|
431
|
+
const transferTxHash = await this.rpc.sendRawTransaction(params.signedTransferTx)
|
|
432
|
+
|
|
433
|
+
// Submit announcement
|
|
434
|
+
const announcementTxHash = await this.rpc.sendRawTransaction(params.signedAnnouncementTx)
|
|
435
|
+
|
|
436
|
+
// Optionally wait for confirmations
|
|
437
|
+
if (params.waitForConfirmation !== false) {
|
|
438
|
+
await Promise.all([
|
|
439
|
+
this.rpc.waitForTransaction(transferTxHash, 1),
|
|
440
|
+
this.rpc.waitForTransaction(announcementTxHash, 1),
|
|
441
|
+
])
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return {
|
|
445
|
+
transferTxHash,
|
|
446
|
+
announcementTxHash,
|
|
447
|
+
stealthAddress: params.stealthAddress,
|
|
448
|
+
amount: params.amount,
|
|
449
|
+
tokenAddress: params.tokenAddress,
|
|
450
|
+
ephemeralPublicKey: params.ephemeralPublicKey,
|
|
451
|
+
viewTag: params.viewTag,
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ─── Claim Methods ───────────────────────────────────────────────────────────
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Prepare a claim transaction
|
|
459
|
+
*
|
|
460
|
+
* @param params - Claim parameters
|
|
461
|
+
* @returns Prepared claim transaction
|
|
462
|
+
*/
|
|
463
|
+
async prepareClaim(params: {
|
|
464
|
+
stealthAddress: {
|
|
465
|
+
address: HexString
|
|
466
|
+
ephemeralPublicKey: HexString
|
|
467
|
+
viewTag: number
|
|
468
|
+
}
|
|
469
|
+
viewingPrivateKey: HexString
|
|
470
|
+
spendingPrivateKey: HexString
|
|
471
|
+
destinationAddress: HexString
|
|
472
|
+
amount: bigint
|
|
473
|
+
tokenContract?: HexString
|
|
474
|
+
}): Promise<PreparedClaim> {
|
|
475
|
+
// Build claim transaction
|
|
476
|
+
const build = this.adapter.buildClaimTransaction({
|
|
477
|
+
stealthAddress: params.stealthAddress,
|
|
478
|
+
ephemeralPublicKey: params.stealthAddress.ephemeralPublicKey,
|
|
479
|
+
viewingPrivateKey: params.viewingPrivateKey,
|
|
480
|
+
spendingPrivateKey: params.spendingPrivateKey,
|
|
481
|
+
destinationAddress: params.destinationAddress,
|
|
482
|
+
amount: params.amount,
|
|
483
|
+
tokenContract: params.tokenContract,
|
|
484
|
+
})
|
|
485
|
+
|
|
486
|
+
// Get fee data - note: we use the stealth address as "from"
|
|
487
|
+
const feeData = await this.rpc.getFeeData()
|
|
488
|
+
|
|
489
|
+
// For claims, nonce needs to be fetched for the stealth address
|
|
490
|
+
// But we can't know it without the RPC having the address funded
|
|
491
|
+
// We'll set nonce to 0 as stealth addresses typically have no prior txs
|
|
492
|
+
const nonce = 0
|
|
493
|
+
|
|
494
|
+
// Prepare claim transaction
|
|
495
|
+
const claimTx: PreparedTransaction = {
|
|
496
|
+
to: build.tx.to,
|
|
497
|
+
value: build.tx.value,
|
|
498
|
+
data: build.tx.data,
|
|
499
|
+
nonce,
|
|
500
|
+
gasLimit: build.estimatedGas,
|
|
501
|
+
chainId: this.chainId,
|
|
502
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
|
503
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
504
|
+
type: 2,
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return {
|
|
508
|
+
claimTx,
|
|
509
|
+
stealthAddress: build.stealthEthAddress,
|
|
510
|
+
stealthPrivateKey: build.stealthPrivateKey,
|
|
511
|
+
destinationAddress: params.destinationAddress,
|
|
512
|
+
amount: params.amount,
|
|
513
|
+
tokenAddress: params.tokenContract,
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Submit a signed claim transaction
|
|
519
|
+
*
|
|
520
|
+
* @param signedTx - Signed claim transaction
|
|
521
|
+
* @param waitForConfirmation - Whether to wait for confirmation
|
|
522
|
+
* @returns Transaction hash
|
|
523
|
+
*/
|
|
524
|
+
async submitClaim(
|
|
525
|
+
signedTx: HexString,
|
|
526
|
+
waitForConfirmation: boolean = true
|
|
527
|
+
): Promise<HexString> {
|
|
528
|
+
const txHash = await this.rpc.sendRawTransaction(signedTx)
|
|
529
|
+
|
|
530
|
+
if (waitForConfirmation) {
|
|
531
|
+
await this.rpc.waitForTransaction(txHash, 1)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
return txHash
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// ─── Balance Methods ─────────────────────────────────────────────────────────
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Get ETH balance of an address
|
|
541
|
+
*
|
|
542
|
+
* @param address - Address to check
|
|
543
|
+
* @returns Balance in wei
|
|
544
|
+
*/
|
|
545
|
+
async getBalance(address: HexString): Promise<bigint> {
|
|
546
|
+
return this.rpc.getBalance(address)
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Check if sender has sufficient balance for transfer
|
|
551
|
+
*
|
|
552
|
+
* @param sender - Sender address
|
|
553
|
+
* @param amount - Amount to transfer
|
|
554
|
+
* @param isToken - Whether this is a token transfer
|
|
555
|
+
* @returns True if sufficient balance
|
|
556
|
+
*/
|
|
557
|
+
async hasSufficientBalance(
|
|
558
|
+
sender: HexString,
|
|
559
|
+
amount: bigint,
|
|
560
|
+
isToken: boolean = false
|
|
561
|
+
): Promise<{ sufficient: boolean; balance: bigint; required: bigint }> {
|
|
562
|
+
const balance = await this.rpc.getBalance(sender)
|
|
563
|
+
|
|
564
|
+
// For token transfers, only need gas
|
|
565
|
+
const gasEstimate = isToken
|
|
566
|
+
? estimateTokenTransferGas(this.network)
|
|
567
|
+
: estimateEthTransferGas(this.network)
|
|
568
|
+
|
|
569
|
+
const required = isToken ? gasEstimate.estimatedCostWei : amount + gasEstimate.estimatedCostWei
|
|
570
|
+
|
|
571
|
+
return {
|
|
572
|
+
sufficient: balance >= required,
|
|
573
|
+
balance,
|
|
574
|
+
required,
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// ─── Utility Methods ─────────────────────────────────────────────────────────
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Get the privacy adapter
|
|
582
|
+
*/
|
|
583
|
+
getAdapter(): EthereumPrivacyAdapter {
|
|
584
|
+
return this.adapter
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Get the RPC client
|
|
589
|
+
*/
|
|
590
|
+
getRpcClient(): EthereumRpcClient {
|
|
591
|
+
return this.rpc
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Get network
|
|
596
|
+
*/
|
|
597
|
+
getNetwork(): EthereumNetwork {
|
|
598
|
+
return this.network
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Get chain ID
|
|
603
|
+
*/
|
|
604
|
+
getChainId(): number {
|
|
605
|
+
return this.chainId
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// ─── Factory Functions ────────────────────────────────────────────────────────
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Create a stealth transfer builder
|
|
613
|
+
*
|
|
614
|
+
* @param network - Target network
|
|
615
|
+
* @param rpcUrl - Optional custom RPC URL
|
|
616
|
+
* @returns Transfer builder
|
|
617
|
+
*/
|
|
618
|
+
export function createStealthTransferBuilder(
|
|
619
|
+
network: EthereumNetwork = 'mainnet',
|
|
620
|
+
rpcUrl?: string
|
|
621
|
+
): StealthTransferBuilder {
|
|
622
|
+
return new StealthTransferBuilder(network, { rpcUrl })
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Create a mainnet transfer builder
|
|
627
|
+
*/
|
|
628
|
+
export function createMainnetTransferBuilder(rpcUrl?: string): StealthTransferBuilder {
|
|
629
|
+
return new StealthTransferBuilder('mainnet', { rpcUrl })
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Create a Sepolia testnet transfer builder
|
|
634
|
+
*/
|
|
635
|
+
export function createSepoliaTransferBuilder(rpcUrl?: string): StealthTransferBuilder {
|
|
636
|
+
return new StealthTransferBuilder('sepolia', { rpcUrl })
|
|
637
|
+
}
|