@sip-protocol/sdk 0.7.2 → 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 +48874 -18336
- package/dist/browser.mjs +674 -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-YWGJ77A2.mjs +33806 -0
- 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-DXh2IGkz.d.ts +24681 -0
- package/dist/index-DeE1ZzA4.d.mts +24681 -0
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48676 -17318
- package/dist/index.mjs +583 -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 +276 -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 +201 -0
- 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 +402 -0
- package/src/chains/solana/providers/index.ts +85 -0
- package/src/chains/solana/providers/interface.ts +221 -0
- 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 +790 -0
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +170 -73
- 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 +77 -7
- 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 +37 -0
- package/src/compliance/range-sas.ts +956 -0
- 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 +785 -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 +336 -0
- package/src/privacy-backends/interface.ts +906 -0
- 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-types.ts +278 -0
- package/src/privacy-backends/privacycash.ts +456 -0
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +690 -0
- package/src/privacy-backends/router.ts +626 -0
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +256 -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 +111 -30
- 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/surveillance/algorithms/address-reuse.ts +143 -0
- package/src/surveillance/algorithms/cluster.ts +247 -0
- package/src/surveillance/algorithms/exchange.ts +295 -0
- package/src/surveillance/algorithms/temporal.ts +337 -0
- package/src/surveillance/analyzer.ts +442 -0
- package/src/surveillance/index.ts +64 -0
- package/src/surveillance/scoring.ts +372 -0
- package/src/surveillance/types.ts +264 -0
- 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-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/constants-VOI7BSLK.mjs +0 -27
- 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-xbWjohNq.d.mts +0 -11390
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-Q4NAVBTS.mjs +0 -46
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShadowWire Privacy Backend
|
|
3
|
+
*
|
|
4
|
+
* Integrates ShadowWire by Radr Labs as a privacy backend for SIP Protocol.
|
|
5
|
+
* ShadowWire uses Pedersen Commitments + Bulletproofs for amount hiding.
|
|
6
|
+
*
|
|
7
|
+
* SIP adds viewing keys to ShadowWire for compliance support.
|
|
8
|
+
*
|
|
9
|
+
* @see https://radrlabs.io
|
|
10
|
+
* @see https://github.com/Radrdotfun/ShadowWire
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { ShadowWireBackend, PrivacyBackendRegistry } from '@sip-protocol/sdk'
|
|
15
|
+
*
|
|
16
|
+
* const backend = new ShadowWireBackend()
|
|
17
|
+
* const registry = new PrivacyBackendRegistry()
|
|
18
|
+
* registry.register(backend)
|
|
19
|
+
*
|
|
20
|
+
* // Execute private transfer
|
|
21
|
+
* const result = await backend.execute({
|
|
22
|
+
* chain: 'solana',
|
|
23
|
+
* sender: 'sender-pubkey',
|
|
24
|
+
* recipient: 'recipient-pubkey',
|
|
25
|
+
* mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
|
|
26
|
+
* amount: 1000000n, // 1 USDC
|
|
27
|
+
* decimals: 6,
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
ShadowWireClient,
|
|
34
|
+
type TransferType,
|
|
35
|
+
type TokenSymbol,
|
|
36
|
+
type WalletAdapter,
|
|
37
|
+
InsufficientBalanceError,
|
|
38
|
+
RecipientNotFoundError,
|
|
39
|
+
InvalidAmountError,
|
|
40
|
+
InvalidAddressError,
|
|
41
|
+
} from '@radr/shadowwire'
|
|
42
|
+
import type { ChainType, ViewingKey } from '@sip-protocol/types'
|
|
43
|
+
import type {
|
|
44
|
+
PrivacyBackend,
|
|
45
|
+
BackendType,
|
|
46
|
+
BackendCapabilities,
|
|
47
|
+
TransferParams,
|
|
48
|
+
TransactionResult,
|
|
49
|
+
AvailabilityResult,
|
|
50
|
+
BackendParams,
|
|
51
|
+
} from './interface'
|
|
52
|
+
import { isTransferParams } from './interface'
|
|
53
|
+
import { generateViewingKey, encryptForViewing } from '../privacy'
|
|
54
|
+
import type { HexString } from '@sip-protocol/types'
|
|
55
|
+
import { bytesToHex } from '@noble/hashes/utils'
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* ShadowWire supported token mint addresses
|
|
59
|
+
* Note: ShadowWire supports a specific set of tokens. Check SUPPORTED_TOKENS in @radr/shadowwire
|
|
60
|
+
*/
|
|
61
|
+
export const SHADOWWIRE_TOKEN_MINTS: Record<TokenSymbol, string> = {
|
|
62
|
+
SOL: 'So11111111111111111111111111111111111111112',
|
|
63
|
+
USDC: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
64
|
+
RADR: 'RADRi35VqLmMu4t7Gax1KVszxnQnbtqEwJQJVfzpump',
|
|
65
|
+
ORE: 'oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhycK7fw73F', // ORE mining token
|
|
66
|
+
BONK: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
|
|
67
|
+
JIM: 'JIMa1xG7h7h7h7h7h7h7h7h7h7h7h7h7h7h7h7h7', // Placeholder
|
|
68
|
+
GODL: 'GODL1111111111111111111111111111111111111', // Placeholder
|
|
69
|
+
HUSTLE: 'HUSTLEexampleaddress1111111111111111111', // Placeholder
|
|
70
|
+
ZEC: 'ZECexampleaddress1111111111111111111111111', // Placeholder
|
|
71
|
+
CRT: 'CRTexampleaddress11111111111111111111111111', // Placeholder
|
|
72
|
+
BLACKCOIN: 'BLACKexampleaddress111111111111111111111', // Placeholder
|
|
73
|
+
GIL: 'GILexampleaddress11111111111111111111111111', // Placeholder
|
|
74
|
+
ANON: 'ANONexampleaddress1111111111111111111111111', // Placeholder
|
|
75
|
+
WLFI: 'WLFIexampleaddress1111111111111111111111111', // Placeholder - World Liberty Financial
|
|
76
|
+
USD1: 'USD1exampleaddress1111111111111111111111111', // Placeholder - USD1 stablecoin
|
|
77
|
+
AOL: 'AOLexampleaddress11111111111111111111111111', // Placeholder
|
|
78
|
+
IQLABS: 'IQLABSexampleaddress111111111111111111111', // Placeholder - IQ Labs token
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Reverse lookup: mint address to symbol
|
|
83
|
+
*/
|
|
84
|
+
const MINT_TO_SYMBOL: Record<string, TokenSymbol> = Object.fromEntries(
|
|
85
|
+
Object.entries(SHADOWWIRE_TOKEN_MINTS).map(([symbol, mint]) => [mint, symbol as TokenSymbol])
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* ShadowWire backend configuration
|
|
90
|
+
*/
|
|
91
|
+
export interface ShadowWireBackendConfig {
|
|
92
|
+
/** API base URL (optional, uses default if not provided) */
|
|
93
|
+
apiBaseUrl?: string
|
|
94
|
+
/** Enable debug logging */
|
|
95
|
+
debug?: boolean
|
|
96
|
+
/** Default transfer type */
|
|
97
|
+
defaultTransferType?: TransferType
|
|
98
|
+
/** Wallet adapter for signing */
|
|
99
|
+
wallet?: WalletAdapter
|
|
100
|
+
/** Enable client-side proof generation (WASM) */
|
|
101
|
+
clientSideProofs?: boolean
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* ShadowWire backend capabilities
|
|
106
|
+
*/
|
|
107
|
+
const SHADOWWIRE_CAPABILITIES: BackendCapabilities = {
|
|
108
|
+
hiddenAmount: true,
|
|
109
|
+
hiddenSender: true,
|
|
110
|
+
hiddenRecipient: true, // Internal transfers only
|
|
111
|
+
hiddenCompute: false,
|
|
112
|
+
complianceSupport: true, // SIP adds viewing keys
|
|
113
|
+
anonymitySet: undefined, // Not pool-based
|
|
114
|
+
setupRequired: false,
|
|
115
|
+
latencyEstimate: 'medium', // ~500ms for proof generation
|
|
116
|
+
supportedTokens: 'spl',
|
|
117
|
+
minAmount: 1n, // Minimum 1 lamport
|
|
118
|
+
maxAmount: undefined,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* ShadowWire Privacy Backend
|
|
123
|
+
*
|
|
124
|
+
* Wraps the ShadowWire SDK to provide a unified PrivacyBackend interface.
|
|
125
|
+
* Adds SIP's viewing key support for compliance.
|
|
126
|
+
*/
|
|
127
|
+
export class ShadowWireBackend implements PrivacyBackend {
|
|
128
|
+
readonly name = 'shadowwire'
|
|
129
|
+
readonly type: BackendType = 'transaction'
|
|
130
|
+
readonly chains: ChainType[] = ['solana']
|
|
131
|
+
|
|
132
|
+
private client: ShadowWireClient
|
|
133
|
+
private config: ShadowWireBackendConfig
|
|
134
|
+
private wallet?: WalletAdapter
|
|
135
|
+
|
|
136
|
+
constructor(config: ShadowWireBackendConfig = {}) {
|
|
137
|
+
this.config = {
|
|
138
|
+
defaultTransferType: 'internal',
|
|
139
|
+
clientSideProofs: false,
|
|
140
|
+
...config,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this.client = new ShadowWireClient({
|
|
144
|
+
debug: config.debug,
|
|
145
|
+
apiBaseUrl: config.apiBaseUrl,
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
this.wallet = config.wallet
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Set wallet adapter for signing
|
|
153
|
+
*/
|
|
154
|
+
setWallet(wallet: WalletAdapter): void {
|
|
155
|
+
this.wallet = wallet
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if backend is available for given parameters
|
|
160
|
+
*/
|
|
161
|
+
async checkAvailability(params: BackendParams): Promise<AvailabilityResult> {
|
|
162
|
+
if (!isTransferParams(params)) {
|
|
163
|
+
return {
|
|
164
|
+
available: false,
|
|
165
|
+
reason: 'ShadowWire only supports transfer operations, not compute',
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Check chain support
|
|
170
|
+
if (params.chain !== 'solana') {
|
|
171
|
+
return {
|
|
172
|
+
available: false,
|
|
173
|
+
reason: `Chain '${params.chain}' not supported. ShadowWire only works on Solana`,
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Check token support
|
|
178
|
+
const tokenSymbol = this.getTokenSymbol(params.mint)
|
|
179
|
+
if (!tokenSymbol) {
|
|
180
|
+
return {
|
|
181
|
+
available: false,
|
|
182
|
+
reason: `Token mint '${params.mint}' not supported by ShadowWire`,
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Check amount validity
|
|
187
|
+
if (params.amount <= 0n) {
|
|
188
|
+
return {
|
|
189
|
+
available: false,
|
|
190
|
+
reason: 'Amount must be greater than 0',
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Check balance (if wallet is connected)
|
|
195
|
+
if (this.wallet) {
|
|
196
|
+
try {
|
|
197
|
+
const balance = await this.client.getBalance(params.sender, tokenSymbol)
|
|
198
|
+
if (BigInt(balance.available) < params.amount) {
|
|
199
|
+
return {
|
|
200
|
+
available: false,
|
|
201
|
+
reason: `Insufficient ShadowWire balance. Have: ${balance.available}, Need: ${params.amount}`,
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// Balance check failed, but might still be available
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
available: true,
|
|
211
|
+
estimatedCost: this.estimateTransferCost(params),
|
|
212
|
+
estimatedTime: 2000, // ~2s for proof generation + confirmation
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get backend capabilities
|
|
218
|
+
*/
|
|
219
|
+
getCapabilities(): BackendCapabilities {
|
|
220
|
+
return { ...SHADOWWIRE_CAPABILITIES }
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Execute a privacy-preserving transfer via ShadowWire
|
|
225
|
+
*/
|
|
226
|
+
async execute(params: TransferParams): Promise<TransactionResult> {
|
|
227
|
+
// Validate parameters
|
|
228
|
+
const validation = await this.checkAvailability(params)
|
|
229
|
+
if (!validation.available) {
|
|
230
|
+
return {
|
|
231
|
+
success: false,
|
|
232
|
+
error: validation.reason,
|
|
233
|
+
backend: this.name,
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Get token symbol
|
|
238
|
+
const tokenSymbol = this.getTokenSymbol(params.mint)
|
|
239
|
+
if (!tokenSymbol) {
|
|
240
|
+
return {
|
|
241
|
+
success: false,
|
|
242
|
+
error: `Unsupported token: ${params.mint}`,
|
|
243
|
+
backend: this.name,
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Determine wallet
|
|
248
|
+
const wallet = this.wallet || (params.options?.wallet as WalletAdapter | undefined)
|
|
249
|
+
if (!wallet) {
|
|
250
|
+
return {
|
|
251
|
+
success: false,
|
|
252
|
+
error: 'Wallet adapter required for ShadowWire transfers. Set via setWallet() or options.wallet',
|
|
253
|
+
backend: this.name,
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
// Determine transfer type
|
|
259
|
+
const transferType: TransferType =
|
|
260
|
+
(params.options?.transferType as TransferType) ||
|
|
261
|
+
this.config.defaultTransferType ||
|
|
262
|
+
'internal'
|
|
263
|
+
|
|
264
|
+
// Convert amount to decimal (ShadowWire uses decimal amounts)
|
|
265
|
+
const decimalAmount = Number(params.amount) / Math.pow(10, params.decimals)
|
|
266
|
+
|
|
267
|
+
// Execute ShadowWire transfer
|
|
268
|
+
const response = await this.client.transfer({
|
|
269
|
+
sender: params.sender,
|
|
270
|
+
recipient: params.recipient,
|
|
271
|
+
amount: decimalAmount,
|
|
272
|
+
token: tokenSymbol,
|
|
273
|
+
type: transferType,
|
|
274
|
+
wallet,
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
// Generate SIP viewing key for compliance
|
|
278
|
+
let viewingKey: ViewingKey | undefined
|
|
279
|
+
let encryptedData: HexString | undefined
|
|
280
|
+
|
|
281
|
+
if (params.viewingKey || params.options?.generateViewingKey) {
|
|
282
|
+
viewingKey = params.viewingKey || generateViewingKey()
|
|
283
|
+
|
|
284
|
+
// Encrypt transaction details for viewing key holder
|
|
285
|
+
const txDetails = {
|
|
286
|
+
sender: params.sender,
|
|
287
|
+
recipient: params.recipient,
|
|
288
|
+
amount: params.amount.toString(),
|
|
289
|
+
token: tokenSymbol,
|
|
290
|
+
timestamp: Date.now(),
|
|
291
|
+
shadowwireTxId: response.tx_signature,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// encryptForViewing returns EncryptedTransaction object
|
|
295
|
+
const encrypted = encryptForViewing(txDetails, viewingKey)
|
|
296
|
+
// Convert to hex string for storage
|
|
297
|
+
const jsonBytes = new TextEncoder().encode(JSON.stringify(encrypted))
|
|
298
|
+
encryptedData = `0x${bytesToHex(jsonBytes)}` as HexString
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
success: true,
|
|
303
|
+
signature: response.tx_signature,
|
|
304
|
+
backend: this.name,
|
|
305
|
+
encryptedData,
|
|
306
|
+
metadata: {
|
|
307
|
+
transferType,
|
|
308
|
+
token: tokenSymbol,
|
|
309
|
+
viewingKeyGenerated: !!viewingKey,
|
|
310
|
+
},
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
return {
|
|
314
|
+
success: false,
|
|
315
|
+
error: this.formatError(error),
|
|
316
|
+
backend: this.name,
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Estimate cost for a transfer
|
|
323
|
+
*/
|
|
324
|
+
async estimateCost(params: BackendParams): Promise<bigint> {
|
|
325
|
+
if (!isTransferParams(params)) {
|
|
326
|
+
return 0n
|
|
327
|
+
}
|
|
328
|
+
return this.estimateTransferCost(params)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Get ShadowWire balance for a token
|
|
333
|
+
*/
|
|
334
|
+
async getBalance(walletAddress: string, token: TokenSymbol): Promise<bigint> {
|
|
335
|
+
const balance = await this.client.getBalance(walletAddress, token)
|
|
336
|
+
return BigInt(balance.available)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Deposit funds into ShadowWire pool
|
|
341
|
+
* Returns an unsigned transaction that must be signed and sent by the caller
|
|
342
|
+
*/
|
|
343
|
+
async deposit(
|
|
344
|
+
walletAddress: string,
|
|
345
|
+
amount: number,
|
|
346
|
+
tokenMint?: string
|
|
347
|
+
): Promise<{ unsignedTx: string; poolAddress: string }> {
|
|
348
|
+
const response = await this.client.deposit({
|
|
349
|
+
wallet: walletAddress,
|
|
350
|
+
amount,
|
|
351
|
+
token_mint: tokenMint,
|
|
352
|
+
})
|
|
353
|
+
return {
|
|
354
|
+
unsignedTx: response.unsigned_tx_base64,
|
|
355
|
+
poolAddress: response.pool_address,
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Withdraw funds from ShadowWire pool
|
|
361
|
+
* Returns an unsigned transaction that must be signed and sent by the caller
|
|
362
|
+
*/
|
|
363
|
+
async withdraw(
|
|
364
|
+
walletAddress: string,
|
|
365
|
+
amount: number,
|
|
366
|
+
tokenMint?: string
|
|
367
|
+
): Promise<{ unsignedTx: string; amountWithdrawn: number; fee: number }> {
|
|
368
|
+
const response = await this.client.withdraw({
|
|
369
|
+
wallet: walletAddress,
|
|
370
|
+
amount,
|
|
371
|
+
token_mint: tokenMint,
|
|
372
|
+
})
|
|
373
|
+
return {
|
|
374
|
+
unsignedTx: response.unsigned_tx_base64,
|
|
375
|
+
amountWithdrawn: response.amount_withdrawn,
|
|
376
|
+
fee: response.fee,
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Get underlying ShadowWire client
|
|
382
|
+
*/
|
|
383
|
+
getClient(): ShadowWireClient {
|
|
384
|
+
return this.client
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// ─── Private Helpers ───────────────────────────────────────────────────────
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Get token symbol from mint address
|
|
391
|
+
*/
|
|
392
|
+
private getTokenSymbol(mint: string | null): TokenSymbol | undefined {
|
|
393
|
+
if (!mint) {
|
|
394
|
+
return 'SOL'
|
|
395
|
+
}
|
|
396
|
+
return MINT_TO_SYMBOL[mint]
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Estimate transfer cost in lamports
|
|
401
|
+
*/
|
|
402
|
+
private estimateTransferCost(params: TransferParams): bigint {
|
|
403
|
+
// Base transaction fee
|
|
404
|
+
let cost = 5000n // ~0.000005 SOL
|
|
405
|
+
|
|
406
|
+
// Add proof generation cost estimate
|
|
407
|
+
const transferType =
|
|
408
|
+
(params.options?.transferType as TransferType) ||
|
|
409
|
+
this.config.defaultTransferType ||
|
|
410
|
+
'internal'
|
|
411
|
+
|
|
412
|
+
if (transferType === 'internal') {
|
|
413
|
+
cost += 10000n // Additional cost for ZK proof verification
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return cost
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Format error for user-friendly message
|
|
421
|
+
*/
|
|
422
|
+
private formatError(error: unknown): string {
|
|
423
|
+
if (error instanceof InsufficientBalanceError) {
|
|
424
|
+
return 'Insufficient balance in ShadowWire pool. Deposit funds first.'
|
|
425
|
+
}
|
|
426
|
+
if (error instanceof RecipientNotFoundError) {
|
|
427
|
+
return 'Recipient must be a ShadowWire user for internal transfers. Use external transfer type for non-users.'
|
|
428
|
+
}
|
|
429
|
+
if (error instanceof InvalidAmountError) {
|
|
430
|
+
return 'Invalid transfer amount'
|
|
431
|
+
}
|
|
432
|
+
if (error instanceof InvalidAddressError) {
|
|
433
|
+
return 'Invalid Solana address'
|
|
434
|
+
}
|
|
435
|
+
if (error instanceof Error) {
|
|
436
|
+
return error.message
|
|
437
|
+
}
|
|
438
|
+
return 'Unknown ShadowWire error'
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Create a ShadowWire backend with default configuration
|
|
444
|
+
*/
|
|
445
|
+
export function createShadowWireBackend(
|
|
446
|
+
config?: ShadowWireBackendConfig
|
|
447
|
+
): ShadowWireBackend {
|
|
448
|
+
return new ShadowWireBackend(config)
|
|
449
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIP Native Privacy Backend
|
|
3
|
+
*
|
|
4
|
+
* Implements the PrivacyBackend interface using SIP's native privacy primitives:
|
|
5
|
+
* - Stealth addresses (EIP-5564 style)
|
|
6
|
+
* - Pedersen commitments (amount hiding)
|
|
7
|
+
* - Viewing keys (compliance support)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { SIPNativeBackend, PrivacyBackendRegistry } from '@sip-protocol/sdk'
|
|
12
|
+
*
|
|
13
|
+
* const backend = new SIPNativeBackend()
|
|
14
|
+
* const registry = new PrivacyBackendRegistry()
|
|
15
|
+
* registry.register(backend)
|
|
16
|
+
*
|
|
17
|
+
* // Check capabilities
|
|
18
|
+
* const caps = backend.getCapabilities()
|
|
19
|
+
* console.log(caps.complianceSupport) // true
|
|
20
|
+
*
|
|
21
|
+
* // Execute transfer
|
|
22
|
+
* const result = await backend.execute({
|
|
23
|
+
* chain: 'solana',
|
|
24
|
+
* sender: 'sender-address',
|
|
25
|
+
* recipient: 'stealth-address',
|
|
26
|
+
* mint: 'token-mint',
|
|
27
|
+
* amount: BigInt(1000000),
|
|
28
|
+
* decimals: 6,
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { ChainType } from '@sip-protocol/types'
|
|
34
|
+
import type {
|
|
35
|
+
PrivacyBackend,
|
|
36
|
+
BackendType,
|
|
37
|
+
BackendCapabilities,
|
|
38
|
+
TransferParams,
|
|
39
|
+
TransactionResult,
|
|
40
|
+
AvailabilityResult,
|
|
41
|
+
PrivacyBackendVersion,
|
|
42
|
+
} from './interface'
|
|
43
|
+
import { CURRENT_BACKEND_VERSION } from './interface'
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Supported chains for SIP Native backend
|
|
47
|
+
*/
|
|
48
|
+
const SUPPORTED_CHAINS: ChainType[] = [
|
|
49
|
+
'solana',
|
|
50
|
+
'ethereum',
|
|
51
|
+
'near',
|
|
52
|
+
'polygon',
|
|
53
|
+
'arbitrum',
|
|
54
|
+
'optimism',
|
|
55
|
+
'base',
|
|
56
|
+
'avalanche',
|
|
57
|
+
'bsc',
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* SIP Native backend capabilities
|
|
62
|
+
*/
|
|
63
|
+
const SIP_NATIVE_CAPABILITIES: BackendCapabilities = {
|
|
64
|
+
hiddenAmount: true,
|
|
65
|
+
hiddenSender: true,
|
|
66
|
+
hiddenRecipient: true,
|
|
67
|
+
hiddenCompute: false,
|
|
68
|
+
complianceSupport: true,
|
|
69
|
+
anonymitySet: undefined, // Not pool-based
|
|
70
|
+
setupRequired: false,
|
|
71
|
+
latencyEstimate: 'fast',
|
|
72
|
+
supportedTokens: 'all',
|
|
73
|
+
minAmount: undefined,
|
|
74
|
+
maxAmount: undefined,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Configuration options for SIP Native backend
|
|
79
|
+
*/
|
|
80
|
+
export interface SIPNativeBackendConfig {
|
|
81
|
+
/** Custom supported chains (overrides default) */
|
|
82
|
+
chains?: ChainType[]
|
|
83
|
+
/** Whether to require viewing keys for all transfers */
|
|
84
|
+
requireViewingKey?: boolean
|
|
85
|
+
/** Minimum amount for transfers (optional) */
|
|
86
|
+
minAmount?: bigint
|
|
87
|
+
/** Maximum amount for transfers (optional) */
|
|
88
|
+
maxAmount?: bigint
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* SIP Native Privacy Backend
|
|
93
|
+
*
|
|
94
|
+
* Uses stealth addresses and Pedersen commitments for transaction privacy,
|
|
95
|
+
* with viewing key support for regulatory compliance.
|
|
96
|
+
*/
|
|
97
|
+
export class SIPNativeBackend implements PrivacyBackend {
|
|
98
|
+
readonly version: PrivacyBackendVersion = CURRENT_BACKEND_VERSION
|
|
99
|
+
readonly name = 'sip-native'
|
|
100
|
+
readonly type: BackendType = 'transaction'
|
|
101
|
+
readonly chains: ChainType[]
|
|
102
|
+
|
|
103
|
+
private config: Required<SIPNativeBackendConfig>
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Create a new SIP Native backend
|
|
107
|
+
*
|
|
108
|
+
* @param config - Backend configuration
|
|
109
|
+
*/
|
|
110
|
+
constructor(config: SIPNativeBackendConfig = {}) {
|
|
111
|
+
this.chains = config.chains ?? SUPPORTED_CHAINS
|
|
112
|
+
this.config = {
|
|
113
|
+
chains: this.chains,
|
|
114
|
+
requireViewingKey: config.requireViewingKey ?? false,
|
|
115
|
+
minAmount: config.minAmount ?? BigInt(0),
|
|
116
|
+
maxAmount: config.maxAmount ?? BigInt(Number.MAX_SAFE_INTEGER),
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if backend is available for given parameters
|
|
122
|
+
*/
|
|
123
|
+
async checkAvailability(params: TransferParams): Promise<AvailabilityResult> {
|
|
124
|
+
// Check chain support
|
|
125
|
+
if (!this.chains.includes(params.chain)) {
|
|
126
|
+
return {
|
|
127
|
+
available: false,
|
|
128
|
+
reason: `Chain '${params.chain}' not supported by SIP Native backend`,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check viewing key requirement
|
|
133
|
+
if (this.config.requireViewingKey && !params.viewingKey) {
|
|
134
|
+
return {
|
|
135
|
+
available: false,
|
|
136
|
+
reason: 'Viewing key required for SIP Native backend',
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check amount bounds
|
|
141
|
+
if (params.amount < this.config.minAmount) {
|
|
142
|
+
return {
|
|
143
|
+
available: false,
|
|
144
|
+
reason: `Amount ${params.amount} below minimum ${this.config.minAmount}`,
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (params.amount > this.config.maxAmount) {
|
|
149
|
+
return {
|
|
150
|
+
available: false,
|
|
151
|
+
reason: `Amount ${params.amount} above maximum ${this.config.maxAmount}`,
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Estimate cost based on chain
|
|
156
|
+
const estimatedCost = this.getEstimatedCostForChain(params.chain)
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
available: true,
|
|
160
|
+
estimatedCost,
|
|
161
|
+
estimatedTime: 1000, // ~1 second for stealth address operations
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get backend capabilities
|
|
167
|
+
*/
|
|
168
|
+
getCapabilities(): BackendCapabilities {
|
|
169
|
+
return {
|
|
170
|
+
...SIP_NATIVE_CAPABILITIES,
|
|
171
|
+
minAmount: this.config.minAmount > BigInt(0) ? this.config.minAmount : undefined,
|
|
172
|
+
maxAmount: this.config.maxAmount < BigInt(Number.MAX_SAFE_INTEGER)
|
|
173
|
+
? this.config.maxAmount
|
|
174
|
+
: undefined,
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Execute a privacy-preserving transfer
|
|
180
|
+
*
|
|
181
|
+
* This creates a stealth address transfer with:
|
|
182
|
+
* - Ephemeral keypair generation
|
|
183
|
+
* - Stealth address derivation
|
|
184
|
+
* - Pedersen commitment for amount
|
|
185
|
+
* - Optional viewing key encryption
|
|
186
|
+
*/
|
|
187
|
+
async execute(params: TransferParams): Promise<TransactionResult> {
|
|
188
|
+
// Validate availability first
|
|
189
|
+
const availability = await this.checkAvailability(params)
|
|
190
|
+
if (!availability.available) {
|
|
191
|
+
return {
|
|
192
|
+
success: false,
|
|
193
|
+
error: availability.reason,
|
|
194
|
+
backend: this.name,
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
// In a real implementation, this would:
|
|
200
|
+
// 1. Generate ephemeral keypair
|
|
201
|
+
// 2. Derive stealth address from recipient's meta-address
|
|
202
|
+
// 3. Create Pedersen commitment for amount
|
|
203
|
+
// 4. Build and submit transaction
|
|
204
|
+
// 5. Optionally encrypt data for viewing key
|
|
205
|
+
|
|
206
|
+
// For now, return a simulated successful result
|
|
207
|
+
// Real implementation depends on chain-specific adapters
|
|
208
|
+
const simulatedSignature = `sim_${Date.now()}_${Math.random().toString(36).slice(2)}`
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
success: true,
|
|
212
|
+
signature: simulatedSignature,
|
|
213
|
+
backend: this.name,
|
|
214
|
+
metadata: {
|
|
215
|
+
chain: params.chain,
|
|
216
|
+
amount: params.amount.toString(),
|
|
217
|
+
hasViewingKey: !!params.viewingKey,
|
|
218
|
+
timestamp: Date.now(),
|
|
219
|
+
},
|
|
220
|
+
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
225
|
+
backend: this.name,
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Estimate cost for a transfer
|
|
232
|
+
*/
|
|
233
|
+
async estimateCost(params: TransferParams): Promise<bigint> {
|
|
234
|
+
return this.getEstimatedCostForChain(params.chain)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Get estimated cost based on chain
|
|
239
|
+
*/
|
|
240
|
+
private getEstimatedCostForChain(chain: ChainType): bigint {
|
|
241
|
+
// Estimated costs in smallest chain units
|
|
242
|
+
const costMap: Partial<Record<ChainType, bigint>> = {
|
|
243
|
+
solana: BigInt(5000), // ~0.000005 SOL
|
|
244
|
+
ethereum: BigInt('50000000000000'), // ~0.00005 ETH
|
|
245
|
+
near: BigInt('1000000000000000000000'), // ~0.001 NEAR
|
|
246
|
+
polygon: BigInt('50000000000000'), // ~0.00005 MATIC
|
|
247
|
+
arbitrum: BigInt('50000000000000'),
|
|
248
|
+
optimism: BigInt('50000000000000'),
|
|
249
|
+
base: BigInt('50000000000000'),
|
|
250
|
+
avalanche: BigInt('50000000000000'),
|
|
251
|
+
bsc: BigInt('50000000000000'),
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return costMap[chain] ?? BigInt(0)
|
|
255
|
+
}
|
|
256
|
+
}
|