@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.
Files changed (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +267 -0
  3. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  4. package/dist/browser.d.mts +10 -4
  5. package/dist/browser.d.ts +10 -4
  6. package/dist/browser.js +47556 -19603
  7. package/dist/browser.mjs +628 -48
  8. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  9. package/dist/chunk-5D7A3L3W.mjs +717 -0
  10. package/dist/chunk-64AYA5F5.mjs +7834 -0
  11. package/dist/chunk-GMDGB22A.mjs +379 -0
  12. package/dist/chunk-I534WKN7.mjs +328 -0
  13. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  14. package/dist/chunk-PRRZAWJE.mjs +223 -0
  15. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  16. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  17. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  18. package/dist/constants-LHAAUC2T.mjs +51 -0
  19. package/dist/dist-2OGQ7FED.mjs +3957 -0
  20. package/dist/dist-IFHPYLDX.mjs +254 -0
  21. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  22. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  23. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  24. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48396 -19623
  28. package/dist/index.mjs +537 -19
  29. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  30. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  31. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  32. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  33. package/dist/proofs/halo2.d.mts +151 -0
  34. package/dist/proofs/halo2.d.ts +151 -0
  35. package/dist/proofs/halo2.js +350 -0
  36. package/dist/proofs/halo2.mjs +11 -0
  37. package/dist/proofs/kimchi.d.mts +160 -0
  38. package/dist/proofs/kimchi.d.ts +160 -0
  39. package/dist/proofs/kimchi.js +431 -0
  40. package/dist/proofs/kimchi.mjs +13 -0
  41. package/dist/proofs/noir.d.mts +1 -1
  42. package/dist/proofs/noir.d.ts +1 -1
  43. package/dist/proofs/noir.js +74 -18
  44. package/dist/proofs/noir.mjs +84 -24
  45. package/dist/solana-U3MEGU7W.mjs +280 -0
  46. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  47. package/package.json +54 -21
  48. package/src/adapters/index.ts +41 -0
  49. package/src/adapters/jupiter.ts +571 -0
  50. package/src/adapters/near-intents.ts +135 -0
  51. package/src/advisor/advisor.ts +653 -0
  52. package/src/advisor/index.ts +54 -0
  53. package/src/advisor/tools.ts +303 -0
  54. package/src/advisor/types.ts +164 -0
  55. package/src/chains/ethereum/announcement.ts +536 -0
  56. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  57. package/src/chains/ethereum/commitment.ts +522 -0
  58. package/src/chains/ethereum/constants.ts +462 -0
  59. package/src/chains/ethereum/deployment.ts +596 -0
  60. package/src/chains/ethereum/gas-estimation.ts +538 -0
  61. package/src/chains/ethereum/index.ts +268 -0
  62. package/src/chains/ethereum/optimizations.ts +614 -0
  63. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  64. package/src/chains/ethereum/registry.ts +584 -0
  65. package/src/chains/ethereum/rpc.ts +905 -0
  66. package/src/chains/ethereum/stealth.ts +491 -0
  67. package/src/chains/ethereum/token.ts +790 -0
  68. package/src/chains/ethereum/transfer.ts +637 -0
  69. package/src/chains/ethereum/types.ts +456 -0
  70. package/src/chains/ethereum/viewing-key.ts +455 -0
  71. package/src/chains/near/commitment.ts +608 -0
  72. package/src/chains/near/constants.ts +284 -0
  73. package/src/chains/near/function-call.ts +871 -0
  74. package/src/chains/near/history.ts +654 -0
  75. package/src/chains/near/implicit-account.ts +840 -0
  76. package/src/chains/near/index.ts +393 -0
  77. package/src/chains/near/native-transfer.ts +658 -0
  78. package/src/chains/near/nep141.ts +775 -0
  79. package/src/chains/near/privacy-adapter.ts +889 -0
  80. package/src/chains/near/resolver.ts +971 -0
  81. package/src/chains/near/rpc.ts +1016 -0
  82. package/src/chains/near/stealth.ts +419 -0
  83. package/src/chains/near/types.ts +317 -0
  84. package/src/chains/near/viewing-key.ts +876 -0
  85. package/src/chains/solana/anchor-transfer.ts +386 -0
  86. package/src/chains/solana/commitment.ts +577 -0
  87. package/src/chains/solana/constants.ts +126 -12
  88. package/src/chains/solana/ephemeral-keys.ts +543 -0
  89. package/src/chains/solana/index.ts +252 -1
  90. package/src/chains/solana/key-derivation.ts +418 -0
  91. package/src/chains/solana/kit-compat.ts +334 -0
  92. package/src/chains/solana/optimizations.ts +560 -0
  93. package/src/chains/solana/privacy-adapter.ts +605 -0
  94. package/src/chains/solana/providers/generic.ts +47 -6
  95. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  96. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  97. package/src/chains/solana/providers/helius.ts +186 -33
  98. package/src/chains/solana/providers/index.ts +31 -0
  99. package/src/chains/solana/providers/interface.ts +61 -18
  100. package/src/chains/solana/providers/quicknode.ts +409 -0
  101. package/src/chains/solana/providers/triton.ts +426 -0
  102. package/src/chains/solana/providers/webhook.ts +338 -67
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +83 -66
  105. package/src/chains/solana/sol-transfer.ts +732 -0
  106. package/src/chains/solana/spl-transfer.ts +886 -0
  107. package/src/chains/solana/stealth-scanner.ts +703 -0
  108. package/src/chains/solana/sunspot-verifier.ts +453 -0
  109. package/src/chains/solana/transaction-builder.ts +755 -0
  110. package/src/chains/solana/transfer.ts +74 -5
  111. package/src/chains/solana/types.ts +57 -6
  112. package/src/chains/solana/utils.ts +110 -0
  113. package/src/chains/solana/viewing-key.ts +807 -0
  114. package/src/compliance/fireblocks.ts +921 -0
  115. package/src/compliance/index.ts +23 -0
  116. package/src/compliance/range-sas.ts +398 -33
  117. package/src/config/endpoints.ts +100 -0
  118. package/src/crypto.ts +11 -8
  119. package/src/errors.ts +82 -0
  120. package/src/evm/erc4337-relayer.ts +830 -0
  121. package/src/evm/index.ts +47 -0
  122. package/src/fees/calculator.ts +396 -0
  123. package/src/fees/index.ts +87 -0
  124. package/src/fees/near-contract.ts +429 -0
  125. package/src/fees/types.ts +268 -0
  126. package/src/index.ts +686 -1
  127. package/src/intent.ts +6 -3
  128. package/src/logger.ts +324 -0
  129. package/src/network/index.ts +80 -0
  130. package/src/network/proxy.ts +691 -0
  131. package/src/optimizations/index.ts +541 -0
  132. package/src/oracle/types.ts +1 -0
  133. package/src/privacy-backends/arcium-types.ts +727 -0
  134. package/src/privacy-backends/arcium.ts +719 -0
  135. package/src/privacy-backends/combined-privacy.ts +866 -0
  136. package/src/privacy-backends/cspl-token.ts +595 -0
  137. package/src/privacy-backends/cspl-types.ts +512 -0
  138. package/src/privacy-backends/cspl.ts +907 -0
  139. package/src/privacy-backends/health.ts +488 -0
  140. package/src/privacy-backends/inco-types.ts +323 -0
  141. package/src/privacy-backends/inco.ts +616 -0
  142. package/src/privacy-backends/index.ts +254 -4
  143. package/src/privacy-backends/interface.ts +649 -6
  144. package/src/privacy-backends/lru-cache.ts +343 -0
  145. package/src/privacy-backends/magicblock.ts +458 -0
  146. package/src/privacy-backends/mock.ts +258 -0
  147. package/src/privacy-backends/privacycash.ts +13 -17
  148. package/src/privacy-backends/private-swap.ts +570 -0
  149. package/src/privacy-backends/rate-limiter.ts +683 -0
  150. package/src/privacy-backends/registry.ts +414 -2
  151. package/src/privacy-backends/router.ts +283 -3
  152. package/src/privacy-backends/shadowwire.ts +449 -0
  153. package/src/privacy-backends/sip-native.ts +3 -0
  154. package/src/privacy-logger.ts +191 -0
  155. package/src/production-safety.ts +373 -0
  156. package/src/proofs/aggregator.ts +1029 -0
  157. package/src/proofs/browser-composer.ts +1150 -0
  158. package/src/proofs/browser.ts +113 -25
  159. package/src/proofs/cache/index.ts +127 -0
  160. package/src/proofs/cache/interface.ts +545 -0
  161. package/src/proofs/cache/key-generator.ts +188 -0
  162. package/src/proofs/cache/lru-cache.ts +481 -0
  163. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  164. package/src/proofs/cache/persistent-cache.ts +788 -0
  165. package/src/proofs/compliance-proof.ts +872 -0
  166. package/src/proofs/composer/base.ts +923 -0
  167. package/src/proofs/composer/index.ts +25 -0
  168. package/src/proofs/composer/interface.ts +518 -0
  169. package/src/proofs/composer/types.ts +383 -0
  170. package/src/proofs/converters/halo2.ts +452 -0
  171. package/src/proofs/converters/index.ts +208 -0
  172. package/src/proofs/converters/interface.ts +363 -0
  173. package/src/proofs/converters/kimchi.ts +462 -0
  174. package/src/proofs/converters/noir.ts +451 -0
  175. package/src/proofs/fallback.ts +888 -0
  176. package/src/proofs/halo2.ts +42 -0
  177. package/src/proofs/index.ts +471 -0
  178. package/src/proofs/interface.ts +13 -0
  179. package/src/proofs/kimchi.ts +42 -0
  180. package/src/proofs/lazy.ts +1004 -0
  181. package/src/proofs/mock.ts +25 -1
  182. package/src/proofs/noir.ts +110 -29
  183. package/src/proofs/orchestrator.ts +960 -0
  184. package/src/proofs/parallel/concurrency.ts +297 -0
  185. package/src/proofs/parallel/dependency-graph.ts +602 -0
  186. package/src/proofs/parallel/executor.ts +420 -0
  187. package/src/proofs/parallel/index.ts +131 -0
  188. package/src/proofs/parallel/interface.ts +685 -0
  189. package/src/proofs/parallel/worker-pool.ts +644 -0
  190. package/src/proofs/providers/halo2.ts +560 -0
  191. package/src/proofs/providers/index.ts +34 -0
  192. package/src/proofs/providers/kimchi.ts +641 -0
  193. package/src/proofs/validator.ts +881 -0
  194. package/src/proofs/verifier.ts +867 -0
  195. package/src/quantum/index.ts +112 -0
  196. package/src/quantum/winternitz-vault.ts +639 -0
  197. package/src/quantum/wots.ts +611 -0
  198. package/src/settlement/backends/direct-chain.ts +1 -0
  199. package/src/settlement/index.ts +9 -0
  200. package/src/settlement/router.ts +732 -46
  201. package/src/solana/index.ts +72 -0
  202. package/src/solana/jito-relayer.ts +687 -0
  203. package/src/solana/noir-verifier-types.ts +430 -0
  204. package/src/solana/noir-verifier.ts +816 -0
  205. package/src/stealth/address-derivation.ts +193 -0
  206. package/src/stealth/ed25519.ts +431 -0
  207. package/src/stealth/index.ts +233 -0
  208. package/src/stealth/meta-address.ts +221 -0
  209. package/src/stealth/secp256k1.ts +368 -0
  210. package/src/stealth/utils.ts +194 -0
  211. package/src/stealth.ts +50 -1504
  212. package/src/sync/index.ts +106 -0
  213. package/src/sync/manager.ts +504 -0
  214. package/src/sync/mock-provider.ts +318 -0
  215. package/src/sync/oblivious.ts +625 -0
  216. package/src/tokens/index.ts +15 -0
  217. package/src/tokens/registry.ts +301 -0
  218. package/src/utils/deprecation.ts +94 -0
  219. package/src/utils/index.ts +9 -0
  220. package/src/wallet/ethereum/index.ts +68 -0
  221. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  222. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  223. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  224. package/src/wallet/ethereum/types.ts +3 -1
  225. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  226. package/src/wallet/hardware/index.ts +10 -0
  227. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  228. package/src/wallet/index.ts +71 -0
  229. package/src/wallet/near/adapter.ts +626 -0
  230. package/src/wallet/near/index.ts +86 -0
  231. package/src/wallet/near/meteor-wallet.ts +1153 -0
  232. package/src/wallet/near/my-near-wallet.ts +790 -0
  233. package/src/wallet/near/wallet-selector.ts +702 -0
  234. package/src/wallet/solana/adapter.ts +6 -4
  235. package/src/wallet/solana/index.ts +13 -0
  236. package/src/wallet/solana/privacy-adapter.ts +567 -0
  237. package/src/wallet/sui/types.ts +6 -4
  238. package/src/zcash/rpc-client.ts +13 -6
  239. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  240. package/dist/chunk-3INS3PR5.mjs +0 -884
  241. package/dist/chunk-3OVABDRH.mjs +0 -17096
  242. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  243. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  244. package/dist/chunk-E6SZWREQ.mjs +0 -57
  245. package/dist/chunk-F6F73W35.mjs +0 -16166
  246. package/dist/chunk-G33LB27A.mjs +0 -16166
  247. package/dist/chunk-HGU6HZRC.mjs +0 -231
  248. package/dist/chunk-L2K34JCU.mjs +0 -1496
  249. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  250. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  251. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  252. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  253. package/dist/constants-VOI7BSLK.mjs +0 -27
  254. package/dist/index-B71aXVzk.d.ts +0 -13264
  255. package/dist/index-BYZbDjal.d.ts +0 -11390
  256. package/dist/index-CHB3KuOB.d.mts +0 -11859
  257. package/dist/index-CzWPI6Le.d.ts +0 -11859
  258. package/dist/index-pOIIuwfV.d.mts +0 -13264
  259. package/dist/index-xbWjohNq.d.mts +0 -11390
  260. package/dist/solana-4O4K45VU.mjs +0 -46
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-NDABAZ6P.mjs +0 -56
  263. package/dist/solana-Q4NAVBTS.mjs +0 -46
  264. 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
+ }