tapimo 0.7.0 → 0.7.2

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 (689) hide show
  1. package/dist/ApiKeys.d.ts +24 -7
  2. package/dist/ApiKeys.d.ts.map +1 -1
  3. package/dist/ApiKeys.js +17 -5
  4. package/dist/ApiKeys.js.map +1 -1
  5. package/dist/App.d.ts +12104 -7861
  6. package/dist/App.d.ts.map +1 -1
  7. package/dist/App.js +191 -128
  8. package/dist/App.js.map +1 -1
  9. package/dist/Assets.d.ts +10 -0
  10. package/dist/Assets.d.ts.map +1 -1
  11. package/dist/Assets.js +17 -4
  12. package/dist/Assets.js.map +1 -1
  13. package/dist/Scope.d.ts +19 -8
  14. package/dist/Scope.d.ts.map +1 -1
  15. package/dist/Scope.js +25 -9
  16. package/dist/Scope.js.map +1 -1
  17. package/dist/Webhooks.d.ts +1 -1
  18. package/dist/admin/App.d.ts +601 -20
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +12 -2
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +94 -11
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +141 -32
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +1069 -0
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -0
  28. package/dist/admin/apps/earn-vaults.js +409 -0
  29. package/dist/admin/apps/earn-vaults.js.map +1 -0
  30. package/dist/admin/apps/verified-tokens.d.ts +166 -166
  31. package/dist/admin/ui.generated.d.ts +1 -1
  32. package/dist/admin/ui.generated.d.ts.map +1 -1
  33. package/dist/admin/ui.generated.js +151 -95
  34. package/dist/admin/ui.generated.js.map +1 -1
  35. package/dist/analytics/Analytics.d.ts +2 -0
  36. package/dist/analytics/Analytics.d.ts.map +1 -1
  37. package/dist/analytics/Analytics.js +18 -2
  38. package/dist/analytics/Analytics.js.map +1 -1
  39. package/dist/analytics/tables/requestEvents.d.ts +22 -1
  40. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  41. package/dist/analytics/tables/requestEvents.js +59 -39
  42. package/dist/analytics/tables/requestEvents.js.map +1 -1
  43. package/dist/apps/Zones.d.ts +8335 -0
  44. package/dist/apps/Zones.d.ts.map +1 -0
  45. package/dist/apps/Zones.js +38 -0
  46. package/dist/apps/Zones.js.map +1 -0
  47. package/dist/apps/data/App.d.ts +14377 -10165
  48. package/dist/apps/data/App.d.ts.map +1 -1
  49. package/dist/apps/data/App.js +91 -19
  50. package/dist/apps/data/App.js.map +1 -1
  51. package/dist/apps/data/FxOracle.d.ts +1 -1
  52. package/dist/apps/data/FxOracle.d.ts.map +1 -1
  53. package/dist/apps/data/index.d.ts +0 -1
  54. package/dist/apps/data/index.d.ts.map +1 -1
  55. package/dist/apps/data/index.js +0 -1
  56. package/dist/apps/data/index.js.map +1 -1
  57. package/dist/apps/data/routes/activities.d.ts +32 -32
  58. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  59. package/dist/apps/data/routes/activities.js +130 -65
  60. package/dist/apps/data/routes/activities.js.map +1 -1
  61. package/dist/apps/data/routes/addresses.d.ts +312 -312
  62. package/dist/apps/data/routes/balances.d.ts +18 -18
  63. package/dist/apps/data/routes/balances.js +5 -5
  64. package/dist/apps/data/routes/balances.js.map +1 -1
  65. package/dist/apps/data/routes/coingecko.d.ts +176 -176
  66. package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
  67. package/dist/apps/data/routes/coingecko.js +62 -35
  68. package/dist/apps/data/routes/coingecko.js.map +1 -1
  69. package/dist/apps/data/routes/earn.d.ts +2144 -0
  70. package/dist/apps/data/routes/earn.d.ts.map +1 -0
  71. package/dist/apps/data/routes/earn.js +947 -0
  72. package/dist/apps/data/routes/earn.js.map +1 -0
  73. package/dist/apps/data/routes/exchanges.d.ts +1231 -324
  74. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  75. package/dist/apps/data/routes/exchanges.js +656 -193
  76. package/dist/apps/data/routes/exchanges.js.map +1 -1
  77. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  78. package/dist/apps/data/routes/fee-amm.js +59 -8
  79. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  80. package/dist/apps/data/routes/funding.d.ts +4092 -387
  81. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  82. package/dist/apps/data/routes/funding.js +1403 -256
  83. package/dist/apps/data/routes/funding.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +5 -5
  85. package/dist/apps/data/routes/indexer.d.ts.map +1 -1
  86. package/dist/apps/data/routes/indexer.js +19 -2
  87. package/dist/apps/data/routes/indexer.js.map +1 -1
  88. package/dist/apps/data/routes/receipts.d.ts +265 -265
  89. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  90. package/dist/apps/data/routes/receipts.js +11 -11
  91. package/dist/apps/data/routes/receipts.js.map +1 -1
  92. package/dist/apps/data/routes/rpc.d.ts +5 -5
  93. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  94. package/dist/apps/data/routes/rpc.js +211 -22
  95. package/dist/apps/data/routes/rpc.js.map +1 -1
  96. package/dist/apps/data/routes/tokenlist.d.ts +36 -36
  97. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  98. package/dist/apps/data/routes/tokenlist.js +49 -9
  99. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  100. package/dist/apps/data/routes/tokens.d.ts +116 -88
  101. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  102. package/dist/apps/data/routes/tokens.js +198 -91
  103. package/dist/apps/data/routes/tokens.js.map +1 -1
  104. package/dist/apps/data/routes/transactions.d.ts +55 -55
  105. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  106. package/dist/apps/data/routes/transactions.js +78 -39
  107. package/dist/apps/data/routes/transactions.js.map +1 -1
  108. package/dist/apps/data/routes/transfers.d.ts +78 -29
  109. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  110. package/dist/apps/data/routes/transfers.js +165 -67
  111. package/dist/apps/data/routes/transfers.js.map +1 -1
  112. package/dist/apps/data/routes/valuation.d.ts +10 -10
  113. package/dist/apps/data/routes/valuation.js +2 -2
  114. package/dist/apps/data/routes/valuation.js.map +1 -1
  115. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
  116. package/dist/apps/data/routes/verified-tokens.js +34 -9
  117. package/dist/apps/data/routes/verified-tokens.js.map +1 -1
  118. package/dist/apps/data/routes/webhooks.d.ts +5 -3
  119. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  120. package/dist/apps/data/routes/webhooks.js +175 -65
  121. package/dist/apps/data/routes/webhooks.js.map +1 -1
  122. package/dist/apps/data/routes/zones.d.ts +281 -0
  123. package/dist/apps/data/routes/zones.d.ts.map +1 -0
  124. package/dist/apps/data/routes/zones.js +252 -0
  125. package/dist/apps/data/routes/zones.js.map +1 -0
  126. package/dist/apps/docs/reference.js +6 -5
  127. package/dist/apps/docs/reference.js.map +1 -1
  128. package/dist/apps/index.d.ts +2 -1
  129. package/dist/apps/index.d.ts.map +1 -1
  130. package/dist/apps/index.js +2 -1
  131. package/dist/apps/index.js.map +1 -1
  132. package/dist/apps/management/App.d.ts +670 -670
  133. package/dist/apps/management/Billing.d.ts +8 -0
  134. package/dist/apps/management/Billing.d.ts.map +1 -1
  135. package/dist/apps/management/Billing.js +12 -0
  136. package/dist/apps/management/Billing.js.map +1 -1
  137. package/dist/apps/management/Error.d.ts +12 -0
  138. package/dist/apps/management/Error.d.ts.map +1 -0
  139. package/dist/apps/management/Error.js +10 -0
  140. package/dist/apps/management/Error.js.map +1 -0
  141. package/dist/apps/management/routes/api-keys.d.ts +5 -5
  142. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  143. package/dist/apps/management/routes/api-keys.js +2 -8
  144. package/dist/apps/management/routes/api-keys.js.map +1 -1
  145. package/dist/apps/management/routes/billing.d.ts +119 -119
  146. package/dist/apps/management/routes/faucet.d.ts +35 -35
  147. package/dist/apps/management/routes/invitations.d.ts +62 -62
  148. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  149. package/dist/apps/management/routes/invitations.js +4 -10
  150. package/dist/apps/management/routes/invitations.js.map +1 -1
  151. package/dist/apps/management/routes/invite-links.d.ts +30 -30
  152. package/dist/apps/management/routes/me.d.ts +6 -6
  153. package/dist/apps/management/routes/members.d.ts +78 -78
  154. package/dist/apps/management/routes/orgs.d.ts +48 -48
  155. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  156. package/dist/apps/management/routes/orgs.js +2 -8
  157. package/dist/apps/management/routes/orgs.js.map +1 -1
  158. package/dist/apps/management/routes/projects.d.ts +9 -9
  159. package/dist/apps/management/routes/scopes.js +2 -2
  160. package/dist/apps/management/routes/scopes.js.map +1 -1
  161. package/dist/apps/management/routes/usage.d.ts +80 -80
  162. package/dist/apps/management/routes/verified-token-requests.d.ts +36 -36
  163. package/dist/apps/management/routes/webhooks.d.ts +50 -50
  164. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  165. package/dist/apps/management/routes/webhooks.js +15 -3
  166. package/dist/apps/management/routes/webhooks.js.map +1 -1
  167. package/dist/apps/mpp/App.d.ts +55 -56
  168. package/dist/apps/mpp/App.d.ts.map +1 -1
  169. package/dist/apps/mpp/App.js +192 -27
  170. package/dist/apps/mpp/App.js.map +1 -1
  171. package/dist/apps/mpp/Mpp.d.ts +0 -20
  172. package/dist/apps/mpp/Mpp.d.ts.map +1 -1
  173. package/dist/apps/mpp/Mpp.js +0 -24
  174. package/dist/apps/mpp/Mpp.js.map +1 -1
  175. package/dist/apps/mpp/internal/Adapter.d.ts +40 -0
  176. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -0
  177. package/dist/apps/mpp/internal/Adapter.js +66 -0
  178. package/dist/apps/mpp/internal/Adapter.js.map +1 -0
  179. package/dist/apps/mpp/internal/Error.d.ts +4 -0
  180. package/dist/apps/mpp/internal/Error.d.ts.map +1 -0
  181. package/dist/apps/mpp/internal/Error.js +41 -0
  182. package/dist/apps/mpp/internal/Error.js.map +1 -0
  183. package/dist/apps/mpp/internal/Idempotency.d.ts +33 -0
  184. package/dist/apps/mpp/internal/Idempotency.d.ts.map +1 -0
  185. package/dist/apps/mpp/internal/Idempotency.js +28 -0
  186. package/dist/apps/mpp/internal/Idempotency.js.map +1 -0
  187. package/dist/apps/mpp/internal/Policy.d.ts +46 -0
  188. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -0
  189. package/dist/apps/mpp/internal/Policy.js +57 -0
  190. package/dist/apps/mpp/internal/Policy.js.map +1 -0
  191. package/dist/apps/mpp/internal/ScreenManager.d.ts +27 -0
  192. package/dist/apps/mpp/internal/ScreenManager.d.ts.map +1 -0
  193. package/dist/apps/mpp/internal/ScreenManager.js +18 -0
  194. package/dist/apps/mpp/internal/ScreenManager.js.map +1 -0
  195. package/dist/apps/mpp/internal/Screening.d.ts +35 -0
  196. package/dist/apps/mpp/internal/Screening.d.ts.map +1 -0
  197. package/dist/apps/mpp/internal/Screening.js +20 -0
  198. package/dist/apps/mpp/internal/Screening.js.map +1 -0
  199. package/dist/apps/mpp/internal/Sponsorship.d.ts +36 -0
  200. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -0
  201. package/dist/apps/mpp/internal/Sponsorship.js +103 -0
  202. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -0
  203. package/dist/apps/mpp/internal/Utils.d.ts +7 -0
  204. package/dist/apps/mpp/internal/Utils.d.ts.map +1 -0
  205. package/dist/apps/mpp/internal/Utils.js +24 -0
  206. package/dist/apps/mpp/internal/Utils.js.map +1 -0
  207. package/dist/apps/relay/App.js +184 -24
  208. package/dist/apps/relay/App.js.map +1 -1
  209. package/dist/apps/relay/Sponsorships.d.ts +4 -0
  210. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  211. package/dist/apps/relay/Sponsorships.js +16 -7
  212. package/dist/apps/relay/Sponsorships.js.map +1 -1
  213. package/dist/db/Db.d.ts +20 -0
  214. package/dist/db/Db.d.ts.map +1 -1
  215. package/dist/db/Db.js +342 -0
  216. package/dist/db/Db.js.map +1 -1
  217. package/dist/db/Schema.d.ts +921 -1
  218. package/dist/db/Schema.d.ts.map +1 -1
  219. package/dist/db/Schema.js +269 -1
  220. package/dist/db/Schema.js.map +1 -1
  221. package/dist/db/tables/earnVaults.d.ts +68 -0
  222. package/dist/db/tables/earnVaults.d.ts.map +1 -0
  223. package/dist/db/tables/earnVaults.js +72 -0
  224. package/dist/db/tables/earnVaults.js.map +1 -0
  225. package/dist/db/tables/fundingCatalog.d.ts +56 -0
  226. package/dist/db/tables/fundingCatalog.d.ts.map +1 -0
  227. package/dist/db/tables/fundingCatalog.js +85 -0
  228. package/dist/db/tables/fundingCatalog.js.map +1 -0
  229. package/dist/db/tables/fundingDepositAddresses.d.ts +159 -0
  230. package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -0
  231. package/dist/db/tables/fundingDepositAddresses.js +206 -0
  232. package/dist/db/tables/fundingDepositAddresses.js.map +1 -0
  233. package/dist/db/tables/fundingDeposits.d.ts +115 -0
  234. package/dist/db/tables/fundingDeposits.d.ts.map +1 -0
  235. package/dist/db/tables/fundingDeposits.js +100 -0
  236. package/dist/db/tables/fundingDeposits.js.map +1 -0
  237. package/dist/db/tables/fundingIdempotency.d.ts +91 -0
  238. package/dist/db/tables/fundingIdempotency.d.ts.map +1 -0
  239. package/dist/db/tables/fundingIdempotency.js +103 -0
  240. package/dist/db/tables/fundingIdempotency.js.map +1 -0
  241. package/dist/db/tables/fundingTransferEvents.d.ts +12 -0
  242. package/dist/db/tables/fundingTransferEvents.d.ts.map +1 -0
  243. package/dist/db/tables/fundingTransferEvents.js +18 -0
  244. package/dist/db/tables/fundingTransferEvents.js.map +1 -0
  245. package/dist/db/tables/fundingTransferTransactions.d.ts +15 -0
  246. package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -0
  247. package/dist/db/tables/fundingTransferTransactions.js +27 -0
  248. package/dist/db/tables/fundingTransferTransactions.js.map +1 -0
  249. package/dist/db/tables/fundingTransfers.d.ts +82 -0
  250. package/dist/db/tables/fundingTransfers.d.ts.map +1 -0
  251. package/dist/db/tables/fundingTransfers.js +89 -0
  252. package/dist/db/tables/fundingTransfers.js.map +1 -0
  253. package/dist/db/tables/organizations.d.ts +8 -0
  254. package/dist/db/tables/organizations.d.ts.map +1 -1
  255. package/dist/db/tables/organizations.js +35 -0
  256. package/dist/db/tables/organizations.js.map +1 -1
  257. package/dist/db/tables/projects.d.ts +8 -0
  258. package/dist/db/tables/projects.d.ts.map +1 -1
  259. package/dist/db/tables/projects.js +16 -0
  260. package/dist/db/tables/projects.js.map +1 -1
  261. package/dist/db/tables/requestUsage.d.ts +13 -0
  262. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  263. package/dist/db/tables/requestUsage.js +16 -0
  264. package/dist/db/tables/requestUsage.js.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.d.ts +4 -2
  266. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  267. package/dist/db/tables/sponsoredTransactions.js +14 -4
  268. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  269. package/dist/db/tables/users.d.ts +8 -0
  270. package/dist/db/tables/users.d.ts.map +1 -1
  271. package/dist/db/tables/users.js +16 -0
  272. package/dist/db/tables/users.js.map +1 -1
  273. package/dist/db/tables/verifiedTokens.d.ts +14 -7
  274. package/dist/db/tables/verifiedTokens.d.ts.map +1 -1
  275. package/dist/db/tables/verifiedTokens.js +9 -7
  276. package/dist/db/tables/verifiedTokens.js.map +1 -1
  277. package/dist/db/tables/webhookSubscriptions.d.ts +31 -1
  278. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  279. package/dist/db/tables/webhookSubscriptions.js +24 -3
  280. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  281. package/dist/handlers/relay.js +108 -108
  282. package/dist/handlers/relay.js.map +1 -1
  283. package/dist/internal/Auth.d.ts +26 -0
  284. package/dist/internal/Auth.d.ts.map +1 -1
  285. package/dist/internal/Auth.js +35 -2
  286. package/dist/internal/Auth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts.map +1 -1
  288. package/dist/internal/Cache.js +16 -10
  289. package/dist/internal/Cache.js.map +1 -1
  290. package/dist/internal/Cursor.js +1 -1
  291. package/dist/internal/Cursor.js.map +1 -1
  292. package/dist/internal/EarnRates.d.ts +89 -0
  293. package/dist/internal/EarnRates.d.ts.map +1 -0
  294. package/dist/internal/EarnRates.js +266 -0
  295. package/dist/internal/EarnRates.js.map +1 -0
  296. package/dist/internal/EarnVaults.d.ts +171 -0
  297. package/dist/internal/EarnVaults.d.ts.map +1 -0
  298. package/dist/internal/EarnVaults.js +547 -0
  299. package/dist/internal/EarnVaults.js.map +1 -0
  300. package/dist/internal/EdgeCache.d.ts +9 -2
  301. package/dist/internal/EdgeCache.d.ts.map +1 -1
  302. package/dist/internal/EdgeCache.js +36 -9
  303. package/dist/internal/EdgeCache.js.map +1 -1
  304. package/dist/internal/Id.d.ts +11 -0
  305. package/dist/internal/Id.d.ts.map +1 -1
  306. package/dist/internal/Id.js +13 -0
  307. package/dist/internal/Id.js.map +1 -1
  308. package/dist/internal/Idempotency.d.ts +83 -0
  309. package/dist/internal/Idempotency.d.ts.map +1 -0
  310. package/dist/internal/Idempotency.js +113 -0
  311. package/dist/internal/Idempotency.js.map +1 -0
  312. package/dist/internal/Log.d.ts +64 -9
  313. package/dist/internal/Log.d.ts.map +1 -1
  314. package/dist/internal/Log.js +29 -7
  315. package/dist/internal/Log.js.map +1 -1
  316. package/dist/internal/MetricSink.d.ts.map +1 -1
  317. package/dist/internal/MetricSink.js +47 -1
  318. package/dist/internal/MetricSink.js.map +1 -1
  319. package/dist/internal/OpenApi.d.ts +1 -1
  320. package/dist/internal/OpenApi.d.ts.map +1 -1
  321. package/dist/internal/OpenApi.js +3 -0
  322. package/dist/internal/OpenApi.js.map +1 -1
  323. package/dist/internal/Provider.d.ts +14 -0
  324. package/dist/internal/Provider.d.ts.map +1 -0
  325. package/dist/internal/Provider.js +5 -0
  326. package/dist/internal/Provider.js.map +1 -0
  327. package/dist/internal/Schema.d.ts +8 -3
  328. package/dist/internal/Schema.d.ts.map +1 -1
  329. package/dist/internal/Schema.js +24 -13
  330. package/dist/internal/Schema.js.map +1 -1
  331. package/dist/internal/Store.d.ts +6 -0
  332. package/dist/internal/Store.d.ts.map +1 -1
  333. package/dist/internal/Store.js +35 -0
  334. package/dist/internal/Store.js.map +1 -1
  335. package/dist/internal/Tidx.d.ts +43 -24
  336. package/dist/internal/Tidx.d.ts.map +1 -1
  337. package/dist/internal/Tidx.js +79 -11
  338. package/dist/internal/Tidx.js.map +1 -1
  339. package/dist/internal/Viem.d.ts +82 -65
  340. package/dist/internal/Viem.d.ts.map +1 -1
  341. package/dist/internal/Viem.js +83 -12
  342. package/dist/internal/Viem.js.map +1 -1
  343. package/dist/internal/WebhookDestination.d.ts.map +1 -1
  344. package/dist/internal/WebhookDestination.js +34 -28
  345. package/dist/internal/WebhookDestination.js.map +1 -1
  346. package/dist/internal/Webhooks.d.ts +9 -0
  347. package/dist/internal/Webhooks.d.ts.map +1 -1
  348. package/dist/internal/Webhooks.js +15 -10
  349. package/dist/internal/Webhooks.js.map +1 -1
  350. package/dist/internal/exchange/Provider.d.ts +219 -0
  351. package/dist/internal/exchange/Provider.d.ts.map +1 -0
  352. package/dist/internal/exchange/Provider.js +117 -0
  353. package/dist/internal/exchange/Provider.js.map +1 -0
  354. package/dist/internal/exchange/index.d.ts +2 -0
  355. package/dist/internal/exchange/index.d.ts.map +1 -0
  356. package/dist/internal/exchange/index.js +2 -0
  357. package/dist/internal/exchange/index.js.map +1 -0
  358. package/dist/internal/exchange/providers/uniswap.d.ts +57 -0
  359. package/dist/internal/exchange/providers/uniswap.d.ts.map +1 -0
  360. package/dist/internal/exchange/providers/uniswap.js +553 -0
  361. package/dist/internal/exchange/providers/uniswap.js.map +1 -0
  362. package/dist/internal/funding/Action.d.ts +55 -0
  363. package/dist/internal/funding/Action.d.ts.map +1 -0
  364. package/dist/internal/funding/Action.js +74 -0
  365. package/dist/internal/funding/Action.js.map +1 -0
  366. package/dist/internal/funding/Catalog.d.ts +107 -0
  367. package/dist/internal/funding/Catalog.d.ts.map +1 -0
  368. package/dist/internal/funding/Catalog.js +270 -0
  369. package/dist/internal/funding/Catalog.js.map +1 -0
  370. package/dist/internal/funding/Chain.d.ts +76 -0
  371. package/dist/internal/funding/Chain.d.ts.map +1 -0
  372. package/dist/internal/funding/Chain.js +38 -0
  373. package/dist/internal/funding/Chain.js.map +1 -0
  374. package/dist/internal/funding/Deposit.d.ts +366 -0
  375. package/dist/internal/funding/Deposit.d.ts.map +1 -0
  376. package/dist/internal/funding/Deposit.js +286 -0
  377. package/dist/internal/funding/Deposit.js.map +1 -0
  378. package/dist/internal/funding/DepositAddress.d.ts +345 -0
  379. package/dist/internal/funding/DepositAddress.d.ts.map +1 -0
  380. package/dist/internal/funding/DepositAddress.js +189 -0
  381. package/dist/internal/funding/DepositAddress.js.map +1 -0
  382. package/dist/internal/funding/Evidence.d.ts +52 -0
  383. package/dist/internal/funding/Evidence.d.ts.map +1 -0
  384. package/dist/internal/funding/Evidence.js +314 -0
  385. package/dist/internal/funding/Evidence.js.map +1 -0
  386. package/dist/internal/funding/Provider.d.ts +1186 -0
  387. package/dist/internal/funding/Provider.d.ts.map +1 -0
  388. package/dist/internal/funding/Provider.js +1081 -0
  389. package/dist/internal/funding/Provider.js.map +1 -0
  390. package/dist/internal/funding/Reconciliation.d.ts +113 -0
  391. package/dist/internal/funding/Reconciliation.d.ts.map +1 -0
  392. package/dist/internal/funding/Reconciliation.js +676 -0
  393. package/dist/internal/funding/Reconciliation.js.map +1 -0
  394. package/dist/internal/funding/Route.d.ts +21 -0
  395. package/dist/internal/funding/Route.d.ts.map +1 -0
  396. package/dist/internal/funding/Route.js +5 -0
  397. package/dist/internal/funding/Route.js.map +1 -0
  398. package/dist/internal/funding/Subsidy.d.ts +113 -0
  399. package/dist/internal/funding/Subsidy.d.ts.map +1 -0
  400. package/dist/internal/funding/Subsidy.js +138 -0
  401. package/dist/internal/funding/Subsidy.js.map +1 -0
  402. package/dist/internal/funding/Token.d.ts +41 -0
  403. package/dist/internal/funding/Token.d.ts.map +1 -0
  404. package/dist/internal/funding/Token.js +22 -0
  405. package/dist/internal/funding/Token.js.map +1 -0
  406. package/dist/internal/funding/Transfer.d.ts +643 -0
  407. package/dist/internal/funding/Transfer.d.ts.map +1 -0
  408. package/dist/internal/funding/Transfer.js +332 -0
  409. package/dist/internal/funding/Transfer.js.map +1 -0
  410. package/dist/internal/funding/index.d.ts +13 -0
  411. package/dist/internal/funding/index.d.ts.map +1 -0
  412. package/dist/internal/funding/index.js +13 -0
  413. package/dist/internal/funding/index.js.map +1 -0
  414. package/dist/internal/funding/providers/across.d.ts +21 -0
  415. package/dist/internal/funding/providers/across.d.ts.map +1 -0
  416. package/dist/internal/funding/providers/across.js +117 -0
  417. package/dist/internal/funding/providers/across.js.map +1 -0
  418. package/dist/internal/funding/providers/relay.d.ts +46 -0
  419. package/dist/internal/funding/providers/relay.d.ts.map +1 -0
  420. package/dist/internal/funding/providers/relay.js +464 -0
  421. package/dist/internal/funding/providers/relay.js.map +1 -0
  422. package/dist/internal/funding/providers/rhino.d.ts +15 -0
  423. package/dist/internal/funding/providers/rhino.d.ts.map +1 -0
  424. package/dist/internal/funding/providers/rhino.js +116 -0
  425. package/dist/internal/funding/providers/rhino.js.map +1 -0
  426. package/dist/internal/funding/providers/squid.d.ts +19 -0
  427. package/dist/internal/funding/providers/squid.d.ts.map +1 -0
  428. package/dist/internal/funding/providers/squid.js +120 -0
  429. package/dist/internal/funding/providers/squid.js.map +1 -0
  430. package/dist/internal/funding/providers/symbiosis.d.ts +20 -0
  431. package/dist/internal/funding/providers/symbiosis.d.ts.map +1 -0
  432. package/dist/internal/funding/providers/symbiosis.js +176 -0
  433. package/dist/internal/funding/providers/symbiosis.js.map +1 -0
  434. package/dist/internal/index.d.ts +5 -1
  435. package/dist/internal/index.d.ts.map +1 -1
  436. package/dist/internal/index.js +5 -1
  437. package/dist/internal/index.js.map +1 -1
  438. package/dist/internal/webhookDestinations/url.js +61 -57
  439. package/dist/internal/webhookDestinations/url.js.map +1 -1
  440. package/dist/providers/index.d.ts +43 -0
  441. package/dist/providers/index.d.ts.map +1 -0
  442. package/dist/providers/index.js +19 -0
  443. package/dist/providers/index.js.map +1 -0
  444. package/package.json +9 -4
  445. package/src/ApiKeys.test.ts +11 -7
  446. package/src/ApiKeys.ts +37 -9
  447. package/src/App.test.ts +85 -10
  448. package/src/App.ts +224 -137
  449. package/src/Assets.ts +29 -4
  450. package/src/Client.test-d.ts +650 -30
  451. package/src/Scope.test.ts +19 -0
  452. package/src/Scope.ts +28 -11
  453. package/src/Webhooks.test.ts +25 -0
  454. package/src/Webhooks.ts +1 -1
  455. package/src/admin/App.test.ts +9 -2
  456. package/src/admin/App.ts +32 -9
  457. package/src/admin/apps/api-keys.test.ts +167 -23
  458. package/src/admin/apps/api-keys.ts +166 -28
  459. package/src/admin/apps/earn-vaults.test.ts +338 -0
  460. package/src/admin/apps/earn-vaults.ts +572 -0
  461. package/src/admin/apps/scopes.test.ts +16 -1
  462. package/src/admin/ui/plugin.ts +2 -2
  463. package/src/admin/ui/src/components/EarnVaultForm.tsx +137 -0
  464. package/src/admin/ui/src/components/MobileProfile.tsx +2 -2
  465. package/src/admin/ui/src/components/Page.tsx +1 -1
  466. package/src/admin/ui/src/components/ThemeToggle.tsx +1 -1
  467. package/src/admin/ui/src/lib/api-keys.ts +37 -7
  468. package/src/admin/ui/src/lib/client.ts +1 -1
  469. package/src/admin/ui/src/lib/config.ts +1 -1
  470. package/src/admin/ui/src/lib/early-access.ts +8 -9
  471. package/src/admin/ui/src/lib/earn-vaults.ts +207 -0
  472. package/src/admin/ui/src/lib/format.ts +13 -0
  473. package/src/admin/ui/src/lib/organizations.test.ts +14 -4
  474. package/src/admin/ui/src/lib/organizations.ts +7 -1
  475. package/src/admin/ui/src/lib/response.ts +22 -0
  476. package/src/admin/ui/src/lib/scopes.test.ts +19 -11
  477. package/src/admin/ui/src/lib/scopes.ts +28 -7
  478. package/src/admin/ui/src/lib/verified-tokens.ts +10 -9
  479. package/src/admin/ui/src/routeTree.gen.ts +70 -7
  480. package/src/admin/ui/src/router.tsx +2 -2
  481. package/src/admin/ui/src/routes/__root.tsx +9 -8
  482. package/src/admin/ui/src/routes/api-keys.tsx +475 -64
  483. package/src/admin/ui/src/routes/early-access.tsx +5 -12
  484. package/src/admin/ui/src/routes/earn.vaults.tsx +348 -0
  485. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +154 -0
  486. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +190 -0
  487. package/src/admin/ui/src/routes/organizations.tsx +4 -7
  488. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +56 -54
  489. package/src/admin/ui/src/routes/verified-tokens.tsx +4 -4
  490. package/src/admin/ui/vite.config.ts +4 -1
  491. package/src/admin/ui.generated.ts +189 -95
  492. package/src/analytics/Analytics.test.ts +69 -10
  493. package/src/analytics/Analytics.ts +20 -1
  494. package/src/analytics/tables/requestEvents.ts +79 -37
  495. package/src/apps/Zones.test.ts +33 -0
  496. package/src/apps/Zones.ts +40 -0
  497. package/src/apps/composition.test.ts +84 -1
  498. package/src/apps/data/App.test.ts +38 -9
  499. package/src/apps/data/App.ts +96 -33
  500. package/src/apps/data/FxOracle.ts +1 -1
  501. package/src/apps/data/index.ts +0 -1
  502. package/src/apps/data/routes/activities.test.ts +82 -6
  503. package/src/apps/data/routes/activities.ts +131 -71
  504. package/src/apps/data/routes/balances.test.ts +50 -37
  505. package/src/apps/data/routes/balances.ts +5 -5
  506. package/src/apps/data/routes/blocks.test.ts +2 -0
  507. package/src/apps/data/routes/coingecko.test.ts +22 -0
  508. package/src/apps/data/routes/coingecko.ts +84 -48
  509. package/src/apps/data/routes/earn.test.ts +1108 -0
  510. package/src/apps/data/routes/earn.ts +1391 -0
  511. package/src/apps/data/routes/exchanges.test.ts +82 -33
  512. package/src/apps/data/routes/exchanges.ts +842 -227
  513. package/src/apps/data/routes/fee-amm.test.ts +4 -6
  514. package/src/apps/data/routes/fee-amm.ts +69 -12
  515. package/src/apps/data/routes/funding.test.ts +2712 -221
  516. package/src/apps/data/routes/funding.ts +1604 -387
  517. package/src/apps/data/routes/indexer.test.ts +43 -34
  518. package/src/apps/data/routes/indexer.ts +19 -2
  519. package/src/apps/data/routes/receipts.test.ts +5 -3
  520. package/src/apps/data/routes/receipts.ts +13 -11
  521. package/src/apps/data/routes/rpc.test.ts +446 -28
  522. package/src/apps/data/routes/rpc.ts +243 -25
  523. package/src/apps/data/routes/tokenlist.test.ts +15 -0
  524. package/src/apps/data/routes/tokenlist.ts +88 -22
  525. package/src/apps/data/routes/tokens.ts +262 -86
  526. package/src/apps/data/routes/transactions.test.ts +2 -0
  527. package/src/apps/data/routes/transactions.ts +77 -42
  528. package/src/apps/data/routes/transfers.test.ts +166 -4
  529. package/src/apps/data/routes/transfers.ts +216 -78
  530. package/src/apps/data/routes/valuation.test.ts +62 -9
  531. package/src/apps/data/routes/valuation.ts +2 -2
  532. package/src/apps/data/routes/verified-tokens.test.ts +51 -0
  533. package/src/apps/data/routes/verified-tokens.ts +52 -15
  534. package/src/apps/data/routes/webhooks.test.ts +432 -33
  535. package/src/apps/data/routes/webhooks.ts +189 -79
  536. package/src/apps/data/routes/zones.test.ts +473 -0
  537. package/src/apps/data/routes/zones.ts +338 -0
  538. package/src/apps/docs/reference.ts +8 -6
  539. package/src/apps/index.ts +2 -1
  540. package/src/apps/management/Billing.test.ts +29 -0
  541. package/src/apps/management/Billing.ts +23 -0
  542. package/src/apps/management/Error.ts +12 -0
  543. package/src/apps/management/routes/api-keys.test.ts +5 -3
  544. package/src/apps/management/routes/api-keys.ts +2 -9
  545. package/src/apps/management/routes/invitations.ts +4 -11
  546. package/src/apps/management/routes/orgs.ts +2 -9
  547. package/src/apps/management/routes/scopes.test.ts +7 -2
  548. package/src/apps/management/routes/scopes.ts +2 -2
  549. package/src/apps/management/routes/webhooks.test.ts +6 -1
  550. package/src/apps/management/routes/webhooks.ts +15 -3
  551. package/src/apps/mpp/App.ts +276 -29
  552. package/src/apps/mpp/Mpp.test.ts +631 -26
  553. package/src/apps/mpp/Mpp.ts +0 -42
  554. package/src/apps/mpp/internal/Adapter.ts +108 -3
  555. package/src/apps/mpp/internal/Error.test.ts +33 -0
  556. package/src/apps/mpp/internal/Error.ts +44 -6
  557. package/src/apps/mpp/internal/Idempotency.test.ts +213 -0
  558. package/src/apps/mpp/internal/Idempotency.ts +59 -5
  559. package/src/apps/mpp/internal/Policy.test.ts +122 -0
  560. package/src/apps/mpp/internal/Policy.ts +98 -0
  561. package/src/apps/mpp/internal/ScreenManager.test.ts +68 -0
  562. package/src/apps/mpp/internal/ScreenManager.ts +41 -0
  563. package/src/apps/mpp/internal/Screening.ts +40 -3
  564. package/src/apps/mpp/internal/Sponsorship.ts +144 -0
  565. package/src/apps/mpp/internal/Utils.ts +30 -0
  566. package/src/apps/relay/App.test.ts +495 -64
  567. package/src/apps/relay/App.ts +234 -24
  568. package/src/apps/relay/Sponsorships.test.ts +51 -0
  569. package/src/apps/relay/Sponsorships.ts +19 -7
  570. package/src/db/Db.ts +439 -0
  571. package/src/db/Schema.ts +325 -2
  572. package/src/db/tables/earnVaults.test.ts +185 -0
  573. package/src/db/tables/earnVaults.ts +151 -0
  574. package/src/db/tables/fundingCatalog.test.ts +108 -0
  575. package/src/db/tables/fundingCatalog.ts +157 -0
  576. package/src/db/tables/fundingDepositAddresses.test.ts +580 -0
  577. package/src/db/tables/fundingDepositAddresses.ts +376 -0
  578. package/src/db/tables/fundingDeposits.test.ts +261 -0
  579. package/src/db/tables/fundingDeposits.ts +229 -0
  580. package/src/db/tables/fundingIdempotency.test.ts +182 -0
  581. package/src/db/tables/fundingIdempotency.ts +180 -0
  582. package/src/db/tables/fundingTransferEvents.ts +28 -0
  583. package/src/db/tables/fundingTransferTransactions.test.ts +69 -0
  584. package/src/db/tables/fundingTransferTransactions.ts +37 -0
  585. package/src/db/tables/fundingTransfers.test.ts +89 -0
  586. package/src/db/tables/fundingTransfers.ts +153 -0
  587. package/src/db/tables/organizations.test.ts +88 -0
  588. package/src/db/tables/organizations.ts +42 -1
  589. package/src/db/tables/projects.ts +16 -0
  590. package/src/db/tables/requestUsage.ts +23 -0
  591. package/src/db/tables/sponsoredTransactions.test.ts +52 -2
  592. package/src/db/tables/sponsoredTransactions.ts +18 -6
  593. package/src/db/tables/users.ts +16 -0
  594. package/src/db/tables/verifiedTokens.ts +19 -14
  595. package/src/db/tables/webhookSubscriptions.ts +58 -3
  596. package/src/handlers/relay.test.ts +2 -0
  597. package/src/handlers/relay.ts +95 -99
  598. package/src/internal/Auth.test.ts +48 -0
  599. package/src/internal/Auth.ts +61 -2
  600. package/src/internal/Cache.ts +13 -9
  601. package/src/internal/Cursor.test.ts +2 -2
  602. package/src/internal/Cursor.ts +1 -1
  603. package/src/internal/EarnRates.test.ts +125 -0
  604. package/src/internal/EarnRates.ts +409 -0
  605. package/src/internal/EarnVaults.test.ts +195 -0
  606. package/src/internal/EarnVaults.ts +876 -0
  607. package/src/internal/EdgeCache.test.ts +37 -5
  608. package/src/internal/EdgeCache.ts +39 -7
  609. package/src/internal/Id.ts +14 -0
  610. package/src/internal/Idempotency.test.ts +109 -0
  611. package/src/internal/Idempotency.ts +237 -0
  612. package/src/internal/Log.test-d.ts +41 -8
  613. package/src/internal/Log.test.ts +189 -8
  614. package/src/internal/Log.ts +124 -17
  615. package/src/internal/MetricSink.test.ts +244 -4
  616. package/src/internal/MetricSink.ts +51 -1
  617. package/src/internal/OpenApi.ts +3 -0
  618. package/src/internal/Provider.test.ts +17 -0
  619. package/src/internal/Provider.ts +17 -0
  620. package/src/internal/Schema.test.ts +13 -0
  621. package/src/internal/Schema.ts +41 -24
  622. package/src/internal/Store.test.ts +25 -0
  623. package/src/internal/Store.ts +46 -0
  624. package/src/internal/Tidx.local.test.ts +78 -3
  625. package/src/internal/Tidx.test.ts +212 -18
  626. package/src/internal/Tidx.ts +112 -32
  627. package/src/internal/VerifiedTokens.test.ts +15 -0
  628. package/src/internal/Viem.test.ts +170 -17
  629. package/src/internal/Viem.ts +111 -28
  630. package/src/internal/WebhookDestination.ts +25 -23
  631. package/src/internal/Webhooks.test.ts +59 -0
  632. package/src/internal/Webhooks.ts +34 -10
  633. package/src/internal/exchange/Provider.test.ts +216 -0
  634. package/src/internal/exchange/Provider.ts +326 -0
  635. package/src/internal/exchange/index.test.ts +6 -0
  636. package/src/internal/exchange/index.ts +1 -0
  637. package/src/internal/exchange/providers/uniswap.test.ts +122 -0
  638. package/src/internal/exchange/providers/uniswap.ts +682 -0
  639. package/src/internal/funding/Action.test.ts +138 -0
  640. package/src/internal/funding/Action.ts +117 -0
  641. package/src/internal/funding/Catalog.test.ts +311 -0
  642. package/src/internal/funding/Catalog.ts +347 -0
  643. package/src/internal/funding/Chain.test.ts +79 -0
  644. package/src/internal/funding/Chain.ts +120 -0
  645. package/src/internal/funding/Deposit.test.ts +26 -0
  646. package/src/internal/funding/Deposit.ts +453 -0
  647. package/src/internal/funding/DepositAddress.test.ts +18 -0
  648. package/src/internal/funding/DepositAddress.ts +312 -0
  649. package/src/internal/funding/Evidence.test.ts +297 -0
  650. package/src/internal/funding/Evidence.ts +430 -0
  651. package/src/internal/funding/Provider.test.ts +1328 -0
  652. package/src/internal/funding/Provider.ts +1796 -0
  653. package/src/internal/funding/Reconciliation.local.test.ts +504 -0
  654. package/src/internal/funding/Reconciliation.test.ts +2020 -0
  655. package/src/internal/funding/Reconciliation.ts +930 -0
  656. package/src/internal/funding/Route.test.ts +66 -0
  657. package/src/internal/funding/Route.ts +29 -0
  658. package/src/internal/funding/Subsidy.local.test.ts +152 -0
  659. package/src/internal/funding/Subsidy.test.ts +75 -0
  660. package/src/internal/funding/Subsidy.ts +260 -0
  661. package/src/internal/funding/Token.test.ts +47 -0
  662. package/src/internal/funding/Token.ts +59 -0
  663. package/src/internal/funding/Transfer.test.ts +369 -0
  664. package/src/internal/funding/Transfer.ts +522 -0
  665. package/src/internal/funding/index.test.ts +20 -0
  666. package/src/internal/funding/index.ts +12 -0
  667. package/src/internal/funding/providers/across.ts +149 -0
  668. package/src/{apps/data/FundingQuoteProviders.test.ts → internal/funding/providers/index.test.ts} +178 -157
  669. package/src/internal/funding/providers/relay.test.ts +474 -0
  670. package/src/internal/funding/providers/relay.ts +559 -0
  671. package/src/internal/funding/providers/rhino.ts +139 -0
  672. package/src/internal/funding/providers/squid.ts +151 -0
  673. package/src/internal/funding/providers/symbiosis.ts +221 -0
  674. package/src/internal/index.test.ts +5 -1
  675. package/src/internal/index.ts +5 -1
  676. package/src/internal/webhookDestinations/url.ts +49 -45
  677. package/src/providers/index.test.ts +14 -0
  678. package/src/providers/index.ts +54 -0
  679. package/dist/apps/data/FundingQuoteProviders.d.ts +0 -174
  680. package/dist/apps/data/FundingQuoteProviders.d.ts.map +0 -1
  681. package/dist/apps/data/FundingQuoteProviders.js +0 -775
  682. package/dist/apps/data/FundingQuoteProviders.js.map +0 -1
  683. package/dist/internal/FundingQuotes.d.ts +0 -864
  684. package/dist/internal/FundingQuotes.d.ts.map +0 -1
  685. package/dist/internal/FundingQuotes.js +0 -672
  686. package/dist/internal/FundingQuotes.js.map +0 -1
  687. package/src/apps/data/FundingQuoteProviders.ts +0 -1043
  688. package/src/internal/FundingQuotes.test.ts +0 -456
  689. package/src/internal/FundingQuotes.ts +0 -944
@@ -1,6 +1,7 @@
1
1
  import { Hono, type Context } from 'hono'
2
2
  import { AbiEvent, AbiParameters } from 'ox'
3
3
  import { type Address, ContractFunctionExecutionError } from 'viem'
4
+ import { Abis } from 'viem/tempo'
4
5
  import * as z from 'zod/mini'
5
6
 
6
7
  import type * as App from '../../../App.js'
@@ -1176,6 +1177,148 @@ export declare namespace resolveToken {
1176
1177
  type Options = getToken.Options
1177
1178
  }
1178
1179
 
1180
+ /** Resolves unique token addresses with RPC metadata and requested curated fields. */
1181
+ export async function resolveTokens(
1182
+ c: Context<App.Environment>,
1183
+ options: resolveTokens.Options,
1184
+ ): Promise<resolveTokens.ReturnType> {
1185
+ const { chainId } = options
1186
+ const addresses = Array.from(
1187
+ new Set(options.addresses.map((address) => Schema.Address.parse(address.toLowerCase()))),
1188
+ )
1189
+ if (addresses.length === 0) return new Map()
1190
+
1191
+ const includeLogoUri = options.include.includes('token.logoUri')
1192
+ const includeVerified = options.include.includes('token.verified')
1193
+ const resolveMetadata = () =>
1194
+ Promise.all(
1195
+ addresses.map(async (address) => {
1196
+ const metadata = options.metadata?.get(address)
1197
+ if (metadata) return [address, metadata] as const
1198
+ try {
1199
+ return [address, await getTokenMetadata(c, { address, chainId })] as const
1200
+ } catch {
1201
+ return [address, undefined] as const
1202
+ }
1203
+ }),
1204
+ )
1205
+ const [snapshot, metadataByAddress, logoByAddress] = await Promise.all([
1206
+ options.snapshot ??
1207
+ (includeLogoUri || includeVerified
1208
+ ? VerifiedTokens.snapshot(c, chainId).catch(() => undefined)
1209
+ : undefined),
1210
+ addresses.every((address) => options.metadata?.has(address))
1211
+ ? resolveMetadata()
1212
+ : Timing.time(c, 'token_metadata', resolveMetadata),
1213
+ includeLogoUri
1214
+ ? Timing.time(c, 'token_logo', () =>
1215
+ Promise.all(
1216
+ addresses.map(
1217
+ async (address) =>
1218
+ [
1219
+ address,
1220
+ await getTokenLogo(c, { address, chainId }).catch(() => undefined),
1221
+ ] as const,
1222
+ ),
1223
+ ),
1224
+ )
1225
+ : [],
1226
+ ])
1227
+
1228
+ const logos = new Map(logoByAddress)
1229
+ const metadataMap = new Map(metadataByAddress)
1230
+ const onchainLogos = new Map(
1231
+ includeLogoUri
1232
+ ? await Timing.time(c, 'token_logo_uri', () =>
1233
+ Promise.all(
1234
+ addresses
1235
+ .filter(
1236
+ (address) =>
1237
+ !logos.get(address) &&
1238
+ !snapshot?.byAddress.get(address)?.logoUri &&
1239
+ !metadataMap.get(address)?.logoUri,
1240
+ )
1241
+ .map(
1242
+ async (address) =>
1243
+ [
1244
+ address,
1245
+ await getTokenLogoUri(c, { address, chainId }).catch(() => undefined),
1246
+ ] as const,
1247
+ ),
1248
+ ),
1249
+ )
1250
+ : [],
1251
+ )
1252
+ const tokens: resolveTokens.ReturnType = new Map()
1253
+ for (const [address, metadata] of metadataByAddress) {
1254
+ if (!metadata) continue
1255
+ tokens.set(address, {
1256
+ address,
1257
+ currency: metadata.currency,
1258
+ decimals: metadata.decimals,
1259
+ id: address,
1260
+ logoUri: includeLogoUri
1261
+ ? (logos.get(address) ??
1262
+ snapshot?.byAddress.get(address)?.logoUri ??
1263
+ metadata.logoUri ??
1264
+ onchainLogos.get(address))
1265
+ : undefined,
1266
+ name: metadata.name,
1267
+ symbol: metadata.symbol,
1268
+ verified: includeVerified ? snapshot?.byAddress.has(address) : undefined,
1269
+ })
1270
+ }
1271
+ return tokens
1272
+ }
1273
+
1274
+ export declare namespace resolveTokens {
1275
+ /** Options for resolving page token metadata. */
1276
+ export type Options = {
1277
+ /** Token addresses to resolve. */
1278
+ addresses: readonly z.output<typeof Schema.Address>[]
1279
+ /** Tempo chain id. */
1280
+ chainId: z.output<typeof Schema.ChainId>
1281
+ /** Curated token fields to include. */
1282
+ include: readonly ('token.logoUri' | 'token.verified')[]
1283
+ /** Token metadata already resolved by the enclosing resource. */
1284
+ metadata?: ReadonlyMap<z.output<typeof Schema.Address>, Metadata> | undefined
1285
+ /** Preloaded verified-token state. */
1286
+ snapshot?: VerifiedTokens.Snapshot | undefined
1287
+ }
1288
+
1289
+ /** Token metadata required by compact references. */
1290
+ export type Metadata = Pick<
1291
+ z.output<typeof schema.Token>,
1292
+ 'currency' | 'decimals' | 'logoUri' | 'name' | 'symbol'
1293
+ >
1294
+
1295
+ /** Token metadata keyed by lowercase address. */
1296
+ export type ReturnType = Map<z.output<typeof Schema.Address>, Token>
1297
+
1298
+ /** Token metadata with opt-in curated fields. */
1299
+ export type Token = Omit<z.output<typeof schema.Token>, 'verified'> & {
1300
+ /** Whether the token is curated, when requested. */
1301
+ verified?: boolean | undefined
1302
+ }
1303
+ }
1304
+
1305
+ function getTokenLogoUri(c: Context<App.Environment>, options: getTokenMetadata.Options) {
1306
+ const { address, chainId } = options
1307
+ return Store.memoize(
1308
+ async () =>
1309
+ (await c.get('getClient')(chainId).readContract({
1310
+ abi: Abis.tip20,
1311
+ address,
1312
+ functionName: 'logoURI',
1313
+ })) || null,
1314
+ {
1315
+ key: `token:v1:${chainId}:${address}:logo-uri`,
1316
+ store: c.get('store'),
1317
+ ttl: Ttl.minutes(1),
1318
+ },
1319
+ ).then((logoUri) => logoUri ?? undefined)
1320
+ }
1321
+
1179
1322
  /**
1180
1323
  * Resolves a token's on-chain metadata (`name`/`symbol`/`decimals`/`currency`/
1181
1324
  * `totalSupply`) via a single `token.getMetadata` RPC, memoized under the shared
@@ -1190,7 +1333,6 @@ export function getTokenMetadata(c: Context<App.Environment>, options: getTokenM
1190
1333
 
1191
1334
  return Store.memoize(
1192
1335
  async () => {
1193
- // TODO(viem): Flatten concurrent metadata multicalls before encoding aggregate3 calldata.
1194
1336
  const fresh = await getClient(chainId).token.getMetadata({ token: address as Address })
1195
1337
  return {
1196
1338
  currency: fresh.currency,
@@ -1319,7 +1461,10 @@ async function fetchExternalLogo(uri: string): Promise<fetchTokenLogo.Logo | und
1319
1461
  if (!url) return undefined
1320
1462
  if (url.protocol !== 'http:' && url.protocol !== 'https:' && url.protocol !== 'data:')
1321
1463
  return undefined
1322
- if ((url.protocol === 'http:' || url.protocol === 'https:') && isBlockedHost(url.hostname))
1464
+ if (
1465
+ (url.protocol === 'http:' || url.protocol === 'https:') &&
1466
+ ExternalLogo.isBlockedHost(url.hostname)
1467
+ )
1323
1468
  return undefined
1324
1469
 
1325
1470
  const response = await fetch(url, {
@@ -1378,26 +1523,28 @@ async function readBodyWithLimit(
1378
1523
  return buffer
1379
1524
  }
1380
1525
 
1381
- // Blocks hosts that resolve to loopback/private/link-local space, including the
1382
- // cloud metadata IP. Hostnames that are not literal IPs are allowed (we cannot
1383
- // resolve DNS here); the `redirect: 'manual'` policy in `fetchExternalLogo`
1384
- // prevents a public host from bouncing us into private space.
1385
- function isBlockedHost(hostname: string): boolean {
1386
- const host = hostname.toLowerCase().replace(/^\[|\]$/g, '')
1387
- if (host === '' || host === 'localhost' || host.endsWith('.localhost')) return true
1388
- if (host === '::1' || host === '::') return true
1389
- if (host.startsWith('fc') || host.startsWith('fd') || host.startsWith('fe80:')) return true
1390
- const ipv4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host)
1391
- if (ipv4) {
1392
- const a = Number(ipv4[1])
1393
- const b = Number(ipv4[2])
1394
- if (a === 0 || a === 10 || a === 127) return true
1395
- if (a === 169 && b === 254) return true
1396
- if (a === 172 && b >= 16 && b <= 31) return true
1397
- if (a === 192 && b === 168) return true
1398
- if (a === 100 && b >= 64 && b <= 127) return true
1526
+ namespace ExternalLogo {
1527
+ // Blocks hosts that resolve to loopback/private/link-local space, including the
1528
+ // cloud metadata IP. Hostnames that are not literal IPs are allowed (we cannot
1529
+ // resolve DNS here); `redirect: 'manual'` prevents a public host from bouncing
1530
+ // into private space.
1531
+ export function isBlockedHost(hostname: string): boolean {
1532
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, '')
1533
+ if (host === '' || host === 'localhost' || host.endsWith('.localhost')) return true
1534
+ if (host === '::1' || host === '::') return true
1535
+ if (host.startsWith('fc') || host.startsWith('fd') || host.startsWith('fe80:')) return true
1536
+ const ipv4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host)
1537
+ if (ipv4) {
1538
+ const a = Number(ipv4[1])
1539
+ const b = Number(ipv4[2])
1540
+ if (a === 0 || a === 10 || a === 127) return true
1541
+ if (a === 169 && b === 254) return true
1542
+ if (a === 172 && b >= 16 && b <= 31) return true
1543
+ if (a === 192 && b === 168) return true
1544
+ if (a === 100 && b >= 64 && b <= 127) return true
1545
+ }
1546
+ return false
1399
1547
  }
1400
- return false
1401
1548
  }
1402
1549
 
1403
1550
  async function getTokenLogosByAddress(
@@ -1565,46 +1712,48 @@ function getTransferStats(c: Context<App.Environment>, options: getTransferStats
1565
1712
  const store = c.get('store')
1566
1713
  const tidx = c.get('getTidx')(chainId)
1567
1714
 
1568
- return Store.memoize<getTransferStats.Stats | null>(
1715
+ return Store.memoize<getTransferStats.Stats>(
1569
1716
  async () => {
1570
- try {
1571
- // Lifetime `Transfer` statistics for the token, aggregated over the
1572
- // raw `logs` event stream by emitting contract. The inline query is
1573
- // cast to `string` so TIDX treats it as a dynamic ClickHouse query
1574
- // that needs no event signature for the `logs` table.
1575
- const result = await tidx.fetch({
1576
- chainId,
1577
- engine: 'clickhouse',
1578
- query: `
1579
- SELECT count() AS transfer_count, min(block_timestamp) AS first_at, max(block_timestamp) AS last_at
1580
- FROM logs
1581
- WHERE address = '${address}' AND selector = '${transferTopic}'
1582
- ` as string,
1583
- })
1584
- const row = result.rows[0]
1585
- // Persist `null` (not `undefined`) so "no transfer data" survives the
1586
- // cache round-trip without being mistaken for a miss.
1587
- const count = Value.toNumber(row?.['transfer_count'])
1588
- if (count === undefined) return null
1589
- // A zero count comes back with ClickHouse epoch-default (1970)
1590
- // `min`/`max` aggregates; report explicit nulls instead.
1591
- if (count === 0) return { count: 0, firstAt: null, lastAt: null }
1592
- // ClickHouse formats timestamps as naive-UTC `YYYY-MM-DD HH:MM:SS.sss`;
1593
- // `Value.toIsoDateTime` normalizes them to strict ISO 8601 UTC.
1594
- return {
1595
- count,
1596
- firstAt: Value.toIsoDateTime(row?.['first_at']) ?? null,
1597
- lastAt: Value.toIsoDateTime(row?.['last_at']) ?? null,
1598
- }
1599
- } catch {
1600
- // Degrade gracefully when transfer data is unavailable (e.g. the
1601
- // indexer cannot answer the aggregation, or the request is rate
1602
- // limited) so token metadata still resolves.
1603
- return null
1717
+ // Lifetime `Transfer` statistics as three primary-key probes instead of
1718
+ // one full aggregation: `count()` is index-counted and first/last read
1719
+ // in `block_num` order, keeping high-volume tokens under the indexer's
1720
+ // execution cap. The inline query is cast to `string` so TIDX treats it
1721
+ // as a dynamic ClickHouse query that needs no event signature for the
1722
+ // `logs` table.
1723
+ const result = await tidx.fetch({
1724
+ chainId,
1725
+ engine: 'clickhouse',
1726
+ query: `
1727
+ SELECT
1728
+ (SELECT count() FROM logs WHERE address = '${address}' AND selector = '${transferTopic}') AS transfer_count,
1729
+ (SELECT block_timestamp FROM logs WHERE address = '${address}' AND selector = '${transferTopic}' ORDER BY block_num ASC LIMIT 1) AS first_at,
1730
+ (SELECT block_timestamp FROM logs WHERE address = '${address}' AND selector = '${transferTopic}' ORDER BY block_num DESC LIMIT 1) AS last_at
1731
+ ` as string,
1732
+ })
1733
+ const row = result.rows[0]
1734
+ const count = Value.toNumber(row?.['transfer_count'])
1735
+ // A malformed row is an upstream failure; degrade like any other error
1736
+ // rather than caching a bogus value.
1737
+ if (count === undefined) throw new Error('malformed transfer stats row')
1738
+ // Empty first/last probes can render as epoch defaults depending on
1739
+ // engine settings; pin the documented shape for zero-transfer tokens.
1740
+ if (count === 0) return { count: 0, firstAt: null, lastAt: null }
1741
+ // ClickHouse formats timestamps as naive-UTC `YYYY-MM-DD HH:MM:SS.sss`;
1742
+ // `Value.toIsoDateTime` normalizes them to strict ISO 8601 UTC.
1743
+ return {
1744
+ count,
1745
+ firstAt: Value.toIsoDateTime(row?.['first_at']) ?? null,
1746
+ lastAt: Value.toIsoDateTime(row?.['last_at']) ?? null,
1604
1747
  }
1605
1748
  },
1606
1749
  { key: `token:v1:${chainId}:${address}:transfer_stats`, store, ttl: Ttl.minutes(5) },
1607
- )
1750
+ ).catch(() => {
1751
+ // Degrade gracefully so token metadata still resolves. Failures are not
1752
+ // memoized and the degraded response stays out of the response cache, so
1753
+ // the next request retries instead of seeing a blank field for the TTL.
1754
+ Cache.setPolicy(c, Cache.policies.noStore)
1755
+ return null
1756
+ })
1608
1757
  }
1609
1758
 
1610
1759
  declare namespace getTransferStats {
@@ -1628,46 +1777,68 @@ async function getTransferStatsByAddress(
1628
1777
 
1629
1778
  if (addresses.length === 0) return {}
1630
1779
 
1631
- return Store.memoize(
1780
+ return Store.memoize<Record<string, getTransferStats.Stats>>(
1632
1781
  async () => {
1633
- try {
1634
- // Batched form of `getTransferStats` for a page of tokens: one grouped
1635
- // aggregation over the raw `logs` stream instead of N per-token scans.
1636
- // Tokens with no `Transfer` events emit no group and are omitted.
1637
- const result = await tidx.fetch({
1638
- chainId: options.chainId,
1639
- engine: 'clickhouse',
1640
- query: `
1641
- SELECT address, count() AS transfer_count, min(block_timestamp) AS first_at, max(block_timestamp) AS last_at
1642
- FROM logs
1643
- WHERE selector = '${transferTopic}' AND address IN (${addresses.map((address) => `'${address}'`).join(', ')})
1644
- GROUP BY address
1645
- ` as string,
1646
- })
1647
-
1648
- const statsByAddress: Record<string, getTransferStats.Stats> = {}
1649
- for (const row of result.rows) {
1782
+ // Batched form of `getTransferStats`: the same three primary-key probes
1783
+ // per token, stitched with UNION ALL in chunks of three (the TIDX proxy
1784
+ // rejects deeper subquery nesting). Zero-transfer tokens surface
1785
+ // `(0, null, null)` rather than dropping out.
1786
+ const chunks: (typeof addresses)[] = []
1787
+ for (let i = 0; i < addresses.length; i += 3) chunks.push(addresses.slice(i, i + 3))
1788
+
1789
+ const statsByAddress: Record<string, getTransferStats.Stats> = {}
1790
+ // Waves of four chunks in flight: the indexer rejects wide bursts of
1791
+ // concurrent queries, and a 200-token page would otherwise fan out ~67
1792
+ // requests at once.
1793
+ for (let i = 0; i < chunks.length; i += 4) {
1794
+ const results = await Promise.all(
1795
+ chunks.slice(i, i + 4).map((group) =>
1796
+ tidx.fetch({
1797
+ chainId: options.chainId,
1798
+ engine: 'clickhouse',
1799
+ query: group
1800
+ .map(
1801
+ (address) => `
1802
+ SELECT
1803
+ '${address}' AS address,
1804
+ (SELECT count() FROM logs WHERE address = '${address}' AND selector = '${transferTopic}') AS transfer_count,
1805
+ (SELECT block_timestamp FROM logs WHERE address = '${address}' AND selector = '${transferTopic}' ORDER BY block_num ASC LIMIT 1) AS first_at,
1806
+ (SELECT block_timestamp FROM logs WHERE address = '${address}' AND selector = '${transferTopic}' ORDER BY block_num DESC LIMIT 1) AS last_at`,
1807
+ )
1808
+ .join('\n UNION ALL'),
1809
+ }),
1810
+ ),
1811
+ )
1812
+ for (const row of results.flatMap((result) => result.rows)) {
1650
1813
  const address = Schema.Address.safeParse(row['address'])
1651
1814
  const count = Value.toNumber(row['transfer_count'])
1652
1815
  if (!address.success || count === undefined) continue
1653
- statsByAddress[address.data] = {
1654
- count,
1655
- firstAt: Value.toIsoDateTime(row['first_at']) ?? null,
1656
- lastAt: Value.toIsoDateTime(row['last_at']) ?? null,
1657
- }
1816
+ // Empty first/last probes can render as epoch defaults depending on
1817
+ // engine settings; pin the documented shape for zero-transfer tokens.
1818
+ statsByAddress[address.data] =
1819
+ count === 0
1820
+ ? { count: 0, firstAt: null, lastAt: null }
1821
+ : {
1822
+ count,
1823
+ firstAt: Value.toIsoDateTime(row['first_at']) ?? null,
1824
+ lastAt: Value.toIsoDateTime(row['last_at']) ?? null,
1825
+ }
1658
1826
  }
1659
- return statsByAddress
1660
- } catch {
1661
- // Degrade gracefully so the token page still resolves without stats.
1662
- return {}
1663
1827
  }
1828
+ return statsByAddress
1664
1829
  },
1665
1830
  {
1666
1831
  key: `token:v1:${options.chainId}:transfer_stats:${addresses.join(',')}`,
1667
1832
  store,
1668
1833
  ttl: Ttl.minutes(5),
1669
1834
  },
1670
- )
1835
+ ).catch(() => {
1836
+ // Degrade gracefully so the token page still resolves without stats.
1837
+ // Failures are not memoized and the degraded response stays out of the
1838
+ // response cache, so the next request retries.
1839
+ Cache.setPolicy(c, Cache.policies.noStore)
1840
+ return {}
1841
+ })
1671
1842
  }
1672
1843
 
1673
1844
  declare namespace getTransferStatsByAddress {
@@ -1821,6 +1992,8 @@ export async function getTokenCreatedAtByAddress(
1821
1992
  try {
1822
1993
  const result = await tidx.fetch({
1823
1994
  chainId: options.chainId,
1995
+ // TODO: Remove the explicit engine after TIDX 1.0 is released.
1996
+ engine: 'clickhouse',
1824
1997
  query: `
1825
1998
  SELECT token, block_timestamp
1826
1999
  FROM tokencreated
@@ -1916,6 +2089,8 @@ async function getTokenCreatedByAddress(
1916
2089
  // needs no event signature for the `logs` table.
1917
2090
  const result = await tidx.fetch({
1918
2091
  chainId: options.chainId,
2092
+ // TODO: Remove the explicit engine after TIDX 1.0 is released.
2093
+ engine: 'clickhouse',
1919
2094
  query: `
1920
2095
  SELECT topic1, data, block_timestamp
1921
2096
  FROM logs
@@ -2300,7 +2475,8 @@ declare namespace getTokens {
2300
2475
  }
2301
2476
  }
2302
2477
 
2303
- function isTokenNotFound(cause: unknown) {
2478
+ /** Matches metadata-read failures for addresses that are not TIP-20 tokens. */
2479
+ export function isTokenNotFound(cause: unknown) {
2304
2480
  if (cause instanceof ContractFunctionExecutionError) return true
2305
2481
  if (cause instanceof Error && cause.message.includes('invalid tip20 address')) return true
2306
2482
  return false
@@ -1,3 +1,5 @@
1
+ /** @module-tag localnet */
2
+
1
3
  import { Schema } from 'tapimo'
2
4
  import { Hex } from 'ox'
3
5
  import { zeroHash } from 'viem'
@@ -1,3 +1,5 @@
1
+ // TODO(tidx-v1): Restore `scanTransactions` from commit `49ad800` after TIDX v1 ships. Remove the dual fetch, dedupe, sort, and slice.
2
+
1
3
  import { Hono, type Context } from 'hono'
2
4
  import { Hex } from 'ox'
3
5
  import * as z from 'zod/mini'
@@ -10,7 +12,7 @@ import * as OpenApi from '../../../internal/OpenApi.js'
10
12
  import * as Response from '../../../internal/Response.js'
11
13
  import * as Schema from '../../../internal/Schema.js'
12
14
  import * as Store from '../../../internal/Store.js'
13
- import type * as Tidx from '../../../internal/Tidx.js'
15
+ import * as Tidx from '../../../internal/Tidx.js'
14
16
  import * as Timing from '../../../internal/Timing.js'
15
17
  import * as Ttl from '../../../internal/Ttl.js'
16
18
  import * as Value from '../../../internal/Value.js'
@@ -1045,8 +1047,8 @@ export function getTransactions(c: Context<App.Environment>, options: getTransac
1045
1047
  }
1046
1048
 
1047
1049
  /**
1048
- * Context-free core of {@link getTransactions}: builds the `txs` query (with the
1049
- * address-scoped `UNION` planner workaround), applies keyset pagination on
1050
+ * Context-free core of {@link getTransactions}: builds the `txs` query (with
1051
+ * address sides merged in application code), applies keyset pagination on
1050
1052
  * `(block_num, idx)`, and reconstructs each row through the same
1051
1053
  * `toRpcTransaction` → `humanizeTransaction` path the detail endpoint uses. Used
1052
1054
  * by the Hono routes (via {@link getTransactions}, which adds Server-Timing +
@@ -1091,10 +1093,9 @@ export async function scanTransactions(
1091
1093
  // extra row to detect `hasMore` without a separate count query.
1092
1094
  //
1093
1095
  // Build the shared filters once (everything except the address-scope
1094
- // predicate); the `address` filter is special-cased below because the
1095
- // TIDX engine errors out on `(from = X OR to = X) ORDER BY ...` for
1096
- // contracts with non-trivial traffic and an index-friendly `UNION`
1097
- // over the two sides plans cleanly.
1096
+ // predicate); the `address` filter is special-cased below because TIDX
1097
+ // rejects both `(from = X OR to = X)` and the equivalent ordered `UNION`
1098
+ // for some accounts.
1098
1099
  const filters: string[] = []
1099
1100
  if (sender !== undefined) filters.push(`"from" = '${sender}'`)
1100
1101
  if (recipient !== undefined)
@@ -1122,45 +1123,79 @@ export async function scanTransactions(
1122
1123
  ]),
1123
1124
  )
1124
1125
 
1125
- // For address-scoped queries, run one branch per side and `UNION` so
1126
- // each branch can use its own (`from`/`to`) index. The `ORDER BY` and
1127
- // `LIMIT` must live *inside* each branch TIDX's planner crashes on
1128
- // a UNION whose outer query orders by `block_num, idx` for
1129
- // high-traffic contracts (and on the `(from = X OR to = X) ORDER BY`
1130
- // form). Pushing the sort+limit down means each branch returns at
1131
- // most `limit + 1` index-ordered rows, the outer query re-merges,
1132
- // and plain `UNION` dedupes the self-transfer case where
1133
- // `from = to = address`.
1134
- // In the offset lane each branch must over-fetch the full window
1135
- // (`offset + limit + 1` rows) because the skip applies to the merged set:
1136
- // the outer query re-sorts the union and discards the first `offset` rows.
1137
- const sideQuery = (side: 'from' | 'to', addr: string) => {
1138
- const where = [`"${side}" = '${addr}'`, ...filters].join(' AND ')
1139
- return `(SELECT ${transactionColumns} FROM txs WHERE ${where} ORDER BY block_num ${sortDirection}, idx ${sortDirection} LIMIT ${(offset ?? 0) + limit + 1})`
1126
+ // Address-scoped queries run each side independently so each request uses one
1127
+ // index and no SQL compound scan. Each side over-fetches the full positional
1128
+ // window because the offset applies after the two result sets are merged.
1129
+ const queryLimit = address === undefined ? limit + 1 : (offset ?? 0) + limit + 1
1130
+ const skip = address === undefined && offset !== undefined ? ` OFFSET ${offset}` : ''
1131
+ const filtered =
1132
+ address !== undefined ||
1133
+ sender !== undefined ||
1134
+ recipient !== undefined ||
1135
+ feePayer !== undefined ||
1136
+ feeToken !== undefined
1137
+ const fetchRows = async (where: readonly string[]) => {
1138
+ try {
1139
+ return await tidx.fetch({
1140
+ chainId,
1141
+ // Raw-table query (no signature-decoded CTE), so the inline SQL is cast
1142
+ // to `string`.
1143
+ query: `
1144
+ SELECT ${transactionColumns}
1145
+ FROM txs
1146
+ ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}
1147
+ ORDER BY block_num ${sortDirection}, idx ${sortDirection}
1148
+ LIMIT ${queryLimit}${skip}
1149
+ ` as string,
1150
+ })
1151
+ } catch (error) {
1152
+ // Planner mis-selectivity turns these top-N scans into a block-ordered
1153
+ // walk that times out when matches sit far from the scan boundary;
1154
+ // `block_num + 0` blocks that walk, forcing the filter index plus a sort.
1155
+ if (!filtered || !Tidx.isDeterministicError(error)) throw error
1156
+ return await tidx.fetch({
1157
+ chainId,
1158
+ // Raw-table query (no signature-decoded CTE), so the inline SQL is cast
1159
+ // to `string`.
1160
+ query: `
1161
+ SELECT ${transactionColumns}
1162
+ FROM txs
1163
+ ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}
1164
+ ORDER BY block_num + 0 ${sortDirection}, idx ${sortDirection}
1165
+ LIMIT ${queryLimit}${skip}
1166
+ ` as string,
1167
+ })
1168
+ }
1140
1169
  }
1141
- const skip = offset !== undefined ? ` OFFSET ${offset}` : ''
1142
- const query =
1143
- address !== undefined
1144
- ? `
1145
- ${sideQuery('from', address)}
1146
- UNION
1147
- ${sideQuery('to', address)}
1148
- ORDER BY block_num ${sortDirection}, idx ${sortDirection}
1149
- LIMIT ${limit + 1}${skip}
1150
- `
1151
- : `
1152
- SELECT ${transactionColumns}
1153
- FROM txs
1154
- ${filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : ''}
1155
- ORDER BY block_num ${sortDirection}, idx ${sortDirection}
1156
- LIMIT ${limit + 1}${skip}
1157
- `
1158
-
1159
- const result = await tidx.fetch({ chainId, query: query as string })
1170
+
1171
+ const rows = await (async () => {
1172
+ if (address === undefined) return (await fetchRows(filters)).rows
1173
+
1174
+ const [from, to] = await Promise.all([
1175
+ fetchRows([`"from" = '${address}'`, ...filters]),
1176
+ fetchRows([`"to" = '${address}'`, ...filters]),
1177
+ ])
1178
+ const seen = new Set<string>()
1179
+ return [...from.rows, ...to.rows]
1180
+ .filter((row) => {
1181
+ const hash = Value.toText(row['hash'])?.toLowerCase()
1182
+ if (!hash) return true
1183
+ if (seen.has(hash)) return false
1184
+ seen.add(hash)
1185
+ return true
1186
+ })
1187
+ .sort((a, b) => {
1188
+ const block = (Value.toNumber(a['block_num']) ?? 0) - (Value.toNumber(b['block_num']) ?? 0)
1189
+ const index = (Value.toNumber(a['idx']) ?? 0) - (Value.toNumber(b['idx']) ?? 0)
1190
+ const order = block === 0 ? index : block
1191
+ return sortDirection === 'ASC' ? order : -order
1192
+ })
1193
+ .slice(offset ?? 0, (offset ?? 0) + limit + 1)
1194
+ })()
1160
1195
 
1161
1196
  // The next page anchors below the last fetched row's `(block, idx)`.
1162
1197
  const page = Cursor.paginate({
1163
- rows: result.rows,
1198
+ rows,
1164
1199
  limit,
1165
1200
  key: (row) => {
1166
1201
  const block = Value.toNumber(row['block_num'])