tapimo 0.15.1 → 0.18.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 (709) hide show
  1. package/README.md +137 -0
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +4 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +37 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +163 -10
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +13085 -11974
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +46 -15
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +1 -1
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +1 -1
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +893 -191
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +5 -1
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +70 -70
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +8 -3
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +66 -27
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  28. package/dist/admin/apps/earn-vaults.js +36 -7
  29. package/dist/admin/apps/earn-vaults.js.map +1 -1
  30. package/dist/admin/apps/organizations.d.ts +25 -25
  31. package/dist/admin/apps/organizations.d.ts.map +1 -1
  32. package/dist/admin/apps/organizations.js +5 -4
  33. package/dist/admin/apps/organizations.js.map +1 -1
  34. package/dist/admin/apps/route-policies.d.ts +632 -0
  35. package/dist/admin/apps/route-policies.d.ts.map +1 -0
  36. package/dist/admin/apps/route-policies.js +257 -0
  37. package/dist/admin/apps/route-policies.js.map +1 -0
  38. package/dist/admin/apps/routes-support.js +39 -3
  39. package/dist/admin/apps/routes-support.js.map +1 -1
  40. package/dist/admin/apps/routes.d.ts +529 -76
  41. package/dist/admin/apps/routes.d.ts.map +1 -1
  42. package/dist/admin/apps/routes.js +82 -1
  43. package/dist/admin/apps/routes.js.map +1 -1
  44. package/dist/admin/apps/verified-tokens.d.ts +157 -157
  45. package/dist/admin/index.d.ts +0 -1
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +0 -1
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/admin/ui.generated.d.ts +1 -1
  50. package/dist/admin/ui.generated.d.ts.map +1 -1
  51. package/dist/admin/ui.generated.js +205 -201
  52. package/dist/admin/ui.generated.js.map +1 -1
  53. package/dist/analytics/Analytics.d.ts.map +1 -1
  54. package/dist/analytics/Analytics.js +65 -1
  55. package/dist/analytics/Analytics.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  57. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  58. package/dist/analytics/tables/requestEvents.js +58 -59
  59. package/dist/analytics/tables/requestEvents.js.map +1 -1
  60. package/dist/apps/data/App.d.ts +2709 -2670
  61. package/dist/apps/data/App.d.ts.map +1 -1
  62. package/dist/apps/data/routes/activities.d.ts +357 -357
  63. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  64. package/dist/apps/data/routes/activities.js +50 -0
  65. package/dist/apps/data/routes/activities.js.map +1 -1
  66. package/dist/apps/data/routes/addresses.d.ts +248 -248
  67. package/dist/apps/data/routes/balances.d.ts +22 -22
  68. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  69. package/dist/apps/data/routes/balances.js +5 -7
  70. package/dist/apps/data/routes/balances.js.map +1 -1
  71. package/dist/apps/data/routes/blocks.d.ts +125 -125
  72. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  73. package/dist/apps/data/routes/earn.d.ts +103 -12
  74. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  75. package/dist/apps/data/routes/earn.js +456 -220
  76. package/dist/apps/data/routes/earn.js.map +1 -1
  77. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  78. package/dist/apps/data/routes/exchanges.js +267 -97
  79. package/dist/apps/data/routes/exchanges.js.map +1 -1
  80. package/dist/apps/data/routes/fee-amm.d.ts +109 -127
  81. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.js +83 -54
  83. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +43 -43
  85. package/dist/apps/data/routes/receipts.d.ts +235 -235
  86. package/dist/apps/data/routes/rpc.d.ts +30 -30
  87. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  88. package/dist/apps/data/routes/tokens.js +11 -6
  89. package/dist/apps/data/routes/tokens.js.map +1 -1
  90. package/dist/apps/data/routes/transactions.d.ts +2 -0
  91. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  92. package/dist/apps/data/routes/transactions.js +30 -22
  93. package/dist/apps/data/routes/transactions.js.map +1 -1
  94. package/dist/apps/data/routes/transfers.d.ts +77 -77
  95. package/dist/apps/data/routes/valuation.d.ts +32 -32
  96. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  97. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  98. package/dist/apps/data/routes/webhooks.js +1 -1
  99. package/dist/apps/data/routes/webhooks.js.map +1 -1
  100. package/dist/apps/data/routes/zones.d.ts +31 -31
  101. package/dist/apps/management/App.d.ts +2909 -2064
  102. package/dist/apps/management/App.d.ts.map +1 -1
  103. package/dist/apps/management/App.js +2 -0
  104. package/dist/apps/management/App.js.map +1 -1
  105. package/dist/apps/management/Billing.d.ts +2 -4
  106. package/dist/apps/management/Billing.d.ts.map +1 -1
  107. package/dist/apps/management/Billing.js +65 -26
  108. package/dist/apps/management/Billing.js.map +1 -1
  109. package/dist/apps/management/routes/api-keys.d.ts +257 -245
  110. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  111. package/dist/apps/management/routes/api-keys.js +70 -11
  112. package/dist/apps/management/routes/api-keys.js.map +1 -1
  113. package/dist/apps/management/routes/billing.d.ts +84 -84
  114. package/dist/apps/management/routes/cli.d.ts +912 -0
  115. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  116. package/dist/apps/management/routes/cli.js +416 -0
  117. package/dist/apps/management/routes/cli.js.map +1 -0
  118. package/dist/apps/management/routes/faucet.d.ts +8 -8
  119. package/dist/apps/management/routes/invitations.d.ts +138 -138
  120. package/dist/apps/management/routes/invite-links.d.ts +172 -172
  121. package/dist/apps/management/routes/members.d.ts +16 -16
  122. package/dist/apps/management/routes/orgs.d.ts +104 -104
  123. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  124. package/dist/apps/management/routes/orgs.js +8 -2
  125. package/dist/apps/management/routes/orgs.js.map +1 -1
  126. package/dist/apps/management/routes/projects.d.ts +125 -125
  127. package/dist/apps/management/routes/usage.d.ts +8 -8
  128. package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
  129. package/dist/apps/management/routes/webhooks.d.ts +485 -485
  130. package/dist/apps/mpp/App.d.ts +44 -44
  131. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  132. package/dist/apps/mpp/internal/Policy.js +4 -2
  133. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  134. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  135. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  136. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  137. package/dist/apps/relay/App.d.ts +8 -0
  138. package/dist/apps/relay/App.d.ts.map +1 -1
  139. package/dist/apps/relay/App.js +16 -4
  140. package/dist/apps/relay/App.js.map +1 -1
  141. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  142. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  143. package/dist/apps/relay/Sponsorships.js +71 -60
  144. package/dist/apps/relay/Sponsorships.js.map +1 -1
  145. package/dist/apps/routes/Access.d.ts +53 -0
  146. package/dist/apps/routes/Access.d.ts.map +1 -1
  147. package/dist/apps/routes/Access.js +121 -0
  148. package/dist/apps/routes/Access.js.map +1 -1
  149. package/dist/apps/routes/App.d.ts +397 -158
  150. package/dist/apps/routes/App.d.ts.map +1 -1
  151. package/dist/apps/routes/App.js.map +1 -1
  152. package/dist/apps/routes/routes/chains.d.ts +25 -25
  153. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  154. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  155. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  156. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  157. package/dist/apps/routes/routes/quotes.d.ts +171 -81
  158. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  159. package/dist/apps/routes/routes/quotes.js +101 -27
  160. package/dist/apps/routes/routes/quotes.js.map +1 -1
  161. package/dist/apps/routes/routes/transfers.d.ts +532 -480
  162. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/transfers.js +182 -37
  164. package/dist/apps/routes/routes/transfers.js.map +1 -1
  165. package/dist/cli/ApiKeys.d.ts +120 -0
  166. package/dist/cli/ApiKeys.d.ts.map +1 -0
  167. package/dist/cli/ApiKeys.js +138 -0
  168. package/dist/cli/ApiKeys.js.map +1 -0
  169. package/dist/cli/Cli.d.ts +92 -34
  170. package/dist/cli/Cli.d.ts.map +1 -1
  171. package/dist/cli/Cli.js +188 -11
  172. package/dist/cli/Cli.js.map +1 -1
  173. package/dist/cli/Credentials.d.ts +95 -0
  174. package/dist/cli/Credentials.d.ts.map +1 -0
  175. package/dist/cli/Credentials.js +110 -0
  176. package/dist/cli/Credentials.js.map +1 -0
  177. package/dist/cli/Spec.d.ts +59 -0
  178. package/dist/cli/Spec.d.ts.map +1 -0
  179. package/dist/cli/Spec.js +77 -0
  180. package/dist/cli/Spec.js.map +1 -0
  181. package/dist/cli/bin.js +5 -1
  182. package/dist/cli/bin.js.map +1 -1
  183. package/dist/cli/commands/admin.d.ts +5 -5
  184. package/dist/cli/commands/admin.d.ts.map +1 -1
  185. package/dist/cli/commands/auth.d.ts +73 -0
  186. package/dist/cli/commands/auth.d.ts.map +1 -0
  187. package/dist/cli/commands/auth.js +204 -0
  188. package/dist/cli/commands/auth.js.map +1 -0
  189. package/dist/cli/commands/keys.d.ts +17 -0
  190. package/dist/cli/commands/keys.d.ts.map +1 -0
  191. package/dist/cli/commands/keys.js +109 -0
  192. package/dist/cli/commands/keys.js.map +1 -0
  193. package/dist/cloudflare.d.ts +27 -2
  194. package/dist/cloudflare.d.ts.map +1 -1
  195. package/dist/cloudflare.js +144 -17
  196. package/dist/cloudflare.js.map +1 -1
  197. package/dist/db/Db.d.ts +23 -0
  198. package/dist/db/Db.d.ts.map +1 -1
  199. package/dist/db/Db.js +413 -1
  200. package/dist/db/Db.js.map +1 -1
  201. package/dist/db/Schema.d.ts +44 -1
  202. package/dist/db/Schema.d.ts.map +1 -1
  203. package/dist/db/Schema.js +56 -3
  204. package/dist/db/Schema.js.map +1 -1
  205. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  206. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  207. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  208. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  209. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  210. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  211. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  212. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  213. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  214. package/dist/db/tables/authAccounts.js +1 -0
  215. package/dist/db/tables/authAccounts.js.map +1 -1
  216. package/dist/db/tables/earnVaults.d.ts +5 -1
  217. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  218. package/dist/db/tables/earnVaults.js +12 -1
  219. package/dist/db/tables/earnVaults.js.map +1 -1
  220. package/dist/db/tables/organizations.d.ts +4 -2
  221. package/dist/db/tables/organizations.d.ts.map +1 -1
  222. package/dist/db/tables/organizations.js +8 -34
  223. package/dist/db/tables/organizations.js.map +1 -1
  224. package/dist/db/tables/requestUsage.d.ts +5 -1
  225. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  226. package/dist/db/tables/requestUsage.js +10 -2
  227. package/dist/db/tables/requestUsage.js.map +1 -1
  228. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  229. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  230. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  231. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  232. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  233. package/dist/db/tables/rewardRuns.js +4 -0
  234. package/dist/db/tables/rewardRuns.js.map +1 -1
  235. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  236. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  237. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  238. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  239. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  240. package/dist/db/tables/routesDepositAddresses.js +84 -31
  241. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  242. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  243. package/dist/db/tables/routesDeposits.js +31 -21
  244. package/dist/db/tables/routesDeposits.js.map +1 -1
  245. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  246. package/dist/db/tables/routesIdempotency.js +2 -0
  247. package/dist/db/tables/routesIdempotency.js.map +1 -1
  248. package/dist/db/tables/routesPolicies.d.ts +58 -0
  249. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  250. package/dist/db/tables/routesPolicies.js +198 -0
  251. package/dist/db/tables/routesPolicies.js.map +1 -0
  252. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  253. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  254. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  255. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  256. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  257. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  258. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  259. package/dist/db/tables/routesTransfers.d.ts +26 -1
  260. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  261. package/dist/db/tables/routesTransfers.js +36 -6
  262. package/dist/db/tables/routesTransfers.js.map +1 -1
  263. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  264. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.js +144 -33
  266. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  267. package/dist/db/tables/users.d.ts +2 -0
  268. package/dist/db/tables/users.d.ts.map +1 -1
  269. package/dist/db/tables/users.js +11 -0
  270. package/dist/db/tables/users.js.map +1 -1
  271. package/dist/handlers/internal/multisig.d.ts +1 -1
  272. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  273. package/dist/handlers/internal/multisig.js +3 -2
  274. package/dist/handlers/internal/multisig.js.map +1 -1
  275. package/dist/handlers/relay.d.ts +2 -0
  276. package/dist/handlers/relay.d.ts.map +1 -1
  277. package/dist/handlers/relay.js +34 -15
  278. package/dist/handlers/relay.js.map +1 -1
  279. package/dist/internal/Auth.d.ts +57 -6
  280. package/dist/internal/Auth.d.ts.map +1 -1
  281. package/dist/internal/Auth.js +182 -78
  282. package/dist/internal/Auth.js.map +1 -1
  283. package/dist/internal/BetterAuth.d.ts +22 -0
  284. package/dist/internal/BetterAuth.d.ts.map +1 -1
  285. package/dist/internal/BetterAuth.js +17 -14
  286. package/dist/internal/BetterAuth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts +5 -0
  288. package/dist/internal/Cache.d.ts.map +1 -1
  289. package/dist/internal/Cache.js +3 -1
  290. package/dist/internal/Cache.js.map +1 -1
  291. package/dist/internal/CliAuth.d.ts +243 -0
  292. package/dist/internal/CliAuth.d.ts.map +1 -0
  293. package/dist/internal/CliAuth.js +249 -0
  294. package/dist/internal/CliAuth.js.map +1 -0
  295. package/dist/internal/EarnSharePrices.d.ts +1 -1
  296. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  297. package/dist/internal/EarnSharePrices.js +7 -3
  298. package/dist/internal/EarnSharePrices.js.map +1 -1
  299. package/dist/internal/EarnVaults.d.ts +47 -0
  300. package/dist/internal/EarnVaults.d.ts.map +1 -1
  301. package/dist/internal/EarnVaults.js +188 -4
  302. package/dist/internal/EarnVaults.js.map +1 -1
  303. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  304. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  305. package/dist/internal/EarnWithdrawals.js +189 -0
  306. package/dist/internal/EarnWithdrawals.js.map +1 -0
  307. package/dist/internal/ExecutionContext.d.ts +21 -0
  308. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  309. package/dist/internal/ExecutionContext.js +16 -0
  310. package/dist/internal/ExecutionContext.js.map +1 -0
  311. package/dist/internal/Log.d.ts +7 -3
  312. package/dist/internal/Log.d.ts.map +1 -1
  313. package/dist/internal/Log.js +163 -130
  314. package/dist/internal/Log.js.map +1 -1
  315. package/dist/internal/MetricSink.d.ts.map +1 -1
  316. package/dist/internal/MetricSink.js +26 -1
  317. package/dist/internal/MetricSink.js.map +1 -1
  318. package/dist/internal/RateLimit.d.ts +67 -0
  319. package/dist/internal/RateLimit.d.ts.map +1 -1
  320. package/dist/internal/RateLimit.js +174 -27
  321. package/dist/internal/RateLimit.js.map +1 -1
  322. package/dist/internal/Store.d.ts +6 -0
  323. package/dist/internal/Store.d.ts.map +1 -1
  324. package/dist/internal/Store.js +4 -5
  325. package/dist/internal/Store.js.map +1 -1
  326. package/dist/internal/Timing.d.ts +6 -0
  327. package/dist/internal/Timing.d.ts.map +1 -1
  328. package/dist/internal/Timing.js +21 -1
  329. package/dist/internal/Timing.js.map +1 -1
  330. package/dist/internal/Tron.d.ts +124 -0
  331. package/dist/internal/Tron.d.ts.map +1 -0
  332. package/dist/internal/Tron.js +202 -0
  333. package/dist/internal/Tron.js.map +1 -0
  334. package/dist/internal/Viem.d.ts +4 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Viem.js +25 -6
  337. package/dist/internal/Viem.js.map +1 -1
  338. package/dist/internal/rewards/Read.d.ts +2 -2
  339. package/dist/internal/rewards/Read.d.ts.map +1 -1
  340. package/dist/internal/rewards/Read.js +11 -2
  341. package/dist/internal/rewards/Read.js.map +1 -1
  342. package/dist/internal/routes/Action.d.ts +27 -0
  343. package/dist/internal/routes/Action.d.ts.map +1 -1
  344. package/dist/internal/routes/Action.js +49 -1
  345. package/dist/internal/routes/Action.js.map +1 -1
  346. package/dist/internal/routes/Chain.d.ts +2 -0
  347. package/dist/internal/routes/Chain.d.ts.map +1 -1
  348. package/dist/internal/routes/Chain.js +4 -0
  349. package/dist/internal/routes/Chain.js.map +1 -1
  350. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  351. package/dist/internal/routes/DepositAddress.js +5 -0
  352. package/dist/internal/routes/DepositAddress.js.map +1 -1
  353. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  354. package/dist/internal/routes/Evidence.js +6 -2
  355. package/dist/internal/routes/Evidence.js.map +1 -1
  356. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  357. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  358. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  359. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  360. package/dist/internal/routes/Policy.d.ts +161 -0
  361. package/dist/internal/routes/Policy.d.ts.map +1 -0
  362. package/dist/internal/routes/Policy.js +249 -0
  363. package/dist/internal/routes/Policy.js.map +1 -0
  364. package/dist/internal/routes/Provider.d.ts +66 -3
  365. package/dist/internal/routes/Provider.d.ts.map +1 -1
  366. package/dist/internal/routes/Provider.js +106 -27
  367. package/dist/internal/routes/Provider.js.map +1 -1
  368. package/dist/internal/routes/Quota.d.ts +57 -0
  369. package/dist/internal/routes/Quota.d.ts.map +1 -0
  370. package/dist/internal/routes/Quota.js +144 -0
  371. package/dist/internal/routes/Quota.js.map +1 -0
  372. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  373. package/dist/internal/routes/Reconciliation.js +163 -47
  374. package/dist/internal/routes/Reconciliation.js.map +1 -1
  375. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  376. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  377. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  378. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  379. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  380. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  381. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  382. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  383. package/dist/internal/routes/Subsidy.d.ts +2 -2
  384. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  385. package/dist/internal/routes/Subsidy.js +2 -2
  386. package/dist/internal/routes/Subsidy.js.map +1 -1
  387. package/dist/internal/routes/Transfer.d.ts +229 -1
  388. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  389. package/dist/internal/routes/Transfer.js +644 -7
  390. package/dist/internal/routes/Transfer.js.map +1 -1
  391. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  392. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  393. package/dist/internal/routes/TransferReconciliation.js +83 -159
  394. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  395. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  396. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  397. package/dist/internal/routes/TransferSettlement.js +2 -0
  398. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  399. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  400. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  401. package/dist/internal/routes/TransferSubsidy.js +64 -5
  402. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  403. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  404. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  405. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  406. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  407. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  408. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  409. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  410. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  411. package/dist/internal/routes/index.d.ts +3 -0
  412. package/dist/internal/routes/index.d.ts.map +1 -1
  413. package/dist/internal/routes/index.js +3 -0
  414. package/dist/internal/routes/index.js.map +1 -1
  415. package/dist/internal/routes/providers/across.d.ts +3 -0
  416. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  417. package/dist/internal/routes/providers/across.js +11 -0
  418. package/dist/internal/routes/providers/across.js.map +1 -1
  419. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  420. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  421. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  422. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  423. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  424. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  425. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  426. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  427. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  428. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  429. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  430. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  431. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  432. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  434. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  435. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  436. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/propAmm.js +524 -0
  438. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  439. package/dist/internal/routes/providers/relay.d.ts +3 -0
  440. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  441. package/dist/internal/routes/providers/relay.js +352 -41
  442. package/dist/internal/routes/providers/relay.js.map +1 -1
  443. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  444. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  445. package/dist/internal/routes/providers/rhino.js +11 -0
  446. package/dist/internal/routes/providers/rhino.js.map +1 -1
  447. package/dist/internal/routes/providers/squid.d.ts +3 -0
  448. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  449. package/dist/internal/routes/providers/squid.js +19 -0
  450. package/dist/internal/routes/providers/squid.js.map +1 -1
  451. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  452. package/dist/internal/routes/providers/stargate.js +22 -9
  453. package/dist/internal/routes/providers/stargate.js.map +1 -1
  454. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  455. package/dist/internal/routes/providers/symbiosis.js +13 -17
  456. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  457. package/dist/providers/index.d.ts +14 -0
  458. package/dist/providers/index.d.ts.map +1 -1
  459. package/dist/providers/index.js +6 -0
  460. package/dist/providers/index.js.map +1 -1
  461. package/package.json +16 -6
  462. package/src/ApiKey.ts +7 -3
  463. package/src/ApiKeys.test.ts +652 -8
  464. package/src/ApiKeys.ts +191 -11
  465. package/src/App.test.ts +405 -18
  466. package/src/App.ts +51 -15
  467. package/src/Client.test-d.ts +157 -10
  468. package/src/Client.test.ts +4 -4
  469. package/src/Scope.ts +1 -2
  470. package/src/admin/App.ts +11 -5
  471. package/src/admin/apps/api-keys.test.ts +98 -2
  472. package/src/admin/apps/api-keys.ts +21 -12
  473. package/src/admin/apps/earn-vaults.test.ts +76 -7
  474. package/src/admin/apps/earn-vaults.ts +47 -8
  475. package/src/admin/apps/organizations.test.ts +147 -31
  476. package/src/admin/apps/organizations.ts +5 -4
  477. package/src/admin/apps/route-policies.test.ts +220 -0
  478. package/src/admin/apps/route-policies.ts +322 -0
  479. package/src/admin/apps/routes-support.test.ts +107 -2
  480. package/src/admin/apps/routes-support.ts +43 -3
  481. package/src/admin/apps/routes.test.ts +150 -0
  482. package/src/admin/apps/routes.ts +97 -1
  483. package/src/admin/apps/scopes.test.ts +1 -1
  484. package/src/admin/index.ts +0 -1
  485. package/src/admin/ui/plugin.ts +2 -1
  486. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  487. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  488. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  489. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  490. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  491. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  492. package/src/admin/ui/src/lib/routes.ts +34 -0
  493. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  494. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  495. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  496. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  497. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  498. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  499. package/src/admin/ui/src/routes/organizations.tsx +1 -0
  500. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  501. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  502. package/src/admin/ui/src/routes/routes.tsx +85 -2
  503. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  504. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  505. package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
  506. package/src/admin/ui.generated.ts +258 -202
  507. package/src/analytics/Analytics.test.ts +4 -50
  508. package/src/analytics/Analytics.ts +65 -1
  509. package/src/analytics/tables/requestEvents.test.ts +402 -1
  510. package/src/analytics/tables/requestEvents.ts +62 -93
  511. package/src/apps/data/routes/activities.test.ts +315 -14
  512. package/src/apps/data/routes/activities.ts +60 -0
  513. package/src/apps/data/routes/balances.ts +5 -7
  514. package/src/apps/data/routes/earn.bench.ts +18 -0
  515. package/src/apps/data/routes/earn.local.test.ts +507 -0
  516. package/src/apps/data/routes/earn.test.ts +405 -127
  517. package/src/apps/data/routes/earn.ts +660 -270
  518. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  519. package/src/apps/data/routes/exchanges.test.ts +166 -2
  520. package/src/apps/data/routes/exchanges.ts +308 -101
  521. package/src/apps/data/routes/fee-amm.test.ts +134 -2
  522. package/src/apps/data/routes/fee-amm.ts +122 -60
  523. package/src/apps/data/routes/receipts.test.ts +21 -18
  524. package/src/apps/data/routes/rpc.test.ts +2 -2
  525. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  526. package/src/apps/data/routes/tokens.test.ts +4 -4
  527. package/src/apps/data/routes/tokens.ts +11 -6
  528. package/src/apps/data/routes/transactions.test.ts +29 -0
  529. package/src/apps/data/routes/transactions.ts +33 -22
  530. package/src/apps/data/routes/webhooks.test.ts +12 -3
  531. package/src/apps/data/routes/webhooks.ts +2 -1
  532. package/src/apps/management/App.ts +4 -0
  533. package/src/apps/management/Billing.test.ts +253 -27
  534. package/src/apps/management/Billing.ts +83 -29
  535. package/src/apps/management/routes/api-keys.test.ts +1 -1
  536. package/src/apps/management/routes/api-keys.ts +85 -11
  537. package/src/apps/management/routes/billing.test.ts +68 -4
  538. package/src/apps/management/routes/cli.test.ts +370 -0
  539. package/src/apps/management/routes/cli.ts +533 -0
  540. package/src/apps/management/routes/me.test.ts +14 -4
  541. package/src/apps/management/routes/orgs.test.ts +108 -4
  542. package/src/apps/management/routes/orgs.ts +7 -2
  543. package/src/apps/management/routes/usage.test.ts +2 -2
  544. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  545. package/src/apps/mpp/internal/Policy.ts +6 -2
  546. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  547. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  548. package/src/apps/relay/App.test.ts +85 -1
  549. package/src/apps/relay/App.ts +28 -4
  550. package/src/apps/relay/Sponsorships.test.ts +97 -1
  551. package/src/apps/relay/Sponsorships.ts +77 -66
  552. package/src/apps/routes/Access.test.ts +319 -0
  553. package/src/apps/routes/Access.ts +147 -0
  554. package/src/apps/routes/App.ts +10 -0
  555. package/src/apps/routes/routes/chains.test.ts +3 -2
  556. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  557. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  558. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  559. package/src/apps/routes/routes/quotes.test.ts +81 -8
  560. package/src/apps/routes/routes/quotes.ts +109 -27
  561. package/src/apps/routes/routes/transfers.test.ts +252 -15
  562. package/src/apps/routes/routes/transfers.ts +212 -33
  563. package/src/cli/ApiKeys.test.ts +265 -0
  564. package/src/cli/ApiKeys.ts +189 -0
  565. package/src/cli/Cli.test.ts +188 -0
  566. package/src/cli/Cli.ts +280 -12
  567. package/src/cli/Credentials.test.ts +122 -0
  568. package/src/cli/Credentials.ts +144 -0
  569. package/src/cli/Spec.test.ts +133 -0
  570. package/src/cli/Spec.ts +132 -0
  571. package/src/cli/bin.test.ts +49 -0
  572. package/src/cli/bin.ts +5 -1
  573. package/src/cli/commands/auth.test.ts +138 -0
  574. package/src/cli/commands/auth.ts +254 -0
  575. package/src/cli/commands/keys.test.ts +68 -0
  576. package/src/cli/commands/keys.ts +125 -0
  577. package/src/cloudflare.ts +184 -36
  578. package/src/db/Db.test.ts +877 -0
  579. package/src/db/Db.ts +498 -1
  580. package/src/db/Schema.ts +75 -4
  581. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  582. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  583. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  584. package/src/db/tables/authAccounts.test.ts +30 -0
  585. package/src/db/tables/authAccounts.ts +1 -0
  586. package/src/db/tables/earnVaults.test.ts +34 -0
  587. package/src/db/tables/earnVaults.ts +17 -2
  588. package/src/db/tables/organizations.test.ts +148 -84
  589. package/src/db/tables/organizations.ts +11 -43
  590. package/src/db/tables/requestUsage.ts +13 -2
  591. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  592. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  593. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  594. package/src/db/tables/rewardRuns.ts +4 -0
  595. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  596. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  597. package/src/db/tables/routesDepositAddresses.ts +118 -34
  598. package/src/db/tables/routesDeposits.test.ts +66 -5
  599. package/src/db/tables/routesDeposits.ts +47 -26
  600. package/src/db/tables/routesIdempotency.test.ts +80 -0
  601. package/src/db/tables/routesIdempotency.ts +2 -0
  602. package/src/db/tables/routesPolicies.test.ts +143 -0
  603. package/src/db/tables/routesPolicies.ts +251 -0
  604. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  605. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  606. package/src/db/tables/routesTransfers.test.ts +183 -2
  607. package/src/db/tables/routesTransfers.ts +65 -6
  608. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  609. package/src/db/tables/sponsoredTransactions.ts +182 -38
  610. package/src/db/tables/users.test.ts +51 -0
  611. package/src/db/tables/users.ts +12 -0
  612. package/src/handlers/internal/multisig.store.test.ts +120 -0
  613. package/src/handlers/internal/multisig.test.ts +389 -0
  614. package/src/handlers/internal/multisig.ts +13 -10
  615. package/src/handlers/relay.test.ts +259 -83
  616. package/src/handlers/relay.ts +36 -17
  617. package/src/internal/Auth.test.ts +291 -8
  618. package/src/internal/Auth.ts +227 -96
  619. package/src/internal/BetterAuth.test.ts +58 -22
  620. package/src/internal/BetterAuth.ts +23 -17
  621. package/src/internal/Cache.ts +3 -1
  622. package/src/internal/CliAuth.test.ts +279 -0
  623. package/src/internal/CliAuth.ts +319 -0
  624. package/src/internal/EarnSharePrices.test.ts +25 -0
  625. package/src/internal/EarnSharePrices.ts +9 -2
  626. package/src/internal/EarnVaults.test.ts +67 -0
  627. package/src/internal/EarnVaults.ts +299 -4
  628. package/src/internal/EarnWithdrawals.test.ts +315 -0
  629. package/src/internal/EarnWithdrawals.ts +266 -0
  630. package/src/internal/ExecutionContext.ts +31 -0
  631. package/src/internal/Log.test.ts +210 -0
  632. package/src/internal/Log.ts +180 -142
  633. package/src/internal/MetricSink.test.ts +190 -15
  634. package/src/internal/MetricSink.ts +27 -1
  635. package/src/internal/RateLimit.test.ts +144 -8
  636. package/src/internal/RateLimit.ts +254 -26
  637. package/src/internal/Store.ts +4 -5
  638. package/src/internal/Timing.test.ts +32 -0
  639. package/src/internal/Timing.ts +20 -1
  640. package/src/internal/Tron.test-d.ts +22 -0
  641. package/src/internal/Tron.test.ts +94 -0
  642. package/src/internal/Tron.ts +289 -0
  643. package/src/internal/Viem.rpc.test.ts +76 -0
  644. package/src/internal/Viem.ts +29 -6
  645. package/src/internal/rewards/Read.test.ts +109 -0
  646. package/src/internal/rewards/Read.ts +13 -4
  647. package/src/internal/routes/Action.test.ts +70 -0
  648. package/src/internal/routes/Action.ts +76 -1
  649. package/src/internal/routes/Chain.test.ts +18 -0
  650. package/src/internal/routes/Chain.ts +5 -0
  651. package/src/internal/routes/DepositAddress.ts +5 -0
  652. package/src/internal/routes/Evidence.test.ts +64 -0
  653. package/src/internal/routes/Evidence.ts +11 -3
  654. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  655. package/src/internal/routes/Policy.test.ts +316 -0
  656. package/src/internal/routes/Policy.ts +399 -0
  657. package/src/internal/routes/Provider.test.ts +103 -2
  658. package/src/internal/routes/Provider.ts +149 -27
  659. package/src/internal/routes/Quota.test.ts +149 -0
  660. package/src/internal/routes/Quota.ts +226 -0
  661. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  662. package/src/internal/routes/Reconciliation.test.ts +371 -13
  663. package/src/internal/routes/Reconciliation.ts +193 -42
  664. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  665. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  666. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  667. package/src/internal/routes/SourceObservation.test.ts +221 -0
  668. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  669. package/src/internal/routes/Subsidy.ts +4 -2
  670. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  671. package/src/internal/routes/Transfer.test.ts +130 -1
  672. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  673. package/src/internal/routes/Transfer.ts +866 -8
  674. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  675. package/src/internal/routes/TransferReconciliation.ts +91 -166
  676. package/src/internal/routes/TransferSettlement.ts +48 -0
  677. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  678. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  679. package/src/internal/routes/TransferSubsidy.ts +87 -12
  680. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  681. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  682. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  683. package/src/internal/routes/index.test.ts +3 -0
  684. package/src/internal/routes/index.ts +3 -0
  685. package/src/internal/routes/providers/across.ts +13 -0
  686. package/src/internal/routes/providers/index.test.ts +141 -0
  687. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  688. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  689. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  690. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  691. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  692. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  693. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  694. package/src/internal/routes/providers/propAmm.ts +640 -0
  695. package/src/internal/routes/providers/relay.test.ts +1263 -41
  696. package/src/internal/routes/providers/relay.ts +423 -38
  697. package/src/internal/routes/providers/rhino.ts +14 -1
  698. package/src/internal/routes/providers/squid.ts +21 -0
  699. package/src/internal/routes/providers/stargate.test.ts +105 -1
  700. package/src/internal/routes/providers/stargate.ts +22 -9
  701. package/src/internal/routes/providers/symbiosis.ts +13 -47
  702. package/src/providers/index.test.ts +2 -0
  703. package/src/providers/index.ts +18 -0
  704. package/dist/admin/Access.d.ts +0 -39
  705. package/dist/admin/Access.d.ts.map +0 -1
  706. package/dist/admin/Access.js +0 -73
  707. package/dist/admin/Access.js.map +0 -1
  708. package/src/admin/Access.test.ts +0 -130
  709. package/src/admin/Access.ts +0 -85
@@ -2661,9 +2661,12 @@ export function exchanges(options: exchanges.Options = {}) {
2661
2661
  const chainId = options.chainId ?? c.get('chainId')
2662
2662
 
2663
2663
  try {
2664
- const pairs = await getPairIndex(c, { chainId })
2665
- const target = pairs.get(base)
2666
- if (!target) return pairNotFoundError(c, { base, pairIndex: pairs })
2664
+ const target = await getPairByBase(c, { base, chainId })
2665
+ if (!target)
2666
+ return pairNotFoundError(c, {
2667
+ base,
2668
+ pairIndex: await getPairIndex(c, { chainId }),
2669
+ })
2667
2670
 
2668
2671
  // Token metadata is opt-in: resolve both pair tokens once and spread
2669
2672
  // onto the `base`/`quote` PairToken slots.
@@ -3102,9 +3105,12 @@ export function exchanges(options: exchanges.Options = {}) {
3102
3105
  Cache.setPolicy(c, Cache.policies.state)
3103
3106
 
3104
3107
  try {
3105
- const pairs = await getPairIndex(c, { chainId })
3106
- const target = pairs.get(baseAddress)
3107
- if (!target) return pairNotFoundError(c, { base: baseAddress, pairIndex: pairs })
3108
+ const target = await getPairByBase(c, { base: baseAddress, chainId })
3109
+ if (!target)
3110
+ return pairNotFoundError(c, {
3111
+ base: baseAddress,
3112
+ pairIndex: await getPairIndex(c, { chainId }),
3113
+ })
3108
3114
 
3109
3115
  const result = await getPairOhlc(c, {
3110
3116
  chainId,
@@ -3208,17 +3214,7 @@ export function exchanges(options: exchanges.Options = {}) {
3208
3214
  const chainId = options.chainId ?? c.get('chainId')
3209
3215
 
3210
3216
  try {
3211
- // Pair definitions are immutable after creation, so cache successful
3212
- // point lookups without making unknown pairs stale.
3213
- const target = await Store.memoize(
3214
- async () =>
3215
- (await getPairsByBase(c, { bases: [baseAddress], chainId })).get(baseAddress),
3216
- {
3217
- key: `exchange:v1:${chainId}:pair-by-base:${baseAddress}:v1`,
3218
- store: c.get('store'),
3219
- ttl: Ttl.minutes(5),
3220
- },
3221
- )
3217
+ const target = await getPairByBase(c, { base: baseAddress, chainId })
3222
3218
  if (!target)
3223
3219
  return pairNotFoundError(c, {
3224
3220
  base: baseAddress,
@@ -3603,6 +3599,48 @@ declare namespace getPairsByBase {
3603
3599
  }
3604
3600
  }
3605
3601
 
3602
+ /**
3603
+ * Resolves one pair by base address without depending on the bounded pair
3604
+ * index. Successful immutable definitions are cached; misses stay fresh.
3605
+ */
3606
+ async function getPairByBase(c: Context<App.Environment>, options: getPairByBase.Options) {
3607
+ const { base, chainId } = options
3608
+ const tidx = c.get('getTidx')(chainId)
3609
+ return Timing.time(c, 'pair_lookup', () =>
3610
+ Store.memoize(
3611
+ async () => {
3612
+ const result = await tidx.fetch({
3613
+ chainId,
3614
+ engine: 'clickhouse',
3615
+ query: `
3616
+ SELECT key, base, quote, tx_hash, block_num, block_timestamp
3617
+ FROM dex_pairs
3618
+ WHERE address = '${stablecoinDex}' AND base = '${base}'
3619
+ ORDER BY block_num ASC, log_idx ASC
3620
+ LIMIT 1
3621
+ ` as string,
3622
+ })
3623
+ const row = result.rows[0]
3624
+ return row ? parsePairRow(row) : undefined
3625
+ },
3626
+ {
3627
+ key: `exchange:v1:${chainId}:pair-by-base:${base}:v2`,
3628
+ store: c.get('store'),
3629
+ ttl: Ttl.minutes(5),
3630
+ },
3631
+ ),
3632
+ )
3633
+ }
3634
+
3635
+ declare namespace getPairByBase {
3636
+ type Options = {
3637
+ /** Base token address identifying the pair. */
3638
+ base: string
3639
+ /** Chain whose pair table should be queried. */
3640
+ chainId: z.output<typeof Schema.ChainId>
3641
+ }
3642
+ }
3643
+
3606
3644
  /**
3607
3645
  * Resolves one pair by its book key with a targeted `dex_pairs` lookup,
3608
3646
  * covering books the bounded pair index ages out of its newest window.
@@ -4846,11 +4884,9 @@ function parseTickSide(value: unknown): { isBid: boolean; tick: number } | undef
4846
4884
  * The candles are aggregated **in ClickHouse**: each bucket folds server-side
4847
4885
  * (open/close by fill position, high/low by executed rate, volume sums and
4848
4886
  * fill counts), so the response covers the entire requested window no matter
4849
- * how many fills it contains — the previous implementation shipped the newest
4850
- * raw fills to the app capped at 1,000, which truncated busy pairs' 7d/30d
4851
- * windows to a few hours. The pair filter still resolves through the
4852
- * OrderPlaced-only `dex_orders` table, so fills of flipped orders remain
4853
- * invisible until order state lands at ingest (the `dex_ohlc_1m` plan).
4887
+ * how many fills it contains. Each fill joins to its state-event history and
4888
+ * selects the latest preceding `OrderPlaced`/`OrderFlipped` log because flip
4889
+ * orders retain their id while changing side and tick.
4854
4890
  *
4855
4891
  * `OrderFilled` only carries the base-token `amountFilled`; the quote-side
4856
4892
  * amount is reconstructed per fill from the order's tick using the DEX's
@@ -4871,13 +4907,14 @@ async function getPairOhlc(c: Context<App.Environment>, options: getPairOhlc.Opt
4871
4907
  new Date(Date.now() - windowMs(window)).toISOString(),
4872
4908
  )
4873
4909
  const bucketMs = intervalMs(interval)
4910
+ const pairTopic = `0x${pair.base.slice(2).padStart(64, '0')}`
4874
4911
 
4875
4912
  return Timing.time(c, 'pair_ohlc', async () => {
4876
4913
  // Taker-perspective rate used only to *select* the high/low fill; the
4877
4914
  // formatted rate string is recomputed in JS from the winning `(tick,
4878
4915
  // isBid)` so it goes through the exact same formatting as open/close.
4879
4916
  const scale = Tick.priceScale
4880
- const rate = `if(p."isBid" = 1, (${scale} + p.tick) / ${scale}, ${scale} / (${scale} + p.tick))`
4917
+ const rate = `if(r.is_bid_int = 1, (${scale} + r.tick) / ${scale}, ${scale} / (${scale} + r.tick))`
4881
4918
  // UInt256 sums are forced through `toString` so values past 2^53 survive
4882
4919
  // JSON; the `(tick, isBid)` tuples are small integers and need no forcing.
4883
4920
  const result = await tidx.fetch({
@@ -4885,21 +4922,37 @@ async function getPairOhlc(c: Context<App.Environment>, options: getPairOhlc.Opt
4885
4922
  engine: 'clickhouse',
4886
4923
  query: `
4887
4924
  SELECT
4888
- intDiv(toUnixTimestamp64Milli(f.block_timestamp), ${bucketMs}) AS bucket,
4925
+ intDiv(toUnixTimestamp64Milli(r.block_timestamp), ${bucketMs}) AS bucket,
4889
4926
  count() AS fill_count,
4890
- toString(sum(f."amountFilled")) AS base_volume,
4891
- toString(sum(intDiv(f."amountFilled" * toUInt256(${scale} + p.tick), ${scale}))) AS quote_volume,
4892
- argMin(tuple(p.tick, p."isBid"), tuple(f.block_num, f.log_idx)) AS open_t,
4893
- argMax(tuple(p.tick, p."isBid"), tuple(f.block_num, f.log_idx)) AS close_t,
4894
- argMax(tuple(p.tick, p."isBid"), ${rate}) AS high_t,
4895
- argMin(tuple(p.tick, p."isBid"), ${rate}) AS low_t
4896
- FROM dex_fills f
4897
- JOIN dex_orders p ON p."orderId" = f."orderId"
4898
- WHERE f.address = '${stablecoinDex}'
4899
- AND f.block_timestamp >= '${fromTimestamp}'
4900
- AND f."orderId" IN (
4901
- SELECT p2."orderId" FROM dex_orders p2 WHERE p2.token = '${pair.base}'
4902
- )
4927
+ toString(sum(r.amount_filled)) AS base_volume,
4928
+ toString(sum(intDiv(r.amount_filled * toUInt256(${scale} + r.tick), ${scale}))) AS quote_volume,
4929
+ argMin(tuple(r.tick, r.is_bid_int), tuple(r.block_num, r.log_idx)) AS open_t,
4930
+ argMax(tuple(r.tick, r.is_bid_int), tuple(r.block_num, r.log_idx)) AS close_t,
4931
+ argMax(tuple(r.tick, r.is_bid_int), ${rate}) AS high_t,
4932
+ argMin(tuple(r.tick, r.is_bid_int), ${rate}) AS low_t
4933
+ FROM (
4934
+ SELECT f.block_timestamp, f.block_num, f.log_idx,
4935
+ f."amountFilled" AS amount_filled,
4936
+ argMax(s.tick, (s.block_num, s.log_idx)) AS tick,
4937
+ argMax(s.is_bid_int, (s.block_num, s.log_idx)) AS is_bid_int
4938
+ FROM dex_fills f
4939
+ INNER JOIN (
4940
+ SELECT
4941
+ reinterpretAsUInt256(reverse(unhex(substring(topic1, 3)))) AS order_id,
4942
+ reinterpretAsInt16(reverse(unhex(substring(data, 191, 4)))) AS tick,
4943
+ data != '' AND substring(data, 130, 1) = '1' AS is_bid_int,
4944
+ block_num,
4945
+ log_idx
4946
+ FROM logs
4947
+ WHERE address = '${stablecoinDex}'
4948
+ AND selector IN ('${orderPlacedTopic}', '${orderFlippedTopic}')
4949
+ AND topic3 = '${pairTopic}'
4950
+ ) AS s ON f."orderId" = s.order_id
4951
+ WHERE f.address = '${stablecoinDex}'
4952
+ AND f.block_timestamp >= '${fromTimestamp}'
4953
+ AND (s.block_num < f.block_num OR (s.block_num = f.block_num AND s.log_idx < f.log_idx))
4954
+ GROUP BY f.block_timestamp, f.block_num, f.log_idx, f."amountFilled"
4955
+ ) AS r
4903
4956
  GROUP BY bucket
4904
4957
  ORDER BY bucket ASC
4905
4958
  ` as string,
@@ -5004,11 +5057,10 @@ const orderCursorTickBias = 32768
5004
5057
  * still applied app-side. ClickHouse aggregates fills per order before the
5005
5058
  * app computes each remaining amount.
5006
5059
  *
5007
- * `remaining = OrderPlaced.amount - sum(OrderFilled.amountFilled)`; orders
5008
- * with an `OrderCancelled` event are excluded outright. Each row is annotated
5009
- * with its pair: the scoped feed reuses the resolved `pair`, the unscoped
5010
- * feed resolves the page's base tokens with one targeted `dex_pairs` lookup
5011
- * (rows whose pair is unknown are dropped).
5060
+ * `remaining` is the latest state event's amount minus subsequent fills;
5061
+ * orders with an `OrderCancelled` event are excluded outright. Each row is
5062
+ * annotated with its pair: the scoped feed reuses the resolved `pair`, the
5063
+ * unscoped feed resolves the page's base tokens with one targeted lookup.
5012
5064
  */
5013
5065
  async function getOrders(c: Context<App.Environment>, options: getOrders.Options) {
5014
5066
  const { chainId, cursor, limit, maker, order, page, pair, side, sort } = options
@@ -5329,9 +5381,10 @@ type RestingOrder = {
5329
5381
  }
5330
5382
 
5331
5383
  /**
5332
- * Loads every resting maker order for a pair: scan `OrderPlaced` filtered by
5333
- * the pair's base token (and optional `maker`), then subtract fills and drop
5334
- * cancelled orders using batched `WHERE "orderId" IN (...)` joins.
5384
+ * Loads every resting maker order for a pair: scan state events filtered by
5385
+ * the pair's base token (and optional `maker`), resolve each order's latest
5386
+ * `OrderPlaced`/`OrderFlipped` generation, then subtract fills after that
5387
+ * generation and drop cancelled orders.
5335
5388
  *
5336
5389
  * Returns the resting set along with a `truncated` flag set when the
5337
5390
  * `OrderPlaced` scan hit `orderScanCap`. Callers surface the flag so
@@ -5349,69 +5402,21 @@ async function loadRestingOrders(
5349
5402
  },
5350
5403
  ): Promise<{ orders: RestingOrder[]; truncated: boolean }> {
5351
5404
  const { base, chainId, maker, scanCap = orderScanCap } = options
5352
- const tidx = c.get('getTidx')(chainId)
5353
-
5354
- // Scan window is intentionally newest-first so a `truncated` snapshot still
5355
- // reflects current market activity rather than ancient placements.
5356
- const filters = [`address = '${stablecoinDex}'`]
5357
- if (base !== undefined) filters.push(`token = '${base}'`)
5358
- if (maker !== undefined) filters.push(`maker = '${maker}'`)
5359
- const where = `WHERE ${filters.join(' AND ')}`
5360
-
5361
- // ClickHouse OLAP path: bloom-filter index on `topic1` (and the `token`
5362
- // string column) handles `WHERE token = '<base>'` and the downstream
5363
- // `"orderId" IN (...)` joins natively, without the per-row decode cost of
5364
- // the Postgres `abi_uint(topic1)` fallback.
5365
- //
5366
- // `"isBid"` is aliased to a name that is *not* in the OrderPlaced event
5367
- // signature so tidx.ts's signature-driven result decoder skips it. ClickHouse
5368
- // serializes booleans as `1`/`0`, but tidx.ts validates `bool` columns with a
5369
- // strict `z.boolean()` derived from the signature and rejects integer
5370
- // representations. Aliasing dodges that decoder and lets us coerce
5371
- // numerically in `parsePlacedRow`.
5372
- const result = await tidx.fetch({
5405
+ const snapshot = await fetchLatestOrderStates(c, { base, chainId, maker, scanCap })
5406
+ if (snapshot.orders.length === 0) return snapshot
5407
+ const cancelled = await fetchCancelledByIds(c, {
5373
5408
  chainId,
5374
- engine: 'clickhouse',
5375
- query: `
5376
- SELECT "orderId", maker, amount, token, "isBid" AS is_bid_int, tick, tx_hash, block_num, log_idx, block_timestamp
5377
- FROM dex_orders
5378
- ${where}
5379
- ORDER BY block_num DESC, log_idx DESC
5380
- LIMIT ${scanCap + 1}
5381
- ` as string,
5409
+ orderIds: snapshot.orders.map((row) => row.orderId),
5382
5410
  })
5383
5411
 
5384
- const truncated = result.rows.length > scanCap
5385
- const placedRows = result.rows.slice(0, scanCap)
5386
- // `dex_orders` can carry duplicate rows per placement; keep the first
5387
- // (newest) copy so pages emit each order once and a duplicate straddling an
5388
- // IN-batch boundary can't double-count fills.
5389
- const placed: RestingOrder[] = []
5390
- const seen = new Set<string>()
5391
- for (const row of placedRows) {
5392
- const parsed = parsePlacedRow(row)
5393
- if (!parsed || seen.has(parsed.orderId)) continue
5394
- seen.add(parsed.orderId)
5395
- placed.push(parsed)
5396
- }
5397
- if (placed.length === 0) return { orders: [], truncated }
5398
-
5399
- const orderIds = placed.map((row) => row.orderId)
5400
- const [cancelled, fillSums] = await Promise.all([
5401
- fetchCancelledByIds(c, { chainId, orderIds }),
5402
- fetchFillSumsByIds(c, { chainId, orderIds }),
5403
- ])
5404
-
5405
5412
  const orders: RestingOrder[] = []
5406
- for (const row of placed) {
5413
+ for (const row of snapshot.orders) {
5407
5414
  if (cancelled.has(row.orderId)) continue
5408
- const filled = fillSums.get(row.orderId) ?? 0n
5409
- const remaining = BigInt(row.amount) - filled
5410
- if (remaining <= 0n) continue
5411
- orders.push({ ...row, remaining: remaining.toString() })
5415
+ if (BigInt(row.remaining) <= 0n) continue
5416
+ orders.push(row)
5412
5417
  }
5413
5418
 
5414
- return { orders, truncated }
5419
+ return { orders, truncated: snapshot.truncated }
5415
5420
  }
5416
5421
 
5417
5422
  /**
@@ -5594,6 +5599,208 @@ function parsePlacedRow(row: Record<string, unknown>): RestingOrder | undefined
5594
5599
  }
5595
5600
  }
5596
5601
 
5602
+ /**
5603
+ * Resolves each scanned order's latest generation from raw state logs and
5604
+ * subtracts only fills after that state event. A fully filled flip generation
5605
+ * therefore resets to the counter-order amount emitted by `OrderFlipped`.
5606
+ */
5607
+ async function fetchLatestOrderStates(
5608
+ c: Context<App.Environment>,
5609
+ options: fetchLatestOrderStates.Options,
5610
+ ): Promise<{ orders: RestingOrder[]; truncated: boolean }> {
5611
+ const { base, chainId, maker, scanCap } = options
5612
+ const tidx = c.get('getTidx')(chainId)
5613
+ let truncated = false
5614
+ const filters = [
5615
+ `address = '${stablecoinDex}'`,
5616
+ `selector IN ('${orderPlacedTopic}', '${orderFlippedTopic}')`,
5617
+ ]
5618
+ if (base !== undefined) filters.push(`topic3 = '0x${base.slice(2).padStart(64, '0')}'`)
5619
+ // Global candidates below already belong to the maker. Keeping topic2 in
5620
+ // that lookup makes the indexer scan a sparse maker instead of indexed IDs.
5621
+ if (base !== undefined && maker !== undefined)
5622
+ filters.push(`topic2 = '0x${maker.slice(2).padStart(64, '0')}'`)
5623
+ let batches = [filters]
5624
+
5625
+ // The global raw-log aggregate is unbounded on hosted TIDX. Bound it to the
5626
+ // newest state events so old placements with recent flips remain candidates.
5627
+ if (base === undefined) {
5628
+ const candidateFilters = [
5629
+ `address = '${stablecoinDex}'`,
5630
+ `selector IN ('${orderPlacedTopic}', '${orderFlippedTopic}')`,
5631
+ ]
5632
+ const candidates = await tidx.fetch({
5633
+ chainId,
5634
+ engine: 'clickhouse',
5635
+ query: `
5636
+ SELECT topic1, topic2
5637
+ FROM logs
5638
+ WHERE ${candidateFilters.join(' AND ')}
5639
+ ORDER BY block_num DESC, log_idx DESC
5640
+ LIMIT ${scanCap + 1}
5641
+ ` as string,
5642
+ })
5643
+ truncated = candidates.rows.length > scanCap
5644
+ const topics = new Set<string>()
5645
+ for (const row of candidates.rows.slice(0, scanCap)) {
5646
+ if (maker !== undefined && row['topic2'] !== `0x${maker.slice(2).padStart(64, '0')}`) continue
5647
+ const topic = Value.toText(row['topic1'])
5648
+ if (topic !== undefined && /^0x[0-9a-fA-F]{64}$/.test(topic)) topics.add(topic)
5649
+ }
5650
+
5651
+ // `logs.topic2` is not a viable hosted-TIDX scan for a sparse maker.
5652
+ // Include its indexed placement window, then resolve current state below.
5653
+ if (maker !== undefined) {
5654
+ const placements = await tidx.fetch({
5655
+ chainId,
5656
+ engine: 'clickhouse',
5657
+ query: `
5658
+ SELECT "orderId"
5659
+ FROM dex_orders
5660
+ WHERE address = '${stablecoinDex}' AND maker = '${maker}'
5661
+ ORDER BY block_num DESC, log_idx DESC
5662
+ LIMIT ${scanCap + 1}
5663
+ ` as string,
5664
+ })
5665
+ truncated ||= placements.rows.length > scanCap
5666
+ for (const row of placements.rows.slice(0, scanCap)) {
5667
+ const orderId = Value.toIntegerString(row['orderId'])
5668
+ if (orderId !== undefined) topics.add(`0x${BigInt(orderId).toString(16).padStart(64, '0')}`)
5669
+ }
5670
+ }
5671
+ if (topics.size === 0) return { orders: [], truncated }
5672
+ // Compact hex avoids oversized GET URLs and TIDX's per-cell SQL scanning
5673
+ // cost. Pad in ClickHouse; batching also bounds maximum-width IDs.
5674
+ const ids = [...topics].map((topic) => `'${BigInt(topic).toString(16)}'`)
5675
+ batches = []
5676
+ for (let i = 0; i < ids.length; i += 512)
5677
+ batches.push([
5678
+ ...filters,
5679
+ `topic1 IN (SELECT concat('0x', leftPad(arrayJoin([${ids.slice(i, i + 512).join(', ')}]), 64, '0')))`,
5680
+ ])
5681
+ }
5682
+
5683
+ const rows: Record<string, unknown>[] = []
5684
+ for (const filters of batches) {
5685
+ const result = await tidx.fetch({
5686
+ chainId,
5687
+ engine: 'clickhouse',
5688
+ // Raw state fields have no signature-backed result schema; every field is validated below.
5689
+ query: `
5690
+ WITH states AS (
5691
+ SELECT topic1,
5692
+ argMax(topic2, (block_num, log_idx)) AS t2,
5693
+ argMax(topic3, (block_num, log_idx)) AS t3,
5694
+ argMax(data, (block_num, log_idx)) AS payload,
5695
+ argMax(tx_hash, (block_num, log_idx)) AS state_tx_hash,
5696
+ argMax(block_num, (block_num, log_idx)) AS state_block_num,
5697
+ argMax(log_idx, (block_num, log_idx)) AS state_log_idx,
5698
+ argMax(block_timestamp, (block_num, log_idx)) AS state_timestamp
5699
+ FROM logs
5700
+ WHERE ${filters.join(' AND ')}
5701
+ GROUP BY topic1
5702
+ ORDER BY state_block_num DESC, state_log_idx DESC
5703
+ LIMIT ${scanCap + 1}
5704
+ )
5705
+ SELECT states.*,
5706
+ toString(sumIf(f."amountFilled",
5707
+ f.block_num > states.state_block_num OR
5708
+ (f.block_num = states.state_block_num AND f.log_idx > states.state_log_idx)
5709
+ )) AS amount_filled
5710
+ FROM states
5711
+ LEFT JOIN dex_fills f
5712
+ ON f.address = '${stablecoinDex}'
5713
+ AND f."orderId" = reinterpretAsUInt256(reverse(unhex(substring(states.topic1, 3))))
5714
+ GROUP BY states.topic1, states.t2, states.t3, states.payload,
5715
+ states.state_tx_hash, states.state_block_num, states.state_log_idx,
5716
+ states.state_timestamp
5717
+ ORDER BY states.state_block_num DESC, states.state_log_idx DESC
5718
+ ` as string,
5719
+ })
5720
+ rows.push(...result.rows)
5721
+ }
5722
+ rows.sort(
5723
+ (a, b) =>
5724
+ Number(b['state_block_num']) - Number(a['state_block_num']) ||
5725
+ Number(b['state_log_idx']) - Number(a['state_log_idx']),
5726
+ )
5727
+ truncated ||= rows.length > scanCap
5728
+ const orders: RestingOrder[] = []
5729
+ for (const row of rows.slice(0, scanCap)) {
5730
+ const state = parseLatestOrderStateRow(row)
5731
+ if (state) orders.push(state)
5732
+ }
5733
+ return { orders, truncated }
5734
+ }
5735
+
5736
+ declare namespace fetchLatestOrderStates {
5737
+ /** Inputs for resolving current resting-order generations. */
5738
+ type Options = {
5739
+ /** Restrict to one pair's base token; omit for the global feed. */
5740
+ base?: z.output<typeof Schema.TokenAddress> | undefined
5741
+ chainId: z.output<typeof Schema.ChainId>
5742
+ /** Restrict to one maker. */
5743
+ maker?: z.output<typeof Schema.Address> | undefined
5744
+ /** Maximum number of current state rows to return. */
5745
+ scanCap: number
5746
+ }
5747
+ }
5748
+
5749
+ /** Decodes one latest-state aggregate into a resting-order snapshot row. */
5750
+ function parseLatestOrderStateRow(row: Record<string, unknown>): RestingOrder | undefined {
5751
+ const topic1 = Value.toText(row['topic1'])
5752
+ const topic2 = Value.toText(row['t2'])
5753
+ const topic3 = Value.toText(row['t3'])
5754
+ const payload = Value.toText(row['payload'])
5755
+ const filled = Value.toIntegerString(row['amount_filled'])
5756
+ const blockNumber = Value.toNumber(row['state_block_num'])
5757
+ const logIndex = Value.toNumber(row['state_log_idx'])
5758
+ const timestamp = Value.toIsoDateTime(row['state_timestamp'])
5759
+ const transactionHash = Schema.Hash.safeParse(row['state_tx_hash'])
5760
+ const maker = Schema.Address.safeParse(
5761
+ topic2 === undefined ? undefined : `0x${topic2.slice(26).toLowerCase()}`,
5762
+ )
5763
+ const token = Schema.TokenAddress.safeParse(
5764
+ topic3 === undefined ? undefined : `0x${topic3.slice(26).toLowerCase()}`,
5765
+ )
5766
+ if (
5767
+ topic1 === undefined ||
5768
+ !/^0x[0-9a-fA-F]{64}$/.test(topic1) ||
5769
+ topic2 === undefined ||
5770
+ !/^0x[0-9a-fA-F]{64}$/.test(topic2) ||
5771
+ topic3 === undefined ||
5772
+ !/^0x[0-9a-fA-F]{64}$/.test(topic3) ||
5773
+ payload === undefined ||
5774
+ payload.length < 2 + 64 * 3 ||
5775
+ filled === undefined ||
5776
+ blockNumber === undefined ||
5777
+ logIndex === undefined ||
5778
+ timestamp === undefined ||
5779
+ !transactionHash.success ||
5780
+ !maker.success ||
5781
+ !token.success
5782
+ )
5783
+ return undefined
5784
+
5785
+ const amount = BigInt(`0x${payload.slice(2, 66)}`)
5786
+ const tickWord = BigInt(`0x${payload.slice(130, 194)}`)
5787
+ const tick = Number(tickWord >= 2n ** 255n ? tickWord - 2n ** 256n : tickWord)
5788
+ const remaining = amount - BigInt(filled)
5789
+ return {
5790
+ amount: amount.toString(),
5791
+ blockNumber,
5792
+ isBid: BigInt(`0x${payload.slice(66, 130)}`) !== 0n,
5793
+ logIndex,
5794
+ maker: maker.data,
5795
+ orderId: BigInt(topic1).toString(),
5796
+ remaining: remaining.toString(),
5797
+ tick,
5798
+ timestamp,
5799
+ token: token.data,
5800
+ transactionHash: transactionHash.data,
5801
+ }
5802
+ }
5803
+
5597
5804
  /**
5598
5805
  * Resolves the set of cancelled `orderId`s in the snapshot window via batched
5599
5806
  * `OrderCancelled WHERE "orderId" IN (...)` queries. Empty input short-circuits
@@ -1,11 +1,17 @@
1
1
  /** @module-tag localnet */
2
2
 
3
3
  import { Schema } from 'tapimo/server'
4
- import { Abis, Addresses } from 'viem/tempo'
4
+ import { Hex } from 'ox'
5
+ import { readContract, sendTransactionSync } from 'viem/actions'
6
+ import { Abis, Actions, Addresses } from 'viem/tempo'
7
+ import * as z from 'zod/mini'
5
8
 
6
9
  import * as TestApp from '../../../../test/App.js'
7
10
  import * as Runtime from '../../../../test/runtime.js'
11
+ import * as Tempo from '../../../../test/Tempo.js'
8
12
  import * as TestViem from '../../../../test/Viem.js'
13
+ import type * as Log from '../../../internal/Log.js'
14
+ import * as Tidx from '../../../internal/Tidx.js'
9
15
  import * as FeeAmm from './fee-amm.js'
10
16
 
11
17
  type JsonSchema = {
@@ -30,8 +36,9 @@ type OpenApiDocument = {
30
36
  }
31
37
 
32
38
  /** Validator-side token with live fee-AMM activity on Tempo Moderato. */
39
+ const runtime = Runtime.get()
33
40
  const validatorToken =
34
- Runtime.get().mode === 'localnet'
41
+ runtime.mode === 'localnet'
35
42
  ? Addresses.pathUsd.toLowerCase()
36
43
  : '0x20c0000000000000000000000000000000000001'
37
44
 
@@ -236,6 +243,131 @@ describe('OpenAPI', () => {
236
243
  })
237
244
  })
238
245
 
246
+ describe('feeTokenSet', () => {
247
+ test.runIf(runtime.mode === 'localnet')(
248
+ 'ignores a liquid pool against an unpreferred validator token',
249
+ async () => {
250
+ const db = TestApp.database()
251
+ await TestApp.verifiedSeed(db, runtime.chainId)
252
+ const account = Tempo.accounts[3]!
253
+ const client = Tempo.getClient({ account })
254
+ await Actions.faucet.fundSync(client, { account, timeout: 60_000 })
255
+ const validators = await readContract(client, {
256
+ abi: Abis.validatorConfig,
257
+ address: Addresses.validator,
258
+ functionName: 'getValidators',
259
+ })
260
+ const preferred = await Promise.all(
261
+ validators
262
+ .filter((validator) => validator.active)
263
+ .map((validator) =>
264
+ readContract(client, {
265
+ abi: Abis.feeManager,
266
+ address: Addresses.feeManager,
267
+ args: [validator.validatorAddress],
268
+ functionName: 'validatorTokens',
269
+ }),
270
+ ),
271
+ )
272
+ const readFeeTokens = async () => {
273
+ const application = TestApp.create({ auth: false, db })
274
+ application.get('/test/fee-tokens', async (c) =>
275
+ c.json({ data: Array.from(await FeeAmm.feeTokenSet(c, runtime.chainId)) }),
276
+ )
277
+ const response = await application.request('/test/fee-tokens')
278
+ expect(response.status, await response.clone().text()).toBe(200)
279
+ return z.object({ data: z.array(Schema.Address) }).parse(await response.json()).data
280
+ }
281
+ const initial = await readFeeTokens()
282
+ const available = (
283
+ [
284
+ '0x20c0000000000000000000000000000000000001',
285
+ '0x20c0000000000000000000000000000000000002',
286
+ '0x20c0000000000000000000000000000000000003',
287
+ ] as const
288
+ ).filter(
289
+ (address) =>
290
+ !initial.includes(address) &&
291
+ !preferred.some((token) => token.toLowerCase() === address.toLowerCase()),
292
+ )
293
+ const [userToken, validatorToken] = available
294
+ if (!userToken || !validatorToken) throw new Error('Need two unpreferred faucet tokens.')
295
+ const receipt = await sendTransactionSync(client, {
296
+ account,
297
+ calls: [
298
+ Actions.token.approve.call({
299
+ amount: 100_000n,
300
+ spender: Addresses.feeManager,
301
+ token: validatorToken,
302
+ }),
303
+ Actions.amm.mint.call({
304
+ to: account.address,
305
+ userTokenAddress: userToken,
306
+ validatorTokenAddress: validatorToken,
307
+ validatorTokenAmount: 100_000n,
308
+ }),
309
+ ],
310
+ })
311
+ await waitForTransaction({ hash: receipt.transactionHash })
312
+
313
+ expect(await readFeeTokens()).not.toContain(userToken)
314
+ },
315
+ )
316
+
317
+ test('records an operational failure when eligibility degrades', async () => {
318
+ const db = TestApp.database()
319
+ const entries: Log.Entry[] = []
320
+ await TestApp.verifiedSeed(db, runtime.chainId)
321
+ const application = TestApp.create({
322
+ auth: false,
323
+ db,
324
+ logger: (entry) => {
325
+ entries.push(entry)
326
+ },
327
+ rpc: { url: () => 'http://127.0.0.1:1' },
328
+ })
329
+ application.get('/test/fee-tokens', async (c) => {
330
+ const data = await FeeAmm.feeTokenSet(c, runtime.chainId).catch(() => undefined)
331
+ return c.json({ data })
332
+ })
333
+
334
+ const response = await application.request('/test/fee-tokens')
335
+
336
+ expect(response.status).toBe(200)
337
+ expect(entries.at(-1)?.providerFailures).toContainEqual({
338
+ chainId: runtime.chainId,
339
+ failure: 'unknown',
340
+ id: 'rpc',
341
+ operation: 'feeTokenSet',
342
+ })
343
+ })
344
+ })
345
+
346
+ async function waitForTransaction(options: waitForTransaction.Options) {
347
+ const tidx = Tidx.getClient({
348
+ chainId: runtime.chainId,
349
+ tidx: { baseUrl: runtime.tidxUrl },
350
+ })
351
+ await vi.waitFor(
352
+ async () => {
353
+ const result = await tidx.fetch({
354
+ chainId: runtime.chainId,
355
+ query: `SELECT hash FROM txs WHERE hash = '${options.hash.toLowerCase()}'` as string,
356
+ })
357
+ expect(result.rows).toHaveLength(1)
358
+ },
359
+ { interval: 500, timeout: 120_000 },
360
+ )
361
+ }
362
+
363
+ declare namespace waitForTransaction {
364
+ /** Inputs for waiting until TIDX observes a transaction. */
365
+ type Options = {
366
+ /** Transaction hash to observe. */
367
+ hash: Hex.Hex
368
+ }
369
+ }
370
+
239
371
  // Skipped: the pools listing runs a ClickHouse `GROUP BY` over every FeeManager
240
372
  // `Mint` log, which exceeds the live indexer's 5s execution cap on high-volume
241
373
  // chains (testnet) and returns `502`. Re-enable once the aggregate fits the