@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
|
@@ -56,7 +56,7 @@ export {
|
|
|
56
56
|
ATA_RENT_LAMPORTS,
|
|
57
57
|
getExplorerUrl,
|
|
58
58
|
getTokenMint,
|
|
59
|
-
|
|
59
|
+
getSolanaTokenDecimals,
|
|
60
60
|
type SolanaCluster,
|
|
61
61
|
} from './constants'
|
|
62
62
|
|
|
@@ -79,6 +79,47 @@ export {
|
|
|
79
79
|
hasTokenAccount,
|
|
80
80
|
} from './transfer'
|
|
81
81
|
|
|
82
|
+
// Enhanced SPL Transfer (Issue #286)
|
|
83
|
+
export {
|
|
84
|
+
resolveTokenMetadata,
|
|
85
|
+
batchResolveTokenMetadata,
|
|
86
|
+
getTokenBalance,
|
|
87
|
+
batchGetTokenBalances,
|
|
88
|
+
validateTransfer,
|
|
89
|
+
sendEnhancedSPLTransfer,
|
|
90
|
+
sendBatchSPLTransfer,
|
|
91
|
+
formatTokenAmount,
|
|
92
|
+
parseTokenAmount,
|
|
93
|
+
type TokenMetadata,
|
|
94
|
+
type TokenBalance,
|
|
95
|
+
type EnhancedSPLTransferParams,
|
|
96
|
+
type EnhancedSPLTransferResult,
|
|
97
|
+
type BatchTransferItem,
|
|
98
|
+
type BatchTransferResult,
|
|
99
|
+
type TransferValidation,
|
|
100
|
+
} from './spl-transfer'
|
|
101
|
+
|
|
102
|
+
// Native SOL Transfer (Issue #292)
|
|
103
|
+
export {
|
|
104
|
+
validateSOLTransfer,
|
|
105
|
+
estimateSOLTransfer,
|
|
106
|
+
sendSOLTransfer,
|
|
107
|
+
sendMaxSOLTransfer,
|
|
108
|
+
sendBatchSOLTransfer,
|
|
109
|
+
formatLamports,
|
|
110
|
+
parseSOLToLamports,
|
|
111
|
+
getSOLBalance,
|
|
112
|
+
RENT_EXEMPT_MINIMUM,
|
|
113
|
+
STEALTH_ACCOUNT_BUFFER,
|
|
114
|
+
type SOLTransferParams,
|
|
115
|
+
type MaxSOLTransferParams,
|
|
116
|
+
type SOLTransferResult,
|
|
117
|
+
type SOLTransferValidation,
|
|
118
|
+
type SOLTransferEstimate,
|
|
119
|
+
type BatchSOLTransferItem,
|
|
120
|
+
type BatchSOLTransferResult,
|
|
121
|
+
} from './sol-transfer'
|
|
122
|
+
|
|
82
123
|
// Scan and claim functions
|
|
83
124
|
export {
|
|
84
125
|
scanForPayments,
|
|
@@ -86,6 +127,48 @@ export {
|
|
|
86
127
|
getStealthBalance,
|
|
87
128
|
} from './scan'
|
|
88
129
|
|
|
130
|
+
// Advanced Stealth Scanner (Issue #262)
|
|
131
|
+
export {
|
|
132
|
+
StealthScanner,
|
|
133
|
+
createStealthScanner,
|
|
134
|
+
batchScanForRecipients,
|
|
135
|
+
fullHistoricalScan,
|
|
136
|
+
type ScanRecipient,
|
|
137
|
+
type StealthScannerOptions,
|
|
138
|
+
type HistoricalScanOptions,
|
|
139
|
+
type DetectedPayment,
|
|
140
|
+
type HistoricalScanResult,
|
|
141
|
+
type PaymentCallback,
|
|
142
|
+
type ErrorCallback,
|
|
143
|
+
} from './stealth-scanner'
|
|
144
|
+
|
|
145
|
+
// Ephemeral Keypair Management (Issue #270)
|
|
146
|
+
export {
|
|
147
|
+
generateEphemeralKeypair,
|
|
148
|
+
generateManagedEphemeralKeypair,
|
|
149
|
+
batchGenerateEphemeralKeypairs,
|
|
150
|
+
batchGenerateManagedEphemeralKeypairs,
|
|
151
|
+
disposeEphemeralKeypairs,
|
|
152
|
+
wipeEphemeralPrivateKey,
|
|
153
|
+
formatEphemeralAnnouncement,
|
|
154
|
+
parseEphemeralAnnouncement,
|
|
155
|
+
type EphemeralKeypair,
|
|
156
|
+
type EphemeralKeyUsageResult,
|
|
157
|
+
type ManagedEphemeralKeypair,
|
|
158
|
+
type BatchGenerationOptions,
|
|
159
|
+
} from './ephemeral-keys'
|
|
160
|
+
|
|
161
|
+
// Privacy Adapter (Issue #276)
|
|
162
|
+
export {
|
|
163
|
+
SolanaPrivacyAdapter,
|
|
164
|
+
createSolanaPrivacyAdapter,
|
|
165
|
+
type SolanaPrivacyAdapterConfig,
|
|
166
|
+
type ShieldedTransferParams,
|
|
167
|
+
type AdapterScanParams,
|
|
168
|
+
type AdapterClaimParams,
|
|
169
|
+
type PrivacyAdapterState,
|
|
170
|
+
} from './privacy-adapter'
|
|
171
|
+
|
|
89
172
|
// RPC Providers (Infrastructure Agnostic)
|
|
90
173
|
export {
|
|
91
174
|
createProvider,
|
|
@@ -103,9 +186,177 @@ export {
|
|
|
103
186
|
export {
|
|
104
187
|
createWebhookHandler,
|
|
105
188
|
processWebhookTransaction,
|
|
189
|
+
verifyWebhookSignature,
|
|
190
|
+
verifyAuthToken,
|
|
106
191
|
type HeliusWebhookTransaction,
|
|
107
192
|
type HeliusEnhancedTransaction,
|
|
108
193
|
type HeliusWebhookPayload,
|
|
109
194
|
type WebhookHandlerConfig,
|
|
110
195
|
type WebhookProcessResult,
|
|
196
|
+
type WebhookRequest,
|
|
197
|
+
type WebhookHandler,
|
|
111
198
|
} from './providers'
|
|
199
|
+
|
|
200
|
+
// Helius Enhanced Transactions (Human-readable TX data)
|
|
201
|
+
export {
|
|
202
|
+
HeliusEnhanced,
|
|
203
|
+
createHeliusEnhanced,
|
|
204
|
+
type HeliusEnhancedConfig,
|
|
205
|
+
type EnhancedTransactionType,
|
|
206
|
+
type NativeTransfer,
|
|
207
|
+
type TokenTransfer,
|
|
208
|
+
type NftTransfer,
|
|
209
|
+
type SwapEvent,
|
|
210
|
+
type EnhancedTransactionEvents,
|
|
211
|
+
type EnhancedAccountData,
|
|
212
|
+
type EnhancedTransaction,
|
|
213
|
+
type ParseTransactionsOptions,
|
|
214
|
+
type GetTransactionHistoryOptions,
|
|
215
|
+
type PrivacyDisplayOptions,
|
|
216
|
+
type SIPTransactionMetadata,
|
|
217
|
+
type SIPEnhancedTransaction,
|
|
218
|
+
type TransactionSummary,
|
|
219
|
+
} from './providers'
|
|
220
|
+
|
|
221
|
+
// Key Derivation (BIP39/SLIP-0010)
|
|
222
|
+
export {
|
|
223
|
+
deriveSolanaStealthKeys,
|
|
224
|
+
deriveViewingKeyFromSpending,
|
|
225
|
+
generateMnemonic,
|
|
226
|
+
isValidMnemonic,
|
|
227
|
+
validateMnemonic,
|
|
228
|
+
validateDerivationPath,
|
|
229
|
+
getDerivationPath,
|
|
230
|
+
SOLANA_DEFAULT_PATH,
|
|
231
|
+
type SolanaKeyDerivationOptions,
|
|
232
|
+
type SolanaKeyDerivationResult,
|
|
233
|
+
} from './key-derivation'
|
|
234
|
+
|
|
235
|
+
// Pedersen Commitments (ed25519)
|
|
236
|
+
export {
|
|
237
|
+
commitSolana,
|
|
238
|
+
verifyOpeningSolana,
|
|
239
|
+
commitSPLToken,
|
|
240
|
+
verifySPLTokenCommitment,
|
|
241
|
+
toSmallestUnits,
|
|
242
|
+
fromSmallestUnits,
|
|
243
|
+
addCommitmentsSolana,
|
|
244
|
+
subtractCommitmentsSolana,
|
|
245
|
+
addBlindingsSolana,
|
|
246
|
+
subtractBlindingsSolana,
|
|
247
|
+
getGeneratorsSolana,
|
|
248
|
+
generateBlindingSolana,
|
|
249
|
+
ED25519_ORDER,
|
|
250
|
+
MAX_SPL_AMOUNT,
|
|
251
|
+
type SolanaPedersenCommitment,
|
|
252
|
+
type SolanaCommitmentPoint,
|
|
253
|
+
type SPLTokenCommitment,
|
|
254
|
+
} from './commitment'
|
|
255
|
+
|
|
256
|
+
// Viewing Key Management
|
|
257
|
+
export {
|
|
258
|
+
generateViewingKeyFromSpending,
|
|
259
|
+
generateRandomViewingKey,
|
|
260
|
+
computeViewingKeyHash,
|
|
261
|
+
computeViewingKeyHashFromPrivate,
|
|
262
|
+
exportViewingKey,
|
|
263
|
+
importViewingKey,
|
|
264
|
+
encryptForViewing,
|
|
265
|
+
decryptWithViewing,
|
|
266
|
+
createMemoryStorage,
|
|
267
|
+
isAnnouncementForViewingKey,
|
|
268
|
+
deriveChildViewingKey,
|
|
269
|
+
getViewingPublicKey,
|
|
270
|
+
type SolanaViewingKey,
|
|
271
|
+
type ViewingKeyExport,
|
|
272
|
+
type EncryptedPayload,
|
|
273
|
+
type SolanaTransactionData,
|
|
274
|
+
type ViewingKeyStorage,
|
|
275
|
+
} from './viewing-key'
|
|
276
|
+
|
|
277
|
+
// RPC Client (Issue #280) + Network Privacy (Issue #798)
|
|
278
|
+
export {
|
|
279
|
+
SolanaRPCClient,
|
|
280
|
+
createRPCClient,
|
|
281
|
+
createPrivateRPCClient,
|
|
282
|
+
createClusterClient,
|
|
283
|
+
RPC_ENDPOINTS,
|
|
284
|
+
RPCErrorType,
|
|
285
|
+
type RPCClientConfig,
|
|
286
|
+
type ClassifiedRPCError,
|
|
287
|
+
type PriorityFeeEstimate,
|
|
288
|
+
type TransactionConfirmationResult,
|
|
289
|
+
type SendTransactionOptions,
|
|
290
|
+
} from './rpc-client'
|
|
291
|
+
|
|
292
|
+
// Transaction Builder (Issue #298)
|
|
293
|
+
export {
|
|
294
|
+
ShieldedTransactionBuilder,
|
|
295
|
+
createTransactionBuilder,
|
|
296
|
+
estimateComputeUnits,
|
|
297
|
+
calculatePriorityFee,
|
|
298
|
+
ShieldedTransactionType,
|
|
299
|
+
DEFAULT_COMPUTE_UNITS,
|
|
300
|
+
DEFAULT_PRIORITY_FEE,
|
|
301
|
+
MIN_COMPUTE_UNITS,
|
|
302
|
+
MAX_COMPUTE_UNITS,
|
|
303
|
+
type TransactionBuilderConfig,
|
|
304
|
+
type ComputeBudgetConfig,
|
|
305
|
+
type SPLTransferInstruction,
|
|
306
|
+
type SOLTransferInstruction,
|
|
307
|
+
type BuiltTransaction,
|
|
308
|
+
type SerializedTransaction,
|
|
309
|
+
} from './transaction-builder'
|
|
310
|
+
|
|
311
|
+
// Anchor Shielded Transfer (Issue #781)
|
|
312
|
+
// Uses the SIP Privacy Anchor program for on-chain privacy
|
|
313
|
+
export {
|
|
314
|
+
shieldedTransfer,
|
|
315
|
+
SIP_PRIVACY_PROGRAM_ID,
|
|
316
|
+
CONFIG_PDA,
|
|
317
|
+
FEE_COLLECTOR,
|
|
318
|
+
type AnchorShieldedTransferParams,
|
|
319
|
+
type AnchorShieldedTransferResult,
|
|
320
|
+
} from './anchor-transfer'
|
|
321
|
+
|
|
322
|
+
// @solana/kit Compatibility Bridge (Issue #931)
|
|
323
|
+
// Utilities for bridging between @solana/web3.js and @solana/kit types
|
|
324
|
+
export {
|
|
325
|
+
toAddress,
|
|
326
|
+
toPublicKey,
|
|
327
|
+
createAddress,
|
|
328
|
+
toKeyPair,
|
|
329
|
+
toKitInstruction,
|
|
330
|
+
toKitTransaction,
|
|
331
|
+
createDualRpcClient,
|
|
332
|
+
toKitCommitment,
|
|
333
|
+
createBlockhash,
|
|
334
|
+
toBlockhashInfo,
|
|
335
|
+
LAMPORTS_PER_SOL as KIT_LAMPORTS_PER_SOL,
|
|
336
|
+
solToLamports,
|
|
337
|
+
lamportsToSol,
|
|
338
|
+
isAddress,
|
|
339
|
+
isPublicKey,
|
|
340
|
+
normalizeAddress,
|
|
341
|
+
RpcHelpers,
|
|
342
|
+
type DualRpcClient,
|
|
343
|
+
type Address,
|
|
344
|
+
type Rpc,
|
|
345
|
+
type RpcSubscriptions,
|
|
346
|
+
type SolanaRpcApi,
|
|
347
|
+
type SolanaRpcSubscriptionsApi,
|
|
348
|
+
type Blockhash as KitBlockhash,
|
|
349
|
+
} from './kit-compat'
|
|
350
|
+
|
|
351
|
+
// Sunspot ZK Verifier (Issue #779)
|
|
352
|
+
export {
|
|
353
|
+
SunspotVerifier,
|
|
354
|
+
ProofType,
|
|
355
|
+
createVerifyInstructionData,
|
|
356
|
+
formatFundingInputs,
|
|
357
|
+
formatOwnershipInputs,
|
|
358
|
+
type SunspotVerifierConfig,
|
|
359
|
+
type VerifyProofParams,
|
|
360
|
+
type VerifyProofResult,
|
|
361
|
+
type Groth16Proof,
|
|
362
|
+
} from './sunspot-verifier'
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana Key Derivation for SIP Stealth Addresses
|
|
3
|
+
*
|
|
4
|
+
* Derives spending and viewing keypairs from Solana seed phrases (BIP39 mnemonics)
|
|
5
|
+
* using standard Solana derivation paths (SLIP-0010 for ed25519).
|
|
6
|
+
*
|
|
7
|
+
* @module chains/solana/key-derivation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
generateMnemonic as bip39GenerateMnemonic,
|
|
12
|
+
validateMnemonic as bip39ValidateMnemonic,
|
|
13
|
+
mnemonicToSeedSync,
|
|
14
|
+
} from '@scure/bip39'
|
|
15
|
+
import { wordlist as english } from '@scure/bip39/wordlists/english.js'
|
|
16
|
+
import { ed25519 } from '@noble/curves/ed25519'
|
|
17
|
+
import { sha256, sha512 } from '@noble/hashes/sha2'
|
|
18
|
+
import { hmac } from '@noble/hashes/hmac'
|
|
19
|
+
import type { StealthMetaAddress, HexString } from '@sip-protocol/types'
|
|
20
|
+
import { ValidationError } from '../../errors'
|
|
21
|
+
import { bytesToHex } from '../../stealth/utils'
|
|
22
|
+
import { secureWipe } from '../../secure-memory'
|
|
23
|
+
|
|
24
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Standard Solana derivation path (BIP44)
|
|
28
|
+
*
|
|
29
|
+
* m/44'/501'/account'/change'
|
|
30
|
+
*
|
|
31
|
+
* - 44' = BIP44 purpose
|
|
32
|
+
* - 501' = Solana coin type
|
|
33
|
+
* - 0' = first account
|
|
34
|
+
* - 0' = external chain (most wallets use this)
|
|
35
|
+
*/
|
|
36
|
+
export const SOLANA_DEFAULT_PATH = "m/44'/501'/0'/0'"
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* SIP-specific derivation context for viewing key
|
|
40
|
+
*
|
|
41
|
+
* The viewing key is derived deterministically from the spending key
|
|
42
|
+
* using HMAC-SHA256 with this context string.
|
|
43
|
+
*/
|
|
44
|
+
const VIEWING_KEY_CONTEXT = 'SIP-viewing-key-v1'
|
|
45
|
+
|
|
46
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Options for key derivation from mnemonic
|
|
50
|
+
*/
|
|
51
|
+
export interface SolanaKeyDerivationOptions {
|
|
52
|
+
/**
|
|
53
|
+
* BIP39 mnemonic phrase (12 or 24 words)
|
|
54
|
+
*/
|
|
55
|
+
mnemonic: string
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Optional passphrase for BIP39 seed derivation
|
|
59
|
+
* @default undefined (no passphrase)
|
|
60
|
+
*/
|
|
61
|
+
passphrase?: string
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Derivation path for the spending key
|
|
65
|
+
* @default "m/44'/501'/0'/0'" (standard Solana)
|
|
66
|
+
*/
|
|
67
|
+
derivationPath?: string
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Account index to use (modifies derivation path)
|
|
71
|
+
* @default 0
|
|
72
|
+
*/
|
|
73
|
+
accountIndex?: number
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Optional label for the generated meta-address
|
|
77
|
+
*/
|
|
78
|
+
label?: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Result of key derivation
|
|
83
|
+
*/
|
|
84
|
+
export interface SolanaKeyDerivationResult {
|
|
85
|
+
/**
|
|
86
|
+
* The stealth meta-address (safe to share publicly)
|
|
87
|
+
*/
|
|
88
|
+
metaAddress: StealthMetaAddress
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Spending private key (CRITICAL - never share)
|
|
92
|
+
*/
|
|
93
|
+
spendingPrivateKey: HexString
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Viewing private key (sensitive - share only with auditors)
|
|
97
|
+
*/
|
|
98
|
+
viewingPrivateKey: HexString
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The derivation path used
|
|
102
|
+
*/
|
|
103
|
+
derivationPath: string
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ─── Validation ───────────────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Validate a BIP39 mnemonic phrase
|
|
110
|
+
*
|
|
111
|
+
* @param mnemonic - The mnemonic to validate
|
|
112
|
+
* @returns true if valid
|
|
113
|
+
* @throws {ValidationError} if invalid
|
|
114
|
+
*/
|
|
115
|
+
export function validateMnemonic(mnemonic: string): boolean {
|
|
116
|
+
if (!mnemonic || typeof mnemonic !== 'string') {
|
|
117
|
+
throw new ValidationError('Mnemonic must be a non-empty string', 'mnemonic')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Normalize: trim, lowercase, and collapse multiple spaces
|
|
121
|
+
const words = mnemonic.trim().toLowerCase().split(/\s+/)
|
|
122
|
+
const normalized = words.join(' ')
|
|
123
|
+
|
|
124
|
+
// Standard BIP39 supports 12, 15, 18, 21, or 24 words
|
|
125
|
+
const validLengths = [12, 15, 18, 21, 24]
|
|
126
|
+
if (!validLengths.includes(words.length)) {
|
|
127
|
+
throw new ValidationError(
|
|
128
|
+
`Mnemonic must have 12, 15, 18, 21, or 24 words (got ${words.length})`,
|
|
129
|
+
'mnemonic'
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Validate using bip39 library
|
|
134
|
+
if (!bip39ValidateMnemonic(normalized, english)) {
|
|
135
|
+
throw new ValidationError(
|
|
136
|
+
'Invalid mnemonic: checksum failed or contains invalid words',
|
|
137
|
+
'mnemonic'
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return true
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Validate a derivation path
|
|
146
|
+
*
|
|
147
|
+
* @param path - The derivation path to validate
|
|
148
|
+
* @returns true if valid
|
|
149
|
+
* @throws {ValidationError} if invalid
|
|
150
|
+
*/
|
|
151
|
+
export function validateDerivationPath(path: string): boolean {
|
|
152
|
+
if (!path || typeof path !== 'string') {
|
|
153
|
+
throw new ValidationError('Derivation path must be a non-empty string', 'derivationPath')
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Must start with 'm/'
|
|
157
|
+
if (!path.startsWith('m/')) {
|
|
158
|
+
throw new ValidationError("Derivation path must start with 'm/'", 'derivationPath')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Validate path format (e.g., m/44'/501'/0'/0')
|
|
162
|
+
const pathRegex = /^m(\/\d+'?)*$/
|
|
163
|
+
if (!pathRegex.test(path)) {
|
|
164
|
+
throw new ValidationError(
|
|
165
|
+
'Invalid derivation path format. Use format like m/44\'/501\'/0\'/0\'',
|
|
166
|
+
'derivationPath'
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return true
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ─── SLIP-0010 ed25519 Key Derivation ─────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Derive ed25519 private key using SLIP-0010 from BIP39 seed
|
|
177
|
+
*
|
|
178
|
+
* SLIP-0010 defines ed25519 key derivation differently from secp256k1.
|
|
179
|
+
* It uses HMAC-SHA512 at each derivation level.
|
|
180
|
+
*
|
|
181
|
+
* Note: SLIP-0010 for ed25519 only supports hardened derivation.
|
|
182
|
+
*
|
|
183
|
+
* @param seed - 64-byte BIP39 seed
|
|
184
|
+
* @param path - Derivation path (all indices must be hardened)
|
|
185
|
+
* @returns 32-byte ed25519 private key
|
|
186
|
+
*/
|
|
187
|
+
function slip0010DeriveEd25519(seed: Uint8Array, path: string): Uint8Array {
|
|
188
|
+
// SLIP-0010 ed25519 master key derivation using HMAC-SHA512
|
|
189
|
+
const I = hmac(sha512, 'ed25519 seed', seed)
|
|
190
|
+
|
|
191
|
+
let key: Uint8Array = new Uint8Array(I.slice(0, 32))
|
|
192
|
+
let chainCode: Uint8Array = new Uint8Array(I.slice(32, 64))
|
|
193
|
+
|
|
194
|
+
// Parse path components (skip 'm')
|
|
195
|
+
const components = path.split('/').slice(1)
|
|
196
|
+
|
|
197
|
+
for (const component of components) {
|
|
198
|
+
// All ed25519 derivations must be hardened
|
|
199
|
+
const hardened = component.endsWith("'")
|
|
200
|
+
const indexStr = hardened ? component.slice(0, -1) : component
|
|
201
|
+
const index = parseInt(indexStr, 10)
|
|
202
|
+
|
|
203
|
+
if (!hardened) {
|
|
204
|
+
throw new ValidationError(
|
|
205
|
+
'SLIP-0010 ed25519 only supports hardened derivation. Add \' to path index.',
|
|
206
|
+
'derivationPath'
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Hardened child: index + 0x80000000
|
|
211
|
+
const hardenedIndex = index + 0x80000000
|
|
212
|
+
|
|
213
|
+
// HMAC-SHA512(chainCode, 0x00 || key || index)
|
|
214
|
+
const data = new Uint8Array(1 + 32 + 4)
|
|
215
|
+
data[0] = 0x00
|
|
216
|
+
data.set(key, 1)
|
|
217
|
+
new DataView(data.buffer).setUint32(33, hardenedIndex, false) // big-endian
|
|
218
|
+
|
|
219
|
+
const derivedI = hmac(sha512, chainCode, data)
|
|
220
|
+
|
|
221
|
+
// Split into key (first 32 bytes) and chain code (last 32 bytes)
|
|
222
|
+
key = new Uint8Array(derivedI.slice(0, 32))
|
|
223
|
+
chainCode = new Uint8Array(derivedI.slice(32, 64))
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return key
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ─── Key Derivation ───────────────────────────────────────────────────────────
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Derive spending and viewing keypairs from a Solana mnemonic
|
|
233
|
+
*
|
|
234
|
+
* This is the primary function for generating SIP stealth keys from an existing
|
|
235
|
+
* Solana wallet's seed phrase.
|
|
236
|
+
*
|
|
237
|
+
* @param options - Derivation options including mnemonic and optional path
|
|
238
|
+
* @returns Stealth meta-address and private keys
|
|
239
|
+
*
|
|
240
|
+
* @example Basic usage
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const result = deriveSolanaStealthKeys({
|
|
243
|
+
* mnemonic: 'abandon abandon abandon ... about',
|
|
244
|
+
* })
|
|
245
|
+
*
|
|
246
|
+
* console.log('Meta-address:', result.metaAddress)
|
|
247
|
+
* // Share metaAddress with senders
|
|
248
|
+
* // Keep spendingPrivateKey SECURE
|
|
249
|
+
* // viewingPrivateKey can be shared with auditors
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @example With custom derivation path
|
|
253
|
+
* ```typescript
|
|
254
|
+
* const result = deriveSolanaStealthKeys({
|
|
255
|
+
* mnemonic: 'your twelve word mnemonic phrase here ...',
|
|
256
|
+
* derivationPath: "m/44'/501'/1'/0'", // Second account
|
|
257
|
+
* label: 'Trading account',
|
|
258
|
+
* })
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* @example With account index shorthand
|
|
262
|
+
* ```typescript
|
|
263
|
+
* const result = deriveSolanaStealthKeys({
|
|
264
|
+
* mnemonic: 'your mnemonic...',
|
|
265
|
+
* accountIndex: 2, // Uses m/44'/501'/2'/0'
|
|
266
|
+
* })
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
export function deriveSolanaStealthKeys(
|
|
270
|
+
options: SolanaKeyDerivationOptions
|
|
271
|
+
): SolanaKeyDerivationResult {
|
|
272
|
+
// Validate mnemonic
|
|
273
|
+
validateMnemonic(options.mnemonic)
|
|
274
|
+
|
|
275
|
+
// Determine derivation path
|
|
276
|
+
let derivationPath = options.derivationPath ?? SOLANA_DEFAULT_PATH
|
|
277
|
+
|
|
278
|
+
// If accountIndex is specified, override the path
|
|
279
|
+
if (options.accountIndex !== undefined) {
|
|
280
|
+
if (options.accountIndex < 0 || !Number.isInteger(options.accountIndex)) {
|
|
281
|
+
throw new ValidationError(
|
|
282
|
+
'accountIndex must be a non-negative integer',
|
|
283
|
+
'accountIndex'
|
|
284
|
+
)
|
|
285
|
+
}
|
|
286
|
+
derivationPath = `m/44'/501'/${options.accountIndex}'/0'`
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
validateDerivationPath(derivationPath)
|
|
290
|
+
|
|
291
|
+
// Convert mnemonic to seed (normalize whitespace and case)
|
|
292
|
+
const normalizedMnemonic = options.mnemonic.trim().toLowerCase().split(/\s+/).join(' ')
|
|
293
|
+
const seed = mnemonicToSeedSync(normalizedMnemonic, options.passphrase)
|
|
294
|
+
|
|
295
|
+
let spendingPrivateKeyBytes: Uint8Array | null = null
|
|
296
|
+
let viewingPrivateKeyBytes: Uint8Array | null = null
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
// Derive spending key using SLIP-0010 for ed25519
|
|
300
|
+
spendingPrivateKeyBytes = slip0010DeriveEd25519(seed, derivationPath)
|
|
301
|
+
|
|
302
|
+
// Derive viewing key deterministically from spending key
|
|
303
|
+
// Using HMAC-SHA256 with context ensures:
|
|
304
|
+
// 1. Different key from spending key
|
|
305
|
+
// 2. Deterministic (can be recovered from spending key)
|
|
306
|
+
// 3. Cryptographically secure derivation
|
|
307
|
+
viewingPrivateKeyBytes = hmac(
|
|
308
|
+
sha256,
|
|
309
|
+
new TextEncoder().encode(VIEWING_KEY_CONTEXT),
|
|
310
|
+
spendingPrivateKeyBytes
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
// Derive public keys
|
|
314
|
+
const spendingPublicKey = ed25519.getPublicKey(spendingPrivateKeyBytes)
|
|
315
|
+
const viewingPublicKey = ed25519.getPublicKey(viewingPrivateKeyBytes)
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
metaAddress: {
|
|
319
|
+
spendingKey: `0x${bytesToHex(spendingPublicKey)}` as HexString,
|
|
320
|
+
viewingKey: `0x${bytesToHex(viewingPublicKey)}` as HexString,
|
|
321
|
+
chain: 'solana',
|
|
322
|
+
label: options.label,
|
|
323
|
+
},
|
|
324
|
+
spendingPrivateKey: `0x${bytesToHex(spendingPrivateKeyBytes)}` as HexString,
|
|
325
|
+
viewingPrivateKey: `0x${bytesToHex(viewingPrivateKeyBytes)}` as HexString,
|
|
326
|
+
derivationPath,
|
|
327
|
+
}
|
|
328
|
+
} finally {
|
|
329
|
+
// Secure wipe sensitive data
|
|
330
|
+
secureWipe(seed)
|
|
331
|
+
if (spendingPrivateKeyBytes) secureWipe(spendingPrivateKeyBytes)
|
|
332
|
+
if (viewingPrivateKeyBytes) secureWipe(viewingPrivateKeyBytes)
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Derive viewing key from spending key
|
|
338
|
+
*
|
|
339
|
+
* Useful when you have the spending private key but need to generate
|
|
340
|
+
* the corresponding viewing key.
|
|
341
|
+
*
|
|
342
|
+
* @param spendingPrivateKey - The spending private key
|
|
343
|
+
* @returns The viewing private key
|
|
344
|
+
*/
|
|
345
|
+
export function deriveViewingKeyFromSpending(
|
|
346
|
+
spendingPrivateKey: HexString
|
|
347
|
+
): HexString {
|
|
348
|
+
if (!spendingPrivateKey || !spendingPrivateKey.startsWith('0x')) {
|
|
349
|
+
throw new ValidationError(
|
|
350
|
+
'spendingPrivateKey must be a hex string with 0x prefix',
|
|
351
|
+
'spendingPrivateKey'
|
|
352
|
+
)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const spendingBytes = new Uint8Array(
|
|
356
|
+
(spendingPrivateKey.slice(2).match(/.{2}/g) ?? []).map(b => parseInt(b, 16))
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
if (spendingBytes.length !== 32) {
|
|
360
|
+
throw new ValidationError(
|
|
361
|
+
'spendingPrivateKey must be 32 bytes',
|
|
362
|
+
'spendingPrivateKey'
|
|
363
|
+
)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
const viewingBytes = hmac(
|
|
368
|
+
sha256,
|
|
369
|
+
new TextEncoder().encode(VIEWING_KEY_CONTEXT),
|
|
370
|
+
spendingBytes
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
return `0x${bytesToHex(viewingBytes)}` as HexString
|
|
374
|
+
} finally {
|
|
375
|
+
secureWipe(spendingBytes)
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Generate a new random mnemonic phrase
|
|
381
|
+
*
|
|
382
|
+
* @param strength - Entropy strength in bits (128 = 12 words, 256 = 24 words)
|
|
383
|
+
* @returns A new BIP39 mnemonic phrase
|
|
384
|
+
*/
|
|
385
|
+
export function generateMnemonic(strength: 128 | 256 = 128): string {
|
|
386
|
+
return bip39GenerateMnemonic(english, strength)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Check if a string is a valid BIP39 mnemonic
|
|
391
|
+
*
|
|
392
|
+
* @param mnemonic - The string to check
|
|
393
|
+
* @returns true if valid mnemonic, false otherwise
|
|
394
|
+
*/
|
|
395
|
+
export function isValidMnemonic(mnemonic: string): boolean {
|
|
396
|
+
try {
|
|
397
|
+
validateMnemonic(mnemonic)
|
|
398
|
+
return true
|
|
399
|
+
} catch {
|
|
400
|
+
return false
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Get derivation path for a specific account index
|
|
406
|
+
*
|
|
407
|
+
* @param accountIndex - Account index (0-based)
|
|
408
|
+
* @returns Standard Solana derivation path for that account
|
|
409
|
+
*/
|
|
410
|
+
export function getDerivationPath(accountIndex: number = 0): string {
|
|
411
|
+
if (accountIndex < 0 || !Number.isInteger(accountIndex)) {
|
|
412
|
+
throw new ValidationError(
|
|
413
|
+
'accountIndex must be a non-negative integer',
|
|
414
|
+
'accountIndex'
|
|
415
|
+
)
|
|
416
|
+
}
|
|
417
|
+
return `m/44'/501'/${accountIndex}'/0'`
|
|
418
|
+
}
|