@getomnichain/omnichain 0.2.0 → 0.3.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 (582) hide show
  1. package/dist/cjs/abstract_gas_pricing.js +27 -0
  2. package/dist/cjs/abstract_gas_pricing.js.map +1 -0
  3. package/dist/cjs/address.factory.js +81 -0
  4. package/dist/cjs/address.factory.js.map +1 -0
  5. package/dist/cjs/address.js +17 -0
  6. package/dist/cjs/address.js.map +1 -0
  7. package/dist/cjs/address_field.decorator.js +37 -0
  8. package/dist/cjs/address_field.decorator.js.map +1 -0
  9. package/dist/cjs/chain.base.js +118 -0
  10. package/dist/cjs/chain.base.js.map +1 -0
  11. package/dist/cjs/chain_ids.js +205 -0
  12. package/dist/cjs/chain_ids.js.map +1 -0
  13. package/dist/cjs/errors.js +118 -0
  14. package/dist/cjs/errors.js.map +1 -0
  15. package/dist/cjs/evm/evm_address.js +63 -0
  16. package/dist/cjs/evm/evm_address.js.map +1 -0
  17. package/dist/cjs/evm/evm_chain.js +1109 -0
  18. package/dist/cjs/evm/evm_chain.js.map +1 -0
  19. package/dist/cjs/evm/evm_chains.js +530 -0
  20. package/dist/cjs/evm/evm_chains.js.map +1 -0
  21. package/dist/cjs/evm/evm_gas_estimate.js +76 -0
  22. package/dist/cjs/evm/evm_gas_estimate.js.map +1 -0
  23. package/dist/cjs/evm/evm_gas_pricing.js +62 -0
  24. package/dist/cjs/evm/evm_gas_pricing.js.map +1 -0
  25. package/dist/cjs/evm/evm_token.js +26 -0
  26. package/dist/cjs/evm/evm_token.js.map +1 -0
  27. package/dist/cjs/evm/evm_tokens.js +109 -0
  28. package/dist/cjs/evm/evm_tokens.js.map +1 -0
  29. package/dist/cjs/evm/evm_transaction_status.js +187 -0
  30. package/dist/cjs/evm/evm_transaction_status.js.map +1 -0
  31. package/dist/cjs/evm/index.js +26 -0
  32. package/dist/cjs/evm/index.js.map +1 -0
  33. package/dist/cjs/evm/unsigned_evm_transaction.js +34 -0
  34. package/dist/cjs/evm/unsigned_evm_transaction.js.map +1 -0
  35. package/dist/cjs/index.js +34 -0
  36. package/dist/cjs/index.js.map +1 -0
  37. package/dist/cjs/is_address.decorator.js +54 -0
  38. package/dist/cjs/is_address.decorator.js.map +1 -0
  39. package/dist/cjs/network_type.js +152 -0
  40. package/dist/cjs/network_type.js.map +1 -0
  41. package/dist/cjs/package.json +3 -0
  42. package/dist/cjs/priority.js +26 -0
  43. package/dist/cjs/priority.js.map +1 -0
  44. package/dist/cjs/solana/index.js +25 -0
  45. package/dist/cjs/solana/index.js.map +1 -0
  46. package/dist/cjs/solana/solana_address.js +49 -0
  47. package/dist/cjs/solana/solana_address.js.map +1 -0
  48. package/dist/cjs/solana/solana_chain.js +1305 -0
  49. package/dist/cjs/solana/solana_chain.js.map +1 -0
  50. package/dist/cjs/solana/solana_chains.js +88 -0
  51. package/dist/cjs/solana/solana_chains.js.map +1 -0
  52. package/dist/cjs/solana/solana_gas_pricing.js +30 -0
  53. package/dist/cjs/solana/solana_gas_pricing.js.map +1 -0
  54. package/dist/cjs/solana/solana_token.js +38 -0
  55. package/dist/cjs/solana/solana_token.js.map +1 -0
  56. package/dist/cjs/solana/solana_tokens.js +29 -0
  57. package/dist/cjs/solana/solana_tokens.js.map +1 -0
  58. package/dist/cjs/solana/solana_transaction_status.js +149 -0
  59. package/dist/cjs/solana/solana_transaction_status.js.map +1 -0
  60. package/dist/cjs/solana/unsigned_solana_transaction.js +63 -0
  61. package/dist/cjs/solana/unsigned_solana_transaction.js.map +1 -0
  62. package/dist/cjs/token.js +66 -0
  63. package/dist/cjs/token.js.map +1 -0
  64. package/dist/cjs/ton/index.js +18 -0
  65. package/dist/cjs/ton/index.js.map +1 -0
  66. package/dist/cjs/ton/ton_address.js +57 -0
  67. package/dist/cjs/ton/ton_address.js.map +1 -0
  68. package/dist/cjs/transaction_status.js +283 -0
  69. package/dist/cjs/transaction_status.js.map +1 -0
  70. package/dist/cjs/unsigned_transaction.js +13 -0
  71. package/dist/cjs/unsigned_transaction.js.map +1 -0
  72. package/dist/cjs/utxo/btc/btc_address.js +43 -0
  73. package/dist/cjs/utxo/btc/btc_address.js.map +1 -0
  74. package/dist/cjs/utxo/btc/btc_chain.js +66 -0
  75. package/dist/cjs/utxo/btc/btc_chain.js.map +1 -0
  76. package/dist/cjs/utxo/btc/btc_chains.js +49 -0
  77. package/dist/cjs/utxo/btc/btc_chains.js.map +1 -0
  78. package/dist/cjs/utxo/btc/btc_token.js +15 -0
  79. package/dist/cjs/utxo/btc/btc_token.js.map +1 -0
  80. package/dist/cjs/utxo/btc/index.js +30 -0
  81. package/dist/cjs/utxo/btc/index.js.map +1 -0
  82. package/dist/cjs/utxo/btc/network_params.js +196 -0
  83. package/dist/cjs/utxo/btc/network_params.js.map +1 -0
  84. package/dist/cjs/utxo/btc/tools/asset_outpoint.js +16 -0
  85. package/dist/cjs/utxo/btc/tools/asset_outpoint.js.map +1 -0
  86. package/dist/cjs/utxo/btc/tools/bitcoin_core.tool.js +179 -0
  87. package/dist/cjs/utxo/btc/tools/bitcoin_core.tool.js.map +1 -0
  88. package/dist/cjs/utxo/btc/tools/esplora.tool.js +120 -0
  89. package/dist/cjs/utxo/btc/tools/esplora.tool.js.map +1 -0
  90. package/dist/cjs/utxo/btc/tools/inscription_index.js +3 -0
  91. package/dist/cjs/utxo/btc/tools/inscription_index.js.map +1 -0
  92. package/dist/cjs/utxo/btc/tools/ordiscan.tool.js +60 -0
  93. package/dist/cjs/utxo/btc/tools/ordiscan.tool.js.map +1 -0
  94. package/dist/cjs/utxo/btc/tools/rare_sat_index.js +3 -0
  95. package/dist/cjs/utxo/btc/tools/rare_sat_index.js.map +1 -0
  96. package/dist/cjs/utxo/btc/tools/rune_index.js +3 -0
  97. package/dist/cjs/utxo/btc/tools/rune_index.js.map +1 -0
  98. package/dist/cjs/utxo/btc/tools/unisat.tool.js +56 -0
  99. package/dist/cjs/utxo/btc/tools/unisat.tool.js.map +1 -0
  100. package/dist/cjs/utxo/coin_selection.js +160 -0
  101. package/dist/cjs/utxo/coin_selection.js.map +1 -0
  102. package/dist/cjs/utxo/doge/doge_chains.js +32 -0
  103. package/dist/cjs/utxo/doge/doge_chains.js.map +1 -0
  104. package/dist/cjs/utxo/doge/index.js +19 -0
  105. package/dist/cjs/utxo/doge/index.js.map +1 -0
  106. package/dist/cjs/utxo/doge/network_params.js +30 -0
  107. package/dist/cjs/utxo/doge/network_params.js.map +1 -0
  108. package/dist/cjs/utxo/ecc.js +47 -0
  109. package/dist/cjs/utxo/ecc.js.map +1 -0
  110. package/dist/cjs/utxo/fee.js +61 -0
  111. package/dist/cjs/utxo/fee.js.map +1 -0
  112. package/dist/cjs/utxo/index.js +36 -0
  113. package/dist/cjs/utxo/index.js.map +1 -0
  114. package/dist/cjs/utxo/ltc/index.js +19 -0
  115. package/dist/cjs/utxo/ltc/index.js.map +1 -0
  116. package/dist/cjs/utxo/ltc/ltc_chains.js +32 -0
  117. package/dist/cjs/utxo/ltc/ltc_chains.js.map +1 -0
  118. package/dist/cjs/utxo/ltc/network_params.js +33 -0
  119. package/dist/cjs/utxo/ltc/network_params.js.map +1 -0
  120. package/dist/cjs/utxo/script.js +59 -0
  121. package/dist/cjs/utxo/script.js.map +1 -0
  122. package/dist/cjs/utxo/tools/broadcaster.js +3 -0
  123. package/dist/cjs/utxo/tools/broadcaster.js.map +1 -0
  124. package/dist/cjs/utxo/tools/chain_tip_provider.js +3 -0
  125. package/dist/cjs/utxo/tools/chain_tip_provider.js.map +1 -0
  126. package/dist/cjs/utxo/tools/fee_estimator.js +3 -0
  127. package/dist/cjs/utxo/tools/fee_estimator.js.map +1 -0
  128. package/dist/cjs/utxo/tools/raw_transaction_provider.js +3 -0
  129. package/dist/cjs/utxo/tools/raw_transaction_provider.js.map +1 -0
  130. package/dist/cjs/utxo/tools/utxo_provider.js +3 -0
  131. package/dist/cjs/utxo/tools/utxo_provider.js.map +1 -0
  132. package/dist/cjs/utxo/unsigned_utxo_transaction.js +36 -0
  133. package/dist/cjs/utxo/unsigned_utxo_transaction.js.map +1 -0
  134. package/dist/cjs/utxo/utxo.js +3 -0
  135. package/dist/{utxo → cjs/utxo}/utxo.js.map +1 -1
  136. package/dist/cjs/utxo/utxo_chain.js +612 -0
  137. package/dist/cjs/utxo/utxo_chain.js.map +1 -0
  138. package/dist/cjs/utxo/utxo_chains.js +68 -0
  139. package/dist/cjs/utxo/utxo_chains.js.map +1 -0
  140. package/dist/cjs/utxo/utxo_gas_pricing.js +24 -0
  141. package/dist/cjs/utxo/utxo_gas_pricing.js.map +1 -0
  142. package/dist/cjs/utxo/utxo_network_params.js +18 -0
  143. package/dist/cjs/utxo/utxo_network_params.js.map +1 -0
  144. package/dist/cjs/utxo/utxo_transaction_status.js +95 -0
  145. package/dist/cjs/utxo/utxo_transaction_status.js.map +1 -0
  146. package/dist/esm/abstract_gas_pricing.d.ts.map +1 -0
  147. package/dist/esm/abstract_gas_pricing.js.map +1 -0
  148. package/dist/esm/address.d.ts.map +1 -0
  149. package/dist/esm/address.factory.d.ts.map +1 -0
  150. package/dist/esm/address.factory.js.map +1 -0
  151. package/dist/esm/address.js.map +1 -0
  152. package/dist/esm/address_field.decorator.d.ts.map +1 -0
  153. package/dist/esm/address_field.decorator.js.map +1 -0
  154. package/dist/{chain.base.d.ts → esm/chain.base.d.ts} +38 -1
  155. package/dist/esm/chain.base.d.ts.map +1 -0
  156. package/dist/esm/chain.base.js.map +1 -0
  157. package/dist/esm/chain_ids.d.ts.map +1 -0
  158. package/dist/esm/chain_ids.js.map +1 -0
  159. package/dist/{errors.d.ts → esm/errors.d.ts} +13 -0
  160. package/dist/esm/errors.d.ts.map +1 -0
  161. package/dist/esm/errors.js +107 -0
  162. package/dist/esm/errors.js.map +1 -0
  163. package/dist/esm/evm/evm_address.d.ts.map +1 -0
  164. package/dist/esm/evm/evm_address.js.map +1 -0
  165. package/dist/{evm → esm/evm}/evm_chain.d.ts +48 -2
  166. package/dist/esm/evm/evm_chain.d.ts.map +1 -0
  167. package/dist/{evm → esm/evm}/evm_chain.js +423 -4
  168. package/dist/esm/evm/evm_chain.js.map +1 -0
  169. package/dist/esm/evm/evm_chains.d.ts.map +1 -0
  170. package/dist/esm/evm/evm_chains.js.map +1 -0
  171. package/dist/esm/evm/evm_gas_estimate.d.ts.map +1 -0
  172. package/dist/esm/evm/evm_gas_estimate.js.map +1 -0
  173. package/dist/esm/evm/evm_gas_pricing.d.ts.map +1 -0
  174. package/dist/esm/evm/evm_gas_pricing.js.map +1 -0
  175. package/dist/esm/evm/evm_token.d.ts.map +1 -0
  176. package/dist/esm/evm/evm_token.js.map +1 -0
  177. package/dist/esm/evm/evm_tokens.d.ts.map +1 -0
  178. package/dist/esm/evm/evm_tokens.js.map +1 -0
  179. package/dist/{evm → esm/evm}/evm_transaction_status.d.ts +4 -0
  180. package/dist/esm/evm/evm_transaction_status.d.ts.map +1 -0
  181. package/dist/{evm → esm/evm}/evm_transaction_status.js +4 -0
  182. package/dist/esm/evm/evm_transaction_status.js.map +1 -0
  183. package/dist/esm/evm/index.d.ts.map +1 -0
  184. package/dist/esm/evm/index.js.map +1 -0
  185. package/dist/{evm → esm/evm}/unsigned_evm_transaction.d.ts +13 -0
  186. package/dist/esm/evm/unsigned_evm_transaction.d.ts.map +1 -0
  187. package/dist/{evm → esm/evm}/unsigned_evm_transaction.js +12 -0
  188. package/dist/esm/evm/unsigned_evm_transaction.js.map +1 -0
  189. package/dist/esm/index.d.ts.map +1 -0
  190. package/dist/esm/index.js.map +1 -0
  191. package/dist/esm/is_address.decorator.d.ts.map +1 -0
  192. package/dist/esm/is_address.decorator.js.map +1 -0
  193. package/dist/esm/network_type.d.ts.map +1 -0
  194. package/dist/esm/network_type.js.map +1 -0
  195. package/dist/esm/package.json +3 -0
  196. package/dist/esm/priority.d.ts.map +1 -0
  197. package/dist/esm/priority.js.map +1 -0
  198. package/dist/esm/solana/index.d.ts.map +1 -0
  199. package/dist/esm/solana/index.js.map +1 -0
  200. package/dist/esm/solana/solana_address.d.ts.map +1 -0
  201. package/dist/esm/solana/solana_address.js.map +1 -0
  202. package/dist/{solana → esm/solana}/solana_chain.d.ts +87 -3
  203. package/dist/esm/solana/solana_chain.d.ts.map +1 -0
  204. package/dist/{solana → esm/solana}/solana_chain.js +618 -23
  205. package/dist/esm/solana/solana_chain.js.map +1 -0
  206. package/dist/esm/solana/solana_chains.d.ts.map +1 -0
  207. package/dist/esm/solana/solana_chains.js.map +1 -0
  208. package/dist/esm/solana/solana_gas_pricing.d.ts.map +1 -0
  209. package/dist/esm/solana/solana_gas_pricing.js.map +1 -0
  210. package/dist/esm/solana/solana_token.d.ts.map +1 -0
  211. package/dist/esm/solana/solana_token.js.map +1 -0
  212. package/dist/esm/solana/solana_tokens.d.ts.map +1 -0
  213. package/dist/esm/solana/solana_tokens.js.map +1 -0
  214. package/dist/esm/solana/solana_transaction_status.d.ts.map +1 -0
  215. package/dist/esm/solana/solana_transaction_status.js.map +1 -0
  216. package/dist/{solana → esm/solana}/unsigned_solana_transaction.d.ts +20 -1
  217. package/dist/esm/solana/unsigned_solana_transaction.d.ts.map +1 -0
  218. package/dist/esm/solana/unsigned_solana_transaction.js +59 -0
  219. package/dist/esm/solana/unsigned_solana_transaction.js.map +1 -0
  220. package/dist/esm/token.d.ts.map +1 -0
  221. package/dist/esm/token.js.map +1 -0
  222. package/dist/esm/ton/index.d.ts.map +1 -0
  223. package/dist/esm/ton/index.js.map +1 -0
  224. package/dist/esm/ton/ton_address.d.ts.map +1 -0
  225. package/dist/esm/ton/ton_address.js.map +1 -0
  226. package/dist/esm/transaction_status.d.ts.map +1 -0
  227. package/dist/esm/transaction_status.js.map +1 -0
  228. package/dist/esm/unsigned_transaction.d.ts.map +1 -0
  229. package/dist/esm/unsigned_transaction.js.map +1 -0
  230. package/dist/esm/utxo/btc/btc_address.d.ts.map +1 -0
  231. package/dist/esm/utxo/btc/btc_address.js.map +1 -0
  232. package/dist/esm/utxo/btc/btc_chain.d.ts.map +1 -0
  233. package/dist/esm/utxo/btc/btc_chain.js.map +1 -0
  234. package/dist/esm/utxo/btc/btc_chains.d.ts.map +1 -0
  235. package/dist/esm/utxo/btc/btc_chains.js.map +1 -0
  236. package/dist/esm/utxo/btc/btc_token.d.ts.map +1 -0
  237. package/dist/esm/utxo/btc/btc_token.js.map +1 -0
  238. package/dist/esm/utxo/btc/index.d.ts.map +1 -0
  239. package/dist/esm/utxo/btc/index.js.map +1 -0
  240. package/dist/esm/utxo/btc/network_params.d.ts.map +1 -0
  241. package/dist/esm/utxo/btc/network_params.js.map +1 -0
  242. package/dist/esm/utxo/btc/tools/asset_outpoint.d.ts.map +1 -0
  243. package/dist/esm/utxo/btc/tools/asset_outpoint.js.map +1 -0
  244. package/dist/esm/utxo/btc/tools/bitcoin_core.tool.d.ts.map +1 -0
  245. package/dist/esm/utxo/btc/tools/bitcoin_core.tool.js.map +1 -0
  246. package/dist/esm/utxo/btc/tools/esplora.tool.d.ts.map +1 -0
  247. package/dist/esm/utxo/btc/tools/esplora.tool.js.map +1 -0
  248. package/dist/esm/utxo/btc/tools/inscription_index.d.ts.map +1 -0
  249. package/dist/esm/utxo/btc/tools/inscription_index.js.map +1 -0
  250. package/dist/esm/utxo/btc/tools/ordiscan.tool.d.ts.map +1 -0
  251. package/dist/esm/utxo/btc/tools/ordiscan.tool.js.map +1 -0
  252. package/dist/esm/utxo/btc/tools/rare_sat_index.d.ts.map +1 -0
  253. package/dist/esm/utxo/btc/tools/rare_sat_index.js.map +1 -0
  254. package/dist/esm/utxo/btc/tools/rune_index.d.ts.map +1 -0
  255. package/dist/esm/utxo/btc/tools/rune_index.js.map +1 -0
  256. package/dist/esm/utxo/btc/tools/unisat.tool.d.ts.map +1 -0
  257. package/dist/esm/utxo/btc/tools/unisat.tool.js.map +1 -0
  258. package/dist/esm/utxo/coin_selection.d.ts.map +1 -0
  259. package/dist/esm/utxo/coin_selection.js.map +1 -0
  260. package/dist/esm/utxo/doge/doge_chains.d.ts.map +1 -0
  261. package/dist/esm/utxo/doge/doge_chains.js.map +1 -0
  262. package/dist/esm/utxo/doge/index.d.ts.map +1 -0
  263. package/dist/esm/utxo/doge/index.js.map +1 -0
  264. package/dist/esm/utxo/doge/network_params.d.ts.map +1 -0
  265. package/dist/esm/utxo/doge/network_params.js.map +1 -0
  266. package/dist/esm/utxo/ecc.d.ts.map +1 -0
  267. package/dist/esm/utxo/ecc.js.map +1 -0
  268. package/dist/esm/utxo/fee.d.ts.map +1 -0
  269. package/dist/esm/utxo/fee.js.map +1 -0
  270. package/dist/esm/utxo/index.d.ts.map +1 -0
  271. package/dist/esm/utxo/index.js.map +1 -0
  272. package/dist/esm/utxo/ltc/index.d.ts.map +1 -0
  273. package/dist/esm/utxo/ltc/index.js.map +1 -0
  274. package/dist/{utxo/doge/doge_chains.d.ts.map → esm/utxo/ltc/ltc_chains.d.ts.map} +1 -1
  275. package/dist/{utxo/doge/doge_chains.js.map → esm/utxo/ltc/ltc_chains.js.map} +1 -1
  276. package/dist/esm/utxo/ltc/network_params.d.ts.map +1 -0
  277. package/dist/esm/utxo/ltc/network_params.js.map +1 -0
  278. package/dist/esm/utxo/script.d.ts.map +1 -0
  279. package/dist/esm/utxo/script.js.map +1 -0
  280. package/dist/esm/utxo/tools/broadcaster.d.ts.map +1 -0
  281. package/dist/esm/utxo/tools/broadcaster.js.map +1 -0
  282. package/dist/esm/utxo/tools/chain_tip_provider.d.ts.map +1 -0
  283. package/dist/esm/utxo/tools/chain_tip_provider.js.map +1 -0
  284. package/dist/esm/utxo/tools/fee_estimator.d.ts.map +1 -0
  285. package/dist/esm/utxo/tools/fee_estimator.js.map +1 -0
  286. package/dist/esm/utxo/tools/raw_transaction_provider.d.ts.map +1 -0
  287. package/dist/esm/utxo/tools/raw_transaction_provider.js.map +1 -0
  288. package/dist/esm/utxo/tools/utxo_provider.d.ts.map +1 -0
  289. package/dist/esm/utxo/tools/utxo_provider.js.map +1 -0
  290. package/dist/esm/utxo/unsigned_utxo_transaction.d.ts.map +1 -0
  291. package/dist/esm/utxo/unsigned_utxo_transaction.js.map +1 -0
  292. package/dist/esm/utxo/utxo.d.ts.map +1 -0
  293. package/dist/esm/utxo/utxo.js.map +1 -0
  294. package/dist/{utxo → esm/utxo}/utxo_chain.d.ts +15 -2
  295. package/dist/esm/utxo/utxo_chain.d.ts.map +1 -0
  296. package/dist/{utxo → esm/utxo}/utxo_chain.js +96 -13
  297. package/dist/esm/utxo/utxo_chain.js.map +1 -0
  298. package/dist/esm/utxo/utxo_chains.d.ts.map +1 -0
  299. package/dist/esm/utxo/utxo_chains.js.map +1 -0
  300. package/dist/esm/utxo/utxo_gas_pricing.d.ts.map +1 -0
  301. package/dist/esm/utxo/utxo_gas_pricing.js.map +1 -0
  302. package/dist/esm/utxo/utxo_network_params.d.ts.map +1 -0
  303. package/dist/esm/utxo/utxo_network_params.js.map +1 -0
  304. package/dist/esm/utxo/utxo_transaction_status.d.ts.map +1 -0
  305. package/dist/esm/utxo/utxo_transaction_status.js.map +1 -0
  306. package/docs/CONNECTIONS.md +33 -0
  307. package/docs/EIP7702.md +77 -0
  308. package/docs/JITO.md +41 -0
  309. package/docs/MULTI_RPC.md +28 -0
  310. package/package.json +32 -16
  311. package/dist/abstract_gas_pricing.d.ts.map +0 -1
  312. package/dist/abstract_gas_pricing.js.map +0 -1
  313. package/dist/address.d.ts.map +0 -1
  314. package/dist/address.factory.d.ts.map +0 -1
  315. package/dist/address.factory.js.map +0 -1
  316. package/dist/address.js.map +0 -1
  317. package/dist/address_field.decorator.d.ts.map +0 -1
  318. package/dist/address_field.decorator.js.map +0 -1
  319. package/dist/chain.base.d.ts.map +0 -1
  320. package/dist/chain.base.js.map +0 -1
  321. package/dist/chain_ids.d.ts.map +0 -1
  322. package/dist/chain_ids.js.map +0 -1
  323. package/dist/errors.d.ts.map +0 -1
  324. package/dist/errors.js +0 -62
  325. package/dist/errors.js.map +0 -1
  326. package/dist/evm/evm_address.d.ts.map +0 -1
  327. package/dist/evm/evm_address.js.map +0 -1
  328. package/dist/evm/evm_chain.d.ts.map +0 -1
  329. package/dist/evm/evm_chain.js.map +0 -1
  330. package/dist/evm/evm_chains.d.ts.map +0 -1
  331. package/dist/evm/evm_chains.js.map +0 -1
  332. package/dist/evm/evm_gas_estimate.d.ts.map +0 -1
  333. package/dist/evm/evm_gas_estimate.js.map +0 -1
  334. package/dist/evm/evm_gas_pricing.d.ts.map +0 -1
  335. package/dist/evm/evm_gas_pricing.js.map +0 -1
  336. package/dist/evm/evm_token.d.ts.map +0 -1
  337. package/dist/evm/evm_token.js.map +0 -1
  338. package/dist/evm/evm_tokens.d.ts.map +0 -1
  339. package/dist/evm/evm_tokens.js.map +0 -1
  340. package/dist/evm/evm_transaction_status.d.ts.map +0 -1
  341. package/dist/evm/evm_transaction_status.js.map +0 -1
  342. package/dist/evm/index.d.ts.map +0 -1
  343. package/dist/evm/index.js.map +0 -1
  344. package/dist/evm/unsigned_evm_transaction.d.ts.map +0 -1
  345. package/dist/evm/unsigned_evm_transaction.js.map +0 -1
  346. package/dist/index.d.ts.map +0 -1
  347. package/dist/index.js.map +0 -1
  348. package/dist/is_address.decorator.d.ts.map +0 -1
  349. package/dist/is_address.decorator.js.map +0 -1
  350. package/dist/network_type.d.ts.map +0 -1
  351. package/dist/network_type.js.map +0 -1
  352. package/dist/priority.d.ts.map +0 -1
  353. package/dist/priority.js.map +0 -1
  354. package/dist/solana/index.d.ts.map +0 -1
  355. package/dist/solana/index.js.map +0 -1
  356. package/dist/solana/solana_address.d.ts.map +0 -1
  357. package/dist/solana/solana_address.js.map +0 -1
  358. package/dist/solana/solana_chain.d.ts.map +0 -1
  359. package/dist/solana/solana_chain.js.map +0 -1
  360. package/dist/solana/solana_chains.d.ts.map +0 -1
  361. package/dist/solana/solana_chains.js.map +0 -1
  362. package/dist/solana/solana_gas_pricing.d.ts.map +0 -1
  363. package/dist/solana/solana_gas_pricing.js.map +0 -1
  364. package/dist/solana/solana_token.d.ts.map +0 -1
  365. package/dist/solana/solana_token.js.map +0 -1
  366. package/dist/solana/solana_tokens.d.ts.map +0 -1
  367. package/dist/solana/solana_tokens.js.map +0 -1
  368. package/dist/solana/solana_transaction_status.d.ts.map +0 -1
  369. package/dist/solana/solana_transaction_status.js.map +0 -1
  370. package/dist/solana/unsigned_solana_transaction.d.ts.map +0 -1
  371. package/dist/solana/unsigned_solana_transaction.js +0 -26
  372. package/dist/solana/unsigned_solana_transaction.js.map +0 -1
  373. package/dist/token.d.ts.map +0 -1
  374. package/dist/token.js.map +0 -1
  375. package/dist/ton/index.d.ts.map +0 -1
  376. package/dist/ton/index.js.map +0 -1
  377. package/dist/ton/ton_address.d.ts.map +0 -1
  378. package/dist/ton/ton_address.js.map +0 -1
  379. package/dist/transaction_status.d.ts.map +0 -1
  380. package/dist/transaction_status.js.map +0 -1
  381. package/dist/unsigned_transaction.d.ts.map +0 -1
  382. package/dist/unsigned_transaction.js.map +0 -1
  383. package/dist/utxo/btc/btc_address.d.ts.map +0 -1
  384. package/dist/utxo/btc/btc_address.js.map +0 -1
  385. package/dist/utxo/btc/btc_chain.d.ts.map +0 -1
  386. package/dist/utxo/btc/btc_chain.js.map +0 -1
  387. package/dist/utxo/btc/btc_chains.d.ts.map +0 -1
  388. package/dist/utxo/btc/btc_chains.js.map +0 -1
  389. package/dist/utxo/btc/btc_token.d.ts.map +0 -1
  390. package/dist/utxo/btc/btc_token.js.map +0 -1
  391. package/dist/utxo/btc/index.d.ts.map +0 -1
  392. package/dist/utxo/btc/index.js.map +0 -1
  393. package/dist/utxo/btc/network_params.d.ts.map +0 -1
  394. package/dist/utxo/btc/network_params.js.map +0 -1
  395. package/dist/utxo/btc/tools/asset_outpoint.d.ts.map +0 -1
  396. package/dist/utxo/btc/tools/asset_outpoint.js.map +0 -1
  397. package/dist/utxo/btc/tools/bitcoin_core.tool.d.ts.map +0 -1
  398. package/dist/utxo/btc/tools/bitcoin_core.tool.js.map +0 -1
  399. package/dist/utxo/btc/tools/esplora.tool.d.ts.map +0 -1
  400. package/dist/utxo/btc/tools/esplora.tool.js.map +0 -1
  401. package/dist/utxo/btc/tools/inscription_index.d.ts.map +0 -1
  402. package/dist/utxo/btc/tools/inscription_index.js.map +0 -1
  403. package/dist/utxo/btc/tools/ordiscan.tool.d.ts.map +0 -1
  404. package/dist/utxo/btc/tools/ordiscan.tool.js.map +0 -1
  405. package/dist/utxo/btc/tools/rare_sat_index.d.ts.map +0 -1
  406. package/dist/utxo/btc/tools/rare_sat_index.js.map +0 -1
  407. package/dist/utxo/btc/tools/rune_index.d.ts.map +0 -1
  408. package/dist/utxo/btc/tools/rune_index.js.map +0 -1
  409. package/dist/utxo/btc/tools/unisat.tool.d.ts.map +0 -1
  410. package/dist/utxo/btc/tools/unisat.tool.js.map +0 -1
  411. package/dist/utxo/coin_selection.d.ts.map +0 -1
  412. package/dist/utxo/coin_selection.js.map +0 -1
  413. package/dist/utxo/doge/index.d.ts.map +0 -1
  414. package/dist/utxo/doge/index.js.map +0 -1
  415. package/dist/utxo/doge/network_params.d.ts.map +0 -1
  416. package/dist/utxo/doge/network_params.js.map +0 -1
  417. package/dist/utxo/ecc.d.ts.map +0 -1
  418. package/dist/utxo/ecc.js.map +0 -1
  419. package/dist/utxo/fee.d.ts.map +0 -1
  420. package/dist/utxo/fee.js.map +0 -1
  421. package/dist/utxo/index.d.ts.map +0 -1
  422. package/dist/utxo/index.js.map +0 -1
  423. package/dist/utxo/ltc/index.d.ts.map +0 -1
  424. package/dist/utxo/ltc/index.js.map +0 -1
  425. package/dist/utxo/ltc/ltc_chains.d.ts.map +0 -1
  426. package/dist/utxo/ltc/ltc_chains.js.map +0 -1
  427. package/dist/utxo/ltc/network_params.d.ts.map +0 -1
  428. package/dist/utxo/ltc/network_params.js.map +0 -1
  429. package/dist/utxo/script.d.ts.map +0 -1
  430. package/dist/utxo/script.js.map +0 -1
  431. package/dist/utxo/tools/broadcaster.d.ts.map +0 -1
  432. package/dist/utxo/tools/broadcaster.js.map +0 -1
  433. package/dist/utxo/tools/chain_tip_provider.d.ts.map +0 -1
  434. package/dist/utxo/tools/chain_tip_provider.js.map +0 -1
  435. package/dist/utxo/tools/fee_estimator.d.ts.map +0 -1
  436. package/dist/utxo/tools/fee_estimator.js.map +0 -1
  437. package/dist/utxo/tools/raw_transaction_provider.d.ts.map +0 -1
  438. package/dist/utxo/tools/raw_transaction_provider.js.map +0 -1
  439. package/dist/utxo/tools/utxo_provider.d.ts.map +0 -1
  440. package/dist/utxo/tools/utxo_provider.js.map +0 -1
  441. package/dist/utxo/unsigned_utxo_transaction.d.ts.map +0 -1
  442. package/dist/utxo/unsigned_utxo_transaction.js.map +0 -1
  443. package/dist/utxo/utxo.d.ts.map +0 -1
  444. package/dist/utxo/utxo_chain.d.ts.map +0 -1
  445. package/dist/utxo/utxo_chain.js.map +0 -1
  446. package/dist/utxo/utxo_chains.d.ts.map +0 -1
  447. package/dist/utxo/utxo_chains.js.map +0 -1
  448. package/dist/utxo/utxo_gas_pricing.d.ts.map +0 -1
  449. package/dist/utxo/utxo_gas_pricing.js.map +0 -1
  450. package/dist/utxo/utxo_network_params.d.ts.map +0 -1
  451. package/dist/utxo/utxo_network_params.js.map +0 -1
  452. package/dist/utxo/utxo_transaction_status.d.ts.map +0 -1
  453. package/dist/utxo/utxo_transaction_status.js.map +0 -1
  454. /package/dist/{abstract_gas_pricing.d.ts → esm/abstract_gas_pricing.d.ts} +0 -0
  455. /package/dist/{abstract_gas_pricing.js → esm/abstract_gas_pricing.js} +0 -0
  456. /package/dist/{address.d.ts → esm/address.d.ts} +0 -0
  457. /package/dist/{address.factory.d.ts → esm/address.factory.d.ts} +0 -0
  458. /package/dist/{address.factory.js → esm/address.factory.js} +0 -0
  459. /package/dist/{address.js → esm/address.js} +0 -0
  460. /package/dist/{address_field.decorator.d.ts → esm/address_field.decorator.d.ts} +0 -0
  461. /package/dist/{address_field.decorator.js → esm/address_field.decorator.js} +0 -0
  462. /package/dist/{chain.base.js → esm/chain.base.js} +0 -0
  463. /package/dist/{chain_ids.d.ts → esm/chain_ids.d.ts} +0 -0
  464. /package/dist/{chain_ids.js → esm/chain_ids.js} +0 -0
  465. /package/dist/{evm → esm/evm}/evm_address.d.ts +0 -0
  466. /package/dist/{evm → esm/evm}/evm_address.js +0 -0
  467. /package/dist/{evm → esm/evm}/evm_chains.d.ts +0 -0
  468. /package/dist/{evm → esm/evm}/evm_chains.js +0 -0
  469. /package/dist/{evm → esm/evm}/evm_gas_estimate.d.ts +0 -0
  470. /package/dist/{evm → esm/evm}/evm_gas_estimate.js +0 -0
  471. /package/dist/{evm → esm/evm}/evm_gas_pricing.d.ts +0 -0
  472. /package/dist/{evm → esm/evm}/evm_gas_pricing.js +0 -0
  473. /package/dist/{evm → esm/evm}/evm_token.d.ts +0 -0
  474. /package/dist/{evm → esm/evm}/evm_token.js +0 -0
  475. /package/dist/{evm → esm/evm}/evm_tokens.d.ts +0 -0
  476. /package/dist/{evm → esm/evm}/evm_tokens.js +0 -0
  477. /package/dist/{evm → esm/evm}/index.d.ts +0 -0
  478. /package/dist/{evm → esm/evm}/index.js +0 -0
  479. /package/dist/{index.d.ts → esm/index.d.ts} +0 -0
  480. /package/dist/{index.js → esm/index.js} +0 -0
  481. /package/dist/{is_address.decorator.d.ts → esm/is_address.decorator.d.ts} +0 -0
  482. /package/dist/{is_address.decorator.js → esm/is_address.decorator.js} +0 -0
  483. /package/dist/{network_type.d.ts → esm/network_type.d.ts} +0 -0
  484. /package/dist/{network_type.js → esm/network_type.js} +0 -0
  485. /package/dist/{priority.d.ts → esm/priority.d.ts} +0 -0
  486. /package/dist/{priority.js → esm/priority.js} +0 -0
  487. /package/dist/{solana → esm/solana}/index.d.ts +0 -0
  488. /package/dist/{solana → esm/solana}/index.js +0 -0
  489. /package/dist/{solana → esm/solana}/solana_address.d.ts +0 -0
  490. /package/dist/{solana → esm/solana}/solana_address.js +0 -0
  491. /package/dist/{solana → esm/solana}/solana_chains.d.ts +0 -0
  492. /package/dist/{solana → esm/solana}/solana_chains.js +0 -0
  493. /package/dist/{solana → esm/solana}/solana_gas_pricing.d.ts +0 -0
  494. /package/dist/{solana → esm/solana}/solana_gas_pricing.js +0 -0
  495. /package/dist/{solana → esm/solana}/solana_token.d.ts +0 -0
  496. /package/dist/{solana → esm/solana}/solana_token.js +0 -0
  497. /package/dist/{solana → esm/solana}/solana_tokens.d.ts +0 -0
  498. /package/dist/{solana → esm/solana}/solana_tokens.js +0 -0
  499. /package/dist/{solana → esm/solana}/solana_transaction_status.d.ts +0 -0
  500. /package/dist/{solana → esm/solana}/solana_transaction_status.js +0 -0
  501. /package/dist/{token.d.ts → esm/token.d.ts} +0 -0
  502. /package/dist/{token.js → esm/token.js} +0 -0
  503. /package/dist/{ton → esm/ton}/index.d.ts +0 -0
  504. /package/dist/{ton → esm/ton}/index.js +0 -0
  505. /package/dist/{ton → esm/ton}/ton_address.d.ts +0 -0
  506. /package/dist/{ton → esm/ton}/ton_address.js +0 -0
  507. /package/dist/{transaction_status.d.ts → esm/transaction_status.d.ts} +0 -0
  508. /package/dist/{transaction_status.js → esm/transaction_status.js} +0 -0
  509. /package/dist/{unsigned_transaction.d.ts → esm/unsigned_transaction.d.ts} +0 -0
  510. /package/dist/{unsigned_transaction.js → esm/unsigned_transaction.js} +0 -0
  511. /package/dist/{utxo → esm/utxo}/btc/btc_address.d.ts +0 -0
  512. /package/dist/{utxo → esm/utxo}/btc/btc_address.js +0 -0
  513. /package/dist/{utxo → esm/utxo}/btc/btc_chain.d.ts +0 -0
  514. /package/dist/{utxo → esm/utxo}/btc/btc_chain.js +0 -0
  515. /package/dist/{utxo → esm/utxo}/btc/btc_chains.d.ts +0 -0
  516. /package/dist/{utxo → esm/utxo}/btc/btc_chains.js +0 -0
  517. /package/dist/{utxo → esm/utxo}/btc/btc_token.d.ts +0 -0
  518. /package/dist/{utxo → esm/utxo}/btc/btc_token.js +0 -0
  519. /package/dist/{utxo → esm/utxo}/btc/index.d.ts +0 -0
  520. /package/dist/{utxo → esm/utxo}/btc/index.js +0 -0
  521. /package/dist/{utxo → esm/utxo}/btc/network_params.d.ts +0 -0
  522. /package/dist/{utxo → esm/utxo}/btc/network_params.js +0 -0
  523. /package/dist/{utxo → esm/utxo}/btc/tools/asset_outpoint.d.ts +0 -0
  524. /package/dist/{utxo → esm/utxo}/btc/tools/asset_outpoint.js +0 -0
  525. /package/dist/{utxo → esm/utxo}/btc/tools/bitcoin_core.tool.d.ts +0 -0
  526. /package/dist/{utxo → esm/utxo}/btc/tools/bitcoin_core.tool.js +0 -0
  527. /package/dist/{utxo → esm/utxo}/btc/tools/esplora.tool.d.ts +0 -0
  528. /package/dist/{utxo → esm/utxo}/btc/tools/esplora.tool.js +0 -0
  529. /package/dist/{utxo → esm/utxo}/btc/tools/inscription_index.d.ts +0 -0
  530. /package/dist/{utxo → esm/utxo}/btc/tools/inscription_index.js +0 -0
  531. /package/dist/{utxo → esm/utxo}/btc/tools/ordiscan.tool.d.ts +0 -0
  532. /package/dist/{utxo → esm/utxo}/btc/tools/ordiscan.tool.js +0 -0
  533. /package/dist/{utxo → esm/utxo}/btc/tools/rare_sat_index.d.ts +0 -0
  534. /package/dist/{utxo → esm/utxo}/btc/tools/rare_sat_index.js +0 -0
  535. /package/dist/{utxo → esm/utxo}/btc/tools/rune_index.d.ts +0 -0
  536. /package/dist/{utxo → esm/utxo}/btc/tools/rune_index.js +0 -0
  537. /package/dist/{utxo → esm/utxo}/btc/tools/unisat.tool.d.ts +0 -0
  538. /package/dist/{utxo → esm/utxo}/btc/tools/unisat.tool.js +0 -0
  539. /package/dist/{utxo → esm/utxo}/coin_selection.d.ts +0 -0
  540. /package/dist/{utxo → esm/utxo}/coin_selection.js +0 -0
  541. /package/dist/{utxo → esm/utxo}/doge/doge_chains.d.ts +0 -0
  542. /package/dist/{utxo → esm/utxo}/doge/doge_chains.js +0 -0
  543. /package/dist/{utxo → esm/utxo}/doge/index.d.ts +0 -0
  544. /package/dist/{utxo → esm/utxo}/doge/index.js +0 -0
  545. /package/dist/{utxo → esm/utxo}/doge/network_params.d.ts +0 -0
  546. /package/dist/{utxo → esm/utxo}/doge/network_params.js +0 -0
  547. /package/dist/{utxo → esm/utxo}/ecc.d.ts +0 -0
  548. /package/dist/{utxo → esm/utxo}/ecc.js +0 -0
  549. /package/dist/{utxo → esm/utxo}/fee.d.ts +0 -0
  550. /package/dist/{utxo → esm/utxo}/fee.js +0 -0
  551. /package/dist/{utxo → esm/utxo}/index.d.ts +0 -0
  552. /package/dist/{utxo → esm/utxo}/index.js +0 -0
  553. /package/dist/{utxo → esm/utxo}/ltc/index.d.ts +0 -0
  554. /package/dist/{utxo → esm/utxo}/ltc/index.js +0 -0
  555. /package/dist/{utxo → esm/utxo}/ltc/ltc_chains.d.ts +0 -0
  556. /package/dist/{utxo → esm/utxo}/ltc/ltc_chains.js +0 -0
  557. /package/dist/{utxo → esm/utxo}/ltc/network_params.d.ts +0 -0
  558. /package/dist/{utxo → esm/utxo}/ltc/network_params.js +0 -0
  559. /package/dist/{utxo → esm/utxo}/script.d.ts +0 -0
  560. /package/dist/{utxo → esm/utxo}/script.js +0 -0
  561. /package/dist/{utxo → esm/utxo}/tools/broadcaster.d.ts +0 -0
  562. /package/dist/{utxo → esm/utxo}/tools/broadcaster.js +0 -0
  563. /package/dist/{utxo → esm/utxo}/tools/chain_tip_provider.d.ts +0 -0
  564. /package/dist/{utxo → esm/utxo}/tools/chain_tip_provider.js +0 -0
  565. /package/dist/{utxo → esm/utxo}/tools/fee_estimator.d.ts +0 -0
  566. /package/dist/{utxo → esm/utxo}/tools/fee_estimator.js +0 -0
  567. /package/dist/{utxo → esm/utxo}/tools/raw_transaction_provider.d.ts +0 -0
  568. /package/dist/{utxo → esm/utxo}/tools/raw_transaction_provider.js +0 -0
  569. /package/dist/{utxo → esm/utxo}/tools/utxo_provider.d.ts +0 -0
  570. /package/dist/{utxo → esm/utxo}/tools/utxo_provider.js +0 -0
  571. /package/dist/{utxo → esm/utxo}/unsigned_utxo_transaction.d.ts +0 -0
  572. /package/dist/{utxo → esm/utxo}/unsigned_utxo_transaction.js +0 -0
  573. /package/dist/{utxo → esm/utxo}/utxo.d.ts +0 -0
  574. /package/dist/{utxo → esm/utxo}/utxo.js +0 -0
  575. /package/dist/{utxo → esm/utxo}/utxo_chains.d.ts +0 -0
  576. /package/dist/{utxo → esm/utxo}/utxo_chains.js +0 -0
  577. /package/dist/{utxo → esm/utxo}/utxo_gas_pricing.d.ts +0 -0
  578. /package/dist/{utxo → esm/utxo}/utxo_gas_pricing.js +0 -0
  579. /package/dist/{utxo → esm/utxo}/utxo_network_params.d.ts +0 -0
  580. /package/dist/{utxo → esm/utxo}/utxo_network_params.js +0 -0
  581. /package/dist/{utxo → esm/utxo}/utxo_transaction_status.d.ts +0 -0
  582. /package/dist/{utxo → esm/utxo}/utxo_transaction_status.js +0 -0
@@ -0,0 +1,1305 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SolanaChain = void 0;
4
+ exports.signatureBase58FromBytes = signatureBase58FromBytes;
5
+ exports.bs58encode = bs58encode;
6
+ const web3_js_1 = require("@solana/web3.js");
7
+ const spl_token_1 = require("@solana/spl-token");
8
+ const chain_base_ts_1 = require("../chain.base.js");
9
+ const errors_ts_1 = require("../errors.js");
10
+ const network_type_ts_1 = require("../network_type.js");
11
+ const priority_ts_1 = require("../priority.js");
12
+ const transaction_status_ts_1 = require("../transaction_status.js");
13
+ const solana_transaction_status_ts_1 = require("./solana_transaction_status.js");
14
+ const solana_address_ts_1 = require("./solana_address.js");
15
+ const solana_token_ts_1 = require("./solana_token.js");
16
+ const unsigned_solana_transaction_ts_1 = require("./unsigned_solana_transaction.js");
17
+ const DEFAULT_COMPUTE_UNIT_LIMIT = 200_000;
18
+ /** Percentile (0..1) of recent prioritization fees picked per Priority. */
19
+ const SOL_PRIORITY_PERCENTILE = {
20
+ [priority_ts_1.Priority.SLOW]: 0.25,
21
+ [priority_ts_1.Priority.NORMAL]: 0.5,
22
+ [priority_ts_1.Priority.FAST]: 0.9,
23
+ };
24
+ /**
25
+ * Solana is account-based but very different from EVM (see docs/solana.md). Key choices made
26
+ * for depositron:
27
+ * - Transfers always build a `VersionedTransaction` (MessageV0) — legacy transactions are
28
+ * deprecated and can't address account-lookup tables for fee reduction.
29
+ * - The fee payer is always the sender (no relayer pattern here).
30
+ * - SPL transfers use `transferChecked` (which asserts the recipient mint matches the
31
+ * declared mint, defeating the entire class of "wrong-token-decimals" attacks).
32
+ * - When the recipient doesn't have an ATA for the mint, we *prepend* a create-ATA
33
+ * instruction paid by the sender. This costs ~2039 lamports of rent-exempt deposit.
34
+ * - We do NOT consult a curated registry to determine SPL vs Token-2022 —
35
+ * instead we read the mint account owner at build time. That's one RPC per transfer but
36
+ * it's authoritative.
37
+ */
38
+ class SolanaChain extends chain_base_ts_1.Chain {
39
+ defaultRpcUrl;
40
+ rpcUrl;
41
+ rpcUrls;
42
+ legacyRpcEnvNames;
43
+ explorerClusterSuffix;
44
+ chainAgnosticGenesisHash;
45
+ jito;
46
+ _nativeToken;
47
+ _connection = null;
48
+ _rpcUrlIndex = 0;
49
+ constructor(init) {
50
+ super(init.chainId, init.name, network_type_ts_1.NetworkType.SOLANA, init.blockTimeSeconds, init.nativeSymbol, init.explorerBaseUrl);
51
+ this.defaultRpcUrl = init.defaultRpcUrl;
52
+ this.rpcUrl = init.rpcUrl;
53
+ this.rpcUrls = init.rpcUrls ?? [];
54
+ if (this.rpcUrls.length > 1) {
55
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `SolanaChainInit.rpcUrls accepts only ONE endpoint in 0.3.0 (got ${this.rpcUrls.length}). Automatic failover retry is deferred to a follow-up release; passing >1 endpoint would silently discard entries.`, { chainId: init.chainId });
56
+ }
57
+ this.legacyRpcEnvNames = init.legacyRpcEnvNames ?? [];
58
+ this.explorerClusterSuffix = init.explorerClusterSuffix ?? '';
59
+ this.chainAgnosticGenesisHash = init.chainAgnosticGenesisHash;
60
+ this.jito = init.jito ?? null;
61
+ this._nativeToken = solana_token_ts_1.SolanaToken.native(init.chainId, init.nativeSymbol, init.nativeDecimals ?? 9);
62
+ (0, network_type_ts_1.registerNonEvmChain)(init.chainId, network_type_ts_1.NetworkType.SOLANA);
63
+ }
64
+ get nativeToken() {
65
+ return this._nativeToken;
66
+ }
67
+ getConnection() {
68
+ if (this._connection)
69
+ return this._connection;
70
+ const rpcUrl = this.readRpcUrl();
71
+ this._connection = new web3_js_1.Connection(rpcUrl, { commitment: 'confirmed' });
72
+ return this._connection;
73
+ }
74
+ /**
75
+ * Network-aware priority fee suggestion in microlamports per compute unit.
76
+ * Samples `getRecentPrioritizationFees({ lockedWritableAccounts: [] })` (cluster-wide, ~150 most recent slots) and
77
+ * picks a percentile per priority:
78
+ * - SLOW = p25
79
+ * - NORMAL = p50
80
+ * - FAST = p90
81
+ * Returns 0 if the cluster has been so quiet that the chosen percentile is 0 (legitimate
82
+ * outcome on devnet / off-peak mainnet). Caller plugs this into
83
+ * `ComputeBudgetProgram.setComputeUnitPrice({ microLamports })`.
84
+ */
85
+ async suggestPriorityFeeMicroLamports(priority) {
86
+ const samples = await this.getConnection().getRecentPrioritizationFees({
87
+ lockedWritableAccounts: [],
88
+ });
89
+ const fees = samples
90
+ .map((s) => s.prioritizationFee)
91
+ .filter((f) => Number.isFinite(f) && f >= 0)
92
+ .sort((a, b) => a - b);
93
+ if (fees.length === 0)
94
+ return 0;
95
+ const percentile = SOL_PRIORITY_PERCENTILE[priority];
96
+ const idx = Math.min(fees.length - 1, Math.floor((fees.length - 1) * percentile));
97
+ return fees[idx];
98
+ }
99
+ /**
100
+ * Env var name for a Solana chain by chain id — mirrors Python's
101
+ * `SolanaChain.rpc_url_env_for_chain_id` (impl/solana/base.py:421-423)
102
+ * exactly, including the signed chainId. Shell operators must set via
103
+ * dotenv / docker / k8s since `SOLANA_-2000_RPC_URL` is not a settable
104
+ * name in sh/bash/zsh.
105
+ */
106
+ static rpcUrlEnvForChainId(chainId) {
107
+ return `SOLANA_${chainId}_RPC_URL`;
108
+ }
109
+ /**
110
+ * Resolution precedence, mirrors omnichain-py/impl/solana/base.py:424-434
111
+ * plus a TS-side legacy fallback for consumers with pre-v0 env-var names:
112
+ * 1. constructor `rpcUrl`
113
+ * 2. env `<NAME_UPPERCASE_UNDERSCORED>_RPC_URL`
114
+ * 3. env `SOLANA_<chainId>_RPC_URL` (Python parity — signed)
115
+ * 4. env from `legacyRpcEnvNames` (if configured — e.g. mainnet checks
116
+ * the pre-rename `SOLANA_RPC_URL` here)
117
+ * 5. `defaultRpcUrl` (never throws — public cluster)
118
+ */
119
+ resolvedRpcUrlForRedaction() {
120
+ try {
121
+ return this.readRpcUrl();
122
+ }
123
+ catch {
124
+ return null;
125
+ }
126
+ }
127
+ async rpcWrap(fn, label) {
128
+ try {
129
+ return await fn();
130
+ }
131
+ catch (err) {
132
+ if (err instanceof errors_ts_1.ChainError)
133
+ throw err;
134
+ const rpc = this.resolvedRpcUrlForRedaction();
135
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana ${label} failed on ${this.name}`, rpc), { chainId: this.chainId }, (0, errors_ts_1.sanitizeCause)(err, rpc));
136
+ }
137
+ }
138
+ readRpcUrl() {
139
+ if (this.rpcUrl && this.rpcUrl.trim().length > 0)
140
+ return this.rpcUrl.trim();
141
+ if (this.rpcUrls.length > 0) {
142
+ for (const candidate of this.rpcUrls) {
143
+ if (candidate && candidate.trim().length > 0)
144
+ return candidate.trim();
145
+ }
146
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcNotConfigured, `${this.name}: rpcUrls was supplied but every entry is blank; refusing to fall back to env or the public default cluster`, { chainId: this.chainId });
147
+ }
148
+ const env = globalThis.process?.env;
149
+ const candidates = [
150
+ this.name.replace(/ /g, '_').toUpperCase() + '_RPC_URL',
151
+ SolanaChain.rpcUrlEnvForChainId(this.chainId),
152
+ ...this.legacyRpcEnvNames,
153
+ ];
154
+ for (const key of candidates) {
155
+ const v = env?.[key];
156
+ if (v && v.trim().length > 0)
157
+ return v.trim();
158
+ }
159
+ return this.defaultRpcUrl;
160
+ }
161
+ getWalletExplorerUrl(address) {
162
+ return `${this.explorerBaseUrl}/account/${address}${this.explorerClusterSuffix}`;
163
+ }
164
+ getTokenExplorerUrl(tokenIdentifier) {
165
+ if (!tokenIdentifier) {
166
+ return this.explorerBaseUrl + this.explorerClusterSuffix;
167
+ }
168
+ return `${this.explorerBaseUrl}/token/${tokenIdentifier}${this.explorerClusterSuffix}`;
169
+ }
170
+ getTransactionExplorerUrl(txHash) {
171
+ return `${this.explorerBaseUrl}/tx/${txHash}${this.explorerClusterSuffix}`;
172
+ }
173
+ validateAddress(raw) {
174
+ try {
175
+ new solana_address_ts_1.SolanaAddress(raw);
176
+ return true;
177
+ }
178
+ catch {
179
+ return false;
180
+ }
181
+ }
182
+ validateTokenIdentifier(raw) {
183
+ if (raw === undefined)
184
+ return true; // native SOL
185
+ return this.validateAddress(raw);
186
+ }
187
+ async getBalance(owner, tokenIdentifier) {
188
+ if (!this.validateAddress(owner)) {
189
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid Solana address: ${owner}`, {
190
+ chainId: this.chainId,
191
+ address: owner,
192
+ });
193
+ }
194
+ const connection = this.getConnection();
195
+ const ownerPk = new web3_js_1.PublicKey(owner);
196
+ try {
197
+ if (tokenIdentifier === undefined) {
198
+ return BigInt(await connection.getBalance(ownerPk));
199
+ }
200
+ if (!this.validateAddress(tokenIdentifier)) {
201
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidTokenIdentifier, `Invalid Solana mint: ${tokenIdentifier}`, { chainId: this.chainId, identifier: tokenIdentifier });
202
+ }
203
+ const mintPk = new web3_js_1.PublicKey(tokenIdentifier);
204
+ const programId = await this.resolveTokenProgramId(mintPk);
205
+ const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(mintPk, ownerPk, false, programId);
206
+ try {
207
+ const acct = await (0, spl_token_1.getAccount)(connection, ata, undefined, programId);
208
+ return acct.amount;
209
+ }
210
+ catch {
211
+ // No ATA → balance 0.
212
+ return 0n;
213
+ }
214
+ }
215
+ catch (err) {
216
+ if (err instanceof errors_ts_1.ChainError)
217
+ throw err;
218
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, `Failed to read Solana balance for ${owner}/${tokenIdentifier ?? 'NATIVE'}: ${err.message}`, { chainId: this.chainId, address: owner, identifier: tokenIdentifier }, err);
219
+ }
220
+ }
221
+ async createTransferUnsignedTransaction(req) {
222
+ if (!req.from) {
223
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, 'Solana transfers require an explicit `from` (no implicit signer)', { chainId: this.chainId });
224
+ }
225
+ if (!this.validateAddress(req.from)) {
226
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid sender: ${req.from}`, {
227
+ chainId: this.chainId,
228
+ address: req.from,
229
+ });
230
+ }
231
+ if (!this.validateAddress(req.to)) {
232
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid recipient: ${req.to}`, {
233
+ chainId: this.chainId,
234
+ address: req.to,
235
+ });
236
+ }
237
+ if (!this.validateTokenIdentifier(req.tokenIdentifier)) {
238
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidTokenIdentifier, `Invalid token identifier: ${req.tokenIdentifier}`, { chainId: this.chainId, identifier: req.tokenIdentifier });
239
+ }
240
+ // gasPricing not yet consumed by Solana builder (Phase 2 follow-up);
241
+ // reject rather than silently ignore.
242
+ if (req.gasPricing !== undefined) {
243
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, 'CreateTransferRequest.gasPricing is not yet consumed by SolanaChain (Phase 2 follow-up). Use `priorityFeeMicroLamportsPerCu` / `computeUnitLimit` on SolanaTransferOptions for now.', { chainId: this.chainId });
244
+ }
245
+ // isFullBalance requires a base-fee + rent-exempt reserve before
246
+ // it can be safely wired — sending all lamports leaves 0 for the
247
+ // 5000-lamport base fee (and ATA rent when feePayer === from on
248
+ // the SPL path). Deferred to a follow-up card.
249
+ if (req.isFullBalance === true) {
250
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, 'CreateTransferRequest.isFullBalance is not yet supported on SolanaChain — pass `amount` or `amountHr` explicitly.', { chainId: this.chainId });
251
+ }
252
+ // Only fetch decimals when amountHr is the input form — avoids the
253
+ // extra getMint RPC on every bigint-amount transfer. Native path
254
+ // uses SDK-declared decimals; SPL path uses resolveMintDecimals
255
+ // (which already throws on RPC failure — no defensive fallback).
256
+ const tokenDecimals = req.amountHr !== undefined
257
+ ? req.tokenIdentifier === undefined
258
+ ? this._nativeToken.decimals
259
+ : await this.resolveMintDecimals(new web3_js_1.PublicKey(req.tokenIdentifier))
260
+ : 0;
261
+ const resolvedAmount = (0, chain_base_ts_1.resolveTransferAmount)(req, tokenDecimals);
262
+ const amountMr = resolvedAmount.kind === 'exact' ? resolvedAmount.amountMr : 0n;
263
+ if (amountMr <= 0n) {
264
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Transfer amount must be positive (got ${amountMr})`, { chainId: this.chainId });
265
+ }
266
+ if (req.feePayer !== undefined && !this.validateAddress(req.feePayer)) {
267
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid feePayer: ${req.feePayer}`, {
268
+ chainId: this.chainId,
269
+ address: req.feePayer,
270
+ });
271
+ }
272
+ const connection = this.getConnection();
273
+ const fromPk = new web3_js_1.PublicKey(req.from);
274
+ const toPk = new web3_js_1.PublicKey(req.to);
275
+ const feePayerAddress = req.feePayer ?? req.from;
276
+ const feePayerPk = new web3_js_1.PublicKey(feePayerAddress);
277
+ const instructions = [];
278
+ if (req.computeUnitLimit !== undefined || req.priorityFeeMicroLamportsPerCu !== undefined) {
279
+ instructions.push(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
280
+ units: req.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT,
281
+ }));
282
+ if (req.priorityFeeMicroLamportsPerCu !== undefined) {
283
+ instructions.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
284
+ microLamports: req.priorityFeeMicroLamportsPerCu,
285
+ }));
286
+ }
287
+ }
288
+ if (req.tokenIdentifier === undefined) {
289
+ instructions.push(web3_js_1.SystemProgram.transfer({
290
+ fromPubkey: fromPk,
291
+ toPubkey: toPk,
292
+ lamports: amountMr,
293
+ }));
294
+ }
295
+ else {
296
+ const mintPk = new web3_js_1.PublicKey(req.tokenIdentifier);
297
+ const programId = await this.resolveTokenProgramId(mintPk);
298
+ // If amountHr wasn't the input form, tokenDecimals is still 0 and
299
+ // we haven't fetched the mint yet — do it now for the transfer-
300
+ // checked instruction (which requires the real decimals).
301
+ const decimals = tokenDecimals > 0 ? tokenDecimals : await this.resolveMintDecimals(mintPk);
302
+ const sourceAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mintPk, fromPk, false, programId);
303
+ const destAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mintPk, toPk, false, programId);
304
+ // Create the destination ATA when missing — the fee payer pays rent.
305
+ const destInfo = await connection.getAccountInfo(destAta);
306
+ if (!destInfo) {
307
+ instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(feePayerPk, destAta, toPk, mintPk, programId));
308
+ }
309
+ instructions.push((0, spl_token_1.createTransferCheckedInstruction)(sourceAta, mintPk, destAta, fromPk, amountMr, decimals, [], programId));
310
+ }
311
+ const { blockhash, lastValidBlockHeight } = await this.rpcWrap(() => connection.getLatestBlockhash('finalized'), 'getLatestBlockhash');
312
+ const alts = validateAltList(req.addressLookupTables, this.chainId);
313
+ let message;
314
+ try {
315
+ message = web3_js_1.MessageV0.compile({
316
+ payerKey: feePayerPk,
317
+ instructions,
318
+ recentBlockhash: blockhash,
319
+ addressLookupTableAccounts: alts,
320
+ });
321
+ }
322
+ catch (err) {
323
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana createTransferUnsignedTransaction: MessageV0.compile failed — instruction or ALT layout invalid`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
324
+ }
325
+ const tx = new web3_js_1.VersionedTransaction(message);
326
+ let serializedSize;
327
+ try {
328
+ serializedSize = tx.serialize().length;
329
+ }
330
+ catch (err) {
331
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds the serialize buffer; supply addressLookupTables to compress the account list`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
332
+ }
333
+ if (serializedSize > 1232) {
334
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Compiled Solana transfer exceeds 1232-byte wire limit; supply addressLookupTables to compress the account list`, { chainId: this.chainId });
335
+ }
336
+ return new unsigned_solana_transaction_ts_1.UnsignedSolanaTransaction({
337
+ chainId: this.chainId,
338
+ transaction: tx,
339
+ feePayer: feePayerAddress,
340
+ recentBlockhash: blockhash,
341
+ lastValidBlockHeight,
342
+ instructions,
343
+ addressLookupTables: alts,
344
+ });
345
+ }
346
+ /**
347
+ * Wraps a caller-supplied list of program instructions into a fully-formed
348
+ * UnsignedSolanaTransaction. Used by depositron's SOL_INSTRUCTIONS action type to support
349
+ * arbitrary program calls (staking, swaps, custom programs) without the SDK having to
350
+ * understand the instruction semantics. The SDK still owns the envelope: CU limit + price,
351
+ * MessageV0 compilation, fresh blockhash, VersionedTransaction wrapping.
352
+ *
353
+ * Caller is responsible for: instruction correctness, signer-account constraints (only the
354
+ * single key the caller will sign with — typically the vault key — can be flagged as signer),
355
+ * ATA creation (if any instruction touches an ATA that doesn't exist yet), and decimals
356
+ * validation (no automatic `transferChecked` fallback here).
357
+ */
358
+ async createInstructionsUnsignedTransaction(req) {
359
+ if (!req.from || !this.validateAddress(req.from)) {
360
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid sender: ${req.from}`, {
361
+ chainId: this.chainId,
362
+ address: req.from,
363
+ });
364
+ }
365
+ if (req.feePayer !== undefined && !this.validateAddress(req.feePayer)) {
366
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid feePayer: ${req.feePayer}`, {
367
+ chainId: this.chainId,
368
+ address: req.feePayer,
369
+ });
370
+ }
371
+ if (!Array.isArray(req.instructions) || req.instructions.length === 0) {
372
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, 'SolanaChain.createInstructionsUnsignedTransaction requires at least one instruction', { chainId: this.chainId });
373
+ }
374
+ const feePayerAddress = req.feePayer ?? req.from;
375
+ const feePayerPk = new web3_js_1.PublicKey(feePayerAddress);
376
+ const allIxs = [];
377
+ if (req.computeUnitLimit !== undefined || req.priorityFeeMicroLamportsPerCu !== undefined) {
378
+ allIxs.push(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
379
+ units: req.computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT,
380
+ }));
381
+ if (req.priorityFeeMicroLamportsPerCu !== undefined) {
382
+ allIxs.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
383
+ microLamports: req.priorityFeeMicroLamportsPerCu,
384
+ }));
385
+ }
386
+ }
387
+ for (const ix of req.instructions)
388
+ allIxs.push(ix);
389
+ const connection = this.getConnection();
390
+ const { blockhash, lastValidBlockHeight } = await this.rpcWrap(() => connection.getLatestBlockhash('finalized'), 'getLatestBlockhash');
391
+ const alts = validateAltList(req.addressLookupTables, this.chainId);
392
+ let message;
393
+ try {
394
+ message = web3_js_1.MessageV0.compile({
395
+ payerKey: feePayerPk,
396
+ instructions: allIxs,
397
+ recentBlockhash: blockhash,
398
+ addressLookupTableAccounts: alts,
399
+ });
400
+ }
401
+ catch (err) {
402
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana createInstructionsUnsignedTransaction: MessageV0.compile failed — instruction or ALT layout invalid`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
403
+ }
404
+ const tx = new web3_js_1.VersionedTransaction(message);
405
+ let serializedSize;
406
+ try {
407
+ serializedSize = tx.serialize().length;
408
+ }
409
+ catch (err) {
410
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds the serialize buffer; supply addressLookupTables to compress the account list`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
411
+ }
412
+ if (serializedSize > 1232) {
413
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds 1232-byte wire limit; supply addressLookupTables to compress the account list`, { chainId: this.chainId });
414
+ }
415
+ return new unsigned_solana_transaction_ts_1.UnsignedSolanaTransaction({
416
+ chainId: this.chainId,
417
+ transaction: tx,
418
+ feePayer: feePayerAddress,
419
+ recentBlockhash: blockhash,
420
+ lastValidBlockHeight,
421
+ instructions: allIxs,
422
+ addressLookupTables: alts,
423
+ });
424
+ }
425
+ /**
426
+ * Returns a fresh UnsignedSolanaTransaction with the same instructions but a newly-fetched
427
+ * blockhash. Use when a previously-built tx couldn't broadcast inside its blockhash window
428
+ * (~60s on mainnet) — Solana drops txs whose blockhash has expired. Caller must re-sign:
429
+ * the new signed message has a different recent_blockhash byte sequence, so any existing
430
+ * signature is invalid.
431
+ */
432
+ async refreshBlockhash(unsigned) {
433
+ const connection = this.getConnection();
434
+ const { blockhash, lastValidBlockHeight } = await this.rpcWrap(() => connection.getLatestBlockhash('finalized'), 'getLatestBlockhash');
435
+ if (blockhash === unsigned.recentBlockhash)
436
+ return unsigned;
437
+ const message = web3_js_1.MessageV0.compile({
438
+ payerKey: unsigned.feePayerPubkey,
439
+ instructions: unsigned.instructions,
440
+ recentBlockhash: blockhash,
441
+ addressLookupTableAccounts: unsigned.addressLookupTables,
442
+ });
443
+ return new unsigned_solana_transaction_ts_1.UnsignedSolanaTransaction({
444
+ chainId: unsigned.chainId,
445
+ transaction: new web3_js_1.VersionedTransaction(message),
446
+ feePayer: unsigned.feePayer,
447
+ recentBlockhash: blockhash,
448
+ lastValidBlockHeight,
449
+ instructions: unsigned.instructions,
450
+ addressLookupTables: unsigned.addressLookupTables,
451
+ });
452
+ }
453
+ /**
454
+ * Simulates the tx and right-sizes its setComputeUnitLimit instruction (10% headroom).
455
+ * Lowers priority-fee cost because the fee = CU price × CU limit; oversized limits pay for
456
+ * unused compute. Returns the unsigned untouched if it has no CU-limit ix or simulation didn't
457
+ * report unitsConsumed. Throws ChainError(SimulationFailed) when the sim returns `err`.
458
+ */
459
+ async estimateAndApplyCu(unsigned) {
460
+ const connection = this.getConnection();
461
+ const sim = await this.rpcWrap(() => connection.simulateTransaction(unsigned.transaction, {
462
+ sigVerify: false,
463
+ replaceRecentBlockhash: true,
464
+ commitment: 'confirmed',
465
+ }), 'simulateTransaction');
466
+ if (sim.value.err) {
467
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.SimulationFailed, `Solana simulation rejected the tx: ${JSON.stringify(sim.value.err)}`, { chainId: this.chainId });
468
+ }
469
+ const consumed = sim.value.unitsConsumed;
470
+ if (!consumed)
471
+ return unsigned;
472
+ const newLimit = Math.ceil(consumed * 1.1);
473
+ const setLimitIxIndex = unsigned.instructions.findIndex((ix) => ix.programId.equals(web3_js_1.ComputeBudgetProgram.programId) &&
474
+ // setComputeUnitLimit ix discriminator is 0x02 in the first data byte.
475
+ ix.data.length >= 1 &&
476
+ ix.data[0] === 0x02);
477
+ if (setLimitIxIndex === -1)
478
+ return unsigned;
479
+ const newInstructions = [...unsigned.instructions];
480
+ newInstructions[setLimitIxIndex] = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
481
+ units: newLimit,
482
+ });
483
+ const message = web3_js_1.MessageV0.compile({
484
+ payerKey: unsigned.feePayerPubkey,
485
+ instructions: newInstructions,
486
+ recentBlockhash: unsigned.recentBlockhash,
487
+ addressLookupTableAccounts: unsigned.addressLookupTables,
488
+ });
489
+ return new unsigned_solana_transaction_ts_1.UnsignedSolanaTransaction({
490
+ chainId: unsigned.chainId,
491
+ transaction: new web3_js_1.VersionedTransaction(message),
492
+ feePayer: unsigned.feePayer,
493
+ recentBlockhash: unsigned.recentBlockhash,
494
+ lastValidBlockHeight: unsigned.lastValidBlockHeight,
495
+ instructions: newInstructions,
496
+ addressLookupTables: unsigned.addressLookupTables,
497
+ });
498
+ }
499
+ /** Whether the given error came from a preflight simulation rejection (vs network/transport). */
500
+ static isSimulationError(err) {
501
+ if (err instanceof errors_ts_1.ChainError && err.kind === errors_ts_1.ChainErrorKinds.SimulationFailed)
502
+ return true;
503
+ const msg = err?.message ?? '';
504
+ return /simulation failed|transaction simulation failed/i.test(msg);
505
+ }
506
+ /** Whether the given error indicates the tx's blockhash has expired and a refresh is needed. */
507
+ static isBlockhashExpiredError(err) {
508
+ const msg = err?.message ?? '';
509
+ return /blockhash not found|expired blockhash|blockhash.*expired/i.test(msg);
510
+ }
511
+ async getTransactionStatus(txHash, opts) {
512
+ if (Array.isArray(txHash)) {
513
+ return runSolanaBatchStatus(txHash, (h, batchSignal) => {
514
+ const composedSignal = opts?.signal
515
+ ? anySignal(opts.signal, batchSignal)
516
+ : batchSignal;
517
+ return this.getSingleSolanaStatus(h, { ...opts, signal: composedSignal });
518
+ });
519
+ }
520
+ return this.getSingleSolanaStatus(txHash, opts);
521
+ }
522
+ async getSingleSolanaStatus(txHash, opts) {
523
+ if (opts?.confirmations !== undefined && opts.confirmations > 1 && !opts.wait) {
524
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `getTransactionStatus: confirmations > 1 requires wait: true (a single status read cannot enforce finality)`, { chainId: this.chainId, txHash });
525
+ }
526
+ if (!opts?.wait)
527
+ return this.getSolanaStatusOnce(txHash);
528
+ if (opts.signal?.aborted) {
529
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `getTransactionStatus aborted before first poll`, { chainId: this.chainId, txHash });
530
+ }
531
+ const c = opts.confirmations ?? 1;
532
+ if (c !== 1 && c < 32) {
533
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana getTransactionStatus.confirmations must be 1 (confirmed) or >=32 (finalized); ${c} would ambiguously map otherwise.`, { chainId: this.chainId, txHash });
534
+ }
535
+ if (opts.timeoutMs === undefined) {
536
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `getTransactionStatus: wait: true requires an explicit timeoutMs. Unbounded polling would pin an RPC worker + connection forever if the tx is dropped.`, { chainId: this.chainId, txHash });
537
+ }
538
+ if (opts.timeoutMs < 0) {
539
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `getTransactionStatus: timeoutMs must be >= 0`, { chainId: this.chainId, txHash });
540
+ }
541
+ const deadline = Date.now() + opts.timeoutMs;
542
+ const pollMs = Math.max(400, this.blockTimeSeconds * 1000);
543
+ const wantFinalized = c >= 32;
544
+ let last;
545
+ while (true) {
546
+ last = await this.getSolanaStatusOnce(txHash);
547
+ if (last.status === 'Success' || last.status === 'Failed') {
548
+ if (!wantFinalized)
549
+ return last;
550
+ let sigStatus;
551
+ try {
552
+ sigStatus = await this.getConnection().getSignatureStatus(txHash, { searchTransactionHistory: true });
553
+ }
554
+ catch (err) {
555
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Failed to poll signature status for finalization on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, txHash }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
556
+ }
557
+ if (sigStatus.value?.confirmationStatus === 'finalized')
558
+ return last;
559
+ if (Date.now() >= deadline) {
560
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, `getTransactionStatus timed out after ${opts.timeoutMs}ms before reaching finalized; last confirmation status: ${sigStatus.value?.confirmationStatus ?? 'unknown'}. Consumer must NOT credit as final.`, { chainId: this.chainId, txHash });
561
+ }
562
+ }
563
+ else if (Date.now() >= deadline) {
564
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, `getTransactionStatus timed out after ${opts.timeoutMs}ms; last observed status was ${last.status}. Consumer must NOT credit as final AND must NOT re-sign — the tx may still land. Re-broadcast the same signed bytes or continue polling with the same txHash.`, { chainId: this.chainId, txHash });
565
+ }
566
+ await solanaInterruptibleSleep(pollMs, opts.signal);
567
+ if (opts.signal?.aborted) {
568
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `getTransactionStatus aborted mid-poll`, { chainId: this.chainId, txHash });
569
+ }
570
+ }
571
+ }
572
+ async getSolanaStatusOnce(txHash) {
573
+ const connection = this.getConnection();
574
+ // Best-effort read of the current rpc URL for message/cause scrubbing.
575
+ // readRpcUrl throws when nothing is configured; there'd be no
576
+ // network call in that case, but defensive null keeps the sanitizer
577
+ // total.
578
+ let scrubUrl = null;
579
+ try {
580
+ scrubUrl = this.readRpcUrl();
581
+ }
582
+ catch {
583
+ scrubUrl = null;
584
+ }
585
+ let tx;
586
+ try {
587
+ tx = await connection.getTransaction(txHash, {
588
+ commitment: 'confirmed',
589
+ maxSupportedTransactionVersion: 0,
590
+ });
591
+ }
592
+ catch (err) {
593
+ const rawMsg = err instanceof Error ? err.message : String(err);
594
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Failed to read Solana tx ${txHash}: ${rawMsg}`, scrubUrl), { chainId: this.chainId, txHash }, (0, errors_ts_1.sanitizeCause)(err, scrubUrl));
595
+ }
596
+ if (!tx) {
597
+ // Full tx not fetchable; fall back to signature status. Consume BOTH
598
+ // fields (`confirmationStatus` + `err`) — the previous fix that
599
+ // always returned Pending on settled-but-unfetchable let a settled-
600
+ // FAILED tx poll indefinitely.
601
+ let sig;
602
+ try {
603
+ sig = await connection.getSignatureStatus(txHash, { searchTransactionHistory: true });
604
+ }
605
+ catch (err) {
606
+ const rawMsg = err instanceof Error ? err.message : String(err);
607
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Failed to read Solana signature status ${txHash}: ${rawMsg}`, scrubUrl), { chainId: this.chainId, txHash }, (0, errors_ts_1.sanitizeCause)(err, scrubUrl));
608
+ }
609
+ if (!sig || !sig.value)
610
+ return solana_transaction_status_ts_1.SolanaTransactionStatus.notFound(this.chainId);
611
+ const settled = sig.value.confirmationStatus === 'finalized' ||
612
+ sig.value.confirmationStatus === 'confirmed';
613
+ if (settled && sig.value.err) {
614
+ // Fees are not reconstructable from a sig-status only — factory
615
+ // now accepts fees: null for exactly this case.
616
+ return solana_transaction_status_ts_1.SolanaTransactionStatus.failed({
617
+ chainId: this.chainId,
618
+ inclusionAt: null,
619
+ error: { code: 'REVERTED', reason: JSON.stringify(sig.value.err) },
620
+ fees: null,
621
+ });
622
+ }
623
+ // settled-Success without a fetchable body OR still propagating —
624
+ // keep polling. NotFound here would misreport a settled deposit.
625
+ return solana_transaction_status_ts_1.SolanaTransactionStatus.pending(this.chainId);
626
+ }
627
+ if (!tx.meta) {
628
+ // A returned tx without meta is a valid RPC response shape (some
629
+ // very old txs or unusual nodes). Report Pending so consumers keep
630
+ // polling rather than throwing from a status read; matches the
631
+ // _decodeBalanceChanges guard at the same file.
632
+ return solana_transaction_status_ts_1.SolanaTransactionStatus.pending(this.chainId);
633
+ }
634
+ const accounts = tx.transaction.message.staticAccountKeys.map((k) => k.toBase58());
635
+ const feePayer = accounts[0] ?? '';
636
+ if (feePayer.length === 0) {
637
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionDecodeFailed, `Solana tx ${txHash} has no fee_payer account`, { chainId: this.chainId, txHash });
638
+ }
639
+ const feeLamports = BigInt(tx.meta.fee);
640
+ const rawCu = tx.meta.computeUnitsConsumed;
641
+ const computeUnitsConsumed = rawCu === undefined || rawCu === null ? null : BigInt(rawCu);
642
+ const preLamports = BigInt(tx.meta.preBalances?.[0] ?? 0);
643
+ const postLamports = BigInt(tx.meta.postBalances?.[0] ?? 0);
644
+ const fees = new solana_transaction_status_ts_1.SolanaTransactionFees({
645
+ feePayer,
646
+ feeLamports,
647
+ computeUnitsConsumed,
648
+ netLamportsChangeByFeePayer: postLamports - preLamports,
649
+ });
650
+ const inclusionAt = tx.blockTime ? new Date(tx.blockTime * 1000) : null;
651
+ if (tx.meta.err) {
652
+ return solana_transaction_status_ts_1.SolanaTransactionStatus.failed({
653
+ chainId: this.chainId,
654
+ inclusionAt,
655
+ error: { code: 'REVERTED', reason: JSON.stringify(tx.meta.err) },
656
+ fees,
657
+ });
658
+ }
659
+ // Wrap the decoder so a malformed uiTokenAmount.amount / pre/postBalance
660
+ // (BigInt(...) throws SyntaxError on non-numeric strings) surfaces as
661
+ // ChainError(TransactionDecodeFailed) rather than a raw SyntaxError.
662
+ // Mirrors evm_chain.ts:decodeBalanceChanges catch.
663
+ let balanceChanges;
664
+ try {
665
+ balanceChanges = this._decodeBalanceChanges(tx);
666
+ }
667
+ catch (err) {
668
+ if (err instanceof errors_ts_1.ChainError)
669
+ throw err;
670
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionDecodeFailed, `Failed to decode Solana tx ${txHash}: ${err instanceof Error ? err.message : String(err)}`, { chainId: this.chainId, txHash }, err instanceof Error ? err : undefined);
671
+ }
672
+ return solana_transaction_status_ts_1.SolanaTransactionStatus.successful({
673
+ chainId: this.chainId,
674
+ inclusionAt,
675
+ balanceChanges,
676
+ fees,
677
+ });
678
+ }
679
+ async getChainTipHeight() {
680
+ return this.rpcWrap(() => this.getConnection().getSlot('confirmed'), 'getSlot');
681
+ }
682
+ async broadcast(signed, opts) {
683
+ if (opts && opts.signal !== undefined) {
684
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.FeatureNotSupported, `Solana broadcast: signal is not honored in 0.3.0 (silently ignoring would let a caller conclude 'not sent' while the tx still lands). Cancellation returns in 0.3.1.`, { chainId: this.chainId });
685
+ }
686
+ let bytes;
687
+ if (typeof signed === 'string') {
688
+ const stripped = signed.startsWith('0x') ? signed.slice(2) : signed;
689
+ if (!/^[0-9a-fA-F]+$/.test(stripped) || stripped.length % 2 !== 0 || stripped.length === 0) {
690
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana broadcast: signed must be Uint8Array or 0x-prefixed hex; got malformed string (len ${signed.length}). Base58/base64 encodings are NOT accepted — decode to bytes first.`, { chainId: this.chainId });
691
+ }
692
+ bytes = new Uint8Array(Buffer.from(stripped, 'hex'));
693
+ }
694
+ else {
695
+ bytes = signed;
696
+ }
697
+ if (bytes.length < 65) {
698
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana broadcast: signed bytes must be >= 65 bytes (1 sig-count + 64-byte signature), got ${bytes.length}`, { chainId: this.chainId });
699
+ }
700
+ if (bytes.length > 1232) {
701
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Solana broadcast: signed tx is ${bytes.length} bytes, exceeds 1232-byte wire limit`, { chainId: this.chainId });
702
+ }
703
+ if (opts?.via === 'jito') {
704
+ if (!this.jito) {
705
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.FeatureNotSupported, `Solana broadcast: via: 'jito' requires SolanaChain to be constructed with jito config`, { chainId: this.chainId });
706
+ }
707
+ if (opts.skipPreflight !== undefined || opts.maxRetries !== undefined) {
708
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana broadcast: skipPreflight/maxRetries do not apply to the Jito path (block-engine has its own retry semantics)`, { chainId: this.chainId });
709
+ }
710
+ const signature = signatureBase58FromBytes(bytes);
711
+ await this.submitJitoBundle([bytes]);
712
+ return signature;
713
+ }
714
+ try {
715
+ const sig = await this.getConnection().sendRawTransaction(bytes, {
716
+ skipPreflight: opts?.skipPreflight ?? false,
717
+ maxRetries: opts?.maxRetries,
718
+ });
719
+ return sig;
720
+ }
721
+ catch (err) {
722
+ const rawMsg = (err instanceof Error ? err.message : String(err)).toLowerCase();
723
+ if (rawMsg.includes('already been processed') || rawMsg.includes('already processed')) {
724
+ return signatureBase58FromBytes(bytes);
725
+ }
726
+ throw this.classifyBroadcastError(err);
727
+ }
728
+ }
729
+ async submitJitoBundle(signedTxs, opts) {
730
+ if (!this.jito) {
731
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.FeatureNotSupported, 'Jito bundle submission requires SolanaChain to be constructed with jito config', { chainId: this.chainId });
732
+ }
733
+ const body = {
734
+ jsonrpc: '2.0',
735
+ id: 1,
736
+ method: 'sendBundle',
737
+ params: [
738
+ signedTxs.map((b) => Buffer.from(b).toString('base64')),
739
+ { encoding: 'base64' },
740
+ ],
741
+ };
742
+ const jitoUrl = this.jito.url;
743
+ const signal = combineJitoSignal(opts?.signal, opts?.timeoutMs ?? 15_000);
744
+ let json;
745
+ try {
746
+ const resp = await fetch(jitoUrl, {
747
+ method: 'POST',
748
+ headers: {
749
+ 'Content-Type': 'application/json',
750
+ ...(this.jito.auth ? { Authorization: `Bearer ${this.jito.auth}` } : {}),
751
+ },
752
+ body: JSON.stringify(body),
753
+ signal,
754
+ });
755
+ if (!resp.ok) {
756
+ // 401/403 = jito auth config problem, not a bundle rejection.
757
+ // Treat as RpcError so consumer doesn't push the tx toward re-sign.
758
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Jito submitBundle HTTP ${resp.status} on ${this.name}`, jitoUrl), { chainId: this.chainId });
759
+ }
760
+ json = (await resp.json());
761
+ }
762
+ catch (err) {
763
+ if (err instanceof errors_ts_1.ChainError)
764
+ throw err;
765
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Jito submitBundle transport failed on ${this.name}`, jitoUrl), { chainId: this.chainId }, (0, errors_ts_1.sanitizeCause)(err, jitoUrl));
766
+ }
767
+ if (json.error || !json.result) {
768
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.BroadcastRejected, (0, errors_ts_1.sanitizeMessage)(`Jito submitBundle rejected on ${this.name}: ${json.error?.message ?? 'no bundle id returned'}`, jitoUrl), { chainId: this.chainId });
769
+ }
770
+ return json.result;
771
+ }
772
+ async getBundleStatus(bundleId, opts) {
773
+ if (!this.jito) {
774
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.FeatureNotSupported, 'Jito getBundleStatus requires SolanaChain to be constructed with jito config', { chainId: this.chainId });
775
+ }
776
+ const ids = Array.isArray(bundleId) ? bundleId : [bundleId];
777
+ const body = {
778
+ jsonrpc: '2.0',
779
+ id: 1,
780
+ method: 'getBundleStatuses',
781
+ params: [ids],
782
+ };
783
+ let json;
784
+ const jitoUrl = this.jito.url;
785
+ const signal = combineJitoSignal(opts?.signal, opts?.timeoutMs ?? 15_000);
786
+ try {
787
+ const resp = await fetch(jitoUrl, {
788
+ method: 'POST',
789
+ headers: {
790
+ 'Content-Type': 'application/json',
791
+ ...(this.jito.auth ? { Authorization: `Bearer ${this.jito.auth}` } : {}),
792
+ },
793
+ body: JSON.stringify(body),
794
+ signal,
795
+ });
796
+ if (!resp.ok) {
797
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Jito getBundleStatuses HTTP ${resp.status} on ${this.name}`, jitoUrl), { chainId: this.chainId });
798
+ }
799
+ json = (await resp.json());
800
+ }
801
+ catch (err) {
802
+ if (err instanceof errors_ts_1.ChainError)
803
+ throw err;
804
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Jito getBundleStatuses transport failed on ${this.name}`, jitoUrl), { chainId: this.chainId }, (0, errors_ts_1.sanitizeCause)(err, jitoUrl));
805
+ }
806
+ if (json.error) {
807
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Jito getBundleStatuses error on ${this.name}: ${json.error.message ?? 'unknown'}`, jitoUrl), { chainId: this.chainId });
808
+ }
809
+ const rawValue = json.result?.value;
810
+ if (rawValue !== undefined && rawValue !== null && !Array.isArray(rawValue)) {
811
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Jito getBundleStatuses returned malformed value (expected array or null)`, jitoUrl), { chainId: this.chainId });
812
+ }
813
+ const rows = Array.isArray(rawValue) ? rawValue : [];
814
+ const statuses = ids.map((id) => {
815
+ const row = rows.find((r) => r != null && r.bundle_id === id);
816
+ if (!row)
817
+ return { bundleId: id, state: 'Pending' };
818
+ // Jito's err field varies: null (success), { Ok: null } (success),
819
+ // { Err: <anything> } (failed), or a plain string (some proxies).
820
+ // Anything that's non-null AND not { Ok: null } means failure.
821
+ const rawErr = row.err;
822
+ const isOk = rawErr === null || rawErr === undefined
823
+ || (typeof rawErr === 'object' && 'Ok' in rawErr && rawErr.Ok === null && !('Err' in rawErr));
824
+ const errStr = isOk
825
+ ? undefined
826
+ : typeof rawErr === 'string'
827
+ ? rawErr
828
+ : typeof rawErr === 'object' && rawErr !== null && 'Err' in rawErr
829
+ ? String(rawErr.Err)
830
+ : JSON.stringify(rawErr);
831
+ const confStatus = row.confirmation_status;
832
+ const state = errStr !== undefined
833
+ ? 'Failed'
834
+ : (confStatus === 'finalized' || confStatus === 'confirmed' ? 'Landed' : 'Pending');
835
+ return { bundleId: id, state, slot: row.slot, err: errStr };
836
+ });
837
+ return Array.isArray(bundleId) ? statuses : statuses[0];
838
+ }
839
+ async createUnsignedTransaction(req) {
840
+ if (req && req.signal !== undefined) {
841
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.FeatureNotSupported, `Solana createUnsignedTransaction: signal is not honored in 0.3.0 (silently ignoring would let a caller conclude 'not built' while getLatestBlockhash continues). Cancellation returns in 0.3.1.`, { chainId: this.chainId });
842
+ }
843
+ if (!req.payer) {
844
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, 'CreateSolanaUnsignedTransactionRequest.payer is required', { chainId: this.chainId });
845
+ }
846
+ let payerKey;
847
+ try {
848
+ payerKey = new web3_js_1.PublicKey(req.payer);
849
+ }
850
+ catch (err) {
851
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid Solana payer pubkey: ${req.payer}`, { chainId: this.chainId, address: req.payer }, err instanceof Error ? err : undefined);
852
+ }
853
+ if (!Array.isArray(req.instructions) || req.instructions.length === 0) {
854
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, 'CreateSolanaUnsignedTransactionRequest.instructions must be a non-empty array', { chainId: this.chainId });
855
+ }
856
+ const connection = this.getConnection();
857
+ let blockhash;
858
+ let lastValidBlockHeight;
859
+ try {
860
+ const bh = await connection.getLatestBlockhash('finalized');
861
+ blockhash = bh.blockhash;
862
+ lastValidBlockHeight = bh.lastValidBlockHeight;
863
+ }
864
+ catch (err) {
865
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana createUnsignedTransaction: getLatestBlockhash failed on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
866
+ }
867
+ let message;
868
+ try {
869
+ message = web3_js_1.MessageV0.compile({
870
+ payerKey,
871
+ instructions: req.instructions,
872
+ recentBlockhash: blockhash,
873
+ addressLookupTableAccounts: req.addressLookupTables ?? [],
874
+ });
875
+ }
876
+ catch (err) {
877
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana createUnsignedTransaction: MessageV0.compile failed — instruction or ALT layout invalid`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
878
+ }
879
+ const tx = new web3_js_1.VersionedTransaction(message);
880
+ let serializedSize;
881
+ try {
882
+ serializedSize = tx.serialize().length;
883
+ }
884
+ catch (err) {
885
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds the serialize buffer; supply addressLookupTables to compress the account list`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
886
+ }
887
+ if (serializedSize > 1232) {
888
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds 1232-byte wire limit; supply addressLookupTables to reduce size`, { chainId: this.chainId });
889
+ }
890
+ return new unsigned_solana_transaction_ts_1.UnsignedSolanaTransaction({
891
+ chainId: this.chainId,
892
+ transaction: tx,
893
+ feePayer: req.payer,
894
+ recentBlockhash: blockhash,
895
+ lastValidBlockHeight,
896
+ instructions: req.instructions,
897
+ addressLookupTables: req.addressLookupTables,
898
+ });
899
+ }
900
+ async getAccountInfo(pubkey) {
901
+ const connection = this.getConnection();
902
+ const toPk = (raw) => {
903
+ try {
904
+ return new web3_js_1.PublicKey(raw);
905
+ }
906
+ catch (err) {
907
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid Solana pubkey: ${raw}`, { chainId: this.chainId, address: raw }, err instanceof Error ? err : undefined);
908
+ }
909
+ };
910
+ if (Array.isArray(pubkey)) {
911
+ const pks = pubkey.map(toPk);
912
+ try {
913
+ const infos = await connection.getMultipleAccountsInfo(pks);
914
+ return infos.map((info) => (info === null ? null : toAccountInfoResult(info)));
915
+ }
916
+ catch (err) {
917
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana getMultipleAccountsInfo RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
918
+ }
919
+ }
920
+ try {
921
+ const info = await connection.getAccountInfo(toPk(pubkey));
922
+ return info === null ? null : toAccountInfoResult(info);
923
+ }
924
+ catch (err) {
925
+ if (err instanceof errors_ts_1.ChainError)
926
+ throw err;
927
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana getAccountInfo RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, address: pubkey }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
928
+ }
929
+ }
930
+ async getTokenAccount(owner, mint, opts) {
931
+ let ownerPk;
932
+ let mintPk;
933
+ try {
934
+ ownerPk = new web3_js_1.PublicKey(owner);
935
+ }
936
+ catch (err) {
937
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid Solana owner pubkey: ${owner}`, { chainId: this.chainId, address: owner }, err instanceof Error ? err : undefined);
938
+ }
939
+ try {
940
+ mintPk = new web3_js_1.PublicKey(mint);
941
+ }
942
+ catch (err) {
943
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidTokenIdentifier, `Invalid Solana mint pubkey: ${mint}`, { chainId: this.chainId, identifier: mint }, err instanceof Error ? err : undefined);
944
+ }
945
+ let programId;
946
+ try {
947
+ programId = await this.resolveTokenProgramId(mintPk);
948
+ }
949
+ catch (err) {
950
+ if (err instanceof errors_ts_1.ChainError)
951
+ throw err;
952
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana getTokenAccount: mint-program lookup failed on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, identifier: mint }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
953
+ }
954
+ let ataPk;
955
+ try {
956
+ ataPk = (0, spl_token_1.getAssociatedTokenAddressSync)(mintPk, ownerPk, opts?.allowOwnerOffCurve ?? false, programId);
957
+ }
958
+ catch (err) {
959
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `ATA derivation failed: ${err instanceof Error ? err.message : String(err)}`, { chainId: this.chainId, address: owner }, err instanceof Error ? err : undefined);
960
+ }
961
+ try {
962
+ const acc = await (0, spl_token_1.getAccount)(this.getConnection(), ataPk, undefined, programId);
963
+ return { ata: ataPk.toBase58(), exists: true, balanceMr: acc.amount };
964
+ }
965
+ catch (err) {
966
+ if (err instanceof spl_token_1.TokenAccountNotFoundError) {
967
+ return { ata: ataPk.toBase58(), exists: false, balanceMr: undefined };
968
+ }
969
+ if (err instanceof spl_token_1.TokenInvalidAccountOwnerError) {
970
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana getTokenAccount: account at ${ataPk.toBase58()} exists but is owned by an unexpected program (hostile squat or wrong mint program). Consumer should NOT create-ATA blindly.`, { chainId: this.chainId, address: ataPk.toBase58() }, err);
971
+ }
972
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana getTokenAccount RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, address: ataPk.toBase58() }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
973
+ }
974
+ }
975
+ async fetchAddressLookupTable(altAddress) {
976
+ let pk;
977
+ try {
978
+ pk = new web3_js_1.PublicKey(altAddress);
979
+ }
980
+ catch (err) {
981
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `Invalid ALT pubkey: ${altAddress}`, { chainId: this.chainId, address: altAddress }, err instanceof Error ? err : undefined);
982
+ }
983
+ let res;
984
+ try {
985
+ res = await this.getConnection().getAddressLookupTable(pk);
986
+ }
987
+ catch (err) {
988
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana fetchAddressLookupTable RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, address: altAddress }, (0, errors_ts_1.sanitizeCause)(err, this.resolvedRpcUrlForRedaction()));
989
+ }
990
+ if (!res.value) {
991
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Address lookup table ${altAddress} not found`, { chainId: this.chainId, address: altAddress });
992
+ }
993
+ return res.value;
994
+ }
995
+ classifyBroadcastError(err) {
996
+ const rpc = this.resolvedRpcUrlForRedaction();
997
+ const msg = err instanceof Error ? err.message.toLowerCase() : String(err).toLowerCase();
998
+ const safeCause = (0, errors_ts_1.sanitizeCause)(err, rpc);
999
+ const transportSignals = /econnreset|econnrefused|econnaborted|etimedout|enotfound|network request failed|fetch failed|socket hang up|too\s+many\s+requests|rate.?limit/;
1000
+ if (/blockhash\s+not\s+found|blockhash\s+expired|block\s+height\s+exceeded/.test(msg)) {
1001
+ return new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.BlockhashExpired, (0, errors_ts_1.sanitizeMessage)(`Solana broadcast rejected: blockhash expired on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
1002
+ }
1003
+ // Preflight/simulation MUST be checked before the size predicate — Solana
1004
+ // preflight errors routinely embed "exceeds <N>" for CU / account-count
1005
+ // limits, and would otherwise be misclassified as TransactionTooLarge.
1006
+ if (msg.includes('preflight') || msg.includes('simulation failed') || msg.includes('sendtransactionerror')) {
1007
+ return new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.SimulationFailed, (0, errors_ts_1.sanitizeMessage)(`Solana broadcast rejected: preflight simulation failed on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
1008
+ }
1009
+ if (/transaction\s+too\s+large|encoded\/raw transaction size exceeds|exceeds\s+the\s+maximum\s+transaction\s+size/.test(msg)) {
1010
+ return new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.TransactionTooLarge, (0, errors_ts_1.sanitizeMessage)(`Solana broadcast rejected: transaction exceeds 1232 bytes on ${this.name} (use ALT)`, rpc), { chainId: this.chainId }, safeCause);
1011
+ }
1012
+ if (transportSignals.test(msg)) {
1013
+ return new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.RpcError, (0, errors_ts_1.sanitizeMessage)(`Solana broadcast RPC transport failure on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
1014
+ }
1015
+ return new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.BroadcastRejected, (0, errors_ts_1.sanitizeMessage)(`Solana broadcast rejected on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
1016
+ }
1017
+ /**
1018
+ * Resolves the token program owner for a given mint. Token-2022 mints are owned by
1019
+ * TOKEN_2022_PROGRAM_ID; classic SPL by TOKEN_PROGRAM_ID. Required for `transferChecked`
1020
+ * and ATA derivation.
1021
+ */
1022
+ async resolveTokenProgramId(mint) {
1023
+ const connection = this.getConnection();
1024
+ const info = await connection.getAccountInfo(mint);
1025
+ if (!info) {
1026
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidTokenIdentifier, `Mint ${mint.toBase58()} not found on chain`, { chainId: this.chainId, identifier: mint.toBase58() });
1027
+ }
1028
+ const owner = info.owner.toBase58();
1029
+ if (owner === spl_token_1.TOKEN_PROGRAM_ID.toBase58())
1030
+ return spl_token_1.TOKEN_PROGRAM_ID;
1031
+ if (owner === spl_token_1.TOKEN_2022_PROGRAM_ID.toBase58())
1032
+ return spl_token_1.TOKEN_2022_PROGRAM_ID;
1033
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidTokenIdentifier, `Mint ${mint.toBase58()} is owned by ${owner}, not an SPL Token program`, { chainId: this.chainId, identifier: mint.toBase58() });
1034
+ }
1035
+ async resolveMintDecimals(mint) {
1036
+ const programId = await this.resolveTokenProgramId(mint);
1037
+ const mintInfo = await (0, spl_token_1.getMint)(this.getConnection(), mint, undefined, programId);
1038
+ return mintInfo.decimals;
1039
+ }
1040
+ /**
1041
+ * Raw-instruction helper for callers that will compile the transaction downstream
1042
+ * (e.g. depositron's SOL_INSTRUCTIONS action type) instead of using
1043
+ * createTransferUnsignedTransaction's compiled-tx surface.
1044
+ *
1045
+ * Synchronous — no RPC.
1046
+ */
1047
+ buildNativeTransferInstruction(from, to, lamports) {
1048
+ if (lamports <= 0n) {
1049
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Native transfer lamports must be positive (got ${lamports})`, { chainId: this.chainId });
1050
+ }
1051
+ return web3_js_1.SystemProgram.transfer({
1052
+ fromPubkey: from,
1053
+ toPubkey: to,
1054
+ lamports,
1055
+ });
1056
+ }
1057
+ /**
1058
+ * Raw-instruction helper for SPL / Token-2022 transfers where the caller will compile
1059
+ * the transaction downstream. Returns [createATA-idempotent?, transferChecked].
1060
+ *
1061
+ * Idempotent ATA (vs the probe-then-create pattern in createTransferUnsignedTransaction)
1062
+ * is deliberate: when a downstream compiler runs the emitted instructions blindly,
1063
+ * a probe done here can race with execution — the idempotent form is a no-op when the
1064
+ * ATA exists and a create when it doesn't, without needing a probe RPC.
1065
+ *
1066
+ * `allowOwnerOffCurve: true` applies to BOTH source and destination ATA derivation —
1067
+ * needed for PDA-owned vaults / program-owned recipients. Defaults to false to match
1068
+ * createTransferUnsignedTransaction.
1069
+ */
1070
+ async buildSplTransferInstructions(req) {
1071
+ if (req.amount <= 0n) {
1072
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `SPL transfer amount must be positive (got ${req.amount})`, { chainId: this.chainId, identifier: req.mint.toBase58() });
1073
+ }
1074
+ const includeCreateAta = req.includeCreateAta ?? true;
1075
+ const allowOwnerOffCurve = req.allowOwnerOffCurve ?? false;
1076
+ const programId = await this.resolveTokenProgramId(req.mint);
1077
+ const decimals = await this.resolveMintDecimals(req.mint);
1078
+ const deriveAta = (owner, role) => {
1079
+ try {
1080
+ return (0, spl_token_1.getAssociatedTokenAddressSync)(req.mint, owner, allowOwnerOffCurve, programId);
1081
+ }
1082
+ catch (err) {
1083
+ // spl-token's TokenOwnerOffCurveError ships with an empty message. Rethrow as
1084
+ // ChainError so consumers see the SDK's declared error surface, and so the
1085
+ // reason is discoverable (pass `allowOwnerOffCurve: true` for PDA-owned wallets).
1086
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidAddress, `${role} owner is off-curve; pass allowOwnerOffCurve:true for PDA-owned wallets`, { chainId: this.chainId, address: owner.toBase58() });
1087
+ }
1088
+ };
1089
+ const sourceAta = deriveAta(req.from, 'source');
1090
+ const destAta = deriveAta(req.to, 'destination');
1091
+ const instructions = [];
1092
+ if (includeCreateAta) {
1093
+ instructions.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(req.from, destAta, req.to, req.mint, programId));
1094
+ }
1095
+ instructions.push((0, spl_token_1.createTransferCheckedInstruction)(sourceAta, req.mint, destAta, req.from, req.amount, decimals, [], programId));
1096
+ return instructions;
1097
+ }
1098
+ /**
1099
+ * Decodes per-account lamport deltas + SPL pre/post token-balance diffs into
1100
+ * a `NestedBalanceChanges` map. Marked internal via naming rather than TS
1101
+ * `private` so chain-agnostic unit tests can exercise it directly without
1102
+ * spinning up a Connection.
1103
+ */
1104
+ _decodeBalanceChanges(tx) {
1105
+ const result = new Map();
1106
+ if (!tx.meta)
1107
+ return result;
1108
+ // For v0 messages, meta.preBalances/postBalances are indexed over
1109
+ // staticAccountKeys ++ loadedAddresses.writable ++ loadedAddresses.readonly.
1110
+ // Iterating only staticAccountKeys silently drops lamport deltas for
1111
+ // any LUT-resolved account — a SOL deposit to a wallet that only
1112
+ // appears via a lookup table produces no balanceChanges row at all.
1113
+ // getTransaction() is called with maxSupportedTransactionVersion: 0
1114
+ // so we always see the resolved addresses.
1115
+ const staticKeys = tx.transaction.message.staticAccountKeys.map((k) => k.toBase58());
1116
+ const loaded = tx.meta.loadedAddresses;
1117
+ const loadedWritable = (loaded?.writable ?? []).map((k) => k.toBase58());
1118
+ const loadedReadonly = (loaded?.readonly ?? []).map((k) => k.toBase58());
1119
+ const accounts = [...staticKeys, ...loadedWritable, ...loadedReadonly];
1120
+ const pre = tx.meta.preBalances ?? [];
1121
+ const post = tx.meta.postBalances ?? [];
1122
+ for (let i = 0; i < accounts.length; i++) {
1123
+ const delta = BigInt(post[i] ?? 0) - BigInt(pre[i] ?? 0);
1124
+ if (delta === 0n)
1125
+ continue;
1126
+ transaction_status_ts_1.AssetBalanceChange.upsert(result, accounts[i], this._nativeToken, transaction_status_ts_1.AssetBalanceChange.fromMr(delta, this._nativeToken.decimals));
1127
+ }
1128
+ const preTok = tx.meta.preTokenBalances ?? [];
1129
+ const postTok = tx.meta.postTokenBalances ?? [];
1130
+ const tokenKey = (b) => `${b.accountIndex}|${b.mint}`;
1131
+ // Track the token account's owner (a wallet) and the mint's decimals,
1132
+ // both surfaced verbatim by getTransaction's parsed token-balance meta.
1133
+ const byKey = new Map();
1134
+ for (const b of preTok) {
1135
+ byKey.set(tokenKey(b), {
1136
+ pre: BigInt(b.uiTokenAmount.amount),
1137
+ post: 0n,
1138
+ mint: b.mint,
1139
+ owner: b.owner ?? null,
1140
+ decimals: b.uiTokenAmount.decimals,
1141
+ });
1142
+ }
1143
+ for (const b of postTok) {
1144
+ const k = tokenKey(b);
1145
+ const cur = byKey.get(k);
1146
+ if (cur) {
1147
+ cur.post = BigInt(b.uiTokenAmount.amount);
1148
+ // Prefer the post-owner if the pre entry lacked one (account
1149
+ // freshly initialized inside the tx).
1150
+ if (cur.owner === null && b.owner)
1151
+ cur.owner = b.owner;
1152
+ }
1153
+ else {
1154
+ byKey.set(k, {
1155
+ pre: 0n,
1156
+ post: BigInt(b.uiTokenAmount.amount),
1157
+ mint: b.mint,
1158
+ owner: b.owner ?? null,
1159
+ decimals: b.uiTokenAmount.decimals,
1160
+ });
1161
+ }
1162
+ }
1163
+ for (const { pre: p, post: q, mint, owner, decimals } of byKey.values()) {
1164
+ const delta = q - p;
1165
+ if (delta === 0n)
1166
+ continue;
1167
+ // Skip entries where the token-account owner is unknown — filling in
1168
+ // the mint as if it were a wallet address would be actively wrong.
1169
+ // Matches Python's behavior in impl/solana/base.py:704-706.
1170
+ if (owner === null)
1171
+ continue;
1172
+ // Symbol is not surfaced by getTransaction; use an UNKNOWN placeholder
1173
+ // built from the first four mint characters. Mirrors the EVM decoder's
1174
+ // UNKNOWN_<hex-slice> shape (evm_chain.ts:480) so consumers can spot
1175
+ // unresolved tokens uniformly.
1176
+ const symbol = `UNKNOWN_${mint.slice(0, 4)}`;
1177
+ const splToken = new solana_token_ts_1.SolanaToken(this.chainId, symbol, mint, decimals);
1178
+ transaction_status_ts_1.AssetBalanceChange.upsert(result, owner, splToken, transaction_status_ts_1.AssetBalanceChange.fromMr(delta, decimals));
1179
+ }
1180
+ return result;
1181
+ }
1182
+ }
1183
+ exports.SolanaChain = SolanaChain;
1184
+ function validateAltList(input, chainId) {
1185
+ if (input === undefined || input === null)
1186
+ return [];
1187
+ if (!Array.isArray(input)) {
1188
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `addressLookupTables must be an array of AddressLookupTableAccount, got ${typeof input}`, { chainId });
1189
+ }
1190
+ for (let i = 0; i < input.length; i++) {
1191
+ const a = input[i];
1192
+ if (a === null || typeof a !== 'object' || !('key' in a) || !('state' in a)) {
1193
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `addressLookupTables[${i}] is not an AddressLookupTableAccount (missing key/state). Use SolanaChain.fetchAddressLookupTable to obtain valid instances.`, { chainId });
1194
+ }
1195
+ }
1196
+ return input;
1197
+ }
1198
+ function signatureBase58FromBytes(txBytes) {
1199
+ if (txBytes.length < 65) {
1200
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana broadcast: signed bytes too short (${txBytes.length}) to extract signature`, {});
1201
+ }
1202
+ const numSigs = txBytes[0];
1203
+ if (numSigs === 0 || txBytes.length < 1 + 64) {
1204
+ throw new errors_ts_1.ChainError(errors_ts_1.ChainErrorKinds.InvalidArgument, `Solana broadcast: no signatures in serialized transaction`, {});
1205
+ }
1206
+ const sigBytes = txBytes.subarray(1, 1 + 64);
1207
+ return bs58encode(sigBytes);
1208
+ }
1209
+ const BS58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
1210
+ function bs58encode(bytes) {
1211
+ let n = 0n;
1212
+ for (const b of bytes)
1213
+ n = (n << 8n) | BigInt(b);
1214
+ let out = '';
1215
+ while (n > 0n) {
1216
+ const rem = Number(n % 58n);
1217
+ out = BS58_ALPHABET[rem] + out;
1218
+ n = n / 58n;
1219
+ }
1220
+ for (const b of bytes) {
1221
+ if (b === 0)
1222
+ out = '1' + out;
1223
+ else
1224
+ break;
1225
+ }
1226
+ return out;
1227
+ }
1228
+ const SOLANA_BATCH_STATUS_CONCURRENCY = 8;
1229
+ async function runSolanaBatchStatus(items, fetchOne) {
1230
+ const results = new Array(items.length);
1231
+ const ac = new AbortController();
1232
+ let cursor = 0;
1233
+ const workers = [];
1234
+ const spawn = async () => {
1235
+ while (!ac.signal.aborted) {
1236
+ const idx = cursor++;
1237
+ if (idx >= items.length)
1238
+ return;
1239
+ try {
1240
+ results[idx] = await fetchOne(items[idx], ac.signal);
1241
+ }
1242
+ catch (err) {
1243
+ ac.abort();
1244
+ throw err;
1245
+ }
1246
+ }
1247
+ };
1248
+ const workerCount = Math.min(SOLANA_BATCH_STATUS_CONCURRENCY, items.length);
1249
+ for (let i = 0; i < workerCount; i++)
1250
+ workers.push(spawn());
1251
+ await Promise.all(workers);
1252
+ return results;
1253
+ }
1254
+ function anySignal(a, b) {
1255
+ if (typeof AbortSignal.any === 'function')
1256
+ return AbortSignal.any([a, b]);
1257
+ const ac = new AbortController();
1258
+ const onAbort = () => ac.abort();
1259
+ if (a.aborted || b.aborted)
1260
+ ac.abort();
1261
+ else {
1262
+ a.addEventListener('abort', onAbort, { once: true });
1263
+ b.addEventListener('abort', onAbort, { once: true });
1264
+ }
1265
+ return ac.signal;
1266
+ }
1267
+ function combineJitoSignal(consumerSignal, timeoutMs) {
1268
+ const timeout = AbortSignal.timeout(timeoutMs);
1269
+ if (!consumerSignal)
1270
+ return timeout;
1271
+ const ac = new AbortController();
1272
+ const onAbort = () => ac.abort();
1273
+ if (consumerSignal.aborted || timeout.aborted)
1274
+ ac.abort();
1275
+ else {
1276
+ consumerSignal.addEventListener('abort', onAbort, { once: true });
1277
+ timeout.addEventListener('abort', onAbort, { once: true });
1278
+ }
1279
+ return ac.signal;
1280
+ }
1281
+ async function solanaInterruptibleSleep(ms, signal) {
1282
+ if (signal?.aborted)
1283
+ return;
1284
+ await new Promise((resolve) => {
1285
+ const t = setTimeout(() => {
1286
+ signal?.removeEventListener('abort', onAbort);
1287
+ resolve();
1288
+ }, ms);
1289
+ const onAbort = () => {
1290
+ clearTimeout(t);
1291
+ resolve();
1292
+ };
1293
+ signal?.addEventListener('abort', onAbort, { once: true });
1294
+ });
1295
+ }
1296
+ function toAccountInfoResult(info) {
1297
+ return {
1298
+ owner: info.owner.toBase58(),
1299
+ lamports: BigInt(info.lamports),
1300
+ data: Uint8Array.from(info.data),
1301
+ executable: info.executable,
1302
+ rentEpoch: info.rentEpoch === undefined ? undefined : BigInt(info.rentEpoch),
1303
+ };
1304
+ }
1305
+ //# sourceMappingURL=solana_chain.js.map