crypto-aio 0.0.2 → 0.1.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 (672) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +144 -14
  3. package/dist/adapters/avalanche/address.d.ts +15 -0
  4. package/dist/adapters/avalanche/address.js +74 -0
  5. package/dist/adapters/avalanche/address.js.map +1 -0
  6. package/dist/adapters/avalanche/api.d.ts +100 -0
  7. package/dist/adapters/avalanche/api.js +381 -0
  8. package/dist/adapters/avalanche/api.js.map +1 -0
  9. package/dist/adapters/avalanche/builder.d.ts +13 -0
  10. package/dist/adapters/avalanche/builder.js +336 -0
  11. package/dist/adapters/avalanche/builder.js.map +1 -0
  12. package/dist/adapters/avalanche/cb58.d.ts +7 -0
  13. package/dist/adapters/avalanche/cb58.js +49 -0
  14. package/dist/adapters/avalanche/cb58.js.map +1 -0
  15. package/dist/adapters/avalanche/chains.d.ts +21 -0
  16. package/dist/adapters/avalanche/chains.js +79 -0
  17. package/dist/adapters/avalanche/chains.js.map +1 -0
  18. package/dist/adapters/avalanche/codec.d.ts +94 -0
  19. package/dist/adapters/avalanche/codec.js +371 -0
  20. package/dist/adapters/avalanche/codec.js.map +1 -0
  21. package/dist/adapters/avalanche/context.d.ts +59 -0
  22. package/dist/adapters/avalanche/context.js +114 -0
  23. package/dist/adapters/avalanche/context.js.map +1 -0
  24. package/dist/adapters/avalanche/decode.d.ts +16 -0
  25. package/dist/adapters/avalanche/decode.js +101 -0
  26. package/dist/adapters/avalanche/decode.js.map +1 -0
  27. package/dist/adapters/avalanche/driver.d.ts +22 -0
  28. package/dist/adapters/avalanche/driver.js +81 -0
  29. package/dist/adapters/avalanche/driver.js.map +1 -0
  30. package/dist/adapters/avalanche/errors.d.ts +18 -0
  31. package/dist/adapters/avalanche/errors.js +61 -0
  32. package/dist/adapters/avalanche/errors.js.map +1 -0
  33. package/dist/adapters/avalanche/fees.d.ts +23 -0
  34. package/dist/adapters/avalanche/fees.js +105 -0
  35. package/dist/adapters/avalanche/fees.js.map +1 -0
  36. package/dist/adapters/avalanche/index.d.ts +19 -0
  37. package/dist/adapters/avalanche/index.js +8 -0
  38. package/dist/adapters/avalanche/index.js.map +1 -0
  39. package/dist/adapters/avalanche/network.d.ts +37 -0
  40. package/dist/adapters/avalanche/network.js +135 -0
  41. package/dist/adapters/avalanche/network.js.map +1 -0
  42. package/dist/adapters/avalanche/plugin.d.ts +21 -0
  43. package/dist/adapters/avalanche/plugin.js +46 -0
  44. package/dist/adapters/avalanche/plugin.js.map +1 -0
  45. package/dist/adapters/avalanche/presets.d.ts +6 -0
  46. package/dist/adapters/avalanche/presets.js +86 -0
  47. package/dist/adapters/avalanche/presets.js.map +1 -0
  48. package/dist/adapters/avalanche/proofs.d.ts +41 -0
  49. package/dist/adapters/avalanche/proofs.js +270 -0
  50. package/dist/adapters/avalanche/proofs.js.map +1 -0
  51. package/dist/adapters/avalanche/reader.d.ts +40 -0
  52. package/dist/adapters/avalanche/reader.js +231 -0
  53. package/dist/adapters/avalanche/reader.js.map +1 -0
  54. package/dist/adapters/avalanche/sdk.d.ts +182 -0
  55. package/dist/adapters/avalanche/sdk.js +21 -0
  56. package/dist/adapters/avalanche/sdk.js.map +1 -0
  57. package/dist/adapters/avalanche/types.d.ts +86 -0
  58. package/dist/{type/common.js → adapters/avalanche/types.js} +1 -1
  59. package/dist/adapters/avalanche/types.js.map +1 -0
  60. package/dist/adapters/evm/builder.d.ts +11 -0
  61. package/dist/adapters/evm/builder.js +326 -0
  62. package/dist/adapters/evm/builder.js.map +1 -0
  63. package/dist/adapters/evm/chains.d.ts +6 -0
  64. package/dist/adapters/evm/chains.js +203 -0
  65. package/dist/adapters/evm/chains.js.map +1 -0
  66. package/dist/adapters/evm/client.d.ts +84 -0
  67. package/dist/adapters/evm/client.js +335 -0
  68. package/dist/adapters/evm/client.js.map +1 -0
  69. package/dist/adapters/evm/decode.d.ts +35 -0
  70. package/dist/adapters/evm/decode.js +170 -0
  71. package/dist/adapters/evm/decode.js.map +1 -0
  72. package/dist/adapters/evm/driver.d.ts +8 -0
  73. package/dist/adapters/evm/driver.js +61 -0
  74. package/dist/adapters/evm/driver.js.map +1 -0
  75. package/dist/adapters/evm/errors.d.ts +20 -0
  76. package/dist/adapters/evm/errors.js +110 -0
  77. package/dist/adapters/evm/errors.js.map +1 -0
  78. package/dist/adapters/evm/ethers-client.d.ts +43 -0
  79. package/dist/adapters/evm/ethers-client.js +135 -0
  80. package/dist/adapters/evm/ethers-client.js.map +1 -0
  81. package/dist/adapters/evm/fees.d.ts +79 -0
  82. package/dist/adapters/evm/fees.js +234 -0
  83. package/dist/adapters/evm/fees.js.map +1 -0
  84. package/dist/adapters/evm/index.d.ts +20 -0
  85. package/dist/adapters/evm/index.js +11 -0
  86. package/dist/adapters/evm/index.js.map +1 -0
  87. package/dist/adapters/evm/network.d.ts +60 -0
  88. package/dist/adapters/evm/network.js +131 -0
  89. package/dist/adapters/evm/network.js.map +1 -0
  90. package/dist/adapters/evm/plugin.d.ts +36 -0
  91. package/dist/adapters/evm/plugin.js +102 -0
  92. package/dist/adapters/evm/plugin.js.map +1 -0
  93. package/dist/adapters/evm/presets.d.ts +2 -0
  94. package/dist/adapters/evm/presets.js +105 -0
  95. package/dist/adapters/evm/presets.js.map +1 -0
  96. package/dist/adapters/evm/proofs.d.ts +19 -0
  97. package/dist/adapters/evm/proofs.js +358 -0
  98. package/dist/adapters/evm/proofs.js.map +1 -0
  99. package/dist/adapters/evm/rawtx.d.ts +25 -0
  100. package/dist/adapters/evm/rawtx.js +176 -0
  101. package/dist/adapters/evm/rawtx.js.map +1 -0
  102. package/dist/adapters/evm/reader.d.ts +65 -0
  103. package/dist/adapters/evm/reader.js +292 -0
  104. package/dist/adapters/evm/reader.js.map +1 -0
  105. package/dist/adapters/evm/rpc.d.ts +39 -0
  106. package/dist/adapters/evm/rpc.js +152 -0
  107. package/dist/adapters/evm/rpc.js.map +1 -0
  108. package/dist/adapters/evm/tokens.d.ts +7 -0
  109. package/dist/adapters/evm/tokens.js +23 -0
  110. package/dist/adapters/evm/tokens.js.map +1 -0
  111. package/dist/adapters/evm/types.d.ts +255 -0
  112. package/dist/{type/account.js → adapters/evm/types.js} +1 -1
  113. package/dist/adapters/evm/types.js.map +1 -0
  114. package/dist/adapters/evm/web3-client.d.ts +23 -0
  115. package/dist/adapters/evm/web3-client.js +159 -0
  116. package/dist/adapters/evm/web3-client.js.map +1 -0
  117. package/dist/adapters/solana/builder.d.ts +18 -0
  118. package/dist/adapters/solana/builder.js +545 -0
  119. package/dist/adapters/solana/builder.js.map +1 -0
  120. package/dist/adapters/solana/chains.d.ts +13 -0
  121. package/dist/adapters/solana/chains.js +37 -0
  122. package/dist/adapters/solana/chains.js.map +1 -0
  123. package/dist/adapters/solana/decode.d.ts +111 -0
  124. package/dist/adapters/solana/decode.js +595 -0
  125. package/dist/adapters/solana/decode.js.map +1 -0
  126. package/dist/adapters/solana/driver.d.ts +15 -0
  127. package/dist/adapters/solana/driver.js +72 -0
  128. package/dist/adapters/solana/driver.js.map +1 -0
  129. package/dist/adapters/solana/errors.d.ts +36 -0
  130. package/dist/adapters/solana/errors.js +154 -0
  131. package/dist/adapters/solana/errors.js.map +1 -0
  132. package/dist/adapters/solana/fees.d.ts +68 -0
  133. package/dist/adapters/solana/fees.js +205 -0
  134. package/dist/adapters/solana/fees.js.map +1 -0
  135. package/dist/adapters/solana/heights.d.ts +47 -0
  136. package/dist/adapters/solana/heights.js +185 -0
  137. package/dist/adapters/solana/heights.js.map +1 -0
  138. package/dist/adapters/solana/history.d.ts +10 -0
  139. package/dist/adapters/solana/history.js +71 -0
  140. package/dist/adapters/solana/history.js.map +1 -0
  141. package/dist/adapters/solana/index.d.ts +16 -0
  142. package/dist/adapters/solana/index.js +9 -0
  143. package/dist/adapters/solana/index.js.map +1 -0
  144. package/dist/adapters/solana/keys.d.ts +13 -0
  145. package/dist/adapters/solana/keys.js +69 -0
  146. package/dist/adapters/solana/keys.js.map +1 -0
  147. package/dist/adapters/solana/network.d.ts +24 -0
  148. package/dist/adapters/solana/network.js +95 -0
  149. package/dist/adapters/solana/network.js.map +1 -0
  150. package/dist/adapters/solana/plugin.d.ts +18 -0
  151. package/dist/adapters/solana/plugin.js +41 -0
  152. package/dist/adapters/solana/plugin.js.map +1 -0
  153. package/dist/adapters/solana/presets.d.ts +2 -0
  154. package/dist/adapters/solana/presets.js +77 -0
  155. package/dist/adapters/solana/presets.js.map +1 -0
  156. package/dist/adapters/solana/programs.d.ts +44 -0
  157. package/dist/adapters/solana/programs.js +159 -0
  158. package/dist/adapters/solana/programs.js.map +1 -0
  159. package/dist/adapters/solana/proofs.d.ts +56 -0
  160. package/dist/adapters/solana/proofs.js +540 -0
  161. package/dist/adapters/solana/proofs.js.map +1 -0
  162. package/dist/adapters/solana/reader.d.ts +82 -0
  163. package/dist/adapters/solana/reader.js +326 -0
  164. package/dist/adapters/solana/reader.js.map +1 -0
  165. package/dist/adapters/solana/rpc.d.ts +102 -0
  166. package/dist/adapters/solana/rpc.js +301 -0
  167. package/dist/adapters/solana/rpc.js.map +1 -0
  168. package/dist/adapters/solana/tokens.d.ts +7 -0
  169. package/dist/adapters/solana/tokens.js +19 -0
  170. package/dist/adapters/solana/tokens.js.map +1 -0
  171. package/dist/adapters/solana/types.d.ts +121 -0
  172. package/dist/{type/lib-types.js → adapters/solana/types.js} +1 -1
  173. package/dist/adapters/solana/types.js.map +1 -0
  174. package/dist/adapters/solana/web3.d.ts +5 -0
  175. package/dist/adapters/solana/web3.js +83 -0
  176. package/dist/adapters/solana/web3.js.map +1 -0
  177. package/dist/adapters/solana/wire.d.ts +62 -0
  178. package/dist/adapters/solana/wire.js +168 -0
  179. package/dist/adapters/solana/wire.js.map +1 -0
  180. package/dist/adapters/ton/address.d.ts +43 -0
  181. package/dist/adapters/ton/address.js +168 -0
  182. package/dist/adapters/ton/address.js.map +1 -0
  183. package/dist/adapters/ton/api.d.ts +344 -0
  184. package/dist/adapters/ton/api.js +942 -0
  185. package/dist/adapters/ton/api.js.map +1 -0
  186. package/dist/adapters/ton/builder.d.ts +18 -0
  187. package/dist/adapters/ton/builder.js +701 -0
  188. package/dist/adapters/ton/builder.js.map +1 -0
  189. package/dist/adapters/ton/chains.d.ts +16 -0
  190. package/dist/adapters/ton/chains.js +39 -0
  191. package/dist/adapters/ton/chains.js.map +1 -0
  192. package/dist/adapters/ton/decode.d.ts +43 -0
  193. package/dist/adapters/ton/decode.js +219 -0
  194. package/dist/adapters/ton/decode.js.map +1 -0
  195. package/dist/adapters/ton/driver.d.ts +10 -0
  196. package/dist/adapters/ton/driver.js +117 -0
  197. package/dist/adapters/ton/driver.js.map +1 -0
  198. package/dist/adapters/ton/errors.d.ts +36 -0
  199. package/dist/adapters/ton/errors.js +89 -0
  200. package/dist/adapters/ton/errors.js.map +1 -0
  201. package/dist/adapters/ton/fees.d.ts +28 -0
  202. package/dist/adapters/ton/fees.js +121 -0
  203. package/dist/adapters/ton/fees.js.map +1 -0
  204. package/dist/adapters/ton/index.d.ts +16 -0
  205. package/dist/adapters/ton/index.js +9 -0
  206. package/dist/adapters/ton/index.js.map +1 -0
  207. package/dist/adapters/ton/messages.d.ts +157 -0
  208. package/dist/adapters/ton/messages.js +397 -0
  209. package/dist/adapters/ton/messages.js.map +1 -0
  210. package/dist/adapters/ton/native-client.d.ts +10 -0
  211. package/dist/adapters/ton/native-client.js +47 -0
  212. package/dist/adapters/ton/native-client.js.map +1 -0
  213. package/dist/adapters/ton/network.d.ts +58 -0
  214. package/dist/adapters/ton/network.js +207 -0
  215. package/dist/adapters/ton/network.js.map +1 -0
  216. package/dist/adapters/ton/plugin.d.ts +24 -0
  217. package/dist/adapters/ton/plugin.js +57 -0
  218. package/dist/adapters/ton/plugin.js.map +1 -0
  219. package/dist/adapters/ton/presets.d.ts +6 -0
  220. package/dist/adapters/ton/presets.js +94 -0
  221. package/dist/adapters/ton/presets.js.map +1 -0
  222. package/dist/adapters/ton/proofs.d.ts +66 -0
  223. package/dist/adapters/ton/proofs.js +813 -0
  224. package/dist/adapters/ton/proofs.js.map +1 -0
  225. package/dist/adapters/ton/reader.d.ts +194 -0
  226. package/dist/adapters/ton/reader.js +781 -0
  227. package/dist/adapters/ton/reader.js.map +1 -0
  228. package/dist/adapters/ton/tokens.d.ts +10 -0
  229. package/dist/adapters/ton/tokens.js +27 -0
  230. package/dist/adapters/ton/tokens.js.map +1 -0
  231. package/dist/adapters/ton/trace.d.ts +48 -0
  232. package/dist/adapters/ton/trace.js +277 -0
  233. package/dist/adapters/ton/trace.js.map +1 -0
  234. package/dist/adapters/ton/types.d.ts +105 -0
  235. package/dist/adapters/ton/types.js +3 -0
  236. package/dist/adapters/ton/types.js.map +1 -0
  237. package/dist/adapters/ton/wallets.d.ts +86 -0
  238. package/dist/adapters/ton/wallets.js +373 -0
  239. package/dist/adapters/ton/wallets.js.map +1 -0
  240. package/dist/adapters/tron/abi.d.ts +39 -0
  241. package/dist/adapters/tron/abi.js +110 -0
  242. package/dist/adapters/tron/abi.js.map +1 -0
  243. package/dist/adapters/tron/address.d.ts +20 -0
  244. package/dist/adapters/tron/address.js +110 -0
  245. package/dist/adapters/tron/address.js.map +1 -0
  246. package/dist/adapters/tron/builder.d.ts +12 -0
  247. package/dist/adapters/tron/builder.js +553 -0
  248. package/dist/adapters/tron/builder.js.map +1 -0
  249. package/dist/adapters/tron/chains.d.ts +12 -0
  250. package/dist/adapters/tron/chains.js +35 -0
  251. package/dist/adapters/tron/chains.js.map +1 -0
  252. package/dist/adapters/tron/codec.d.ts +10 -0
  253. package/dist/adapters/tron/codec.js +322 -0
  254. package/dist/adapters/tron/codec.js.map +1 -0
  255. package/dist/adapters/tron/decode.d.ts +50 -0
  256. package/dist/adapters/tron/decode.js +280 -0
  257. package/dist/adapters/tron/decode.js.map +1 -0
  258. package/dist/adapters/tron/driver.d.ts +12 -0
  259. package/dist/adapters/tron/driver.js +106 -0
  260. package/dist/adapters/tron/driver.js.map +1 -0
  261. package/dist/adapters/tron/errors.d.ts +74 -0
  262. package/dist/adapters/tron/errors.js +261 -0
  263. package/dist/adapters/tron/errors.js.map +1 -0
  264. package/dist/adapters/tron/fees.d.ts +49 -0
  265. package/dist/adapters/tron/fees.js +166 -0
  266. package/dist/adapters/tron/fees.js.map +1 -0
  267. package/dist/adapters/tron/http.d.ts +173 -0
  268. package/dist/adapters/tron/http.js +729 -0
  269. package/dist/adapters/tron/http.js.map +1 -0
  270. package/dist/adapters/tron/index.d.ts +16 -0
  271. package/dist/adapters/tron/index.js +15 -0
  272. package/dist/adapters/tron/index.js.map +1 -0
  273. package/dist/adapters/tron/network.d.ts +44 -0
  274. package/dist/adapters/tron/network.js +163 -0
  275. package/dist/adapters/tron/network.js.map +1 -0
  276. package/dist/adapters/tron/plugin.d.ts +17 -0
  277. package/dist/adapters/tron/plugin.js +39 -0
  278. package/dist/adapters/tron/plugin.js.map +1 -0
  279. package/dist/adapters/tron/presets.d.ts +5 -0
  280. package/dist/adapters/tron/presets.js +68 -0
  281. package/dist/adapters/tron/presets.js.map +1 -0
  282. package/dist/adapters/tron/proofs.d.ts +80 -0
  283. package/dist/adapters/tron/proofs.js +370 -0
  284. package/dist/adapters/tron/proofs.js.map +1 -0
  285. package/dist/adapters/tron/protobuf.d.ts +36 -0
  286. package/dist/adapters/tron/protobuf.js +90 -0
  287. package/dist/adapters/tron/protobuf.js.map +1 -0
  288. package/dist/adapters/tron/reader.d.ts +47 -0
  289. package/dist/adapters/tron/reader.js +203 -0
  290. package/dist/adapters/tron/reader.js.map +1 -0
  291. package/dist/adapters/tron/tokens.d.ts +7 -0
  292. package/dist/adapters/tron/tokens.js +14 -0
  293. package/dist/adapters/tron/tokens.js.map +1 -0
  294. package/dist/adapters/tron/types.d.ts +166 -0
  295. package/dist/adapters/tron/types.js +3 -0
  296. package/dist/adapters/tron/types.js.map +1 -0
  297. package/dist/adapters/utxo/address.d.ts +51 -0
  298. package/dist/adapters/utxo/address.js +341 -0
  299. package/dist/adapters/utxo/address.js.map +1 -0
  300. package/dist/adapters/utxo/builder.d.ts +35 -0
  301. package/dist/adapters/utxo/builder.js +380 -0
  302. package/dist/adapters/utxo/builder.js.map +1 -0
  303. package/dist/adapters/utxo/chains.d.ts +17 -0
  304. package/dist/adapters/utxo/chains.js +99 -0
  305. package/dist/adapters/utxo/chains.js.map +1 -0
  306. package/dist/adapters/utxo/codec.d.ts +120 -0
  307. package/dist/adapters/utxo/codec.js +408 -0
  308. package/dist/adapters/utxo/codec.js.map +1 -0
  309. package/dist/adapters/utxo/coinselect.d.ts +48 -0
  310. package/dist/adapters/utxo/coinselect.js +131 -0
  311. package/dist/adapters/utxo/coinselect.js.map +1 -0
  312. package/dist/adapters/utxo/context.d.ts +57 -0
  313. package/dist/adapters/utxo/context.js +118 -0
  314. package/dist/adapters/utxo/context.js.map +1 -0
  315. package/dist/adapters/utxo/decode.d.ts +14 -0
  316. package/dist/adapters/utxo/decode.js +85 -0
  317. package/dist/adapters/utxo/decode.js.map +1 -0
  318. package/dist/adapters/utxo/driver.d.ts +16 -0
  319. package/dist/adapters/utxo/driver.js +74 -0
  320. package/dist/adapters/utxo/driver.js.map +1 -0
  321. package/dist/adapters/utxo/ecc.d.ts +9 -0
  322. package/dist/adapters/utxo/ecc.js +26 -0
  323. package/dist/adapters/utxo/ecc.js.map +1 -0
  324. package/dist/adapters/utxo/errors.d.ts +52 -0
  325. package/dist/adapters/utxo/errors.js +191 -0
  326. package/dist/adapters/utxo/errors.js.map +1 -0
  327. package/dist/adapters/utxo/esplora.d.ts +79 -0
  328. package/dist/adapters/utxo/esplora.js +451 -0
  329. package/dist/adapters/utxo/esplora.js.map +1 -0
  330. package/dist/adapters/utxo/fees.d.ts +41 -0
  331. package/dist/adapters/utxo/fees.js +125 -0
  332. package/dist/adapters/utxo/fees.js.map +1 -0
  333. package/dist/adapters/utxo/index.d.ts +17 -0
  334. package/dist/adapters/utxo/index.js +8 -0
  335. package/dist/adapters/utxo/index.js.map +1 -0
  336. package/dist/adapters/utxo/network.d.ts +50 -0
  337. package/dist/adapters/utxo/network.js +165 -0
  338. package/dist/adapters/utxo/network.js.map +1 -0
  339. package/dist/adapters/utxo/plugin.d.ts +17 -0
  340. package/dist/adapters/utxo/plugin.js +41 -0
  341. package/dist/adapters/utxo/plugin.js.map +1 -0
  342. package/dist/adapters/utxo/presets.d.ts +12 -0
  343. package/dist/adapters/utxo/presets.js +47 -0
  344. package/dist/adapters/utxo/presets.js.map +1 -0
  345. package/dist/adapters/utxo/preview.d.ts +3 -0
  346. package/dist/adapters/utxo/preview.js +65 -0
  347. package/dist/adapters/utxo/preview.js.map +1 -0
  348. package/dist/adapters/utxo/proofs.d.ts +57 -0
  349. package/dist/adapters/utxo/proofs.js +331 -0
  350. package/dist/adapters/utxo/proofs.js.map +1 -0
  351. package/dist/adapters/utxo/rawtx.d.ts +59 -0
  352. package/dist/adapters/utxo/rawtx.js +234 -0
  353. package/dist/adapters/utxo/rawtx.js.map +1 -0
  354. package/dist/adapters/utxo/reader.d.ts +36 -0
  355. package/dist/adapters/utxo/reader.js +265 -0
  356. package/dist/adapters/utxo/reader.js.map +1 -0
  357. package/dist/adapters/utxo/sdk.d.ts +18 -0
  358. package/dist/adapters/utxo/sdk.js +17 -0
  359. package/dist/adapters/utxo/sdk.js.map +1 -0
  360. package/dist/adapters/utxo/signed-psbt.d.ts +36 -0
  361. package/dist/adapters/utxo/signed-psbt.js +428 -0
  362. package/dist/adapters/utxo/signed-psbt.js.map +1 -0
  363. package/dist/adapters/utxo/spend.d.ts +59 -0
  364. package/dist/adapters/utxo/spend.js +230 -0
  365. package/dist/adapters/utxo/spend.js.map +1 -0
  366. package/dist/adapters/utxo/types.d.ts +167 -0
  367. package/dist/adapters/utxo/types.js +3 -0
  368. package/dist/adapters/utxo/types.js.map +1 -0
  369. package/dist/core/assets/service.d.ts +18 -0
  370. package/dist/core/assets/service.js +69 -0
  371. package/dist/core/assets/service.js.map +1 -0
  372. package/dist/core/blockchain/default-ref.d.ts +4 -0
  373. package/dist/core/blockchain/default-ref.js +16 -0
  374. package/dist/core/blockchain/default-ref.js.map +1 -0
  375. package/dist/core/blockchain/handle.d.ts +200 -0
  376. package/dist/core/blockchain/handle.js +579 -0
  377. package/dist/core/blockchain/handle.js.map +1 -0
  378. package/dist/core/blockchain/internal.d.ts +19 -0
  379. package/dist/core/blockchain/internal.js +16 -0
  380. package/dist/core/blockchain/internal.js.map +1 -0
  381. package/dist/core/blockchain/mapping.d.ts +22 -0
  382. package/dist/core/blockchain/mapping.js +136 -0
  383. package/dist/core/blockchain/mapping.js.map +1 -0
  384. package/dist/core/config/env.d.ts +8 -0
  385. package/dist/core/config/env.js +60 -0
  386. package/dist/core/config/env.js.map +1 -0
  387. package/dist/core/config/merge.d.ts +26 -0
  388. package/dist/core/config/merge.js +144 -0
  389. package/dist/core/config/merge.js.map +1 -0
  390. package/dist/core/config/resolve.d.ts +12 -0
  391. package/dist/core/config/resolve.js +251 -0
  392. package/dist/core/config/resolve.js.map +1 -0
  393. package/dist/core/config/types.d.ts +165 -0
  394. package/dist/core/config/types.js +3 -0
  395. package/dist/core/config/types.js.map +1 -0
  396. package/dist/core/container/builtins.d.ts +4 -0
  397. package/dist/core/container/builtins.js +13 -0
  398. package/dist/core/container/builtins.js.map +1 -0
  399. package/dist/core/container/container.d.ts +69 -0
  400. package/dist/core/container/container.js +466 -0
  401. package/dist/core/container/container.js.map +1 -0
  402. package/dist/core/container/default.d.ts +15 -0
  403. package/dist/core/container/default.js +70 -0
  404. package/dist/core/container/default.js.map +1 -0
  405. package/dist/core/container/internals.d.ts +54 -0
  406. package/dist/core/container/internals.js +21 -0
  407. package/dist/core/container/internals.js.map +1 -0
  408. package/dist/core/container/pool.d.ts +27 -0
  409. package/dist/core/container/pool.js +77 -0
  410. package/dist/core/container/pool.js.map +1 -0
  411. package/dist/core/driver/types.d.ts +346 -0
  412. package/dist/core/driver/types.js +3 -0
  413. package/dist/core/driver/types.js.map +1 -0
  414. package/dist/core/errors/codes.d.ts +153 -0
  415. package/dist/core/errors/codes.js +49 -0
  416. package/dist/core/errors/codes.js.map +1 -0
  417. package/dist/core/errors/error.d.ts +66 -0
  418. package/dist/core/errors/error.js +129 -0
  419. package/dist/core/errors/error.js.map +1 -0
  420. package/dist/core/events/bus.d.ts +12 -0
  421. package/dist/core/events/bus.js +46 -0
  422. package/dist/core/events/bus.js.map +1 -0
  423. package/dist/core/events/logger.d.ts +13 -0
  424. package/dist/core/events/logger.js +42 -0
  425. package/dist/core/events/logger.js.map +1 -0
  426. package/dist/core/events/types.d.ts +131 -0
  427. package/dist/core/events/types.js +3 -0
  428. package/dist/core/events/types.js.map +1 -0
  429. package/dist/core/lifecycle/engine-rules.d.ts +107 -0
  430. package/dist/core/lifecycle/engine-rules.js +257 -0
  431. package/dist/core/lifecycle/engine-rules.js.map +1 -0
  432. package/dist/core/lifecycle/engine.d.ts +500 -0
  433. package/dist/core/lifecycle/engine.js +1732 -0
  434. package/dist/core/lifecycle/engine.js.map +1 -0
  435. package/dist/core/lifecycle/evaluate.d.ts +19 -0
  436. package/dist/core/lifecycle/evaluate.js +72 -0
  437. package/dist/core/lifecycle/evaluate.js.map +1 -0
  438. package/dist/core/lifecycle/intent.d.ts +11 -0
  439. package/dist/core/lifecycle/intent.js +88 -0
  440. package/dist/core/lifecycle/intent.js.map +1 -0
  441. package/dist/core/lifecycle/monitor.d.ts +138 -0
  442. package/dist/core/lifecycle/monitor.js +606 -0
  443. package/dist/core/lifecycle/monitor.js.map +1 -0
  444. package/dist/core/lifecycle/observations.d.ts +17 -0
  445. package/dist/core/lifecycle/observations.js +59 -0
  446. package/dist/core/lifecycle/observations.js.map +1 -0
  447. package/dist/core/lifecycle/reconcile.d.ts +58 -0
  448. package/dist/core/lifecycle/reconcile.js +112 -0
  449. package/dist/core/lifecycle/reconcile.js.map +1 -0
  450. package/dist/core/lifecycle/views.d.ts +49 -0
  451. package/dist/core/lifecycle/views.js +57 -0
  452. package/dist/core/lifecycle/views.js.map +1 -0
  453. package/dist/core/lifecycle/workers.d.ts +82 -0
  454. package/dist/core/lifecycle/workers.js +329 -0
  455. package/dist/core/lifecycle/workers.js.map +1 -0
  456. package/dist/core/model/address.d.ts +32 -0
  457. package/dist/core/model/address.js +43 -0
  458. package/dist/core/model/address.js.map +1 -0
  459. package/dist/core/model/amount.d.ts +25 -0
  460. package/dist/core/model/amount.js +102 -0
  461. package/dist/core/model/amount.js.map +1 -0
  462. package/dist/core/model/asset.d.ts +28 -0
  463. package/dist/core/model/asset.js +47 -0
  464. package/dist/core/model/asset.js.map +1 -0
  465. package/dist/core/model/capability.d.ts +3 -0
  466. package/dist/core/model/capability.js +18 -0
  467. package/dist/core/model/capability.js.map +1 -0
  468. package/dist/core/model/chain.d.ts +63 -0
  469. package/dist/core/model/chain.js +8 -0
  470. package/dist/core/model/chain.js.map +1 -0
  471. package/dist/core/model/fee.d.ts +36 -0
  472. package/dist/core/model/fee.js +17 -0
  473. package/dist/core/model/fee.js.map +1 -0
  474. package/dist/core/model/ids.d.ts +37 -0
  475. package/dist/core/model/ids.js +13 -0
  476. package/dist/core/model/ids.js.map +1 -0
  477. package/dist/core/model/intent.d.ts +63 -0
  478. package/dist/core/model/intent.js +81 -0
  479. package/dist/core/model/intent.js.map +1 -0
  480. package/dist/core/model/ordering.d.ts +20 -0
  481. package/dist/core/model/ordering.js +29 -0
  482. package/dist/core/model/ordering.js.map +1 -0
  483. package/dist/core/model/transaction.d.ts +116 -0
  484. package/dist/core/model/transaction.js +3 -0
  485. package/dist/core/model/transaction.js.map +1 -0
  486. package/dist/core/observe/scanner.d.ts +135 -0
  487. package/dist/core/observe/scanner.js +355 -0
  488. package/dist/core/observe/scanner.js.map +1 -0
  489. package/dist/core/ordering/reservations.d.ts +16 -0
  490. package/dist/core/ordering/reservations.js +53 -0
  491. package/dist/core/ordering/reservations.js.map +1 -0
  492. package/dist/core/ordering/sequence.d.ts +61 -0
  493. package/dist/core/ordering/sequence.js +155 -0
  494. package/dist/core/ordering/sequence.js.map +1 -0
  495. package/dist/core/registry/adapters.d.ts +10 -0
  496. package/dist/core/registry/adapters.js +56 -0
  497. package/dist/core/registry/adapters.js.map +1 -0
  498. package/dist/core/registry/assets.d.ts +18 -0
  499. package/dist/core/registry/assets.js +90 -0
  500. package/dist/core/registry/assets.js.map +1 -0
  501. package/dist/core/registry/chains.d.ts +10 -0
  502. package/dist/core/registry/chains.js +80 -0
  503. package/dist/core/registry/chains.js.map +1 -0
  504. package/dist/core/registry/plugin.d.ts +41 -0
  505. package/dist/core/registry/plugin.js +109 -0
  506. package/dist/core/registry/plugin.js.map +1 -0
  507. package/dist/core/registry/providers.d.ts +31 -0
  508. package/dist/core/registry/providers.js +43 -0
  509. package/dist/core/registry/providers.js.map +1 -0
  510. package/dist/core/registry/schemes.d.ts +30 -0
  511. package/dist/core/registry/schemes.js +84 -0
  512. package/dist/core/registry/schemes.js.map +1 -0
  513. package/dist/core/secret/fragments.d.ts +33 -0
  514. package/dist/core/secret/fragments.js +110 -0
  515. package/dist/core/secret/fragments.js.map +1 -0
  516. package/dist/core/secret/redact.d.ts +10 -0
  517. package/dist/core/secret/redact.js +110 -0
  518. package/dist/core/secret/redact.js.map +1 -0
  519. package/dist/core/secret/secret.d.ts +14 -0
  520. package/dist/core/secret/secret.js +42 -0
  521. package/dist/core/secret/secret.js.map +1 -0
  522. package/dist/core/signing/callback.d.ts +10 -0
  523. package/dist/core/signing/callback.js +22 -0
  524. package/dist/core/signing/callback.js.map +1 -0
  525. package/dist/core/signing/guard.d.ts +18 -0
  526. package/dist/core/signing/guard.js +72 -0
  527. package/dist/core/signing/guard.js.map +1 -0
  528. package/dist/core/signing/hd.d.ts +36 -0
  529. package/dist/core/signing/hd.js +167 -0
  530. package/dist/core/signing/hd.js.map +1 -0
  531. package/dist/core/signing/local.d.ts +48 -0
  532. package/dist/core/signing/local.js +190 -0
  533. package/dist/core/signing/local.js.map +1 -0
  534. package/dist/core/signing/orchestrator.d.ts +40 -0
  535. package/dist/core/signing/orchestrator.js +300 -0
  536. package/dist/core/signing/orchestrator.js.map +1 -0
  537. package/dist/core/signing/types.d.ts +64 -0
  538. package/dist/core/signing/types.js +3 -0
  539. package/dist/core/signing/types.js.map +1 -0
  540. package/dist/core/signing/wallet.d.ts +48 -0
  541. package/dist/core/signing/wallet.js +153 -0
  542. package/dist/core/signing/wallet.js.map +1 -0
  543. package/dist/core/store/clone.d.ts +25 -0
  544. package/dist/core/store/clone.js +71 -0
  545. package/dist/core/store/clone.js.map +1 -0
  546. package/dist/core/store/memory.d.ts +38 -0
  547. package/dist/core/store/memory.js +325 -0
  548. package/dist/core/store/memory.js.map +1 -0
  549. package/dist/core/store/types.d.ts +246 -0
  550. package/dist/core/store/types.js +117 -0
  551. package/dist/core/store/types.js.map +1 -0
  552. package/dist/core/transport/backoff.d.ts +8 -0
  553. package/dist/core/transport/backoff.js +27 -0
  554. package/dist/core/transport/backoff.js.map +1 -0
  555. package/dist/core/transport/circuit.d.ts +25 -0
  556. package/dist/core/transport/circuit.js +61 -0
  557. package/dist/core/transport/circuit.js.map +1 -0
  558. package/dist/core/transport/http-transport.d.ts +30 -0
  559. package/dist/core/transport/http-transport.js +1695 -0
  560. package/dist/core/transport/http-transport.js.map +1 -0
  561. package/dist/core/transport/rate-limit.d.ts +27 -0
  562. package/dist/core/transport/rate-limit.js +78 -0
  563. package/dist/core/transport/rate-limit.js.map +1 -0
  564. package/dist/core/transport/stale-view.d.ts +11 -0
  565. package/dist/core/transport/stale-view.js +17 -0
  566. package/dist/core/transport/stale-view.js.map +1 -0
  567. package/dist/core/transport/types.d.ts +144 -0
  568. package/dist/core/transport/types.js +6 -0
  569. package/dist/core/transport/types.js.map +1 -0
  570. package/dist/core/util/bytes.d.ts +9 -0
  571. package/dist/core/util/bytes.js +40 -0
  572. package/dist/core/util/bytes.js.map +1 -0
  573. package/dist/core/util/clock.d.ts +6 -0
  574. package/dist/core/util/clock.js +26 -0
  575. package/dist/core/util/clock.js.map +1 -0
  576. package/dist/core/util/freeze.d.ts +8 -0
  577. package/dist/core/util/freeze.js +31 -0
  578. package/dist/core/util/freeze.js.map +1 -0
  579. package/dist/core/util/json.d.ts +29 -0
  580. package/dist/core/util/json.js +165 -0
  581. package/dist/core/util/json.js.map +1 -0
  582. package/dist/core/util/names.d.ts +21 -0
  583. package/dist/core/util/names.js +46 -0
  584. package/dist/core/util/names.js.map +1 -0
  585. package/dist/index.d.ts +64 -14
  586. package/dist/index.js +105 -49
  587. package/dist/index.js.map +1 -1
  588. package/dist/native.d.ts +21 -0
  589. package/dist/native.js +44 -0
  590. package/dist/native.js.map +1 -0
  591. package/dist/testing/contracts/api.d.ts +12 -0
  592. package/dist/testing/contracts/api.js +58 -0
  593. package/dist/testing/contracts/api.js.map +1 -0
  594. package/dist/testing/contracts/cursors.d.ts +6 -0
  595. package/dist/testing/contracts/cursors.js +43 -0
  596. package/dist/testing/contracts/cursors.js.map +1 -0
  597. package/dist/testing/contracts/locks.d.ts +10 -0
  598. package/dist/testing/contracts/locks.js +63 -0
  599. package/dist/testing/contracts/locks.js.map +1 -0
  600. package/dist/testing/contracts/operations.d.ts +21 -0
  601. package/dist/testing/contracts/operations.js +718 -0
  602. package/dist/testing/contracts/operations.js.map +1 -0
  603. package/dist/testing/contracts/sequences.d.ts +6 -0
  604. package/dist/testing/contracts/sequences.js +68 -0
  605. package/dist/testing/contracts/sequences.js.map +1 -0
  606. package/dist/testing/env.d.ts +63 -0
  607. package/dist/testing/env.js +105 -0
  608. package/dist/testing/env.js.map +1 -0
  609. package/dist/testing/fake-chain.d.ts +118 -0
  610. package/dist/testing/fake-chain.js +536 -0
  611. package/dist/testing/fake-chain.js.map +1 -0
  612. package/dist/testing/fake-clock.d.ts +15 -0
  613. package/dist/testing/fake-clock.js +86 -0
  614. package/dist/testing/fake-clock.js.map +1 -0
  615. package/dist/testing/fake-driver.d.ts +15 -0
  616. package/dist/testing/fake-driver.js +458 -0
  617. package/dist/testing/fake-driver.js.map +1 -0
  618. package/dist/testing/fake-fetch.d.ts +32 -0
  619. package/dist/testing/fake-fetch.js +81 -0
  620. package/dist/testing/fake-fetch.js.map +1 -0
  621. package/dist/testing/fake-plugin.d.ts +30 -0
  622. package/dist/testing/fake-plugin.js +66 -0
  623. package/dist/testing/fake-plugin.js.map +1 -0
  624. package/dist/testing/faulty-store.d.ts +36 -0
  625. package/dist/testing/faulty-store.js +66 -0
  626. package/dist/testing/faulty-store.js.map +1 -0
  627. package/dist/testing/generation.d.ts +60 -0
  628. package/dist/testing/generation.js +252 -0
  629. package/dist/testing/generation.js.map +1 -0
  630. package/dist/testing/index.d.ts +28 -0
  631. package/dist/testing/index.js +51 -0
  632. package/dist/testing/index.js.map +1 -0
  633. package/package.json +188 -44
  634. package/dist/libs/eth/account.d.ts +0 -9
  635. package/dist/libs/eth/account.js +0 -58
  636. package/dist/libs/eth/account.js.map +0 -1
  637. package/dist/libs/eth/contract.d.ts +0 -2
  638. package/dist/libs/eth/contract.js +0 -7
  639. package/dist/libs/eth/contract.js.map +0 -1
  640. package/dist/libs/eth/index.d.ts +0 -20
  641. package/dist/libs/eth/index.js +0 -62
  642. package/dist/libs/eth/index.js.map +0 -1
  643. package/dist/libs/eth/transact.d.ts +0 -2
  644. package/dist/libs/eth/transact.js +0 -7
  645. package/dist/libs/eth/transact.js.map +0 -1
  646. package/dist/libs/index.d.ts +0 -1
  647. package/dist/libs/index.js +0 -18
  648. package/dist/libs/index.js.map +0 -1
  649. package/dist/tool/common.d.ts +0 -28
  650. package/dist/tool/common.js +0 -33
  651. package/dist/tool/common.js.map +0 -1
  652. package/dist/tool/eth-tools.d.ts +0 -3
  653. package/dist/tool/eth-tools.js +0 -33
  654. package/dist/tool/eth-tools.js.map +0 -1
  655. package/dist/tool/index.d.ts +0 -4
  656. package/dist/tool/index.js +0 -21
  657. package/dist/tool/index.js.map +0 -1
  658. package/dist/tool/logging.d.ts +0 -3
  659. package/dist/tool/logging.js +0 -11
  660. package/dist/tool/logging.js.map +0 -1
  661. package/dist/tool/options.d.ts +0 -4
  662. package/dist/tool/options.js +0 -28
  663. package/dist/tool/options.js.map +0 -1
  664. package/dist/type/account.d.ts +0 -9
  665. package/dist/type/account.js.map +0 -1
  666. package/dist/type/common.d.ts +0 -18
  667. package/dist/type/common.js.map +0 -1
  668. package/dist/type/index.d.ts +0 -3
  669. package/dist/type/index.js +0 -20
  670. package/dist/type/index.js.map +0 -1
  671. package/dist/type/lib-types.d.ts +0 -7
  672. package/dist/type/lib-types.js.map +0 -1
@@ -0,0 +1,718 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SAMPLE_ORDERINGS = void 0;
7
+ exports.sampleOperation = sampleOperation;
8
+ exports.sampleAttempt = sampleAttempt;
9
+ exports.describeOperationStoreContract = describeOperationStoreContract;
10
+ const strict_1 = __importDefault(require("node:assert/strict"));
11
+ const api_1 = require("./api");
12
+ /**
13
+ * Narrows a `Promise.allSettled` result to its rejected variant, so a batch of
14
+ * promises that are expected to include failures can be driven with a single
15
+ * `Promise.allSettled` (a bare `Promise.all` would short-circuit on the first
16
+ * rejection and discard the others) and then inspected without repeated casts.
17
+ */
18
+ function isRejected(result) {
19
+ return result.status === 'rejected';
20
+ }
21
+ let counter = 0;
22
+ function sampleOperation(overrides = {}) {
23
+ counter += 1;
24
+ return {
25
+ id: `op_contract_${counter}`,
26
+ namespace: 'ns',
27
+ idempotencyKey: `key-${counter}`,
28
+ intentHash: 'hash',
29
+ context: {
30
+ chain: 'c',
31
+ network: 'n',
32
+ library: 'lib',
33
+ providers: ['p'],
34
+ indexers: [],
35
+ wallet: 'w',
36
+ configHash: 'cfg',
37
+ },
38
+ kind: 'transfer',
39
+ state: 'created',
40
+ intent: {
41
+ assetId: 'c:n/native',
42
+ asset: 'native',
43
+ outputs: [{ to: 'to', amount: 10n }],
44
+ from: 'from',
45
+ fee: 'normal',
46
+ },
47
+ attempts: [],
48
+ ...overrides,
49
+ };
50
+ }
51
+ function sampleAttempt(id, overrides = {}) {
52
+ const fee = {
53
+ kind: 'x',
54
+ speed: 'normal',
55
+ charges: [{ asset: 'native', amount: 1n, label: 'network' }],
56
+ bound: 'exact',
57
+ details: {},
58
+ };
59
+ return {
60
+ id,
61
+ ref: { id: `ref-${id}`, idKind: 'tx-hash', canonical: true },
62
+ raw: { encoding: 'hex', data: '00' },
63
+ ordering: { kind: 'nonce', nonce: 7n },
64
+ fee,
65
+ unsigned: {
66
+ payload: { encoding: 'hex', data: '00' },
67
+ signingRequests: [
68
+ {
69
+ id: 'r0',
70
+ scheme: 'secp256k1-ecdsa',
71
+ payload: new Uint8Array([1, 2]),
72
+ payloadKind: 'digest',
73
+ publicKey: new Uint8Array([3]),
74
+ },
75
+ ],
76
+ ordering: { kind: 'nonce', nonce: 7n },
77
+ fee,
78
+ summary: { asset: 'c:n/native', outputs: [] },
79
+ },
80
+ purpose: 'original',
81
+ createdAt: 1,
82
+ ...overrides,
83
+ };
84
+ }
85
+ /**
86
+ * An ordering of each kind the built-in families record, with each family's own
87
+ * properties. Proofs read these facts from the stored ordering, never from signed bytes,
88
+ * so a store must keep every one whole: a dropped property costs liveness, but a changed
89
+ * one (a `refBlockHash`, a `blockhash`, a `validFrom` moved later, a bigint narrowed to a
90
+ * number) can prove a transaction absent while a block holds it, and `rebuild` then pays
91
+ * twice. The bigints exceed 2^53. The core's `OrderingData` does not name these fields:
92
+ * each family exports its typed ordering, and this contract pins that a store keeps them.
93
+ */
94
+ exports.SAMPLE_ORDERINGS = Object.freeze([
95
+ ['an EVM nonce', { kind: 'nonce', nonce: 2n ** 64n - 1n }],
96
+ [
97
+ 'UTXO inputs',
98
+ {
99
+ kind: 'inputs',
100
+ inputs: [`${'ab'.repeat(32)}:0`, `${'cd'.repeat(32)}:4294967295`],
101
+ },
102
+ ],
103
+ [
104
+ 'a Tron expiry',
105
+ {
106
+ kind: 'expiry',
107
+ expiresAtMs: 1_790_000_000_123,
108
+ lastValidHeight: 2n ** 53n + 65537n,
109
+ refBlockHash: '0a1b2c3d4e5f6071',
110
+ },
111
+ ],
112
+ [
113
+ 'a Solana expiry',
114
+ {
115
+ kind: 'expiry',
116
+ lastValidHeight: 2n ** 63n + 150n,
117
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
118
+ blockhashSlot: 2n ** 53n + 1n,
119
+ },
120
+ ],
121
+ [
122
+ 'a TON seqno',
123
+ {
124
+ kind: 'seqno',
125
+ seqno: 2n ** 32n - 1n,
126
+ validUntil: 1_790_000_060,
127
+ validFrom: 1_789_999_700,
128
+ },
129
+ ],
130
+ ]);
131
+ /** Every property of `expected`, and no other, with the same value and type. */
132
+ function assertWholeOrdering(actual, expected, where) {
133
+ strict_1.default.ok(actual !== null && typeof actual === 'object', `${where}: missing`);
134
+ const got = actual;
135
+ strict_1.default.deepEqual(Object.keys(got).sort(), Object.keys(expected).sort(), `${where}: properties`);
136
+ for (const [key, value] of Object.entries(expected)) {
137
+ strict_1.default.equal(typeof got[key], typeof value, `${where}.${key}: type`);
138
+ strict_1.default.deepEqual(got[key], value, `${where}.${key}: value`);
139
+ }
140
+ }
141
+ function describeOperationStoreContract(api, create) {
142
+ api.describe('OperationStore contract', () => {
143
+ api.it('creates if absent on (namespace, idempotencyKey)', async () => {
144
+ const { operations } = await create();
145
+ const first = await operations.create(sampleOperation({ idempotencyKey: 'same' }));
146
+ strict_1.default.equal(first.created, true);
147
+ strict_1.default.equal(first.record.version, 1);
148
+ const second = await operations.create(sampleOperation({ idempotencyKey: 'same' }));
149
+ strict_1.default.equal(second.created, false);
150
+ strict_1.default.equal(second.record.id, first.record.id);
151
+ const otherNs = await operations.create(sampleOperation({ idempotencyKey: 'same', namespace: 'other' }));
152
+ strict_1.default.equal(otherNs.created, true);
153
+ strict_1.default.equal((await operations.getByKey('ns', 'same'))?.id, first.record.id);
154
+ strict_1.default.equal(await operations.get('ns', 'missing'), null);
155
+ strict_1.default.equal(await operations.getByKey('ns', 'missing'), null);
156
+ });
157
+ api.it('rejects create when the runtime input carries a store-owned field, storing nothing', async () => {
158
+ const { operations } = await create();
159
+ const forbidden = {
160
+ claim: { workerId: 'w', token: '1', until: 1 },
161
+ version: 1,
162
+ createdAt: 1,
163
+ updatedAt: 1,
164
+ };
165
+ for (const key of Object.keys(forbidden)) {
166
+ const operation = {
167
+ ...sampleOperation(),
168
+ [key]: forbidden[key],
169
+ };
170
+ await (0, api_1.rejectsWithCode)(operations.create(operation), 'INVALID_TRANSITION');
171
+ strict_1.default.equal(await operations.get(operation.namespace, operation.id), null);
172
+ strict_1.default.equal(await operations.getByKey(operation.namespace, operation.idempotencyKey), null);
173
+ }
174
+ });
175
+ api.it('updates with compare-and-set versions and clears fields', async () => {
176
+ const { operations } = await create();
177
+ const { record } = await operations.create(sampleOperation());
178
+ const updated = await operations.update('ns', record.id, {
179
+ state: 'prepared',
180
+ reservation: { kind: 'nonce', nonce: 3n },
181
+ error: {
182
+ name: 'E',
183
+ code: 'TIMEOUT',
184
+ category: 'timeout',
185
+ message: 'm',
186
+ retryable: true,
187
+ ambiguous: false,
188
+ context: {},
189
+ },
190
+ }, 1);
191
+ strict_1.default.equal(updated.version, 2);
192
+ strict_1.default.equal(updated.state, 'prepared');
193
+ await (0, api_1.rejectsWithCode)(operations.update('ns', record.id, { state: 'signed' }, 1), 'VERSION_CONFLICT');
194
+ await (0, api_1.rejectsWithCode)(operations.update('ns', 'missing', { state: 'signed' }, 1), 'NOT_FOUND');
195
+ const cleared = await operations.update('ns', record.id, { clear: ['reservation', 'error'] }, 2);
196
+ strict_1.default.equal(cleared.reservation, undefined);
197
+ strict_1.default.equal(cleared.error, undefined);
198
+ strict_1.default.equal(cleared.state, 'prepared');
199
+ });
200
+ api.it('bumps the version on every successful update, even one that changes nothing', async () => {
201
+ // The engine fences a stale writer with a no-effect compare-and-set; a store
202
+ // that skipped writing an unchanged record would let the stale write land.
203
+ const { operations } = await create();
204
+ const { record } = await operations.create(sampleOperation());
205
+ strict_1.default.equal(record.error, undefined);
206
+ const bumped = await operations.update('ns', record.id, { clear: ['error'] }, record.version);
207
+ strict_1.default.equal(bumped.version, record.version + 1);
208
+ await (0, api_1.rejectsWithCode)(operations.update('ns', record.id, { state: 'prepared' }, record.version), 'VERSION_CONFLICT');
209
+ });
210
+ api.it('appends attempts atomically with the state change', async () => {
211
+ const { operations } = await create();
212
+ const { record } = await operations.create(sampleOperation());
213
+ const next = await operations.appendAttempt('ns', record.id, sampleAttempt('a1'), { state: 'signed' }, 1);
214
+ strict_1.default.equal(next.version, 2);
215
+ strict_1.default.equal(next.state, 'signed');
216
+ strict_1.default.equal(next.activeAttemptId, 'a1');
217
+ strict_1.default.equal(next.attempts.length, 1);
218
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', record.id, sampleAttempt('a1'), {}, 2), 'INVALID_TRANSITION');
219
+ const stored = await operations.get('ns', record.id);
220
+ const request = stored?.attempts[0]?.unsigned.signingRequests[0];
221
+ strict_1.default.deepEqual(request?.payload, new Uint8Array([1, 2]));
222
+ const ordering = stored?.attempts[0]?.ordering;
223
+ strict_1.default.equal(ordering?.kind === 'nonce' ? ordering.nonce : undefined, 7n);
224
+ });
225
+ api.it('keeps every ordering whole: each property, with its value and its type', async () => {
226
+ const { operations } = await create();
227
+ for (const [name, ordering] of exports.SAMPLE_ORDERINGS) {
228
+ const { record } = await operations.create(sampleOperation());
229
+ const sample = sampleAttempt('a1');
230
+ const appended = await operations.appendAttempt('ns', record.id, { ...sample, ordering, unsigned: { ...sample.unsigned, ordering } }, { state: 'signed', reservation: ordering }, record.version);
231
+ // Read back after the append, and again after a later write to the record.
232
+ const stored = await operations.get('ns', record.id);
233
+ const updated = await operations.update('ns', record.id, { state: 'submitted' }, appended.version);
234
+ const reread = await operations.get('ns', record.id);
235
+ for (const [when, read] of [
236
+ ['appendAttempt', appended],
237
+ ['get', stored],
238
+ ['update', updated],
239
+ ['get after update', reread],
240
+ ]) {
241
+ const where = `${name} (${when})`;
242
+ assertWholeOrdering(read?.attempts[0]?.ordering, ordering, `${where} ordering`);
243
+ assertWholeOrdering(read?.attempts[0]?.unsigned.ordering, ordering, `${where} unsigned.ordering`);
244
+ assertWholeOrdering(read?.reservation, ordering, `${where} reservation`);
245
+ }
246
+ }
247
+ });
248
+ api.it('isolates returned records from the store', async () => {
249
+ const { operations } = await create();
250
+ const { record } = await operations.create(sampleOperation());
251
+ record.intent.outputs.push({
252
+ to: 'x',
253
+ amount: 1n,
254
+ });
255
+ strict_1.default.equal((await operations.get('ns', record.id))?.intent.outputs.length, 1);
256
+ });
257
+ api.it('versions observations and finds operations by ref or tx hash', async () => {
258
+ const { operations } = await create();
259
+ const { record } = await operations.create(sampleOperation());
260
+ await operations.appendAttempt('ns', record.id, sampleAttempt('a2'), { state: 'signed' }, 1);
261
+ const base = {
262
+ attemptId: 'a2',
263
+ operationId: record.id,
264
+ state: 'included',
265
+ evidence: 'observed',
266
+ confirmations: 1,
267
+ txHash: 'canonical-hash',
268
+ blockHeight: 2n ** 40n,
269
+ };
270
+ const obs = await operations.putObservation(base, null);
271
+ strict_1.default.equal(obs.version, 1);
272
+ await (0, api_1.rejectsWithCode)(operations.putObservation(base, null), 'VERSION_CONFLICT');
273
+ strict_1.default.equal((await operations.putObservation({ ...base, confirmations: 2 }, 1)).version, 2);
274
+ strict_1.default.equal((await operations.getObservation('a2'))?.blockHeight, 2n ** 40n);
275
+ strict_1.default.equal((await operations.findByRef('ns', 'ref-a2'))?.id, record.id);
276
+ strict_1.default.equal((await operations.findByRef('ns', 'canonical-hash'))?.id, record.id);
277
+ strict_1.default.equal(await operations.findByRef('other', 'ref-a2'), null);
278
+ });
279
+ api.it('replaces an observation whole: a key left out or set to undefined reads back undefined (never null)', async () => {
280
+ // The core clears a stale reason or block by leaving it out or setting
281
+ // it to undefined. A store that merged records, or kept undefined as a value such as
282
+ // null, would return a stale or wrong field.
283
+ const { operations } = await create();
284
+ const { record } = await operations.create(sampleOperation());
285
+ await operations.appendAttempt('ns', record.id, sampleAttempt('a3'), { state: 'signed' }, 1);
286
+ const failed = await operations.putObservation({
287
+ attemptId: 'a3',
288
+ operationId: record.id,
289
+ state: 'failed',
290
+ evidence: 'observed',
291
+ confirmations: 1,
292
+ blockHeight: 7n,
293
+ blockHash: 'block-7',
294
+ reason: 'transfer bounced',
295
+ }, null);
296
+ await operations.putObservation({
297
+ attemptId: 'a3',
298
+ operationId: record.id,
299
+ state: 'pending',
300
+ evidence: 'observed',
301
+ confirmations: 0,
302
+ reason: undefined,
303
+ }, failed.version);
304
+ const reread = await operations.getObservation('a3');
305
+ strict_1.default.equal(reread?.state, 'pending');
306
+ strict_1.default.equal(reread?.blockHeight, undefined);
307
+ strict_1.default.equal(reread?.blockHash, undefined);
308
+ strict_1.default.equal(reread?.reason, undefined);
309
+ });
310
+ api.it('claims due operations exclusively and fences stale workers', async () => {
311
+ const { operations } = await create();
312
+ const a = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }))).record;
313
+ const b = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }))).record;
314
+ await operations.create(sampleOperation({ state: 'final', nextCheckAt: 100 }));
315
+ await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 10_000 }));
316
+ // Unscheduled operations (no nextCheckAt) are still being built or signed: never due.
317
+ await operations.create(sampleOperation({ state: 'prepared' }));
318
+ const w1 = await operations.claimDue('ns', 'w1', 1_000, 500, 1);
319
+ const w2 = await operations.claimDue('ns', 'w2', 1_000, 500, 10);
320
+ strict_1.default.equal(w1.length, 1);
321
+ strict_1.default.equal(w2.length, 1);
322
+ strict_1.default.notEqual(w1[0]?.id, w2[0]?.id);
323
+ strict_1.default.deepEqual(new Set([w1[0]?.id, w2[0]?.id]), new Set([a.id, b.id]));
324
+ strict_1.default.equal((await operations.claimDue('ns', 'w3', 1_200, 500, 10)).length, 0);
325
+ const staleClaim = w1[0];
326
+ const retaken = await operations.claimDue('ns', 'w3', 1_600, 500, 10);
327
+ const takeover = retaken.find((r) => r.id === staleClaim.id);
328
+ strict_1.default.ok(takeover);
329
+ strict_1.default.ok(BigInt(takeover.claim.token) > BigInt(staleClaim.claim.token));
330
+ await (0, api_1.rejectsWithCode)(operations.update('ns', staleClaim.id, { nextCheckAt: 5 }, takeover.version, {
331
+ claimToken: staleClaim.claim.token,
332
+ }), 'FENCING');
333
+ await (0, api_1.rejectsWithCode)(operations.releaseClaim('ns', staleClaim.id, {
334
+ claimToken: staleClaim.claim.token,
335
+ }), 'FENCING');
336
+ await operations.releaseClaim('ns', staleClaim.id, {
337
+ claimToken: takeover.claim.token,
338
+ });
339
+ strict_1.default.equal((await operations.get('ns', staleClaim.id))?.claim, undefined);
340
+ });
341
+ api.it('lists by filter in creation order', async () => {
342
+ const { operations } = await create();
343
+ const one = (await operations.create(sampleOperation({
344
+ namespace: 'list',
345
+ intent: { ...sampleOperation().intent, from: 'alice' },
346
+ }))).record;
347
+ await operations.create(sampleOperation({
348
+ namespace: 'list',
349
+ state: 'final',
350
+ intent: { ...sampleOperation().intent, from: 'alice' },
351
+ }));
352
+ await operations.create(sampleOperation({
353
+ namespace: 'list',
354
+ intent: { ...sampleOperation().intent, from: 'bob' },
355
+ }));
356
+ const alice = await operations.list({
357
+ namespace: 'list',
358
+ from: 'alice',
359
+ states: ['created'],
360
+ });
361
+ strict_1.default.deepEqual(alice.map((r) => r.id), [one.id]);
362
+ strict_1.default.equal((await operations.list({ namespace: 'list' })).length, 3);
363
+ strict_1.default.equal((await operations.list({ namespace: 'list', limit: 2 })).length, 2);
364
+ });
365
+ api.it('rejects patch fields outside the writable whitelist, leaving the record unchanged', async () => {
366
+ const { operations } = await create();
367
+ const created = await operations.create(sampleOperation());
368
+ const afterAppend = await operations.appendAttempt('ns', created.record.id, sampleAttempt('w1'), { state: 'signed' }, 1);
369
+ const snapshot = await operations.get('ns', created.record.id);
370
+ await (0, api_1.rejectsWithCode)(operations.update('ns', created.record.id, { attempts: [] }, afterAppend.version), 'INVALID_TRANSITION');
371
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
372
+ await (0, api_1.rejectsWithCode)(operations.update('ns', created.record.id, {
373
+ claim: undefined,
374
+ state: 'submitted',
375
+ ...{ id: 'x' },
376
+ }, afterAppend.version), 'INVALID_TRANSITION');
377
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
378
+ await (0, api_1.rejectsWithCode)(operations.update('ns', created.record.id, { clear: ['attempts', 'claim'] }, afterAppend.version), 'INVALID_TRANSITION');
379
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
380
+ });
381
+ api.it("rejects appendAttempt's patch fields outside the writable whitelist, leaving the record unchanged", async () => {
382
+ const { operations } = await create();
383
+ const created = await operations.create(sampleOperation());
384
+ const snapshot = await operations.get('ns', created.record.id);
385
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('wl1'), { attempts: [] }, 1), 'INVALID_TRANSITION');
386
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
387
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('wl2'), {
388
+ claim: undefined,
389
+ state: 'submitted',
390
+ ...{ id: 'x' },
391
+ }, 1), 'INVALID_TRANSITION');
392
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
393
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('wl3'), { clear: ['attempts', 'claim'] }, 1), 'INVALID_TRANSITION');
394
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
395
+ });
396
+ api.it('rejects a clear that is not an array, leaving the record unchanged', async () => {
397
+ // A serialized store cannot read a number, an object or a Set as a list either;
398
+ // reading one as `[]` would let a malformed patch commit as if it cleared nothing.
399
+ const { operations } = await create();
400
+ const created = await operations.create(sampleOperation());
401
+ const snapshot = await operations.get('ns', created.record.id);
402
+ for (const clear of [5, {}, null, 'error', new Set(['error'])]) {
403
+ const patch = { state: 'prepared', clear };
404
+ await (0, api_1.rejectsWithCode)(operations.update('ns', created.record.id, patch, 1), 'INVALID_TRANSITION');
405
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
406
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('n7'), patch, 1), 'INVALID_TRANSITION');
407
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
408
+ }
409
+ });
410
+ api.it('keeps the idempotency key and the wallet address out of its errors', async () => {
411
+ // Both are `sensitive` data, and error messages reach logs.
412
+ const { operations } = await create();
413
+ const from = 'TRonWa11etAddre55C0ffee000000000000';
414
+ const idempotencyKey = 'withdrawal-7f3a9c-customer-4417';
415
+ const secrets = [from, idempotencyKey];
416
+ const operation = sampleOperation({
417
+ idempotencyKey,
418
+ state: 'submitted',
419
+ nextCheckAt: 100,
420
+ intent: { ...sampleOperation().intent, from },
421
+ });
422
+ const { record } = await operations.create(operation);
423
+ await (0, api_1.rejectsWithCodeKeepingOut)(operations.create({ ...operation, idempotencyKey: 'another-key' }), 'INVALID_TRANSITION', secrets);
424
+ await (0, api_1.rejectsWithCodeKeepingOut)(operations.update('ns', record.id, { state: 'prepared' }, 9), 'VERSION_CONFLICT', secrets);
425
+ await (0, api_1.rejectsWithCodeKeepingOut)(operations.update('ns', record.id, { idempotencyKey: 'x' }, record.version), 'INVALID_TRANSITION', secrets);
426
+ const appended = await operations.appendAttempt('ns', record.id, sampleAttempt('k1'), {}, record.version);
427
+ await (0, api_1.rejectsWithCodeKeepingOut)(operations.appendAttempt('ns', record.id, sampleAttempt('k1'), {}, appended.version), 'INVALID_TRANSITION', secrets);
428
+ await (0, api_1.rejectsWithCodeKeepingOut)(operations.appendAttempt('ns', record.id, sampleAttempt('k2'), {}, 1), 'VERSION_CONFLICT', secrets);
429
+ const [stale] = await operations.claimDue('ns', 'w1', 1_000, 500, 10);
430
+ await operations.claimDue('ns', 'w2', 1_600, 500, 10);
431
+ const current = await operations.get('ns', record.id);
432
+ await (0, api_1.rejectsWithCodeKeepingOut)(operations.update('ns', record.id, {}, current.version, {
433
+ claimToken: stale.claim.token,
434
+ }), 'FENCING', secrets);
435
+ });
436
+ api.it('purges what the filter matches and nothing else, when it implements purge', async () => {
437
+ const { operations } = await create();
438
+ if (operations.purge === undefined)
439
+ return;
440
+ const done = (await operations.create(sampleOperation({ namespace: 'purge', state: 'final' }))).record;
441
+ await operations.appendAttempt('purge', done.id, sampleAttempt('p1'), {}, done.version);
442
+ await operations.putObservation({
443
+ attemptId: 'p1',
444
+ operationId: done.id,
445
+ state: 'included',
446
+ evidence: 'proven',
447
+ confirmations: 3,
448
+ txHash: 'purged-hash',
449
+ }, null);
450
+ const live = (await operations.create(sampleOperation({ namespace: 'purge', state: 'submitted' }))).record;
451
+ const elsewhere = (await operations.create(sampleOperation({ namespace: 'kept', state: 'final' }))).record;
452
+ const liveBefore = await operations.get('purge', live.id);
453
+ const elsewhereBefore = await operations.get('kept', elsewhere.id);
454
+ strict_1.default.equal(await operations.purge({ namespace: 'purge', states: ['final'] }), 1);
455
+ strict_1.default.equal(await operations.get('purge', done.id), null);
456
+ strict_1.default.equal(await operations.getByKey('purge', done.idempotencyKey), null);
457
+ strict_1.default.equal(await operations.findByRef('purge', 'ref-p1'), null);
458
+ strict_1.default.equal(await operations.findByRef('purge', 'purged-hash'), null);
459
+ strict_1.default.equal(await operations.getObservation('p1'), null);
460
+ strict_1.default.deepEqual(await operations.get('purge', live.id), liveBefore);
461
+ strict_1.default.deepEqual(await operations.get('kept', elsewhere.id), elsewhereBefore);
462
+ // The idempotency key is free again: a new Operation may take it.
463
+ const again = await operations.create(sampleOperation({
464
+ namespace: 'purge',
465
+ idempotencyKey: done.idempotencyKey,
466
+ id: `${done.id}-again`,
467
+ }));
468
+ strict_1.default.equal(again.created, true);
469
+ strict_1.default.equal(await operations.purge({ namespace: 'empty' }), 0);
470
+ });
471
+ api.it('purges at most limit records, the oldest first, when it implements purge', async () => {
472
+ const { operations } = await create();
473
+ if (operations.purge === undefined)
474
+ return;
475
+ const ids = [];
476
+ for (let i = 0; i < 3; i += 1) {
477
+ const { record } = await operations.create(sampleOperation({ namespace: 'purge-limit', state: 'failed' }));
478
+ ids.push(record.id);
479
+ }
480
+ strict_1.default.equal(await operations.purge({ namespace: 'purge-limit', limit: 2 }), 2);
481
+ strict_1.default.deepEqual((await operations.list({ namespace: 'purge-limit' })).map((r) => r.id), [ids[2]]);
482
+ strict_1.default.equal(await operations.purge({ namespace: 'purge-limit', limit: 0 }), 0);
483
+ strict_1.default.equal((await operations.list({ namespace: 'purge-limit' })).length, 1);
484
+ });
485
+ api.it('rejects appendAttempt with a duplicate id even when the content differs, leaving the record unchanged', async () => {
486
+ const { operations } = await create();
487
+ const created = await operations.create(sampleOperation());
488
+ const afterFirst = await operations.appendAttempt('ns', created.record.id, sampleAttempt('dup'), { state: 'signed' }, 1);
489
+ const snapshot = await operations.get('ns', created.record.id);
490
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('dup', {
491
+ purpose: 'replacement',
492
+ raw: { encoding: 'hex', data: 'ff' },
493
+ }), { state: 'failed' }, afterFirst.version), 'INVALID_TRANSITION');
494
+ const after = await operations.get('ns', created.record.id);
495
+ strict_1.default.deepEqual(after, snapshot);
496
+ strict_1.default.equal(after?.attempts.length, 1);
497
+ strict_1.default.equal(after?.version, afterFirst.version);
498
+ strict_1.default.equal(after?.state, 'signed');
499
+ });
500
+ api.it('rejects appendAttempt with a stale expectedVersion, leaving the record unchanged', async () => {
501
+ const { operations } = await create();
502
+ const created = await operations.create(sampleOperation());
503
+ await operations.appendAttempt('ns', created.record.id, sampleAttempt('s1'), { state: 'signed' }, 1);
504
+ const snapshot = await operations.get('ns', created.record.id);
505
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('s2'), { state: 'submitted' }, 1), 'VERSION_CONFLICT');
506
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
507
+ });
508
+ api.it('rejects appendAttempt from a stale fencing token after a claim takeover, leaving the record unchanged', async () => {
509
+ const { operations } = await create();
510
+ const created = await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }));
511
+ const [stale] = await operations.claimDue('ns', 'w1', 1_000, 500, 10);
512
+ const [takeover] = await operations.claimDue('ns', 'w2', 1_600, 500, 10);
513
+ const snapshot = await operations.get('ns', created.record.id);
514
+ await (0, api_1.rejectsWithCode)(operations.appendAttempt('ns', created.record.id, sampleAttempt('f1'), { state: 'signed' }, takeover.version, { claimToken: stale.claim.token }), 'FENCING');
515
+ strict_1.default.deepEqual(await operations.get('ns', created.record.id), snapshot);
516
+ });
517
+ api.it("isolates a stored attempt from later mutation of the caller's input", async () => {
518
+ const { operations } = await create();
519
+ const created = await operations.create(sampleOperation());
520
+ const attempt = sampleAttempt('iso1');
521
+ await operations.appendAttempt('ns', created.record.id, attempt, { state: 'signed' }, 1);
522
+ attempt.unsigned.signingRequests[0].payload[0] = 99;
523
+ attempt.raw.data = 'ff';
524
+ const stored = await operations.get('ns', created.record.id);
525
+ const storedAttempt = stored?.attempts[0];
526
+ strict_1.default.deepEqual(storedAttempt?.unsigned.signingRequests[0]?.payload, new Uint8Array([1, 2]));
527
+ strict_1.default.equal(storedAttempt?.raw.data, '00');
528
+ });
529
+ api.it('appends attempts in order without rewriting earlier ones', async () => {
530
+ const { operations } = await create();
531
+ const created = await operations.create(sampleOperation());
532
+ const afterFirst = await operations.appendAttempt('ns', created.record.id, sampleAttempt('a1'), { state: 'signed' }, 1);
533
+ const firstAttemptSnapshot = afterFirst.attempts[0];
534
+ const afterSecond = await operations.appendAttempt('ns', created.record.id, sampleAttempt('a2'), { state: 'submitted' }, afterFirst.version);
535
+ strict_1.default.deepEqual(afterSecond.attempts.map((a) => a.id), ['a1', 'a2']);
536
+ strict_1.default.deepEqual(afterSecond.attempts[0], firstAttemptSnapshot);
537
+ });
538
+ api.it('resolves N concurrent creates under one idempotency key, with distinct ids, to exactly one winner', async () => {
539
+ const { operations } = await create();
540
+ const results = await Promise.all(Array.from({ length: 5 }, () => operations.create(sampleOperation({ idempotencyKey: 'race-create' }))));
541
+ const winners = results.filter((r) => r.created);
542
+ strict_1.default.equal(winners.length, 1);
543
+ const winnerId = winners[0].record.id;
544
+ for (const r of results)
545
+ strict_1.default.equal(r.record.id, winnerId);
546
+ const listed = (await operations.list({ namespace: 'ns' })).filter((r) => r.idempotencyKey === 'race-create');
547
+ strict_1.default.equal(listed.length, 1);
548
+ strict_1.default.equal((await operations.getByKey('ns', 'race-create'))?.id, winnerId);
549
+ });
550
+ api.it('resolves N concurrent updates with the same expectedVersion to exactly one winner', async () => {
551
+ const { operations } = await create();
552
+ const created = await operations.create(sampleOperation());
553
+ const results = await Promise.allSettled(Array.from({ length: 5 }, () => operations.update('ns', created.record.id, { state: 'prepared' }, 1)));
554
+ strict_1.default.equal(results.filter((r) => r.status === 'fulfilled').length, 1);
555
+ const rejected = results.filter(isRejected);
556
+ strict_1.default.equal(rejected.length, 4);
557
+ for (const r of rejected) {
558
+ strict_1.default.equal(r.reason.code, 'VERSION_CONFLICT');
559
+ }
560
+ });
561
+ api.it('resolves N concurrent appendAttempt calls with the same expectedVersion to exactly one winner', async () => {
562
+ const { operations } = await create();
563
+ const created = await operations.create(sampleOperation());
564
+ const results = await Promise.allSettled(Array.from({ length: 5 }, (_, i) => operations.appendAttempt('ns', created.record.id, sampleAttempt(`c${i}`), { state: 'signed' }, 1)));
565
+ strict_1.default.equal(results.filter((r) => r.status === 'fulfilled').length, 1);
566
+ const rejected = results.filter(isRejected);
567
+ strict_1.default.equal(rejected.length, 4);
568
+ for (const r of rejected) {
569
+ strict_1.default.equal(r.reason.code, 'VERSION_CONFLICT');
570
+ }
571
+ strict_1.default.equal((await operations.get('ns', created.record.id))?.attempts.length, 1);
572
+ });
573
+ api.it('returns disjoint id sets for two concurrent claimDue calls', async () => {
574
+ const { operations } = await create();
575
+ for (let i = 0; i < 4; i++) {
576
+ await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }));
577
+ }
578
+ const [first, second] = await Promise.all([
579
+ operations.claimDue('ns', 'w1', 1_000, 500, 2),
580
+ operations.claimDue('ns', 'w2', 1_000, 500, 2),
581
+ ]);
582
+ strict_1.default.equal(first.length + second.length, 4);
583
+ const firstIds = new Set(first.map((r) => r.id));
584
+ for (const record of second)
585
+ strict_1.default.equal(firstIds.has(record.id), false);
586
+ });
587
+ api.it('returns the original record unchanged when a second create uses the same key but a different intentHash', async () => {
588
+ const { operations } = await create();
589
+ const first = await operations.create(sampleOperation({ idempotencyKey: 'conflict', intentHash: 'hash-a' }));
590
+ const second = await operations.create(sampleOperation({ idempotencyKey: 'conflict', intentHash: 'hash-b' }));
591
+ strict_1.default.equal(second.created, false);
592
+ strict_1.default.deepEqual(second.record, first.record);
593
+ strict_1.default.equal(second.record.intentHash, 'hash-a');
594
+ strict_1.default.deepEqual(await operations.get('ns', first.record.id), first.record);
595
+ });
596
+ api.it('treats an explicit undefined patch value as a no-op for that field', async () => {
597
+ const { operations } = await create();
598
+ const created = await operations.create(sampleOperation());
599
+ const withReservation = await operations.update('ns', created.record.id, { reservation: { kind: 'nonce', nonce: 5n } }, 1);
600
+ const untouched = await operations.update('ns', created.record.id, { reservation: undefined }, withReservation.version);
601
+ strict_1.default.deepEqual(untouched.reservation, { kind: 'nonce', nonce: 5n });
602
+ strict_1.default.deepEqual((await operations.get('ns', created.record.id))?.reservation, {
603
+ kind: 'nonce',
604
+ nonce: 5n,
605
+ });
606
+ });
607
+ api.it('clear removes the field entirely, not just sets it to undefined', async () => {
608
+ const { operations } = await create();
609
+ const created = await operations.create(sampleOperation());
610
+ const withReservation = await operations.update('ns', created.record.id, { reservation: { kind: 'nonce', nonce: 5n } }, 1);
611
+ const cleared = await operations.update('ns', created.record.id, { clear: ['reservation'] }, withReservation.version);
612
+ strict_1.default.equal('reservation' in cleared, false);
613
+ const reread = await operations.get('ns', created.record.id);
614
+ strict_1.default.equal(reread !== null && 'reservation' in reread, false);
615
+ });
616
+ api.it('never returns claims from another namespace', async () => {
617
+ const { operations } = await create();
618
+ await operations.create(sampleOperation({ namespace: 'other', state: 'submitted', nextCheckAt: 50 }));
619
+ await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 50 }));
620
+ const claimed = await operations.claimDue('ns', 'w1', 1_000, 500, 10);
621
+ strict_1.default.equal(claimed.length, 1);
622
+ strict_1.default.equal(claimed.every((r) => r.namespace === 'ns'), true);
623
+ });
624
+ api.it('orders claims by (nextCheckAt, createdAt)', async () => {
625
+ const { operations } = await create();
626
+ const c = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 300 }))).record;
627
+ const a = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }))).record;
628
+ const b = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 200 }))).record;
629
+ const claimed = await operations.claimDue('ns', 'w1', 1_000, 500, 10);
630
+ strict_1.default.deepEqual(claimed.map((r) => r.id), [a.id, b.id, c.id]);
631
+ });
632
+ api.it('limit picks the earliest due record after sorting, not by insertion order', async () => {
633
+ const { operations } = await create();
634
+ // Created in descending nextCheckAt order, so a limit-before-sort bug (e.g.
635
+ // slicing then sorting, instead of sorting then slicing) would return the
636
+ // first-inserted (highest nextCheckAt) record instead of the earliest-due one.
637
+ await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 300 }));
638
+ await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 200 }));
639
+ const earliest = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }))).record;
640
+ const claimed = await operations.claimDue('ns', 'w1', 1_000, 500, 1);
641
+ strict_1.default.deepEqual(claimed.map((r) => r.id), [earliest.id]);
642
+ });
643
+ api.it('limit 2 returns the two earliest due records in order, on fresh records', async () => {
644
+ const { operations } = await create();
645
+ await operations.create(sampleOperation({ namespace: 'limit2', state: 'submitted', nextCheckAt: 300 }));
646
+ const second = (await operations.create(sampleOperation({
647
+ namespace: 'limit2',
648
+ state: 'submitted',
649
+ nextCheckAt: 200,
650
+ }))).record;
651
+ const first = (await operations.create(sampleOperation({
652
+ namespace: 'limit2',
653
+ state: 'submitted',
654
+ nextCheckAt: 100,
655
+ }))).record;
656
+ const claimed = await operations.claimDue('limit2', 'w1', 1_000, 500, 2);
657
+ strict_1.default.deepEqual(claimed.map((r) => r.id), [first.id, second.id]);
658
+ });
659
+ api.it('breaks a nextCheckAt tie by createdAt, in creation order', async () => {
660
+ const { operations, advance } = await create();
661
+ const first = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }))).record;
662
+ await advance(10);
663
+ const second = (await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }))).record;
664
+ const claimed = await operations.claimDue('ns', 'w1', 1_000, 500, 10);
665
+ strict_1.default.deepEqual(claimed.map((r) => r.id), [first.id, second.id]);
666
+ });
667
+ api.it('limit 0 returns no claims', async () => {
668
+ const { operations } = await create();
669
+ await operations.create(sampleOperation({ state: 'submitted', nextCheckAt: 100 }));
670
+ strict_1.default.deepEqual(await operations.claimDue('ns', 'w1', 1_000, 500, 0), []);
671
+ });
672
+ api.it('returns matching records in creation order', async () => {
673
+ const { operations } = await create();
674
+ const a = (await operations.create(sampleOperation({ namespace: 'order' }))).record;
675
+ const b = (await operations.create(sampleOperation({ namespace: 'order' }))).record;
676
+ const c = (await operations.create(sampleOperation({ namespace: 'order' }))).record;
677
+ const found = await operations.list({ namespace: 'order' });
678
+ strict_1.default.deepEqual(found.map((r) => r.id), [a.id, b.id, c.id]);
679
+ });
680
+ api.it('putObservation never changes the Operation version, and rejects a stale expectedVersion', async () => {
681
+ const { operations } = await create();
682
+ const created = await operations.create(sampleOperation());
683
+ const afterAppend = await operations.appendAttempt('ns', created.record.id, sampleAttempt('obs1'), { state: 'signed' }, 1);
684
+ const base = {
685
+ attemptId: 'obs1',
686
+ operationId: created.record.id,
687
+ state: 'included',
688
+ evidence: 'observed',
689
+ confirmations: 1,
690
+ };
691
+ await operations.putObservation(base, null);
692
+ strict_1.default.equal((await operations.get('ns', created.record.id))?.version, afterAppend.version);
693
+ await operations.putObservation({ ...base, confirmations: 2 }, 1);
694
+ strict_1.default.equal((await operations.get('ns', created.record.id))?.version, afterAppend.version);
695
+ await (0, api_1.rejectsWithCode)(operations.putObservation({ ...base, confirmations: 3 }, 1), 'VERSION_CONFLICT');
696
+ });
697
+ api.it('does not resolve a tx hash to an operation with the same id in a different namespace', async () => {
698
+ const { operations } = await create();
699
+ const sharedId = 'op_shared_1';
700
+ await operations.create(sampleOperation({ id: sharedId, namespace: 'ns-a', idempotencyKey: 'key-a' }));
701
+ await operations.create(sampleOperation({ id: sharedId, namespace: 'ns-b', idempotencyKey: 'key-b' }));
702
+ await operations.appendAttempt('ns-a', sharedId, sampleAttempt('shared-attempt'), { state: 'signed' }, 1);
703
+ await operations.putObservation({
704
+ attemptId: 'shared-attempt',
705
+ operationId: sharedId,
706
+ state: 'included',
707
+ evidence: 'observed',
708
+ confirmations: 1,
709
+ txHash: 'shared-hash',
710
+ }, null);
711
+ const found = await operations.findByRef('ns-a', 'shared-hash');
712
+ strict_1.default.equal(found?.id, sharedId);
713
+ strict_1.default.equal(found?.namespace, 'ns-a');
714
+ strict_1.default.equal(await operations.findByRef('ns-b', 'shared-hash'), null);
715
+ });
716
+ });
717
+ }
718
+ //# sourceMappingURL=operations.js.map