@sip-protocol/sdk 0.7.3 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +47556 -19603
- package/dist/browser.mjs +628 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
- package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48396 -19623
- package/dist/index.mjs +537 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +54 -21
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +252 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +47 -6
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +186 -33
- package/src/chains/solana/providers/index.ts +31 -0
- package/src/chains/solana/providers/interface.ts +61 -18
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +338 -67
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +83 -66
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +57 -6
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +23 -0
- package/src/compliance/range-sas.ts +398 -33
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +686 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +254 -4
- package/src/privacy-backends/interface.ts +649 -6
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash.ts +13 -17
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +414 -2
- package/src/privacy-backends/router.ts +283 -3
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +3 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +110 -29
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-2XIVXWHA.mjs +0 -1930
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-7RFRWDCW.mjs +0 -1504
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-F6F73W35.mjs +0 -16166
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-OFDBEIEK.mjs +0 -16166
- package/dist/chunk-SF7YSLF5.mjs +0 -1515
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/chunk-WWUSGOXE.mjs +0 -17129
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-B71aXVzk.d.ts +0 -13264
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-pOIIuwfV.d.mts +0 -13264
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-4O4K45VU.mjs +0 -46
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-NDABAZ6P.mjs +0 -56
- package/dist/solana-Q4NAVBTS.mjs +0 -46
- package/dist/solana-ZYO63LY5.mjs +0 -46
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NEAR Privacy Adapter
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates privacy operations for NEAR same-chain transactions.
|
|
5
|
+
* Provides a unified interface for stealth transfers, scanning, and claiming.
|
|
6
|
+
*
|
|
7
|
+
* @module chains/near/privacy-adapter
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { StealthMetaAddress, HexString, StealthAddress } from '@sip-protocol/types'
|
|
11
|
+
import {
|
|
12
|
+
generateNEARStealthMetaAddress,
|
|
13
|
+
generateNEARStealthAddress,
|
|
14
|
+
parseNEARStealthMetaAddress,
|
|
15
|
+
encodeNEARStealthMetaAddress,
|
|
16
|
+
ed25519PublicKeyToImplicitAccount,
|
|
17
|
+
deriveNEARStealthPrivateKey,
|
|
18
|
+
checkNEARStealthAddress,
|
|
19
|
+
} from './stealth'
|
|
20
|
+
import {
|
|
21
|
+
buildPrivateTransfer,
|
|
22
|
+
buildPrivateTokenTransfer,
|
|
23
|
+
buildStorageDeposit,
|
|
24
|
+
deriveStealthAccountKeyPair,
|
|
25
|
+
buildClaimTransaction,
|
|
26
|
+
buildDeleteStealthAccount,
|
|
27
|
+
type NEARPrivateTransferBuild,
|
|
28
|
+
type NEARAction,
|
|
29
|
+
} from './implicit-account'
|
|
30
|
+
import {
|
|
31
|
+
NEARStealthScanner,
|
|
32
|
+
createNEARStealthScanner,
|
|
33
|
+
type NEARScanRecipient,
|
|
34
|
+
type NEARStealthScannerOptions,
|
|
35
|
+
type NEARDetectedPaymentResult,
|
|
36
|
+
} from './resolver'
|
|
37
|
+
import {
|
|
38
|
+
exportNEARViewingKey,
|
|
39
|
+
importNEARViewingKey,
|
|
40
|
+
type NEARViewingKey,
|
|
41
|
+
type NEARViewingKeyExport,
|
|
42
|
+
} from './viewing-key'
|
|
43
|
+
import {
|
|
44
|
+
NEAR_RPC_ENDPOINTS,
|
|
45
|
+
DEFAULT_GAS,
|
|
46
|
+
isValidAccountId,
|
|
47
|
+
getExplorerUrl,
|
|
48
|
+
} from './constants'
|
|
49
|
+
import type { NEARAnnouncement } from './types'
|
|
50
|
+
|
|
51
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Network type (limited to mainnet/testnet for scanner compatibility)
|
|
55
|
+
*/
|
|
56
|
+
export type NEARPrivacyNetwork = 'mainnet' | 'testnet'
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Privacy levels for NEAR transactions
|
|
60
|
+
*/
|
|
61
|
+
export type NEARPrivacyLevel = 'transparent' | 'shielded' | 'compliant'
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Configuration for NEARPrivacyAdapter
|
|
65
|
+
*/
|
|
66
|
+
export interface NEARPrivacyAdapterConfig {
|
|
67
|
+
/**
|
|
68
|
+
* NEAR RPC URL
|
|
69
|
+
*/
|
|
70
|
+
rpcUrl: string
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Network type
|
|
74
|
+
* @default 'mainnet'
|
|
75
|
+
*/
|
|
76
|
+
network?: NEARPrivacyNetwork
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Default privacy level
|
|
80
|
+
* @default 'shielded'
|
|
81
|
+
*/
|
|
82
|
+
defaultPrivacyLevel?: NEARPrivacyLevel
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Custom announcement contract (for future use)
|
|
86
|
+
*/
|
|
87
|
+
announcementContract?: string
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Scanner options
|
|
91
|
+
*/
|
|
92
|
+
scannerOptions?: Partial<NEARStealthScannerOptions>
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parameters for shielded NEAR transfer
|
|
97
|
+
*/
|
|
98
|
+
export interface NEARShieldedTransferParams {
|
|
99
|
+
/**
|
|
100
|
+
* Sender's NEAR account ID
|
|
101
|
+
*/
|
|
102
|
+
senderAccountId: string
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Recipient's stealth meta-address
|
|
106
|
+
*/
|
|
107
|
+
recipient: StealthMetaAddress | string
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Amount in yoctoNEAR
|
|
111
|
+
*/
|
|
112
|
+
amount: bigint
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Privacy level for this transaction
|
|
116
|
+
*/
|
|
117
|
+
privacyLevel?: NEARPrivacyLevel
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Optional memo (visible on-chain)
|
|
121
|
+
*/
|
|
122
|
+
memo?: string
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Parameters for shielded token transfer
|
|
127
|
+
*/
|
|
128
|
+
export interface NEARShieldedTokenTransferParams extends NEARShieldedTransferParams {
|
|
129
|
+
/**
|
|
130
|
+
* NEP-141 token contract address
|
|
131
|
+
*/
|
|
132
|
+
tokenContract: string
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Result of building a shielded transfer
|
|
137
|
+
*/
|
|
138
|
+
export interface NEARShieldedTransferBuild {
|
|
139
|
+
/**
|
|
140
|
+
* Built transfer details
|
|
141
|
+
*/
|
|
142
|
+
transfer: NEARPrivateTransferBuild
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Privacy level used
|
|
146
|
+
*/
|
|
147
|
+
privacyLevel: NEARPrivacyLevel
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Stealth address details
|
|
151
|
+
*/
|
|
152
|
+
stealthAddress: StealthAddress
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Stealth account ID (NEAR implicit account)
|
|
156
|
+
*/
|
|
157
|
+
stealthAccountId: string
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Parameters for claiming a payment
|
|
162
|
+
*/
|
|
163
|
+
export interface NEARAdapterClaimParams {
|
|
164
|
+
/**
|
|
165
|
+
* Detected payment to claim
|
|
166
|
+
*/
|
|
167
|
+
payment: NEARDetectedPaymentResult
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Viewing private key (hex)
|
|
171
|
+
*/
|
|
172
|
+
viewingPrivateKey: HexString
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Spending private key (hex)
|
|
176
|
+
*/
|
|
177
|
+
spendingPrivateKey: HexString
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Destination account ID
|
|
181
|
+
*/
|
|
182
|
+
destinationAccountId: string
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Whether to delete the stealth account after claiming
|
|
186
|
+
* @default true
|
|
187
|
+
*/
|
|
188
|
+
deleteAccount?: boolean
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Gas estimation result
|
|
193
|
+
*/
|
|
194
|
+
export interface NEARGasEstimate {
|
|
195
|
+
/**
|
|
196
|
+
* Estimated gas in gas units
|
|
197
|
+
*/
|
|
198
|
+
gas: bigint
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Estimated cost in yoctoNEAR (at current gas price)
|
|
202
|
+
*/
|
|
203
|
+
estimatedCost: bigint
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Breakdown by action
|
|
207
|
+
*/
|
|
208
|
+
breakdown: {
|
|
209
|
+
action: string
|
|
210
|
+
gas: bigint
|
|
211
|
+
}[]
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Privacy adapter state
|
|
216
|
+
*/
|
|
217
|
+
export interface NEARPrivacyAdapterState {
|
|
218
|
+
/**
|
|
219
|
+
* Whether the adapter is initialized
|
|
220
|
+
*/
|
|
221
|
+
isInitialized: boolean
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Current network
|
|
225
|
+
*/
|
|
226
|
+
network: NEARPrivacyNetwork
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* RPC URL being used
|
|
230
|
+
*/
|
|
231
|
+
rpcUrl: string
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Default privacy level
|
|
235
|
+
*/
|
|
236
|
+
defaultPrivacyLevel: NEARPrivacyLevel
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Number of recipients in the scanner
|
|
240
|
+
*/
|
|
241
|
+
scannerRecipientCount: number
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ─── NEARPrivacyAdapter Class ─────────────────────────────────────────────────
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* NEAR Privacy Adapter
|
|
248
|
+
*
|
|
249
|
+
* Provides a unified interface for privacy operations on NEAR:
|
|
250
|
+
* - Shielded transfers to stealth addresses
|
|
251
|
+
* - Payment scanning and detection
|
|
252
|
+
* - Claiming detected payments
|
|
253
|
+
* - Meta-address and keypair generation
|
|
254
|
+
*
|
|
255
|
+
* @example Basic usage
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const adapter = new NEARPrivacyAdapter({
|
|
258
|
+
* rpcUrl: 'https://rpc.mainnet.near.org',
|
|
259
|
+
* network: 'mainnet',
|
|
260
|
+
* })
|
|
261
|
+
*
|
|
262
|
+
* // Generate meta-address for recipient
|
|
263
|
+
* const { metaAddress, viewingPrivateKey, spendingPrivateKey } =
|
|
264
|
+
* adapter.generateMetaAddress('Primary Wallet')
|
|
265
|
+
*
|
|
266
|
+
* // Build shielded transfer
|
|
267
|
+
* const build = adapter.buildShieldedTransfer({
|
|
268
|
+
* senderAccountId: 'alice.near',
|
|
269
|
+
* recipient: recipientMetaAddress,
|
|
270
|
+
* amount: ONE_NEAR,
|
|
271
|
+
* })
|
|
272
|
+
*
|
|
273
|
+
* // Sign and submit transaction externally
|
|
274
|
+
* const result = await signAndSubmit(build.transfer)
|
|
275
|
+
* ```
|
|
276
|
+
*
|
|
277
|
+
* @example Scanning and claiming
|
|
278
|
+
* ```typescript
|
|
279
|
+
* // Add recipient for scanning
|
|
280
|
+
* adapter.addScanRecipient({
|
|
281
|
+
* viewingPrivateKey,
|
|
282
|
+
* spendingPrivateKey,
|
|
283
|
+
* label: 'Main Wallet',
|
|
284
|
+
* })
|
|
285
|
+
*
|
|
286
|
+
* // Scan announcements
|
|
287
|
+
* const payments = await adapter.scanAnnouncements(announcements)
|
|
288
|
+
*
|
|
289
|
+
* // Claim a payment
|
|
290
|
+
* const claimBuild = adapter.buildClaimTransaction({
|
|
291
|
+
* payment: payments[0],
|
|
292
|
+
* viewingPrivateKey,
|
|
293
|
+
* spendingPrivateKey,
|
|
294
|
+
* destinationAccountId: 'alice.near',
|
|
295
|
+
* })
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
export class NEARPrivacyAdapter {
|
|
299
|
+
private rpcUrl: string
|
|
300
|
+
private network: NEARPrivacyNetwork
|
|
301
|
+
private defaultPrivacyLevel: NEARPrivacyLevel
|
|
302
|
+
private scanner: NEARStealthScanner
|
|
303
|
+
// Reserved for future use when announcement contract is deployed
|
|
304
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
305
|
+
private _announcementContract?: string
|
|
306
|
+
private initialized: boolean = false
|
|
307
|
+
|
|
308
|
+
constructor(config: NEARPrivacyAdapterConfig) {
|
|
309
|
+
this.rpcUrl = config.rpcUrl
|
|
310
|
+
this.network = config.network ?? 'mainnet'
|
|
311
|
+
this.defaultPrivacyLevel = config.defaultPrivacyLevel ?? 'shielded'
|
|
312
|
+
this._announcementContract = config.announcementContract
|
|
313
|
+
|
|
314
|
+
// Initialize scanner
|
|
315
|
+
this.scanner = createNEARStealthScanner({
|
|
316
|
+
rpcUrl: this.rpcUrl,
|
|
317
|
+
network: this.network,
|
|
318
|
+
...config.scannerOptions,
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
this.initialized = true
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ─── Meta-Address Generation ────────────────────────────────────────────────
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Generate a new stealth meta-address
|
|
328
|
+
*
|
|
329
|
+
* Creates a new keypair for receiving private payments.
|
|
330
|
+
* The meta-address can be shared publicly; only the private keys
|
|
331
|
+
* enable scanning and claiming.
|
|
332
|
+
*
|
|
333
|
+
* @param label - Optional label for the address
|
|
334
|
+
* @returns Meta-address and private keys
|
|
335
|
+
*/
|
|
336
|
+
generateMetaAddress(label?: string): {
|
|
337
|
+
metaAddress: StealthMetaAddress
|
|
338
|
+
encoded: string
|
|
339
|
+
viewingPrivateKey: HexString
|
|
340
|
+
spendingPrivateKey: HexString
|
|
341
|
+
} {
|
|
342
|
+
const result = generateNEARStealthMetaAddress(label)
|
|
343
|
+
const encoded = encodeNEARStealthMetaAddress(result.metaAddress)
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
metaAddress: result.metaAddress,
|
|
347
|
+
encoded,
|
|
348
|
+
viewingPrivateKey: result.viewingPrivateKey,
|
|
349
|
+
spendingPrivateKey: result.spendingPrivateKey,
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Parse an encoded meta-address string
|
|
355
|
+
*
|
|
356
|
+
* @param encoded - Encoded meta-address (sip:near:...)
|
|
357
|
+
* @returns Decoded meta-address
|
|
358
|
+
*/
|
|
359
|
+
parseMetaAddress(encoded: string): StealthMetaAddress {
|
|
360
|
+
return parseNEARStealthMetaAddress(encoded)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Encode a meta-address to string format
|
|
365
|
+
*
|
|
366
|
+
* @param metaAddress - Meta-address to encode
|
|
367
|
+
* @returns Encoded string (sip:near:...)
|
|
368
|
+
*/
|
|
369
|
+
encodeMetaAddress(metaAddress: StealthMetaAddress): string {
|
|
370
|
+
return encodeNEARStealthMetaAddress(metaAddress)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ─── Viewing Key Management ─────────────────────────────────────────────────
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Export a viewing key for sharing (compliance)
|
|
377
|
+
*
|
|
378
|
+
* @param viewingKey - Viewing key to export
|
|
379
|
+
* @returns Exportable viewing key data
|
|
380
|
+
*/
|
|
381
|
+
exportViewingKey(viewingKey: NEARViewingKey): NEARViewingKeyExport {
|
|
382
|
+
return exportNEARViewingKey(viewingKey)
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Import a viewing key from export format
|
|
387
|
+
*
|
|
388
|
+
* @param exported - Exported viewing key data
|
|
389
|
+
* @returns Viewing key
|
|
390
|
+
*/
|
|
391
|
+
importViewingKey(exported: NEARViewingKeyExport): NEARViewingKey {
|
|
392
|
+
return importNEARViewingKey(exported)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ─── Stealth Address Resolution ─────────────────────────────────────────────
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Resolve a meta-address to a one-time stealth address
|
|
399
|
+
*
|
|
400
|
+
* Generates a fresh stealth address for the recipient.
|
|
401
|
+
* Each call produces a different, unlinkable address.
|
|
402
|
+
*
|
|
403
|
+
* @param recipient - Recipient's meta-address
|
|
404
|
+
* @returns Stealth address details
|
|
405
|
+
*/
|
|
406
|
+
resolveStealthAddress(recipient: StealthMetaAddress | string): {
|
|
407
|
+
stealthAddress: StealthAddress
|
|
408
|
+
stealthAccountId: string
|
|
409
|
+
sharedSecret: HexString
|
|
410
|
+
} {
|
|
411
|
+
const metaAddress = typeof recipient === 'string'
|
|
412
|
+
? parseNEARStealthMetaAddress(recipient)
|
|
413
|
+
: recipient
|
|
414
|
+
|
|
415
|
+
const { stealthAddress, sharedSecret } = generateNEARStealthAddress(metaAddress)
|
|
416
|
+
|
|
417
|
+
const stealthAccountId = ed25519PublicKeyToImplicitAccount(stealthAddress.address)
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
stealthAddress,
|
|
421
|
+
stealthAccountId,
|
|
422
|
+
sharedSecret,
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Check if a stealth address belongs to a recipient
|
|
428
|
+
*
|
|
429
|
+
* @param stealthAddress - Stealth address object
|
|
430
|
+
* @param spendingPrivateKey - Spending private key (hex)
|
|
431
|
+
* @param viewingPrivateKey - Viewing private key (hex)
|
|
432
|
+
* @returns True if the address belongs to the recipient
|
|
433
|
+
*/
|
|
434
|
+
checkStealthAddress(
|
|
435
|
+
stealthAddress: StealthAddress,
|
|
436
|
+
spendingPrivateKey: HexString,
|
|
437
|
+
viewingPrivateKey: HexString
|
|
438
|
+
): boolean {
|
|
439
|
+
return checkNEARStealthAddress(
|
|
440
|
+
stealthAddress,
|
|
441
|
+
spendingPrivateKey,
|
|
442
|
+
viewingPrivateKey
|
|
443
|
+
)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// ─── Shielded Transfers ─────────────────────────────────────────────────────
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Build a shielded NEAR transfer
|
|
450
|
+
*
|
|
451
|
+
* Creates transaction actions for a private NEAR transfer.
|
|
452
|
+
* The transaction must be signed and submitted externally.
|
|
453
|
+
*
|
|
454
|
+
* @param params - Transfer parameters
|
|
455
|
+
* @returns Built transfer ready for signing
|
|
456
|
+
*/
|
|
457
|
+
buildShieldedTransfer(params: NEARShieldedTransferParams): NEARShieldedTransferBuild {
|
|
458
|
+
const privacyLevel = params.privacyLevel ?? this.defaultPrivacyLevel
|
|
459
|
+
|
|
460
|
+
// For transparent level, throw - use regular transfer instead
|
|
461
|
+
if (privacyLevel === 'transparent') {
|
|
462
|
+
throw new Error('Use regular NEAR transfer for transparent privacy level')
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const metaAddress = typeof params.recipient === 'string'
|
|
466
|
+
? parseNEARStealthMetaAddress(params.recipient)
|
|
467
|
+
: params.recipient
|
|
468
|
+
|
|
469
|
+
const transfer = buildPrivateTransfer(metaAddress, params.amount)
|
|
470
|
+
|
|
471
|
+
return {
|
|
472
|
+
transfer,
|
|
473
|
+
privacyLevel,
|
|
474
|
+
stealthAddress: transfer.stealthAddress,
|
|
475
|
+
stealthAccountId: transfer.stealthAccountId,
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Build a shielded token transfer
|
|
481
|
+
*
|
|
482
|
+
* Creates transaction actions for a private NEP-141 token transfer.
|
|
483
|
+
* The transaction must be signed and submitted externally.
|
|
484
|
+
*
|
|
485
|
+
* @param params - Transfer parameters
|
|
486
|
+
* @returns Built transfer ready for signing
|
|
487
|
+
*/
|
|
488
|
+
buildShieldedTokenTransfer(params: NEARShieldedTokenTransferParams): NEARShieldedTransferBuild {
|
|
489
|
+
const privacyLevel = params.privacyLevel ?? this.defaultPrivacyLevel
|
|
490
|
+
|
|
491
|
+
if (privacyLevel === 'transparent') {
|
|
492
|
+
throw new Error('Use regular NEP-141 transfer for transparent privacy level')
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (!isValidAccountId(params.tokenContract)) {
|
|
496
|
+
throw new Error(`Invalid token contract: ${params.tokenContract}`)
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const metaAddress = typeof params.recipient === 'string'
|
|
500
|
+
? parseNEARStealthMetaAddress(params.recipient)
|
|
501
|
+
: params.recipient
|
|
502
|
+
|
|
503
|
+
const transfer = buildPrivateTokenTransfer(
|
|
504
|
+
metaAddress,
|
|
505
|
+
params.tokenContract,
|
|
506
|
+
params.amount,
|
|
507
|
+
params.memo
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
return {
|
|
511
|
+
transfer,
|
|
512
|
+
privacyLevel,
|
|
513
|
+
stealthAddress: transfer.stealthAddress,
|
|
514
|
+
stealthAccountId: transfer.stealthAccountId,
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Build a storage deposit transaction
|
|
520
|
+
*
|
|
521
|
+
* Required for token transfers to new accounts.
|
|
522
|
+
*
|
|
523
|
+
* @param stealthAccountId - Stealth account to deposit for (64 hex chars)
|
|
524
|
+
* @param tokenContract - Token contract address
|
|
525
|
+
* @param amount - Deposit amount (defaults to STORAGE_DEPOSIT_DEFAULT)
|
|
526
|
+
* @returns Actions for storage deposit
|
|
527
|
+
*/
|
|
528
|
+
buildStorageDeposit(
|
|
529
|
+
stealthAccountId: string,
|
|
530
|
+
tokenContract: string,
|
|
531
|
+
amount?: bigint
|
|
532
|
+
): NEARAction[] {
|
|
533
|
+
return buildStorageDeposit(stealthAccountId, tokenContract, amount)
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// ─── Gas Estimation ─────────────────────────────────────────────────────────
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Estimate gas for a shielded transfer
|
|
540
|
+
*
|
|
541
|
+
* @param isTokenTransfer - Whether this is a token transfer
|
|
542
|
+
* @param needsStorageDeposit - Whether storage deposit is needed
|
|
543
|
+
* @returns Gas estimate
|
|
544
|
+
*/
|
|
545
|
+
estimateTransferGas(
|
|
546
|
+
isTokenTransfer: boolean = false,
|
|
547
|
+
needsStorageDeposit: boolean = false
|
|
548
|
+
): NEARGasEstimate {
|
|
549
|
+
const breakdown: { action: string; gas: bigint }[] = []
|
|
550
|
+
|
|
551
|
+
// Base transfer gas
|
|
552
|
+
const transferGas = isTokenTransfer ? DEFAULT_GAS : 5_000_000_000_000n // 5 TGas for native
|
|
553
|
+
breakdown.push({
|
|
554
|
+
action: isTokenTransfer ? 'ft_transfer' : 'transfer',
|
|
555
|
+
gas: transferGas,
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
// Storage deposit if needed
|
|
559
|
+
let storageGas = 0n
|
|
560
|
+
if (needsStorageDeposit) {
|
|
561
|
+
storageGas = DEFAULT_GAS // 30 TGas
|
|
562
|
+
breakdown.push({
|
|
563
|
+
action: 'storage_deposit',
|
|
564
|
+
gas: storageGas,
|
|
565
|
+
})
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const totalGas = transferGas + storageGas
|
|
569
|
+
|
|
570
|
+
// Estimate cost (rough approximation: 1 yoctoNEAR per gas unit at base price)
|
|
571
|
+
// Actual price depends on network conditions
|
|
572
|
+
const estimatedCost = totalGas / 10_000n // Very rough estimate
|
|
573
|
+
|
|
574
|
+
return {
|
|
575
|
+
gas: totalGas,
|
|
576
|
+
estimatedCost,
|
|
577
|
+
breakdown,
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Estimate gas for claiming a payment
|
|
583
|
+
*
|
|
584
|
+
* @param deleteAccount - Whether the account will be deleted
|
|
585
|
+
* @returns Gas estimate
|
|
586
|
+
*/
|
|
587
|
+
estimateClaimGas(deleteAccount: boolean = true): NEARGasEstimate {
|
|
588
|
+
const breakdown: { action: string; gas: bigint }[] = []
|
|
589
|
+
|
|
590
|
+
// Transfer action
|
|
591
|
+
breakdown.push({
|
|
592
|
+
action: 'transfer',
|
|
593
|
+
gas: 5_000_000_000_000n,
|
|
594
|
+
})
|
|
595
|
+
|
|
596
|
+
// Delete account if requested
|
|
597
|
+
if (deleteAccount) {
|
|
598
|
+
breakdown.push({
|
|
599
|
+
action: 'delete_account',
|
|
600
|
+
gas: 1_000_000_000_000n,
|
|
601
|
+
})
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
const totalGas = breakdown.reduce((sum, b) => sum + b.gas, 0n)
|
|
605
|
+
|
|
606
|
+
return {
|
|
607
|
+
gas: totalGas,
|
|
608
|
+
estimatedCost: totalGas / 10_000n,
|
|
609
|
+
breakdown,
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// ─── Payment Scanning ───────────────────────────────────────────────────────
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Add a recipient to the scanner
|
|
617
|
+
*
|
|
618
|
+
* @param recipient - Recipient keys and label
|
|
619
|
+
*/
|
|
620
|
+
addScanRecipient(recipient: NEARScanRecipient): void {
|
|
621
|
+
this.scanner.addRecipient(recipient)
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Add recipient from a viewing key
|
|
626
|
+
*
|
|
627
|
+
* @param viewingKey - Viewing key
|
|
628
|
+
* @param spendingPrivateKey - Spending private key
|
|
629
|
+
*/
|
|
630
|
+
addRecipientFromViewingKey(
|
|
631
|
+
viewingKey: NEARViewingKey,
|
|
632
|
+
spendingPrivateKey: HexString
|
|
633
|
+
): void {
|
|
634
|
+
this.scanner.addRecipientFromViewingKey(viewingKey, spendingPrivateKey)
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Remove a recipient from the scanner
|
|
639
|
+
*
|
|
640
|
+
* @param label - Recipient label to remove
|
|
641
|
+
*/
|
|
642
|
+
removeScanRecipient(label: string): void {
|
|
643
|
+
this.scanner.removeRecipient(label)
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Get all scan recipients (labels only, keys are sensitive)
|
|
648
|
+
*/
|
|
649
|
+
getScanRecipients(): Array<{ label?: string }> {
|
|
650
|
+
return this.scanner.getRecipients()
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Clear all scan recipients
|
|
655
|
+
*/
|
|
656
|
+
clearScanRecipients(): void {
|
|
657
|
+
this.scanner.clearRecipients()
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Scan a list of announcements against configured recipients
|
|
662
|
+
*
|
|
663
|
+
* @param announcements - Announcements to check
|
|
664
|
+
* @param txMetadata - Optional transaction metadata
|
|
665
|
+
* @returns Detected payments
|
|
666
|
+
*/
|
|
667
|
+
async scanAnnouncements(
|
|
668
|
+
announcements: NEARAnnouncement[],
|
|
669
|
+
txMetadata?: Array<{
|
|
670
|
+
txHash: string
|
|
671
|
+
blockHeight: number
|
|
672
|
+
timestamp: number
|
|
673
|
+
amount?: bigint
|
|
674
|
+
tokenContract?: string
|
|
675
|
+
decimals?: number
|
|
676
|
+
}>
|
|
677
|
+
): Promise<NEARDetectedPaymentResult[]> {
|
|
678
|
+
return this.scanner.scanAnnouncements(announcements, txMetadata)
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Get balance of a stealth address
|
|
683
|
+
*
|
|
684
|
+
* @param stealthAddress - Stealth address (implicit account ID)
|
|
685
|
+
* @returns Balance in yoctoNEAR
|
|
686
|
+
*/
|
|
687
|
+
async getStealthAddressBalance(stealthAddress: string): Promise<bigint> {
|
|
688
|
+
return this.scanner.getStealthAddressBalance(stealthAddress)
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Get current block height
|
|
693
|
+
*
|
|
694
|
+
* @returns Current block height
|
|
695
|
+
*/
|
|
696
|
+
async getCurrentBlockHeight(): Promise<number> {
|
|
697
|
+
return this.scanner.getCurrentBlockHeight()
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Enable caching for announcements
|
|
702
|
+
*/
|
|
703
|
+
enableCache(): void {
|
|
704
|
+
this.scanner.enableCache()
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Disable caching
|
|
709
|
+
*/
|
|
710
|
+
disableCache(): void {
|
|
711
|
+
this.scanner.disableCache()
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// ─── Payment Claiming ───────────────────────────────────────────────────────
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Build a claim transaction
|
|
718
|
+
*
|
|
719
|
+
* Derives the stealth private key and creates transaction actions
|
|
720
|
+
* to transfer funds to the destination.
|
|
721
|
+
*
|
|
722
|
+
* @param params - Claim parameters
|
|
723
|
+
* @returns Claim transaction build
|
|
724
|
+
*/
|
|
725
|
+
buildClaimTransaction(params: NEARAdapterClaimParams): {
|
|
726
|
+
stealthAccountId: string
|
|
727
|
+
stealthPrivateKey: HexString
|
|
728
|
+
actions: NEARAction[]
|
|
729
|
+
destinationAccountId: string
|
|
730
|
+
} {
|
|
731
|
+
const deleteAccount = params.deleteAccount ?? true
|
|
732
|
+
|
|
733
|
+
// Construct StealthAddress from payment data
|
|
734
|
+
const stealthAddress: StealthAddress = {
|
|
735
|
+
address: params.payment.stealthPublicKey,
|
|
736
|
+
ephemeralPublicKey: params.payment.ephemeralPublicKey,
|
|
737
|
+
viewTag: params.payment.viewTag,
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// Derive the stealth private key
|
|
741
|
+
const { privateKey: stealthPrivateKey } = deriveStealthAccountKeyPair({
|
|
742
|
+
stealthAddress,
|
|
743
|
+
viewingPrivateKey: params.viewingPrivateKey,
|
|
744
|
+
spendingPrivateKey: params.spendingPrivateKey,
|
|
745
|
+
})
|
|
746
|
+
|
|
747
|
+
// Build claim or delete transaction
|
|
748
|
+
let actions: NEARAction[]
|
|
749
|
+
|
|
750
|
+
if (deleteAccount) {
|
|
751
|
+
actions = buildDeleteStealthAccount(
|
|
752
|
+
params.payment.stealthAddress,
|
|
753
|
+
params.destinationAccountId
|
|
754
|
+
)
|
|
755
|
+
} else {
|
|
756
|
+
const claimBuild = buildClaimTransaction({
|
|
757
|
+
stealthAccountId: params.payment.stealthAddress,
|
|
758
|
+
destinationAccountId: params.destinationAccountId,
|
|
759
|
+
amount: params.payment.amount,
|
|
760
|
+
})
|
|
761
|
+
actions = claimBuild.actions
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
return {
|
|
765
|
+
stealthAccountId: params.payment.stealthAddress,
|
|
766
|
+
stealthPrivateKey,
|
|
767
|
+
actions,
|
|
768
|
+
destinationAccountId: params.destinationAccountId,
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Derive the private key for a stealth address
|
|
774
|
+
*
|
|
775
|
+
* @param stealthAddress - Stealth address object
|
|
776
|
+
* @param spendingPrivateKey - Spending private key
|
|
777
|
+
* @param viewingPrivateKey - Viewing private key
|
|
778
|
+
* @returns Derived stealth address recovery with private key
|
|
779
|
+
*/
|
|
780
|
+
deriveStealthPrivateKey(
|
|
781
|
+
stealthAddress: StealthAddress,
|
|
782
|
+
spendingPrivateKey: HexString,
|
|
783
|
+
viewingPrivateKey: HexString
|
|
784
|
+
): { stealthAddress: HexString; ephemeralPublicKey: HexString; privateKey: HexString } {
|
|
785
|
+
return deriveNEARStealthPrivateKey(
|
|
786
|
+
stealthAddress,
|
|
787
|
+
spendingPrivateKey,
|
|
788
|
+
viewingPrivateKey
|
|
789
|
+
)
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// ─── State & Utilities ──────────────────────────────────────────────────────
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Get adapter state
|
|
796
|
+
*/
|
|
797
|
+
getState(): NEARPrivacyAdapterState {
|
|
798
|
+
return {
|
|
799
|
+
isInitialized: this.initialized,
|
|
800
|
+
network: this.network,
|
|
801
|
+
rpcUrl: this.rpcUrl,
|
|
802
|
+
defaultPrivacyLevel: this.defaultPrivacyLevel,
|
|
803
|
+
scannerRecipientCount: this.scanner.getRecipients().length,
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Get the RPC URL
|
|
809
|
+
*/
|
|
810
|
+
getRpcUrl(): string {
|
|
811
|
+
return this.rpcUrl
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Get the network
|
|
816
|
+
*/
|
|
817
|
+
getNetwork(): NEARPrivacyNetwork {
|
|
818
|
+
return this.network
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Get explorer URL for a transaction
|
|
823
|
+
*/
|
|
824
|
+
getTransactionExplorerUrl(txHash: string): string {
|
|
825
|
+
return getExplorerUrl(txHash, this.network)
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Get the default RPC URL for a network
|
|
830
|
+
*/
|
|
831
|
+
static getDefaultRpcUrl(network: NEARPrivacyNetwork): string {
|
|
832
|
+
return NEAR_RPC_ENDPOINTS[network]
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Dispose of the adapter and clean up resources
|
|
837
|
+
*/
|
|
838
|
+
dispose(): void {
|
|
839
|
+
this.scanner.clearRecipients()
|
|
840
|
+
this.initialized = false
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// ─── Factory Function ─────────────────────────────────────────────────────────
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Create a new NEAR privacy adapter
|
|
848
|
+
*
|
|
849
|
+
* @param config - Adapter configuration
|
|
850
|
+
* @returns Configured privacy adapter
|
|
851
|
+
*
|
|
852
|
+
* @example
|
|
853
|
+
* ```typescript
|
|
854
|
+
* const adapter = createNEARPrivacyAdapter({
|
|
855
|
+
* rpcUrl: 'https://rpc.mainnet.near.org',
|
|
856
|
+
* network: 'mainnet',
|
|
857
|
+
* defaultPrivacyLevel: 'shielded',
|
|
858
|
+
* })
|
|
859
|
+
* ```
|
|
860
|
+
*/
|
|
861
|
+
export function createNEARPrivacyAdapter(
|
|
862
|
+
config: NEARPrivacyAdapterConfig
|
|
863
|
+
): NEARPrivacyAdapter {
|
|
864
|
+
return new NEARPrivacyAdapter(config)
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Create a NEAR privacy adapter with default mainnet configuration
|
|
869
|
+
*
|
|
870
|
+
* @returns Configured privacy adapter for mainnet
|
|
871
|
+
*/
|
|
872
|
+
export function createMainnetNEARPrivacyAdapter(): NEARPrivacyAdapter {
|
|
873
|
+
return new NEARPrivacyAdapter({
|
|
874
|
+
rpcUrl: NEAR_RPC_ENDPOINTS.mainnet,
|
|
875
|
+
network: 'mainnet',
|
|
876
|
+
})
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* Create a NEAR privacy adapter with default testnet configuration
|
|
881
|
+
*
|
|
882
|
+
* @returns Configured privacy adapter for testnet
|
|
883
|
+
*/
|
|
884
|
+
export function createTestnetNEARPrivacyAdapter(): NEARPrivacyAdapter {
|
|
885
|
+
return new NEARPrivacyAdapter({
|
|
886
|
+
rpcUrl: NEAR_RPC_ENDPOINTS.testnet,
|
|
887
|
+
network: 'testnet',
|
|
888
|
+
})
|
|
889
|
+
}
|