@sip-protocol/sdk 0.7.3 → 0.8.0
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/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 +44 -11
- 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,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NEAR Stealth Address Generation
|
|
3
|
+
*
|
|
4
|
+
* Implements stealth addresses for NEAR Protocol using ed25519 curve.
|
|
5
|
+
* Stealth addresses are indistinguishable from regular NEAR implicit accounts.
|
|
6
|
+
*
|
|
7
|
+
* NEAR uses ed25519 for all cryptographic operations. Implicit accounts are
|
|
8
|
+
* derived directly from ed25519 public keys (32-byte hex string).
|
|
9
|
+
*
|
|
10
|
+
* @example Generate stealth meta-address
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { generateNEARStealthMetaAddress } from '@sip-protocol/sdk'
|
|
13
|
+
*
|
|
14
|
+
* const { metaAddress, spendingPrivateKey, viewingPrivateKey } =
|
|
15
|
+
* generateNEARStealthMetaAddress()
|
|
16
|
+
*
|
|
17
|
+
* console.log(metaAddress)
|
|
18
|
+
* // => sip:near:0x<spending_key>:0x<viewing_key>
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @example Generate one-time stealth address
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { generateNEARStealthAddress } from '@sip-protocol/sdk'
|
|
24
|
+
*
|
|
25
|
+
* const { stealthAddress, sharedSecret } = generateNEARStealthAddress(metaAddress)
|
|
26
|
+
*
|
|
27
|
+
* // stealthAddress.address is an ed25519 public key (0x-prefixed hex)
|
|
28
|
+
* // Convert to NEAR implicit account:
|
|
29
|
+
* const implicitAccount = stealthAddress.address.slice(2) // Remove 0x prefix
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @packageDocumentation
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import type {
|
|
36
|
+
StealthMetaAddress,
|
|
37
|
+
StealthAddress,
|
|
38
|
+
StealthAddressRecovery,
|
|
39
|
+
HexString,
|
|
40
|
+
} from '@sip-protocol/types'
|
|
41
|
+
import {
|
|
42
|
+
generateEd25519StealthMetaAddress,
|
|
43
|
+
generateEd25519StealthAddress,
|
|
44
|
+
deriveEd25519StealthPrivateKey,
|
|
45
|
+
checkEd25519StealthAddress,
|
|
46
|
+
validateEd25519StealthMetaAddress,
|
|
47
|
+
validateEd25519StealthAddress,
|
|
48
|
+
} from '../../stealth/ed25519'
|
|
49
|
+
import { ValidationError } from '../../errors'
|
|
50
|
+
import { isImplicitAccount } from './constants'
|
|
51
|
+
|
|
52
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* NEAR-specific stealth address result
|
|
56
|
+
*/
|
|
57
|
+
export interface NEARStealthAddressResult {
|
|
58
|
+
/** The one-time stealth address (ed25519 public key) */
|
|
59
|
+
stealthAddress: StealthAddress
|
|
60
|
+
/** Shared secret for deriving the stealth private key */
|
|
61
|
+
sharedSecret: HexString
|
|
62
|
+
/** NEAR implicit account ID (64 hex chars, derived from stealth address) */
|
|
63
|
+
implicitAccountId: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* NEAR stealth meta-address generation result
|
|
68
|
+
*/
|
|
69
|
+
export interface NEARStealthMetaAddressResult {
|
|
70
|
+
/** The stealth meta-address (contains spending and viewing public keys) */
|
|
71
|
+
metaAddress: StealthMetaAddress
|
|
72
|
+
/** Spending private key (keep secret!) */
|
|
73
|
+
spendingPrivateKey: HexString
|
|
74
|
+
/** Viewing private key (can be shared with auditors) */
|
|
75
|
+
viewingPrivateKey: HexString
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ─── Meta-Address Generation ─────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Generate a new NEAR stealth meta-address keypair
|
|
82
|
+
*
|
|
83
|
+
* The meta-address can be shared publicly. It contains:
|
|
84
|
+
* - spendingKey: Used to derive stealth private keys (keep corresponding private key secret!)
|
|
85
|
+
* - viewingKey: Used to scan for incoming payments (can share private key with auditors)
|
|
86
|
+
*
|
|
87
|
+
* @param label - Optional human-readable label for this meta-address
|
|
88
|
+
* @returns Meta-address and private keys
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const result = generateNEARStealthMetaAddress('My NEAR Wallet')
|
|
93
|
+
*
|
|
94
|
+
* // Share metaAddress publicly
|
|
95
|
+
* console.log(result.metaAddress)
|
|
96
|
+
*
|
|
97
|
+
* // Store private keys securely
|
|
98
|
+
* saveSecurely(result.spendingPrivateKey)
|
|
99
|
+
* saveSecurely(result.viewingPrivateKey)
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export function generateNEARStealthMetaAddress(
|
|
103
|
+
label?: string
|
|
104
|
+
): NEARStealthMetaAddressResult {
|
|
105
|
+
return generateEd25519StealthMetaAddress('near', label)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ─── Stealth Address Generation ──────────────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Generate a one-time stealth address for a NEAR recipient
|
|
112
|
+
*
|
|
113
|
+
* The sender uses this to create a fresh address that only the recipient
|
|
114
|
+
* can detect and spend from.
|
|
115
|
+
*
|
|
116
|
+
* @param recipientMetaAddress - Recipient's stealth meta-address
|
|
117
|
+
* @returns Stealth address, shared secret, and NEAR implicit account ID
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* // Sender creates stealth address for recipient
|
|
122
|
+
* const { stealthAddress, implicitAccountId } =
|
|
123
|
+
* generateNEARStealthAddress(recipientMetaAddress)
|
|
124
|
+
*
|
|
125
|
+
* // Send NEAR/tokens to implicitAccountId
|
|
126
|
+
* await nearConnection.sendMoney(implicitAccountId, amount)
|
|
127
|
+
*
|
|
128
|
+
* // Include announcement in memo for recipient to scan
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export function generateNEARStealthAddress(
|
|
132
|
+
recipientMetaAddress: StealthMetaAddress | string
|
|
133
|
+
): NEARStealthAddressResult {
|
|
134
|
+
// Parse if string format
|
|
135
|
+
const metaAddr =
|
|
136
|
+
typeof recipientMetaAddress === 'string'
|
|
137
|
+
? parseNEARStealthMetaAddress(recipientMetaAddress)
|
|
138
|
+
: recipientMetaAddress
|
|
139
|
+
|
|
140
|
+
// Validate it's a NEAR meta-address
|
|
141
|
+
if (metaAddr.chain !== 'near') {
|
|
142
|
+
throw new ValidationError(
|
|
143
|
+
`Expected NEAR meta-address, got chain '${metaAddr.chain}'`,
|
|
144
|
+
'recipientMetaAddress.chain'
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Generate stealth address using ed25519
|
|
149
|
+
const { stealthAddress, sharedSecret } =
|
|
150
|
+
generateEd25519StealthAddress(metaAddr)
|
|
151
|
+
|
|
152
|
+
// Convert to NEAR implicit account ID
|
|
153
|
+
const implicitAccountId = ed25519PublicKeyToImplicitAccount(
|
|
154
|
+
stealthAddress.address
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
stealthAddress,
|
|
159
|
+
sharedSecret,
|
|
160
|
+
implicitAccountId,
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ─── Private Key Derivation ──────────────────────────────────────────────────
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Derive the private key for a NEAR stealth address
|
|
168
|
+
*
|
|
169
|
+
* The recipient uses this to derive the private key that controls
|
|
170
|
+
* the funds sent to a stealth address.
|
|
171
|
+
*
|
|
172
|
+
* @param stealthAddress - The one-time stealth address
|
|
173
|
+
* @param spendingPrivateKey - Recipient's spending private key
|
|
174
|
+
* @param viewingPrivateKey - Recipient's viewing private key
|
|
175
|
+
* @returns Recovery data including the derived private key
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* // Recipient derives private key to spend funds
|
|
180
|
+
* const recovery = deriveNEARStealthPrivateKey(
|
|
181
|
+
* detectedPayment.stealthAddress,
|
|
182
|
+
* mySpendingPrivateKey,
|
|
183
|
+
* myViewingPrivateKey
|
|
184
|
+
* )
|
|
185
|
+
*
|
|
186
|
+
* // Use privateKey to sign NEAR transactions
|
|
187
|
+
* const keypair = nearKeyFromPrivateKey(recovery.privateKey)
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
export function deriveNEARStealthPrivateKey(
|
|
191
|
+
stealthAddress: StealthAddress,
|
|
192
|
+
spendingPrivateKey: HexString,
|
|
193
|
+
viewingPrivateKey: HexString
|
|
194
|
+
): StealthAddressRecovery {
|
|
195
|
+
return deriveEd25519StealthPrivateKey(
|
|
196
|
+
stealthAddress,
|
|
197
|
+
spendingPrivateKey,
|
|
198
|
+
viewingPrivateKey
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ─── Address Checking ────────────────────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Check if a NEAR stealth address was intended for this recipient
|
|
206
|
+
*
|
|
207
|
+
* Efficiently checks if a stealth address belongs to the owner of
|
|
208
|
+
* the given spending/viewing keys.
|
|
209
|
+
*
|
|
210
|
+
* @param stealthAddress - The stealth address to check
|
|
211
|
+
* @param spendingPrivateKey - Recipient's spending private key
|
|
212
|
+
* @param viewingPrivateKey - Recipient's viewing private key
|
|
213
|
+
* @returns True if the address belongs to this recipient
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* // Check if a detected address is for us
|
|
218
|
+
* const isForMe = checkNEARStealthAddress(
|
|
219
|
+
* announcement.stealthAddress,
|
|
220
|
+
* mySpendingPrivateKey,
|
|
221
|
+
* myViewingPrivateKey
|
|
222
|
+
* )
|
|
223
|
+
*
|
|
224
|
+
* if (isForMe) {
|
|
225
|
+
* // Derive private key and claim funds
|
|
226
|
+
* }
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
export function checkNEARStealthAddress(
|
|
230
|
+
stealthAddress: StealthAddress,
|
|
231
|
+
spendingPrivateKey: HexString,
|
|
232
|
+
viewingPrivateKey: HexString
|
|
233
|
+
): boolean {
|
|
234
|
+
return checkEd25519StealthAddress(
|
|
235
|
+
stealthAddress,
|
|
236
|
+
spendingPrivateKey,
|
|
237
|
+
viewingPrivateKey
|
|
238
|
+
)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ─── Address Format Conversion ───────────────────────────────────────────────
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Convert ed25519 public key to NEAR implicit account ID
|
|
245
|
+
*
|
|
246
|
+
* NEAR implicit accounts are the 64-character lowercase hex representation
|
|
247
|
+
* of the ed25519 public key (without 0x prefix).
|
|
248
|
+
*
|
|
249
|
+
* @param publicKey - Ed25519 public key (0x-prefixed hex)
|
|
250
|
+
* @returns NEAR implicit account ID (64 hex chars)
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```typescript
|
|
254
|
+
* const accountId = ed25519PublicKeyToImplicitAccount(
|
|
255
|
+
* '0x1234567890abcdef...'
|
|
256
|
+
* )
|
|
257
|
+
* // => '1234567890abcdef...' (64 chars)
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export function ed25519PublicKeyToImplicitAccount(publicKey: HexString): string {
|
|
261
|
+
// Remove 0x prefix and ensure lowercase
|
|
262
|
+
const hex = publicKey.slice(2).toLowerCase()
|
|
263
|
+
|
|
264
|
+
// Validate length (32 bytes = 64 hex chars)
|
|
265
|
+
if (hex.length !== 64) {
|
|
266
|
+
throw new ValidationError(
|
|
267
|
+
`Invalid ed25519 public key length: expected 64 hex chars, got ${hex.length}`,
|
|
268
|
+
'publicKey'
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Validate hex characters
|
|
273
|
+
if (!/^[0-9a-f]{64}$/.test(hex)) {
|
|
274
|
+
throw new ValidationError(
|
|
275
|
+
'Invalid ed25519 public key: must contain only hex characters',
|
|
276
|
+
'publicKey'
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return hex
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Convert NEAR implicit account ID to ed25519 public key
|
|
285
|
+
*
|
|
286
|
+
* @param accountId - NEAR implicit account ID (64 hex chars)
|
|
287
|
+
* @returns Ed25519 public key (0x-prefixed hex)
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```typescript
|
|
291
|
+
* const publicKey = implicitAccountToEd25519PublicKey(
|
|
292
|
+
* '1234567890abcdef...'
|
|
293
|
+
* )
|
|
294
|
+
* // => '0x1234567890abcdef...'
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
export function implicitAccountToEd25519PublicKey(accountId: string): HexString {
|
|
298
|
+
if (!isImplicitAccount(accountId)) {
|
|
299
|
+
throw new ValidationError(
|
|
300
|
+
'Invalid NEAR implicit account ID: must be 64 lowercase hex characters',
|
|
301
|
+
'accountId'
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return `0x${accountId.toLowerCase()}` as HexString
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ─── Meta-Address Encoding/Decoding ──────────────────────────────────────────
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Encode a NEAR stealth meta-address to string format
|
|
312
|
+
*
|
|
313
|
+
* Format: sip:near:<spendingKey>:<viewingKey>
|
|
314
|
+
*
|
|
315
|
+
* @param metaAddress - The stealth meta-address object
|
|
316
|
+
* @returns Encoded string format
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```typescript
|
|
320
|
+
* const encoded = encodeNEARStealthMetaAddress(metaAddress)
|
|
321
|
+
* // => 'sip:near:0x1234...5678:0xabcd...ef01'
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
export function encodeNEARStealthMetaAddress(
|
|
325
|
+
metaAddress: StealthMetaAddress
|
|
326
|
+
): string {
|
|
327
|
+
validateEd25519StealthMetaAddress(metaAddress)
|
|
328
|
+
|
|
329
|
+
if (metaAddress.chain !== 'near') {
|
|
330
|
+
throw new ValidationError(
|
|
331
|
+
`Expected chain 'near', got '${metaAddress.chain}'`,
|
|
332
|
+
'metaAddress.chain'
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return `sip:near:${metaAddress.spendingKey}:${metaAddress.viewingKey}`
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Decode a NEAR stealth meta-address from string format
|
|
341
|
+
*
|
|
342
|
+
* @param encoded - Encoded string (sip:near:<spendingKey>:<viewingKey>)
|
|
343
|
+
* @returns Parsed stealth meta-address
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const metaAddress = parseNEARStealthMetaAddress(
|
|
348
|
+
* 'sip:near:0x1234...5678:0xabcd...ef01'
|
|
349
|
+
* )
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
export function parseNEARStealthMetaAddress(encoded: string): StealthMetaAddress {
|
|
353
|
+
const parts = encoded.split(':')
|
|
354
|
+
|
|
355
|
+
if (parts.length < 4) {
|
|
356
|
+
throw new ValidationError(
|
|
357
|
+
"Invalid meta-address format: expected 'sip:near:<spendingKey>:<viewingKey>'",
|
|
358
|
+
'encoded'
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const [prefix, chain, spendingKey, viewingKey] = parts
|
|
363
|
+
|
|
364
|
+
if (prefix !== 'sip') {
|
|
365
|
+
throw new ValidationError(
|
|
366
|
+
`Invalid meta-address prefix: expected 'sip', got '${prefix}'`,
|
|
367
|
+
'encoded'
|
|
368
|
+
)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (chain !== 'near') {
|
|
372
|
+
throw new ValidationError(
|
|
373
|
+
`Invalid chain: expected 'near', got '${chain}'`,
|
|
374
|
+
'encoded'
|
|
375
|
+
)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const metaAddress: StealthMetaAddress = {
|
|
379
|
+
spendingKey: spendingKey as HexString,
|
|
380
|
+
viewingKey: viewingKey as HexString,
|
|
381
|
+
chain: 'near',
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Validate the parsed address
|
|
385
|
+
validateEd25519StealthMetaAddress(metaAddress)
|
|
386
|
+
|
|
387
|
+
return metaAddress
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ─── Validation Helpers ──────────────────────────────────────────────────────
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Validate a NEAR stealth meta-address
|
|
394
|
+
*
|
|
395
|
+
* @param metaAddress - The meta-address to validate
|
|
396
|
+
* @throws {ValidationError} If the meta-address is invalid
|
|
397
|
+
*/
|
|
398
|
+
export function validateNEARStealthMetaAddress(
|
|
399
|
+
metaAddress: StealthMetaAddress
|
|
400
|
+
): void {
|
|
401
|
+
validateEd25519StealthMetaAddress(metaAddress, 'metaAddress')
|
|
402
|
+
|
|
403
|
+
if (metaAddress.chain !== 'near') {
|
|
404
|
+
throw new ValidationError(
|
|
405
|
+
`Expected chain 'near', got '${metaAddress.chain}'`,
|
|
406
|
+
'metaAddress.chain'
|
|
407
|
+
)
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Validate a NEAR stealth address
|
|
413
|
+
*
|
|
414
|
+
* @param stealthAddress - The stealth address to validate
|
|
415
|
+
* @throws {ValidationError} If the stealth address is invalid
|
|
416
|
+
*/
|
|
417
|
+
export function validateNEARStealthAddress(stealthAddress: StealthAddress): void {
|
|
418
|
+
validateEd25519StealthAddress(stealthAddress, 'stealthAddress')
|
|
419
|
+
}
|