@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,595 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C-SPL Token Service
|
|
3
|
+
*
|
|
4
|
+
* Higher-level service wrapper for CSPLClient that provides:
|
|
5
|
+
* - Token registration and validation
|
|
6
|
+
* - Enhanced error handling with Result pattern
|
|
7
|
+
* - Delegate approvals for DeFi integrations
|
|
8
|
+
* - Cost estimation utilities
|
|
9
|
+
*
|
|
10
|
+
* This service is used by CombinedPrivacyService to integrate C-SPL
|
|
11
|
+
* encrypted amounts with SIP Native stealth addresses.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { CSPLTokenService } from '@sip-protocol/sdk'
|
|
16
|
+
*
|
|
17
|
+
* const service = new CSPLTokenService({
|
|
18
|
+
* rpcUrl: 'https://api.devnet.solana.com',
|
|
19
|
+
* })
|
|
20
|
+
*
|
|
21
|
+
* await service.initialize()
|
|
22
|
+
*
|
|
23
|
+
* // Wrap tokens with proper error handling
|
|
24
|
+
* const result = await service.wrap({
|
|
25
|
+
* mint: 'So11111111111111111111111111111111111111112',
|
|
26
|
+
* amount: 1_000_000_000n,
|
|
27
|
+
* owner: walletAddress,
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* // IMPORTANT: Always check success before accessing result fields
|
|
31
|
+
* if (!result.success) {
|
|
32
|
+
* console.error('Wrap failed:', result.error)
|
|
33
|
+
* return
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Now safe to access result fields
|
|
37
|
+
* console.log('C-SPL mint:', result.csplMint)
|
|
38
|
+
* console.log('Encrypted balance:', result.encryptedBalance)
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @see CSPLClient for the underlying client implementation
|
|
42
|
+
* @see CombinedPrivacyService for integration with stealth addresses
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
import type { CSPLToken, ConfidentialBalance, ConfidentialTransferResult } from './cspl-types'
|
|
46
|
+
import { CSPLClient, type CSPLClientConfig } from './cspl'
|
|
47
|
+
|
|
48
|
+
// ─── Types ─────────────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parameters for wrapping SPL tokens to C-SPL
|
|
52
|
+
*/
|
|
53
|
+
export interface WrapParams {
|
|
54
|
+
/** SPL token mint address */
|
|
55
|
+
mint: string
|
|
56
|
+
/** Amount to wrap (in smallest units) */
|
|
57
|
+
amount: bigint
|
|
58
|
+
/** Owner wallet address */
|
|
59
|
+
owner: string
|
|
60
|
+
/** Create C-SPL account if it doesn't exist (default: true) */
|
|
61
|
+
createAccount?: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Result of a wrap operation
|
|
66
|
+
*
|
|
67
|
+
* IMPORTANT: Always check `success` before accessing other fields!
|
|
68
|
+
* The csplMint and encryptedBalance are only present when success is true.
|
|
69
|
+
*/
|
|
70
|
+
export interface WrapResult {
|
|
71
|
+
/** Whether the wrap operation succeeded */
|
|
72
|
+
success: boolean
|
|
73
|
+
/** Transaction signature (only if success) */
|
|
74
|
+
signature?: string
|
|
75
|
+
/** The C-SPL token mint address (only if success) */
|
|
76
|
+
csplMint?: string
|
|
77
|
+
/** The encrypted balance after wrapping (only if success) */
|
|
78
|
+
encryptedBalance?: Uint8Array
|
|
79
|
+
/** Error message (only if !success) */
|
|
80
|
+
error?: string
|
|
81
|
+
/** Token info (only if success) */
|
|
82
|
+
token?: CSPLToken
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Parameters for unwrapping C-SPL back to SPL
|
|
87
|
+
*/
|
|
88
|
+
export interface UnwrapParams {
|
|
89
|
+
/** C-SPL token mint address */
|
|
90
|
+
csplMint: string
|
|
91
|
+
/** Encrypted amount to unwrap */
|
|
92
|
+
encryptedAmount: Uint8Array
|
|
93
|
+
/** Owner wallet address */
|
|
94
|
+
owner: string
|
|
95
|
+
/** Proof of ownership (optional, for zero-knowledge unwrap) */
|
|
96
|
+
proof?: Uint8Array
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Result of an unwrap operation
|
|
101
|
+
*/
|
|
102
|
+
export interface UnwrapResult {
|
|
103
|
+
/** Whether the unwrap operation succeeded */
|
|
104
|
+
success: boolean
|
|
105
|
+
/** Transaction signature (only if success) */
|
|
106
|
+
signature?: string
|
|
107
|
+
/** The decrypted/unwrapped amount (only if success) */
|
|
108
|
+
amount?: bigint
|
|
109
|
+
/** Error message (only if !success) */
|
|
110
|
+
error?: string
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Parameters for delegate approval
|
|
115
|
+
*/
|
|
116
|
+
export interface ApproveParams {
|
|
117
|
+
/** C-SPL token mint address */
|
|
118
|
+
csplMint: string
|
|
119
|
+
/** Delegate address (e.g., DEX contract) */
|
|
120
|
+
delegate: string
|
|
121
|
+
/** Owner wallet address */
|
|
122
|
+
owner: string
|
|
123
|
+
/** Maximum encrypted amount the delegate can transfer */
|
|
124
|
+
maxAmount?: Uint8Array
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Result of an approve/revoke operation
|
|
129
|
+
*/
|
|
130
|
+
export interface ApproveResult {
|
|
131
|
+
/** Whether the operation succeeded */
|
|
132
|
+
success: boolean
|
|
133
|
+
/** Transaction signature (only if success) */
|
|
134
|
+
signature?: string
|
|
135
|
+
/** Error message (only if !success) */
|
|
136
|
+
error?: string
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Service status information
|
|
141
|
+
*/
|
|
142
|
+
export interface CSPLServiceStatus {
|
|
143
|
+
/** Whether the service is initialized */
|
|
144
|
+
initialized: boolean
|
|
145
|
+
/** Whether connected to Solana RPC */
|
|
146
|
+
connected: boolean
|
|
147
|
+
/** Number of registered tokens */
|
|
148
|
+
registeredTokenCount: number
|
|
149
|
+
/** RPC endpoint URL */
|
|
150
|
+
rpcUrl: string
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ─── Service Implementation ────────────────────────────────────────────────────
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Configuration for CSPLTokenService
|
|
157
|
+
*/
|
|
158
|
+
export interface CSPLTokenServiceConfig extends CSPLClientConfig {
|
|
159
|
+
/** Pre-register these tokens on initialization */
|
|
160
|
+
initialTokens?: CSPLToken[]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* C-SPL Token Service
|
|
165
|
+
*
|
|
166
|
+
* Wraps CSPLClient with:
|
|
167
|
+
* - Proper error handling (always check success before field access)
|
|
168
|
+
* - Token registration
|
|
169
|
+
* - Delegate approvals
|
|
170
|
+
* - Cost estimation
|
|
171
|
+
*/
|
|
172
|
+
export class CSPLTokenService {
|
|
173
|
+
private client: CSPLClient
|
|
174
|
+
private config: CSPLTokenServiceConfig
|
|
175
|
+
private registeredTokens: Map<string, CSPLToken> = new Map()
|
|
176
|
+
private initialized: boolean = false
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Create a new C-SPL Token Service
|
|
180
|
+
*
|
|
181
|
+
* @param config - Service configuration
|
|
182
|
+
*/
|
|
183
|
+
constructor(config: CSPLTokenServiceConfig = {}) {
|
|
184
|
+
this.config = config
|
|
185
|
+
this.client = new CSPLClient(config)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Initialize the service
|
|
190
|
+
*
|
|
191
|
+
* Connects to Solana RPC and registers initial tokens.
|
|
192
|
+
*/
|
|
193
|
+
async initialize(): Promise<void> {
|
|
194
|
+
if (this.initialized) {
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
await this.client.connect(this.config.rpcUrl)
|
|
199
|
+
|
|
200
|
+
// Register initial tokens if provided
|
|
201
|
+
if (this.config.initialTokens) {
|
|
202
|
+
for (const token of this.config.initialTokens) {
|
|
203
|
+
this.registeredTokens.set(token.mint, token)
|
|
204
|
+
this.registeredTokens.set(token.confidentialMint, token)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
this.initialized = true
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Wrap SPL tokens to C-SPL (encrypted tokens)
|
|
213
|
+
*
|
|
214
|
+
* IMPORTANT: Always check result.success before accessing result.csplMint
|
|
215
|
+
* or other fields. This is the proper pattern to avoid undefined access.
|
|
216
|
+
*
|
|
217
|
+
* @param params - Wrap parameters
|
|
218
|
+
* @returns Wrap result with success status
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```typescript
|
|
222
|
+
* const result = await service.wrap({
|
|
223
|
+
* mint: 'So11111111111111111111111111111111111111112',
|
|
224
|
+
* amount: 1_000_000_000n,
|
|
225
|
+
* owner: wallet,
|
|
226
|
+
* })
|
|
227
|
+
*
|
|
228
|
+
* // CORRECT: Check success first
|
|
229
|
+
* if (!result.success) {
|
|
230
|
+
* console.error(result.error)
|
|
231
|
+
* return
|
|
232
|
+
* }
|
|
233
|
+
* console.log(result.csplMint) // Safe to access
|
|
234
|
+
*
|
|
235
|
+
* // INCORRECT: Don't do this!
|
|
236
|
+
* // console.log(result.csplMint!) // Unsafe non-null assertion
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
async wrap(params: WrapParams): Promise<WrapResult> {
|
|
240
|
+
if (!this.initialized) {
|
|
241
|
+
return {
|
|
242
|
+
success: false,
|
|
243
|
+
error: 'Service not initialized. Call initialize() first.',
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Validate inputs
|
|
248
|
+
if (!params.mint || params.mint.trim() === '') {
|
|
249
|
+
return {
|
|
250
|
+
success: false,
|
|
251
|
+
error: 'Token mint address is required',
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (!params.owner || params.owner.trim() === '') {
|
|
256
|
+
return {
|
|
257
|
+
success: false,
|
|
258
|
+
error: 'Owner address is required',
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (params.amount <= BigInt(0)) {
|
|
263
|
+
return {
|
|
264
|
+
success: false,
|
|
265
|
+
error: 'Amount must be greater than 0',
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
// Call the underlying client
|
|
271
|
+
const clientResult = await this.client.wrapToken({
|
|
272
|
+
mint: params.mint,
|
|
273
|
+
amount: params.amount,
|
|
274
|
+
owner: params.owner,
|
|
275
|
+
createAccount: params.createAccount ?? true,
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
// Check client result success FIRST before accessing fields
|
|
279
|
+
if (!clientResult.success) {
|
|
280
|
+
return {
|
|
281
|
+
success: false,
|
|
282
|
+
error: clientResult.error ?? 'Wrap operation failed',
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Now safe to access fields - they exist when success is true
|
|
287
|
+
// Register the token for future lookups
|
|
288
|
+
if (clientResult.token) {
|
|
289
|
+
this.registeredTokens.set(clientResult.token.mint, clientResult.token)
|
|
290
|
+
this.registeredTokens.set(clientResult.token.confidentialMint, clientResult.token)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
success: true,
|
|
295
|
+
signature: clientResult.signature,
|
|
296
|
+
csplMint: clientResult.token?.confidentialMint,
|
|
297
|
+
encryptedBalance: clientResult.encryptedBalance,
|
|
298
|
+
token: clientResult.token,
|
|
299
|
+
}
|
|
300
|
+
} catch (error) {
|
|
301
|
+
return {
|
|
302
|
+
success: false,
|
|
303
|
+
error: error instanceof Error ? error.message : 'Unknown error during wrap',
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Unwrap C-SPL tokens back to SPL
|
|
310
|
+
*
|
|
311
|
+
* @param params - Unwrap parameters
|
|
312
|
+
* @returns Unwrap result with success status
|
|
313
|
+
*/
|
|
314
|
+
async unwrap(params: UnwrapParams): Promise<UnwrapResult> {
|
|
315
|
+
if (!this.initialized) {
|
|
316
|
+
return {
|
|
317
|
+
success: false,
|
|
318
|
+
error: 'Service not initialized. Call initialize() first.',
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Find the token by C-SPL mint
|
|
323
|
+
const token = this.registeredTokens.get(params.csplMint)
|
|
324
|
+
if (!token) {
|
|
325
|
+
return {
|
|
326
|
+
success: false,
|
|
327
|
+
error: `Token ${params.csplMint} not registered. Wrap it first or register it manually.`,
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
const clientResult = await this.client.unwrapToken({
|
|
333
|
+
token,
|
|
334
|
+
encryptedAmount: params.encryptedAmount,
|
|
335
|
+
owner: params.owner,
|
|
336
|
+
proof: params.proof,
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
// Check success FIRST
|
|
340
|
+
if (!clientResult.success) {
|
|
341
|
+
return {
|
|
342
|
+
success: false,
|
|
343
|
+
error: clientResult.error ?? 'Unwrap operation failed',
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
success: true,
|
|
349
|
+
signature: clientResult.signature,
|
|
350
|
+
amount: clientResult.amount,
|
|
351
|
+
}
|
|
352
|
+
} catch (error) {
|
|
353
|
+
return {
|
|
354
|
+
success: false,
|
|
355
|
+
error: error instanceof Error ? error.message : 'Unknown error during unwrap',
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Execute a confidential transfer
|
|
362
|
+
*
|
|
363
|
+
* @param params - Transfer parameters
|
|
364
|
+
* @returns Transfer result with success status
|
|
365
|
+
*/
|
|
366
|
+
async transfer(params: {
|
|
367
|
+
csplMint: string
|
|
368
|
+
from: string
|
|
369
|
+
to: string
|
|
370
|
+
encryptedAmount: Uint8Array
|
|
371
|
+
memo?: string
|
|
372
|
+
}): Promise<ConfidentialTransferResult> {
|
|
373
|
+
if (!this.initialized) {
|
|
374
|
+
return {
|
|
375
|
+
success: false,
|
|
376
|
+
error: 'Service not initialized. Call initialize() first.',
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const token = this.registeredTokens.get(params.csplMint)
|
|
381
|
+
if (!token) {
|
|
382
|
+
return {
|
|
383
|
+
success: false,
|
|
384
|
+
error: `Token ${params.csplMint} not registered.`,
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
const result = await this.client.transfer({
|
|
390
|
+
from: params.from,
|
|
391
|
+
to: params.to,
|
|
392
|
+
token,
|
|
393
|
+
encryptedAmount: params.encryptedAmount,
|
|
394
|
+
memo: params.memo,
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
return result
|
|
398
|
+
} catch (error) {
|
|
399
|
+
return {
|
|
400
|
+
success: false,
|
|
401
|
+
error: error instanceof Error ? error.message : 'Unknown error during transfer',
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Get confidential balance for an account
|
|
408
|
+
*
|
|
409
|
+
* @param csplMint - C-SPL token mint address
|
|
410
|
+
* @param owner - Account owner address
|
|
411
|
+
* @returns Confidential balance or null if not found
|
|
412
|
+
*/
|
|
413
|
+
async getBalance(csplMint: string, owner: string): Promise<ConfidentialBalance | null> {
|
|
414
|
+
if (!this.initialized) {
|
|
415
|
+
return null
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const token = this.registeredTokens.get(csplMint)
|
|
419
|
+
if (!token) {
|
|
420
|
+
return null
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
return await this.client.getBalance(owner, token)
|
|
425
|
+
} catch {
|
|
426
|
+
return null
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Approve a delegate to transfer C-SPL tokens
|
|
432
|
+
*
|
|
433
|
+
* Used for DEX integrations where a contract needs to transfer on behalf of user.
|
|
434
|
+
*
|
|
435
|
+
* @param params - Approval parameters
|
|
436
|
+
* @returns Approval result
|
|
437
|
+
*/
|
|
438
|
+
async approve(params: ApproveParams): Promise<ApproveResult> {
|
|
439
|
+
if (!this.initialized) {
|
|
440
|
+
return {
|
|
441
|
+
success: false,
|
|
442
|
+
error: 'Service not initialized. Call initialize() first.',
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Validate inputs
|
|
447
|
+
if (!params.csplMint || !params.delegate || !params.owner) {
|
|
448
|
+
return {
|
|
449
|
+
success: false,
|
|
450
|
+
error: 'csplMint, delegate, and owner are all required',
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const token = this.registeredTokens.get(params.csplMint)
|
|
455
|
+
if (!token) {
|
|
456
|
+
return {
|
|
457
|
+
success: false,
|
|
458
|
+
error: `Token ${params.csplMint} not registered.`,
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
try {
|
|
463
|
+
// In production: Create and submit approval transaction
|
|
464
|
+
// const tx = await createApprovalTransaction(token, params.delegate, params.owner, params.maxAmount)
|
|
465
|
+
// const signature = await sendTransaction(tx)
|
|
466
|
+
|
|
467
|
+
// Simulated success
|
|
468
|
+
const simulatedSignature = `approve_${Date.now()}_${Math.random().toString(36).slice(2)}`
|
|
469
|
+
|
|
470
|
+
return {
|
|
471
|
+
success: true,
|
|
472
|
+
signature: simulatedSignature,
|
|
473
|
+
}
|
|
474
|
+
} catch (error) {
|
|
475
|
+
return {
|
|
476
|
+
success: false,
|
|
477
|
+
error: error instanceof Error ? error.message : 'Unknown error during approval',
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Revoke a delegate's approval
|
|
484
|
+
*
|
|
485
|
+
* @param csplMint - C-SPL token mint address
|
|
486
|
+
* @param delegate - Delegate address to revoke
|
|
487
|
+
* @param owner - Token owner address
|
|
488
|
+
* @returns Revoke result
|
|
489
|
+
*/
|
|
490
|
+
async revoke(
|
|
491
|
+
csplMint: string,
|
|
492
|
+
_delegate: string,
|
|
493
|
+
_owner: string
|
|
494
|
+
): Promise<ApproveResult> {
|
|
495
|
+
// Note: _delegate and _owner are reserved for production implementation.
|
|
496
|
+
// They will be used in createRevokeTransaction() when C-SPL SDK is integrated.
|
|
497
|
+
|
|
498
|
+
if (!this.initialized) {
|
|
499
|
+
return {
|
|
500
|
+
success: false,
|
|
501
|
+
error: 'Service not initialized. Call initialize() first.',
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const token = this.registeredTokens.get(csplMint)
|
|
506
|
+
if (!token) {
|
|
507
|
+
return {
|
|
508
|
+
success: false,
|
|
509
|
+
error: `Token ${csplMint} not registered.`,
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
try {
|
|
514
|
+
// In production: Create and submit revoke transaction
|
|
515
|
+
// const tx = await createRevokeTransaction(token, _delegate, _owner)
|
|
516
|
+
// const signature = await sendTransaction(tx)
|
|
517
|
+
|
|
518
|
+
// Simulated success
|
|
519
|
+
const simulatedSignature = `revoke_${Date.now()}_${Math.random().toString(36).slice(2)}`
|
|
520
|
+
|
|
521
|
+
return {
|
|
522
|
+
success: true,
|
|
523
|
+
signature: simulatedSignature,
|
|
524
|
+
}
|
|
525
|
+
} catch (error) {
|
|
526
|
+
return {
|
|
527
|
+
success: false,
|
|
528
|
+
error: error instanceof Error ? error.message : 'Unknown error during revoke',
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Estimate cost for an operation
|
|
535
|
+
*
|
|
536
|
+
* @param operation - Operation type ('wrap', 'unwrap', 'transfer', 'approve')
|
|
537
|
+
* @returns Estimated cost in lamports
|
|
538
|
+
*/
|
|
539
|
+
async estimateCost(operation: 'wrap' | 'unwrap' | 'transfer' | 'approve'): Promise<bigint> {
|
|
540
|
+
const costs: Record<string, bigint> = {
|
|
541
|
+
wrap: BigInt(5_000),
|
|
542
|
+
unwrap: BigInt(5_000),
|
|
543
|
+
transfer: BigInt(10_000),
|
|
544
|
+
approve: BigInt(5_000),
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
return costs[operation] ?? BigInt(0)
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Get all supported/registered tokens
|
|
552
|
+
*
|
|
553
|
+
* @returns Array of registered C-SPL tokens
|
|
554
|
+
*/
|
|
555
|
+
getSupportedTokens(): CSPLToken[] {
|
|
556
|
+
// De-duplicate (tokens are registered by both mint and confidentialMint)
|
|
557
|
+
const uniqueTokens = new Map<string, CSPLToken>()
|
|
558
|
+
for (const token of this.registeredTokens.values()) {
|
|
559
|
+
uniqueTokens.set(token.confidentialMint, token)
|
|
560
|
+
}
|
|
561
|
+
return Array.from(uniqueTokens.values())
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Register a token for use with the service
|
|
566
|
+
*
|
|
567
|
+
* @param token - Token to register
|
|
568
|
+
*/
|
|
569
|
+
registerToken(token: CSPLToken): void {
|
|
570
|
+
this.registeredTokens.set(token.mint, token)
|
|
571
|
+
this.registeredTokens.set(token.confidentialMint, token)
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Get service status
|
|
576
|
+
*
|
|
577
|
+
* @returns Service status information
|
|
578
|
+
*/
|
|
579
|
+
getStatus(): CSPLServiceStatus {
|
|
580
|
+
return {
|
|
581
|
+
initialized: this.initialized,
|
|
582
|
+
connected: this.client.isConnected(),
|
|
583
|
+
registeredTokenCount: this.getSupportedTokens().length,
|
|
584
|
+
rpcUrl: this.config.rpcUrl ?? 'https://api.devnet.solana.com',
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Disconnect and cleanup
|
|
590
|
+
*/
|
|
591
|
+
async disconnect(): Promise<void> {
|
|
592
|
+
await this.client.disconnect()
|
|
593
|
+
this.initialized = false
|
|
594
|
+
}
|
|
595
|
+
}
|