@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.
Files changed (263) hide show
  1. package/README.md +267 -0
  2. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  3. package/dist/browser.d.mts +10 -4
  4. package/dist/browser.d.ts +10 -4
  5. package/dist/browser.js +47556 -19603
  6. package/dist/browser.mjs +628 -48
  7. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  8. package/dist/chunk-5D7A3L3W.mjs +717 -0
  9. package/dist/chunk-64AYA5F5.mjs +7834 -0
  10. package/dist/chunk-GMDGB22A.mjs +379 -0
  11. package/dist/chunk-I534WKN7.mjs +328 -0
  12. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  13. package/dist/chunk-PRRZAWJE.mjs +223 -0
  14. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  15. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  16. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  17. package/dist/constants-LHAAUC2T.mjs +51 -0
  18. package/dist/dist-2OGQ7FED.mjs +3957 -0
  19. package/dist/dist-IFHPYLDX.mjs +254 -0
  20. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  21. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  22. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  23. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  24. package/dist/index.d.mts +9 -3
  25. package/dist/index.d.ts +9 -3
  26. package/dist/index.js +48396 -19623
  27. package/dist/index.mjs +537 -19
  28. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  29. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  30. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  31. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  32. package/dist/proofs/halo2.d.mts +151 -0
  33. package/dist/proofs/halo2.d.ts +151 -0
  34. package/dist/proofs/halo2.js +350 -0
  35. package/dist/proofs/halo2.mjs +11 -0
  36. package/dist/proofs/kimchi.d.mts +160 -0
  37. package/dist/proofs/kimchi.d.ts +160 -0
  38. package/dist/proofs/kimchi.js +431 -0
  39. package/dist/proofs/kimchi.mjs +13 -0
  40. package/dist/proofs/noir.d.mts +1 -1
  41. package/dist/proofs/noir.d.ts +1 -1
  42. package/dist/proofs/noir.js +74 -18
  43. package/dist/proofs/noir.mjs +84 -24
  44. package/dist/solana-U3MEGU7W.mjs +280 -0
  45. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  46. package/package.json +44 -11
  47. package/src/adapters/index.ts +41 -0
  48. package/src/adapters/jupiter.ts +571 -0
  49. package/src/adapters/near-intents.ts +135 -0
  50. package/src/advisor/advisor.ts +653 -0
  51. package/src/advisor/index.ts +54 -0
  52. package/src/advisor/tools.ts +303 -0
  53. package/src/advisor/types.ts +164 -0
  54. package/src/chains/ethereum/announcement.ts +536 -0
  55. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  56. package/src/chains/ethereum/commitment.ts +522 -0
  57. package/src/chains/ethereum/constants.ts +462 -0
  58. package/src/chains/ethereum/deployment.ts +596 -0
  59. package/src/chains/ethereum/gas-estimation.ts +538 -0
  60. package/src/chains/ethereum/index.ts +268 -0
  61. package/src/chains/ethereum/optimizations.ts +614 -0
  62. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  63. package/src/chains/ethereum/registry.ts +584 -0
  64. package/src/chains/ethereum/rpc.ts +905 -0
  65. package/src/chains/ethereum/stealth.ts +491 -0
  66. package/src/chains/ethereum/token.ts +790 -0
  67. package/src/chains/ethereum/transfer.ts +637 -0
  68. package/src/chains/ethereum/types.ts +456 -0
  69. package/src/chains/ethereum/viewing-key.ts +455 -0
  70. package/src/chains/near/commitment.ts +608 -0
  71. package/src/chains/near/constants.ts +284 -0
  72. package/src/chains/near/function-call.ts +871 -0
  73. package/src/chains/near/history.ts +654 -0
  74. package/src/chains/near/implicit-account.ts +840 -0
  75. package/src/chains/near/index.ts +393 -0
  76. package/src/chains/near/native-transfer.ts +658 -0
  77. package/src/chains/near/nep141.ts +775 -0
  78. package/src/chains/near/privacy-adapter.ts +889 -0
  79. package/src/chains/near/resolver.ts +971 -0
  80. package/src/chains/near/rpc.ts +1016 -0
  81. package/src/chains/near/stealth.ts +419 -0
  82. package/src/chains/near/types.ts +317 -0
  83. package/src/chains/near/viewing-key.ts +876 -0
  84. package/src/chains/solana/anchor-transfer.ts +386 -0
  85. package/src/chains/solana/commitment.ts +577 -0
  86. package/src/chains/solana/constants.ts +126 -12
  87. package/src/chains/solana/ephemeral-keys.ts +543 -0
  88. package/src/chains/solana/index.ts +252 -1
  89. package/src/chains/solana/key-derivation.ts +418 -0
  90. package/src/chains/solana/kit-compat.ts +334 -0
  91. package/src/chains/solana/optimizations.ts +560 -0
  92. package/src/chains/solana/privacy-adapter.ts +605 -0
  93. package/src/chains/solana/providers/generic.ts +47 -6
  94. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  95. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  96. package/src/chains/solana/providers/helius.ts +186 -33
  97. package/src/chains/solana/providers/index.ts +31 -0
  98. package/src/chains/solana/providers/interface.ts +61 -18
  99. package/src/chains/solana/providers/quicknode.ts +409 -0
  100. package/src/chains/solana/providers/triton.ts +426 -0
  101. package/src/chains/solana/providers/webhook.ts +338 -67
  102. package/src/chains/solana/rpc-client.ts +1150 -0
  103. package/src/chains/solana/scan.ts +83 -66
  104. package/src/chains/solana/sol-transfer.ts +732 -0
  105. package/src/chains/solana/spl-transfer.ts +886 -0
  106. package/src/chains/solana/stealth-scanner.ts +703 -0
  107. package/src/chains/solana/sunspot-verifier.ts +453 -0
  108. package/src/chains/solana/transaction-builder.ts +755 -0
  109. package/src/chains/solana/transfer.ts +74 -5
  110. package/src/chains/solana/types.ts +57 -6
  111. package/src/chains/solana/utils.ts +110 -0
  112. package/src/chains/solana/viewing-key.ts +807 -0
  113. package/src/compliance/fireblocks.ts +921 -0
  114. package/src/compliance/index.ts +23 -0
  115. package/src/compliance/range-sas.ts +398 -33
  116. package/src/config/endpoints.ts +100 -0
  117. package/src/crypto.ts +11 -8
  118. package/src/errors.ts +82 -0
  119. package/src/evm/erc4337-relayer.ts +830 -0
  120. package/src/evm/index.ts +47 -0
  121. package/src/fees/calculator.ts +396 -0
  122. package/src/fees/index.ts +87 -0
  123. package/src/fees/near-contract.ts +429 -0
  124. package/src/fees/types.ts +268 -0
  125. package/src/index.ts +686 -1
  126. package/src/intent.ts +6 -3
  127. package/src/logger.ts +324 -0
  128. package/src/network/index.ts +80 -0
  129. package/src/network/proxy.ts +691 -0
  130. package/src/optimizations/index.ts +541 -0
  131. package/src/oracle/types.ts +1 -0
  132. package/src/privacy-backends/arcium-types.ts +727 -0
  133. package/src/privacy-backends/arcium.ts +719 -0
  134. package/src/privacy-backends/combined-privacy.ts +866 -0
  135. package/src/privacy-backends/cspl-token.ts +595 -0
  136. package/src/privacy-backends/cspl-types.ts +512 -0
  137. package/src/privacy-backends/cspl.ts +907 -0
  138. package/src/privacy-backends/health.ts +488 -0
  139. package/src/privacy-backends/inco-types.ts +323 -0
  140. package/src/privacy-backends/inco.ts +616 -0
  141. package/src/privacy-backends/index.ts +254 -4
  142. package/src/privacy-backends/interface.ts +649 -6
  143. package/src/privacy-backends/lru-cache.ts +343 -0
  144. package/src/privacy-backends/magicblock.ts +458 -0
  145. package/src/privacy-backends/mock.ts +258 -0
  146. package/src/privacy-backends/privacycash.ts +13 -17
  147. package/src/privacy-backends/private-swap.ts +570 -0
  148. package/src/privacy-backends/rate-limiter.ts +683 -0
  149. package/src/privacy-backends/registry.ts +414 -2
  150. package/src/privacy-backends/router.ts +283 -3
  151. package/src/privacy-backends/shadowwire.ts +449 -0
  152. package/src/privacy-backends/sip-native.ts +3 -0
  153. package/src/privacy-logger.ts +191 -0
  154. package/src/production-safety.ts +373 -0
  155. package/src/proofs/aggregator.ts +1029 -0
  156. package/src/proofs/browser-composer.ts +1150 -0
  157. package/src/proofs/browser.ts +113 -25
  158. package/src/proofs/cache/index.ts +127 -0
  159. package/src/proofs/cache/interface.ts +545 -0
  160. package/src/proofs/cache/key-generator.ts +188 -0
  161. package/src/proofs/cache/lru-cache.ts +481 -0
  162. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  163. package/src/proofs/cache/persistent-cache.ts +788 -0
  164. package/src/proofs/compliance-proof.ts +872 -0
  165. package/src/proofs/composer/base.ts +923 -0
  166. package/src/proofs/composer/index.ts +25 -0
  167. package/src/proofs/composer/interface.ts +518 -0
  168. package/src/proofs/composer/types.ts +383 -0
  169. package/src/proofs/converters/halo2.ts +452 -0
  170. package/src/proofs/converters/index.ts +208 -0
  171. package/src/proofs/converters/interface.ts +363 -0
  172. package/src/proofs/converters/kimchi.ts +462 -0
  173. package/src/proofs/converters/noir.ts +451 -0
  174. package/src/proofs/fallback.ts +888 -0
  175. package/src/proofs/halo2.ts +42 -0
  176. package/src/proofs/index.ts +471 -0
  177. package/src/proofs/interface.ts +13 -0
  178. package/src/proofs/kimchi.ts +42 -0
  179. package/src/proofs/lazy.ts +1004 -0
  180. package/src/proofs/mock.ts +25 -1
  181. package/src/proofs/noir.ts +110 -29
  182. package/src/proofs/orchestrator.ts +960 -0
  183. package/src/proofs/parallel/concurrency.ts +297 -0
  184. package/src/proofs/parallel/dependency-graph.ts +602 -0
  185. package/src/proofs/parallel/executor.ts +420 -0
  186. package/src/proofs/parallel/index.ts +131 -0
  187. package/src/proofs/parallel/interface.ts +685 -0
  188. package/src/proofs/parallel/worker-pool.ts +644 -0
  189. package/src/proofs/providers/halo2.ts +560 -0
  190. package/src/proofs/providers/index.ts +34 -0
  191. package/src/proofs/providers/kimchi.ts +641 -0
  192. package/src/proofs/validator.ts +881 -0
  193. package/src/proofs/verifier.ts +867 -0
  194. package/src/quantum/index.ts +112 -0
  195. package/src/quantum/winternitz-vault.ts +639 -0
  196. package/src/quantum/wots.ts +611 -0
  197. package/src/settlement/backends/direct-chain.ts +1 -0
  198. package/src/settlement/index.ts +9 -0
  199. package/src/settlement/router.ts +732 -46
  200. package/src/solana/index.ts +72 -0
  201. package/src/solana/jito-relayer.ts +687 -0
  202. package/src/solana/noir-verifier-types.ts +430 -0
  203. package/src/solana/noir-verifier.ts +816 -0
  204. package/src/stealth/address-derivation.ts +193 -0
  205. package/src/stealth/ed25519.ts +431 -0
  206. package/src/stealth/index.ts +233 -0
  207. package/src/stealth/meta-address.ts +221 -0
  208. package/src/stealth/secp256k1.ts +368 -0
  209. package/src/stealth/utils.ts +194 -0
  210. package/src/stealth.ts +50 -1504
  211. package/src/sync/index.ts +106 -0
  212. package/src/sync/manager.ts +504 -0
  213. package/src/sync/mock-provider.ts +318 -0
  214. package/src/sync/oblivious.ts +625 -0
  215. package/src/tokens/index.ts +15 -0
  216. package/src/tokens/registry.ts +301 -0
  217. package/src/utils/deprecation.ts +94 -0
  218. package/src/utils/index.ts +9 -0
  219. package/src/wallet/ethereum/index.ts +68 -0
  220. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  221. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  222. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  223. package/src/wallet/ethereum/types.ts +3 -1
  224. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  225. package/src/wallet/hardware/index.ts +10 -0
  226. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  227. package/src/wallet/index.ts +71 -0
  228. package/src/wallet/near/adapter.ts +626 -0
  229. package/src/wallet/near/index.ts +86 -0
  230. package/src/wallet/near/meteor-wallet.ts +1153 -0
  231. package/src/wallet/near/my-near-wallet.ts +790 -0
  232. package/src/wallet/near/wallet-selector.ts +702 -0
  233. package/src/wallet/solana/adapter.ts +6 -4
  234. package/src/wallet/solana/index.ts +13 -0
  235. package/src/wallet/solana/privacy-adapter.ts +567 -0
  236. package/src/wallet/sui/types.ts +6 -4
  237. package/src/zcash/rpc-client.ts +13 -6
  238. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  239. package/dist/chunk-3INS3PR5.mjs +0 -884
  240. package/dist/chunk-3OVABDRH.mjs +0 -17096
  241. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  242. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  243. package/dist/chunk-E6SZWREQ.mjs +0 -57
  244. package/dist/chunk-F6F73W35.mjs +0 -16166
  245. package/dist/chunk-G33LB27A.mjs +0 -16166
  246. package/dist/chunk-HGU6HZRC.mjs +0 -231
  247. package/dist/chunk-L2K34JCU.mjs +0 -1496
  248. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  249. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  250. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  251. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  252. package/dist/constants-VOI7BSLK.mjs +0 -27
  253. package/dist/index-B71aXVzk.d.ts +0 -13264
  254. package/dist/index-BYZbDjal.d.ts +0 -11390
  255. package/dist/index-CHB3KuOB.d.mts +0 -11859
  256. package/dist/index-CzWPI6Le.d.ts +0 -11859
  257. package/dist/index-pOIIuwfV.d.mts +0 -13264
  258. package/dist/index-xbWjohNq.d.mts +0 -11390
  259. package/dist/solana-4O4K45VU.mjs +0 -46
  260. package/dist/solana-5EMCTPTS.mjs +0 -46
  261. package/dist/solana-NDABAZ6P.mjs +0 -56
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
  263. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -0,0 +1,658 @@
1
+ /**
2
+ * NEAR Native Transfer with Stealth Addresses
3
+ *
4
+ * Privacy-preserving NEAR native token transfers using stealth addresses.
5
+ * Extends basic transfer functionality with:
6
+ * - Amount commitments for hidden transfer values
7
+ * - Batch transfers to multiple stealth addresses
8
+ * - Gas sponsorship for sender anonymity
9
+ * - Minimum balance handling for account creation
10
+ *
11
+ * @example Private NEAR transfer with commitment
12
+ * ```typescript
13
+ * import { buildPrivateNativeTransferWithCommitment } from '@sip-protocol/sdk'
14
+ *
15
+ * const result = buildPrivateNativeTransferWithCommitment({
16
+ * recipientMetaAddress: 'sip:near:0x...:0x...',
17
+ * amount: ONE_NEAR,
18
+ * hideAmount: true,
19
+ * })
20
+ *
21
+ * // result.commitment contains the hidden amount
22
+ * // result.transfer contains the transaction actions
23
+ * ```
24
+ *
25
+ * @example Batch NEAR transfers
26
+ * ```typescript
27
+ * import { buildBatchPrivateNativeTransfer } from '@sip-protocol/sdk'
28
+ *
29
+ * const result = buildBatchPrivateNativeTransfer({
30
+ * transfers: [
31
+ * { recipientMetaAddress: 'sip:near:0x...', amount: ONE_NEAR },
32
+ * { recipientMetaAddress: 'sip:near:0x...', amount: 2n * ONE_NEAR },
33
+ * ],
34
+ * hideAmounts: true,
35
+ * })
36
+ * ```
37
+ *
38
+ * @packageDocumentation
39
+ */
40
+
41
+ import type { StealthAddress, StealthMetaAddress } from '@sip-protocol/types'
42
+ import { ValidationError } from '../../errors'
43
+ import { generateNEARStealthAddress, parseNEARStealthMetaAddress } from './stealth'
44
+ import { createAnnouncementMemo } from './types'
45
+ import { commitNEAR, verifyOpeningNEAR, type NEARPedersenCommitment } from './commitment'
46
+ import type {
47
+ NEARAction,
48
+ NEARTransferAction,
49
+ NEARPrivateTransferBuild,
50
+ } from './implicit-account'
51
+
52
+ // ─── Types ────────────────────────────────────────────────────────────────────
53
+
54
+ /**
55
+ * Parameters for a privacy-wrapped native NEAR transfer with commitment
56
+ */
57
+ export interface PrivateNativeTransferWithCommitmentParams {
58
+ /** Recipient's stealth meta-address */
59
+ recipientMetaAddress: StealthMetaAddress | string
60
+ /** Amount in yoctoNEAR */
61
+ amount: bigint
62
+ /** Whether to create a Pedersen commitment for the amount (default: true) */
63
+ hideAmount?: boolean
64
+ /** Optional pre-generated blinding factor */
65
+ blinding?: Uint8Array
66
+ }
67
+
68
+ /**
69
+ * Result of building a privacy-wrapped native NEAR transfer with commitment
70
+ */
71
+ export interface PrivateNativeTransferWithCommitmentResult {
72
+ /** The transfer build (actions, stealth address, etc.) */
73
+ transfer: NEARPrivateTransferBuild
74
+ /** Amount commitment (if hideAmount is true) */
75
+ commitment?: NEARPedersenCommitment
76
+ /** The stealth address */
77
+ stealthAddress: StealthAddress
78
+ /** NEAR implicit account ID */
79
+ stealthAccountId: string
80
+ /** Minimum balance for account creation */
81
+ minimumBalance: bigint
82
+ /** Whether transfer amount meets minimum balance */
83
+ meetsMinimum: boolean
84
+ }
85
+
86
+ /**
87
+ * Parameters for batch native NEAR transfer
88
+ */
89
+ export interface BatchNativeTransferParams {
90
+ /** List of transfers to execute */
91
+ transfers: Array<{
92
+ /** Recipient's stealth meta-address */
93
+ recipientMetaAddress: StealthMetaAddress | string
94
+ /** Amount in yoctoNEAR */
95
+ amount: bigint
96
+ }>
97
+ /** Create commitments for amounts */
98
+ hideAmounts?: boolean
99
+ }
100
+
101
+ /**
102
+ * Result of building batch native NEAR transfers
103
+ */
104
+ export interface BatchNativeTransferResult {
105
+ /** Individual transfer results */
106
+ transfers: Array<{
107
+ stealthAddress: StealthAddress
108
+ stealthAccountId: string
109
+ announcementMemo: string
110
+ amount: bigint
111
+ commitment?: NEARPedersenCommitment
112
+ }>
113
+ /** Combined actions for all transfers (must be sent as separate txs) */
114
+ transactions: Array<{
115
+ receiverId: string
116
+ actions: NEARAction[]
117
+ }>
118
+ /** Total amount being transferred */
119
+ totalAmount: bigint
120
+ /** Number of transfers that meet minimum balance */
121
+ validTransferCount: number
122
+ }
123
+
124
+ /**
125
+ * Parameters for gas-sponsored transfer
126
+ */
127
+ export interface GasSponsoredTransferParams {
128
+ /** Recipient's stealth meta-address */
129
+ recipientMetaAddress: StealthMetaAddress | string
130
+ /** Amount in yoctoNEAR to transfer */
131
+ amount: bigint
132
+ /** Relayer account that will pay for gas */
133
+ relayerAccountId: string
134
+ /** Maximum gas fee the relayer will cover */
135
+ maxRelayerFee?: bigint
136
+ /** Hide amount with commitment */
137
+ hideAmount?: boolean
138
+ }
139
+
140
+ /**
141
+ * Result of building a gas-sponsored transfer
142
+ */
143
+ export interface GasSponsoredTransferResult {
144
+ /** Actions for the relayer to execute */
145
+ relayerActions: NEARAction[]
146
+ /** The stealth address */
147
+ stealthAddress: StealthAddress
148
+ /** NEAR implicit account ID */
149
+ stealthAccountId: string
150
+ /** Announcement memo */
151
+ announcementMemo: string
152
+ /** Amount commitment (if hideAmount is true) */
153
+ commitment?: NEARPedersenCommitment
154
+ /** Estimated relayer fee */
155
+ estimatedFee: bigint
156
+ }
157
+
158
+ /**
159
+ * Account creation cost estimate
160
+ */
161
+ export interface AccountCreationCost {
162
+ /** Minimum balance for account existence */
163
+ minimumBalance: bigint
164
+ /** Storage cost per byte */
165
+ storagePerByte: bigint
166
+ /** Recommended transfer amount */
167
+ recommendedMinimum: bigint
168
+ }
169
+
170
+ // ─── Constants ────────────────────────────────────────────────────────────────
171
+
172
+ /**
173
+ * Minimum balance for implicit account creation (0.00182 NEAR)
174
+ */
175
+ export const IMPLICIT_ACCOUNT_CREATION_COST = 1_820_000_000_000_000_000_000n
176
+
177
+ /**
178
+ * Storage cost per byte on NEAR (0.00001 NEAR = 10^19 yoctoNEAR)
179
+ */
180
+ export const STORAGE_COST_PER_BYTE = 10_000_000_000_000_000_000n
181
+
182
+ /**
183
+ * Recommended minimum for stealth transfers (0.01 NEAR to cover creation + storage)
184
+ */
185
+ export const RECOMMENDED_STEALTH_MINIMUM = 10_000_000_000_000_000_000_000n
186
+
187
+ /**
188
+ * Default gas for relayer operations (100 TGas)
189
+ */
190
+ export const RELAYER_GAS = 100_000_000_000_000n
191
+
192
+ // ─── Privacy-Wrapped Native Transfers ─────────────────────────────────────────
193
+
194
+ /**
195
+ * Build a privacy-wrapped native NEAR transfer with optional amount commitment
196
+ *
197
+ * @param params - Transfer parameters
198
+ * @returns Transfer build with optional commitment
199
+ *
200
+ * @example
201
+ * ```typescript
202
+ * const result = buildPrivateNativeTransferWithCommitment({
203
+ * recipientMetaAddress: 'sip:near:0x...:0x...',
204
+ * amount: ONE_NEAR,
205
+ * hideAmount: true,
206
+ * })
207
+ *
208
+ * // Verify the transfer meets minimum balance
209
+ * if (!result.meetsMinimum) {
210
+ * console.warn('Transfer may fail - below minimum balance')
211
+ * }
212
+ * ```
213
+ */
214
+ export function buildPrivateNativeTransferWithCommitment(
215
+ params: PrivateNativeTransferWithCommitmentParams
216
+ ): PrivateNativeTransferWithCommitmentResult {
217
+ const {
218
+ recipientMetaAddress,
219
+ amount,
220
+ hideAmount = true,
221
+ blinding,
222
+ } = params
223
+
224
+ // Parse meta-address if string
225
+ const metaAddr = typeof recipientMetaAddress === 'string'
226
+ ? parseNEARStealthMetaAddress(recipientMetaAddress)
227
+ : recipientMetaAddress
228
+
229
+ // Validate chain
230
+ if (metaAddr.chain !== 'near') {
231
+ throw new ValidationError(
232
+ `Expected NEAR meta-address, got chain '${metaAddr.chain}'`,
233
+ 'recipientMetaAddress'
234
+ )
235
+ }
236
+
237
+ // Validate amount
238
+ if (amount <= 0n) {
239
+ throw new ValidationError('amount must be greater than 0', 'amount')
240
+ }
241
+
242
+ // Generate stealth address
243
+ const { stealthAddress, implicitAccountId } = generateNEARStealthAddress(metaAddr)
244
+
245
+ // Create announcement memo
246
+ const announcementMemo = createAnnouncementMemo(
247
+ stealthAddress.ephemeralPublicKey,
248
+ stealthAddress.viewTag
249
+ )
250
+
251
+ // Create amount commitment if requested
252
+ let commitment: NEARPedersenCommitment | undefined
253
+ if (hideAmount) {
254
+ commitment = commitNEAR(amount, blinding)
255
+ }
256
+
257
+ // Build transfer action
258
+ const actions: NEARAction[] = [
259
+ {
260
+ type: 'Transfer',
261
+ params: {
262
+ deposit: amount,
263
+ } as NEARTransferAction,
264
+ },
265
+ ]
266
+
267
+ const transfer: NEARPrivateTransferBuild = {
268
+ stealthAddress,
269
+ stealthAccountId: implicitAccountId,
270
+ announcementMemo,
271
+ actions,
272
+ receiverId: implicitAccountId,
273
+ }
274
+
275
+ return {
276
+ transfer,
277
+ commitment,
278
+ stealthAddress,
279
+ stealthAccountId: implicitAccountId,
280
+ minimumBalance: IMPLICIT_ACCOUNT_CREATION_COST,
281
+ meetsMinimum: amount >= IMPLICIT_ACCOUNT_CREATION_COST,
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Build batch privacy-wrapped native NEAR transfers
287
+ *
288
+ * Note: Unlike token batch transfers, native NEAR transfers to different
289
+ * accounts cannot be batched in a single transaction. This returns
290
+ * separate transactions for each transfer.
291
+ *
292
+ * @param params - Batch transfer parameters
293
+ * @returns Batch transfer build with individual transactions
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * const result = buildBatchPrivateNativeTransfer({
298
+ * transfers: [
299
+ * { recipientMetaAddress: meta1, amount: ONE_NEAR },
300
+ * { recipientMetaAddress: meta2, amount: 2n * ONE_NEAR },
301
+ * ],
302
+ * hideAmounts: true,
303
+ * })
304
+ *
305
+ * // Send each transaction
306
+ * for (const tx of result.transactions) {
307
+ * await sendTransaction(tx.receiverId, tx.actions)
308
+ * }
309
+ * ```
310
+ */
311
+ export function buildBatchPrivateNativeTransfer(
312
+ params: BatchNativeTransferParams
313
+ ): BatchNativeTransferResult {
314
+ const {
315
+ transfers,
316
+ hideAmounts = false,
317
+ } = params
318
+
319
+ // Validate transfers
320
+ if (!transfers || transfers.length === 0) {
321
+ throw new ValidationError('At least one transfer is required', 'transfers')
322
+ }
323
+
324
+ if (transfers.length > 100) {
325
+ throw new ValidationError(
326
+ 'Maximum 100 transfers per batch',
327
+ 'transfers'
328
+ )
329
+ }
330
+
331
+ const results: BatchNativeTransferResult['transfers'] = []
332
+ const transactions: BatchNativeTransferResult['transactions'] = []
333
+ let totalAmount = 0n
334
+ let validTransferCount = 0
335
+
336
+ for (const transfer of transfers) {
337
+ const { recipientMetaAddress, amount } = transfer
338
+
339
+ // Parse meta-address if string
340
+ const metaAddr = typeof recipientMetaAddress === 'string'
341
+ ? parseNEARStealthMetaAddress(recipientMetaAddress)
342
+ : recipientMetaAddress
343
+
344
+ // Validate chain
345
+ if (metaAddr.chain !== 'near') {
346
+ throw new ValidationError(
347
+ `Expected NEAR meta-address, got chain '${metaAddr.chain}'`,
348
+ 'recipientMetaAddress'
349
+ )
350
+ }
351
+
352
+ // Validate amount
353
+ if (amount <= 0n) {
354
+ throw new ValidationError('amount must be greater than 0', 'amount')
355
+ }
356
+
357
+ // Generate stealth address
358
+ const { stealthAddress, implicitAccountId } = generateNEARStealthAddress(metaAddr)
359
+
360
+ // Create announcement memo
361
+ const announcementMemo = createAnnouncementMemo(
362
+ stealthAddress.ephemeralPublicKey,
363
+ stealthAddress.viewTag
364
+ )
365
+
366
+ // Create commitment if hiding amounts
367
+ let commitment: NEARPedersenCommitment | undefined
368
+ if (hideAmounts) {
369
+ commitment = commitNEAR(amount)
370
+ }
371
+
372
+ // Build transfer action
373
+ const actions: NEARAction[] = [
374
+ {
375
+ type: 'Transfer',
376
+ params: {
377
+ deposit: amount,
378
+ } as NEARTransferAction,
379
+ },
380
+ ]
381
+
382
+ transactions.push({
383
+ receiverId: implicitAccountId,
384
+ actions,
385
+ })
386
+
387
+ results.push({
388
+ stealthAddress,
389
+ stealthAccountId: implicitAccountId,
390
+ announcementMemo,
391
+ amount,
392
+ commitment,
393
+ })
394
+
395
+ totalAmount += amount
396
+
397
+ if (amount >= IMPLICIT_ACCOUNT_CREATION_COST) {
398
+ validTransferCount++
399
+ }
400
+ }
401
+
402
+ return {
403
+ transfers: results,
404
+ transactions,
405
+ totalAmount,
406
+ validTransferCount,
407
+ }
408
+ }
409
+
410
+ // ─── Gas Sponsorship ──────────────────────────────────────────────────────────
411
+
412
+ /**
413
+ * Build a gas-sponsored transfer for sender anonymity
414
+ *
415
+ * In a gas-sponsored transfer, a relayer pays for gas on behalf of the sender,
416
+ * helping preserve sender anonymity as the sender's account doesn't need NEAR
417
+ * for gas.
418
+ *
419
+ * @param params - Gas-sponsored transfer parameters
420
+ * @returns Transfer build for relayer execution
421
+ *
422
+ * @example
423
+ * ```typescript
424
+ * // User builds sponsored transfer
425
+ * const result = buildGasSponsoredTransfer({
426
+ * recipientMetaAddress: 'sip:near:0x...',
427
+ * amount: ONE_NEAR,
428
+ * relayerAccountId: 'relayer.near',
429
+ * hideAmount: true,
430
+ * })
431
+ *
432
+ * // User sends signed actions to relayer
433
+ * // Relayer executes on behalf of user
434
+ * ```
435
+ */
436
+ export function buildGasSponsoredTransfer(
437
+ params: GasSponsoredTransferParams
438
+ ): GasSponsoredTransferResult {
439
+ const {
440
+ recipientMetaAddress,
441
+ amount,
442
+ relayerAccountId,
443
+ maxRelayerFee = 100_000_000_000_000_000_000_000n, // 0.1 NEAR default max
444
+ hideAmount = false,
445
+ } = params
446
+
447
+ // Parse meta-address if string
448
+ const metaAddr = typeof recipientMetaAddress === 'string'
449
+ ? parseNEARStealthMetaAddress(recipientMetaAddress)
450
+ : recipientMetaAddress
451
+
452
+ // Validate chain
453
+ if (metaAddr.chain !== 'near') {
454
+ throw new ValidationError(
455
+ `Expected NEAR meta-address, got chain '${metaAddr.chain}'`,
456
+ 'recipientMetaAddress'
457
+ )
458
+ }
459
+
460
+ // Validate amount
461
+ if (amount <= 0n) {
462
+ throw new ValidationError('amount must be greater than 0', 'amount')
463
+ }
464
+
465
+ // Validate relayer account ID (must be a valid named account)
466
+ if (!relayerAccountId || relayerAccountId.length < 2) {
467
+ throw new ValidationError('Invalid relayerAccountId', 'relayerAccountId')
468
+ }
469
+
470
+ // Generate stealth address
471
+ const { stealthAddress, implicitAccountId } = generateNEARStealthAddress(metaAddr)
472
+
473
+ // Create announcement memo
474
+ const announcementMemo = createAnnouncementMemo(
475
+ stealthAddress.ephemeralPublicKey,
476
+ stealthAddress.viewTag
477
+ )
478
+
479
+ // Create commitment if hiding amounts
480
+ let commitment: NEARPedersenCommitment | undefined
481
+ if (hideAmount) {
482
+ commitment = commitNEAR(amount)
483
+ }
484
+
485
+ // Estimated gas fee (conservative estimate)
486
+ const estimatedFee = RELAYER_GAS / 1_000_000n // ~0.0001 NEAR gas cost
487
+
488
+ // Validate fee doesn't exceed max
489
+ if (estimatedFee > maxRelayerFee) {
490
+ throw new ValidationError(
491
+ `Estimated fee ${estimatedFee} exceeds maxRelayerFee ${maxRelayerFee}`,
492
+ 'maxRelayerFee'
493
+ )
494
+ }
495
+
496
+ // Build relayer actions
497
+ // The relayer will execute a function call to a relay contract
498
+ // that handles the transfer
499
+ const relayerActions: NEARAction[] = [
500
+ {
501
+ type: 'Transfer',
502
+ params: {
503
+ deposit: amount,
504
+ } as NEARTransferAction,
505
+ },
506
+ ]
507
+
508
+ return {
509
+ relayerActions,
510
+ stealthAddress,
511
+ stealthAccountId: implicitAccountId,
512
+ announcementMemo,
513
+ commitment,
514
+ estimatedFee,
515
+ }
516
+ }
517
+
518
+ // ─── Account Creation Helpers ─────────────────────────────────────────────────
519
+
520
+ /**
521
+ * Get account creation cost estimate
522
+ *
523
+ * @returns Cost estimate for creating an implicit account
524
+ */
525
+ export function getAccountCreationCost(): AccountCreationCost {
526
+ return {
527
+ minimumBalance: IMPLICIT_ACCOUNT_CREATION_COST,
528
+ storagePerByte: STORAGE_COST_PER_BYTE,
529
+ recommendedMinimum: RECOMMENDED_STEALTH_MINIMUM,
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Check if an amount meets the minimum balance for account creation
535
+ *
536
+ * @param amount - Amount in yoctoNEAR
537
+ * @returns True if amount meets minimum balance
538
+ */
539
+ export function meetsMinimumBalance(amount: bigint): boolean {
540
+ return amount >= IMPLICIT_ACCOUNT_CREATION_COST
541
+ }
542
+
543
+ /**
544
+ * Calculate the recommended transfer amount
545
+ *
546
+ * Ensures the transfer amount is sufficient for account creation
547
+ * and includes a buffer for storage costs.
548
+ *
549
+ * @param desiredAmount - The desired transfer amount
550
+ * @returns Recommended amount (at least the minimum)
551
+ */
552
+ export function calculateRecommendedAmount(desiredAmount: bigint): bigint {
553
+ return desiredAmount >= RECOMMENDED_STEALTH_MINIMUM
554
+ ? desiredAmount
555
+ : RECOMMENDED_STEALTH_MINIMUM
556
+ }
557
+
558
+ /**
559
+ * Adjust transfer amount to ensure it meets minimum requirements
560
+ *
561
+ * @param amount - Original amount
562
+ * @param ensureMinimum - Whether to adjust to minimum if below
563
+ * @returns Adjusted amount
564
+ */
565
+ export function adjustTransferAmount(
566
+ amount: bigint,
567
+ ensureMinimum: boolean = true
568
+ ): { amount: bigint; adjusted: boolean; originalAmount: bigint } {
569
+ if (ensureMinimum && amount < IMPLICIT_ACCOUNT_CREATION_COST) {
570
+ return {
571
+ amount: IMPLICIT_ACCOUNT_CREATION_COST,
572
+ adjusted: true,
573
+ originalAmount: amount,
574
+ }
575
+ }
576
+
577
+ return {
578
+ amount,
579
+ adjusted: false,
580
+ originalAmount: amount,
581
+ }
582
+ }
583
+
584
+ // ─── Transfer Amount Formatting ───────────────────────────────────────────────
585
+
586
+ /**
587
+ * Format NEAR amount for display
588
+ *
589
+ * @param amount - Amount in yoctoNEAR
590
+ * @returns Formatted string (e.g., "1.5 NEAR")
591
+ */
592
+ export function formatNEARAmount(amount: bigint): string {
593
+ const str = amount.toString().padStart(25, '0')
594
+ const whole = str.slice(0, -24) || '0'
595
+ const fraction = str.slice(-24).replace(/0+$/, '')
596
+
597
+ const formatted = fraction ? `${whole}.${fraction}` : whole
598
+ return `${formatted} NEAR`
599
+ }
600
+
601
+ /**
602
+ * Parse NEAR amount from display string
603
+ *
604
+ * @param displayAmount - Human-readable amount (e.g., "1.5" or "1.5 NEAR")
605
+ * @returns Amount in yoctoNEAR
606
+ */
607
+ export function parseNEARAmount(displayAmount: string): bigint {
608
+ // Remove NEAR suffix and any whitespace
609
+ const cleaned = displayAmount.replace(/\s*NEAR\s*/i, '').trim()
610
+
611
+ const [whole, fraction = ''] = cleaned.split('.')
612
+ const paddedFraction = fraction.padEnd(24, '0').slice(0, 24)
613
+
614
+ return BigInt(whole + paddedFraction)
615
+ }
616
+
617
+ // ─── Transfer Commitment Verification ─────────────────────────────────────────
618
+
619
+ /**
620
+ * Verify a native NEAR transfer commitment
621
+ *
622
+ * @param commitment - The commitment to verify
623
+ * @param expectedAmount - The expected amount in yoctoNEAR
624
+ * @returns True if commitment opens to expected amount
625
+ */
626
+ export function verifyNativeTransferCommitment(
627
+ commitment: NEARPedersenCommitment,
628
+ expectedAmount: bigint
629
+ ): boolean {
630
+ return verifyOpeningNEAR(commitment.commitment, expectedAmount, commitment.blinding)
631
+ }
632
+
633
+ /**
634
+ * Create a commitment proof for a native NEAR transfer
635
+ *
636
+ * This can be shared off-chain with the recipient to prove
637
+ * the transfer amount without revealing it on-chain.
638
+ *
639
+ * @param amount - The transfer amount
640
+ * @param blinding - Optional blinding factor
641
+ * @returns Commitment proof
642
+ */
643
+ export function createTransferCommitmentProof(
644
+ amount: bigint,
645
+ blinding?: Uint8Array
646
+ ): {
647
+ commitment: NEARPedersenCommitment
648
+ amount: bigint
649
+ amountFormatted: string
650
+ } {
651
+ const commitment = commitNEAR(amount, blinding)
652
+
653
+ return {
654
+ commitment,
655
+ amount,
656
+ amountFormatted: formatNEARAmount(amount),
657
+ }
658
+ }