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,3 +1,7 @@
1
+ import { ZoneRpcAuthentication } from 'ox/tempo'
2
+ import { defineChain, type Chain } from 'viem'
3
+ import { tempoTestnet } from 'viem/tempo/chains'
4
+
1
5
  import type * as Auth from './Auth.js'
2
6
  import * as Viem from './Viem.js'
3
7
 
@@ -11,6 +15,21 @@ const apiKeyPrincipal: Auth.Principal = {
11
15
  orgId: 'org_test',
12
16
  type: 'api_key',
13
17
  }
18
+ const zone = defineChain({
19
+ ...tempoTestnet,
20
+ contracts: {
21
+ ...tempoTestnet.contracts,
22
+ messenger: { address: '0x0000000000000000000000000000000000000001' },
23
+ portal: { address: '0x0000000000000000000000000000000000000002' },
24
+ },
25
+ id: 421_700_001,
26
+ name: 'Zone E',
27
+ rpcUrls: {
28
+ default: { http: ['https://zone.rpc.test'] },
29
+ internal: { http: ['https://internal.zone.rpc.test'] },
30
+ },
31
+ sourceId: tempoTestnet.id,
32
+ }) satisfies Chain
14
33
 
15
34
  describe('isMainnet', () => {
16
35
  test('is true only for the mainnet chain id', () => {
@@ -24,15 +43,41 @@ describe('isMainnet', () => {
24
43
  })
25
44
  })
26
45
 
27
- describe('resolve', () => {
46
+ describe('configuredChainIds', () => {
47
+ test('returns ids from object and serialized URL maps', () => {
48
+ expect(Viem.configuredChainIds({ 31_318: 'https://nextfork.tidx.test' })).toEqual([31_318])
49
+ expect(
50
+ Viem.configuredChainIds(
51
+ JSON.stringify({
52
+ 31_318: 'https://nextfork.tidx.test',
53
+ 421_700_002: 'https://zone.tidx.test',
54
+ }),
55
+ ),
56
+ ).toEqual([31_318, 421_700_002])
57
+ })
58
+
59
+ test('returns no ids for shared URLs and dynamic resolvers', () => {
60
+ expect(Viem.configuredChainIds('https://tidx.test')).toEqual([])
61
+ expect(Viem.configuredChainIds(() => 'https://tidx.test')).toEqual([])
62
+ })
63
+
64
+ test('rejects malformed chain-id maps', () => {
65
+ for (const chainId of ['-1', '0', '031318', '0x7a56', '1e3', '9007199254740992', 'devnet'])
66
+ expect(() =>
67
+ Viem.configuredChainIds(JSON.stringify({ [chainId]: 'https://tidx.test' })),
68
+ ).toThrow('Expected a URL or a chain-id-to-URL JSON object.')
69
+ })
70
+ })
71
+
72
+ describe('resolveRpc', () => {
28
73
  test('defaults to the per-chain RPC URL', () => {
29
- expect(Viem.resolve(undefined, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
74
+ expect(Viem.resolveRpc(undefined, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
30
75
  {
31
76
  "basicAuth": undefined,
32
77
  "url": "https://rpc.tempo.xyz",
33
78
  }
34
79
  `)
35
- expect(Viem.resolve(undefined, { chainId: 42431, principal: null })).toMatchInlineSnapshot(`
80
+ expect(Viem.resolveRpc(undefined, { chainId: 42431, principal: null })).toMatchInlineSnapshot(`
36
81
  {
37
82
  "basicAuth": undefined,
38
83
  "url": "https://rpc.testnet.tempo.xyz",
@@ -42,8 +87,8 @@ describe('resolve', () => {
42
87
 
43
88
  test('uses a static config override', () => {
44
89
  expect(
45
- Viem.resolve(
46
- { basicAuth: 'user:pass', url: (chainId) => `https://${chainId}.rpc.test` },
90
+ Viem.resolveRpc(
91
+ { auth: 'user:pass', url: (chainId) => `https://${chainId}.rpc.test` },
47
92
  { chainId: 4217, principal: null },
48
93
  ),
49
94
  ).toMatchInlineSnapshot(`
@@ -54,15 +99,62 @@ describe('resolve', () => {
54
99
  `)
55
100
  })
56
101
 
102
+ test('selects RPC URLs by chain id', () => {
103
+ const rpc = {
104
+ publicZoneUrl: JSON.stringify({ 421_700_001: 'https://public.zone.rpc.test' }),
105
+ url: JSON.stringify({ 4217: 'https://mainnet.rpc.test' }),
106
+ }
107
+
108
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
109
+ {
110
+ "basicAuth": undefined,
111
+ "url": "https://mainnet.rpc.test",
112
+ }
113
+ `)
114
+ expect(Viem.resolveRpc(rpc, { chainId: zone.id, principal: null, zone }))
115
+ .toMatchInlineSnapshot(`
116
+ {
117
+ "basicAuth": undefined,
118
+ "publicZoneUrl": "https://public.zone.rpc.test",
119
+ "url": "https://internal.zone.rpc.test",
120
+ }
121
+ `)
122
+ })
123
+
124
+ test('selects auth and scheme by chain id', () => {
125
+ const rpc = { auth: { 4217: 'mainnet:secret', 42431: 'testnet-token' } }
126
+
127
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null }).basicAuth).toBe(
128
+ 'mainnet:secret',
129
+ )
130
+ expect(Viem.resolveRpc(rpc, { chainId: 42431, principal: null }).bearerAuth).toBe(
131
+ 'testnet-token',
132
+ )
133
+ expect(
134
+ Viem.resolveRpc(rpc, { chainId: 421_700_001, principal: null }).basicAuth,
135
+ ).toBeUndefined()
136
+ })
137
+
138
+ test('parses serialized Basic auth by chain id', () => {
139
+ const rpc = { auth: JSON.stringify({ 4217: 'mainnet:secret' }) }
140
+
141
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null }).basicAuth).toBe(
142
+ 'mainnet:secret',
143
+ )
144
+ expect(Viem.resolveRpc(rpc, { chainId: 42431, principal: null }).basicAuth).toBeUndefined()
145
+ })
146
+
57
147
  test('the static form ignores the principal', () => {
58
- const rpc = { basicAuth: 'user:pass', url: () => 'https://internal.rpc' }
59
- expect(Viem.resolve(rpc, { chainId: 4217, principal: publicPrincipal })).toMatchInlineSnapshot(`
148
+ const rpc = { auth: 'user:pass', url: () => 'https://internal.rpc' }
149
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: publicPrincipal }))
150
+ .toMatchInlineSnapshot(`
60
151
  {
61
152
  "basicAuth": "user:pass",
62
153
  "url": "https://internal.rpc",
63
154
  }
64
155
  `)
65
- expect(Viem.resolve(rpc, { chainId: 4217, principal: apiKeyPrincipal })).toMatchInlineSnapshot(`
156
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: apiKeyPrincipal }))
157
+ .toMatchInlineSnapshot(`
66
158
  {
67
159
  "basicAuth": "user:pass",
68
160
  "url": "https://internal.rpc",
@@ -71,17 +163,19 @@ describe('resolve', () => {
71
163
  })
72
164
 
73
165
  test('the resolver form routes anonymous callers to a separate upstream', () => {
74
- const rpc = ({ principal }: Viem.resolve.Context) =>
166
+ const rpc = ({ principal }: Viem.resolveRpc.Context) =>
75
167
  principal?.type === 'public'
76
168
  ? { url: 'https://rpc.tempo.xyz' }
77
- : { basicAuth: 'user:pass', url: 'https://internal.rpc' }
78
- expect(Viem.resolve(rpc, { chainId: 4217, principal: publicPrincipal })).toMatchInlineSnapshot(`
169
+ : { auth: 'user:pass', url: 'https://internal.rpc' }
170
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: publicPrincipal }))
171
+ .toMatchInlineSnapshot(`
79
172
  {
80
173
  "basicAuth": undefined,
81
174
  "url": "https://rpc.tempo.xyz",
82
175
  }
83
176
  `)
84
- expect(Viem.resolve(rpc, { chainId: 4217, principal: apiKeyPrincipal })).toMatchInlineSnapshot(`
177
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: apiKeyPrincipal }))
178
+ .toMatchInlineSnapshot(`
85
179
  {
86
180
  "basicAuth": "user:pass",
87
181
  "url": "https://internal.rpc",
@@ -90,11 +184,11 @@ describe('resolve', () => {
90
184
  })
91
185
 
92
186
  test('a null principal (trusted poller) takes the non-public branch', () => {
93
- const rpc = ({ principal }: Viem.resolve.Context) =>
187
+ const rpc = ({ principal }: Viem.resolveRpc.Context) =>
94
188
  principal?.type === 'public'
95
189
  ? { url: 'https://rpc.tempo.xyz' }
96
- : { basicAuth: 'user:pass', url: 'https://internal.rpc' }
97
- expect(Viem.resolve(rpc, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
190
+ : { auth: 'user:pass', url: 'https://internal.rpc' }
191
+ expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
98
192
  {
99
193
  "basicAuth": "user:pass",
100
194
  "url": "https://internal.rpc",
@@ -104,7 +198,7 @@ describe('resolve', () => {
104
198
 
105
199
  test('a resolver that omits url falls back to the built-in public host', () => {
106
200
  const rpc = () => ({})
107
- expect(Viem.resolve(rpc, { chainId: 42431, principal: publicPrincipal }))
201
+ expect(Viem.resolveRpc(rpc, { chainId: 42431, principal: publicPrincipal }))
108
202
  .toMatchInlineSnapshot(`
109
203
  {
110
204
  "basicAuth": undefined,
@@ -112,6 +206,65 @@ describe('resolve', () => {
112
206
  }
113
207
  `)
114
208
  })
209
+
210
+ test('a resolver that omits url falls back to the Zone internal host', () => {
211
+ expect(Viem.resolveRpc(() => ({}), { chainId: zone.id, principal: publicPrincipal, zone }))
212
+ .toMatchInlineSnapshot(`
213
+ {
214
+ "basicAuth": undefined,
215
+ "publicZoneUrl": "https://zone.rpc.test",
216
+ "url": "https://internal.zone.rpc.test",
217
+ }
218
+ `)
219
+ })
220
+ })
221
+
222
+ describe('getClient', () => {
223
+ test('sends inferred Bearer auth', async () => {
224
+ const fetch = vi
225
+ .spyOn(globalThis, 'fetch')
226
+ .mockResolvedValue(Response.json({ id: 1, jsonrpc: '2.0', result: '0x1079' }))
227
+ try {
228
+ const client = Viem.getClient({
229
+ chainId: 4217,
230
+ rpc: { auth: 'rpc-token', url: 'https://internal.rpc.test' },
231
+ })
232
+ await client.getChainId()
233
+
234
+ const [input, init] = fetch.mock.calls[0]!
235
+ const upstream = new Request(input, init)
236
+ expect(upstream.headers.get('authorization')).toBe('Bearer rpc-token')
237
+ } finally {
238
+ fetch.mockRestore()
239
+ }
240
+ })
241
+
242
+ test('does not send RPC auth to a public Zone URL', async () => {
243
+ const fetch = vi
244
+ .spyOn(globalThis, 'fetch')
245
+ .mockResolvedValue(Response.json({ id: 1, jsonrpc: '2.0', result: '0x1079' }))
246
+ try {
247
+ const client = Viem.getClient({
248
+ chainId: zone.id,
249
+ rpc: {
250
+ auth: 'rpc:secret',
251
+ publicZoneUrl: 'https://public.zone.rpc.test',
252
+ url: 'https://internal.rpc.test',
253
+ },
254
+ zone,
255
+ zoneToken: 'zone-token',
256
+ })
257
+ await client.getChainId()
258
+
259
+ const [input, init] = fetch.mock.calls[0]!
260
+ const upstream = new Request(input, init)
261
+ expect(upstream.url).toBe('https://public.zone.rpc.test/')
262
+ expect(upstream.headers.get('authorization')).toBeNull()
263
+ expect(upstream.headers.get(ZoneRpcAuthentication.headerName)).toBe('zone-token')
264
+ } finally {
265
+ fetch.mockRestore()
266
+ }
267
+ })
115
268
  })
116
269
 
117
270
  describe('createGetClient', () => {
@@ -120,7 +273,7 @@ describe('createGetClient', () => {
120
273
  rpc: ({ principal }) =>
121
274
  principal?.type === 'public'
122
275
  ? { url: 'https://rpc.tempo.xyz' }
123
- : { basicAuth: 'user:pass', url: 'https://internal.rpc' },
276
+ : { auth: 'user:pass', url: 'https://internal.rpc' },
124
277
  })
125
278
 
126
279
  expect(getClient(4217, apiKeyPrincipal)).toBe(getClient(4217, apiKeyPrincipal))
@@ -1,12 +1,12 @@
1
1
  import { ZoneRpcAuthentication } from 'ox/tempo'
2
2
  import { createClient, http, publicActions } from 'viem'
3
- import type { Client as core_Client, HttpTransport, PublicActions } from 'viem'
3
+ import type { Chain as core_Chain, Client as core_Client, HttpTransport, PublicActions } from 'viem'
4
4
  import { tempoActions } from 'viem/tempo'
5
5
  import type { TempoActions } from 'viem/tempo'
6
6
  import { tempoMainnet, tempoTestnet } from 'viem/tempo/chains'
7
7
  import type * as z from 'zod/mini'
8
8
 
9
- import type * as Auth from './Auth.js'
9
+ import * as Auth from './Auth.js'
10
10
  import type * as Schema from './Schema.js'
11
11
 
12
12
  /** Known Tempo chains keyed by id, for metadata lookups. */
@@ -41,22 +41,29 @@ export type Chain = Omit<typeof tempoMainnet, 'id'> & { id: ChainId }
41
41
  /** Gets a Tempo viem client for a chain id. */
42
42
  export type GetClient = (chainId?: ChainId) => getClient.ReturnType
43
43
 
44
- /**
45
- * Resolves an RPC URL for a Tempo chain id. May return `undefined` to fall back
46
- * to the built-in {@link url} map (e.g. for a chain the resolver doesn't serve).
47
- */
48
- export type UrlResolver = (chainId: ChainId) => string | undefined
44
+ /** Shared, per-chain, or dynamically resolved RPC URLs. */
45
+ export type UrlResolver =
46
+ | string
47
+ | Record<number, string>
48
+ | ((chainId: ChainId) => string | undefined)
49
+
50
+ /** Returns chain ids declared by a static chain-id-to-URL map. */
51
+ export function configuredChainIds(value: UrlResolver | undefined): number[] {
52
+ const urls = parseUrls(value)
53
+ if (!urls || typeof urls === 'string' || typeof urls === 'function') return []
54
+ return Object.keys(urls).map(Number)
55
+ }
49
56
 
50
57
  /**
51
58
  * Resolves the effective RPC config for a single request.
52
59
  *
53
60
  * Accepts either a static config object or a per-request resolver function. The
54
- * resolver receives a {@link resolve.Context} (`chainId` plus the request
61
+ * resolver receives a {@link resolveRpc.Context} (`chainId` plus the request
55
62
  * `principal`), so callers can route traffic per caller — e.g. send anonymous
56
63
  * (`principal.type === 'public'`) traffic to a separate, no-auth upstream. A
57
64
  * `null` principal denotes a trusted, non-request caller (the scheduled
58
65
  * webhook poller). A missing `url` falls back to the built-in public host map
59
- * ({@link url}); a missing `basicAuth` means no Basic auth is sent.
66
+ * ({@link url}); missing `auth` means no Authorization header is sent.
60
67
  *
61
68
  * Memoization is keyed on the resolved output (see {@link createGetClient} and
62
69
  * {@link Tidx.createGetClient}), not the context, so a resolver may branch on
@@ -64,20 +71,27 @@ export type UrlResolver = (chainId: ChainId) => string | undefined
64
71
  * resolve to the same upstream share a client. Pass the result to
65
72
  * {@link getClient} (or let `getClient` resolve for you) to build a client.
66
73
  */
67
- export function resolve(
74
+ export function resolveRpc(
68
75
  rpc: getClient.Rpc | undefined,
69
- context: resolve.Context,
70
- ): resolve.Resolved {
76
+ context: resolveRpc.Context,
77
+ ): resolveRpc.Resolved {
71
78
  const config = typeof rpc === 'function' ? rpc(context) : rpc
79
+ const auth = Auth.resolveCredential({ chainId: context.chainId, value: config?.auth })
80
+ const publicZoneUrl = context.zone
81
+ ? (resolveUrl(config?.publicZoneUrl, context.chainId) ?? context.zone.rpcUrls.default.http[0])
82
+ : undefined
72
83
  return {
73
- basicAuth: config?.basicAuth,
84
+ ...auth,
85
+ ...(publicZoneUrl ? { publicZoneUrl } : {}),
74
86
  url:
75
- (typeof config?.url === 'function' ? config.url(context.chainId) : config?.url) ??
87
+ resolveUrl(config?.url, context.chainId) ??
88
+ context.zone?.rpcUrls['internal']?.http[0] ??
89
+ context.zone?.rpcUrls.default.http[0] ??
76
90
  url[context.chainId],
77
91
  }
78
92
  }
79
93
 
80
- export declare namespace resolve {
94
+ export declare namespace resolveRpc {
81
95
  /** RPC resolution context. */
82
96
  type Context = {
83
97
  /** Tempo chain id. */
@@ -88,12 +102,18 @@ export declare namespace resolve {
88
102
  * `type: 'public'` principal; authenticated requests a `type: 'api_key'` one.
89
103
  */
90
104
  principal: Auth.Principal | null
105
+ /** Zone chain selected for this request, when applicable. */
106
+ zone?: core_Chain | undefined
91
107
  }
92
108
 
93
109
  /** Resolved RPC config for a single request. */
94
110
  type Resolved = {
95
111
  /** Basic auth credentials, or undefined to send no Basic auth. */
96
112
  basicAuth?: string | undefined
113
+ /** Bearer auth credential, or undefined to send no Bearer auth. */
114
+ bearerAuth?: string | undefined
115
+ /** Public Zone RPC URL that accepts a caller-provided authorization token. */
116
+ publicZoneUrl?: string | undefined
97
117
  /**
98
118
  * Resolved RPC URL, or `undefined` when neither a configured `rpc` nor the
99
119
  * built-in {@link url} map covers the chain (e.g. an unconfigured localnet).
@@ -104,13 +124,27 @@ export declare namespace resolve {
104
124
  }
105
125
 
106
126
  export function getClient(options: getClient.Options): getClient.ReturnType {
107
- const { chainId = defaultChainId, principal = null, rpc, zoneToken } = options
108
- const { basicAuth, url: rpcUrl } = resolve(rpc, { chainId, principal })
127
+ const { chainId = defaultChainId, principal = null, rpc, zone, zoneToken } = options
128
+ const { basicAuth, bearerAuth, publicZoneUrl, url } = resolveRpc(rpc, {
129
+ chainId,
130
+ principal,
131
+ zone,
132
+ })
133
+ const usePublicZoneUrl = Boolean(zoneToken && publicZoneUrl)
134
+ const rpcUrl = usePublicZoneUrl ? publicZoneUrl : url
135
+ // Public Zone endpoints authenticate with the caller's token, never internal RPC credentials.
136
+ const authorization = usePublicZoneUrl
137
+ ? undefined
138
+ : basicAuth
139
+ ? `Basic ${btoa(basicAuth)}`
140
+ : bearerAuth
141
+ ? `Bearer ${bearerAuth}`
142
+ : undefined
109
143
  const fetchOptions =
110
- basicAuth || zoneToken
144
+ authorization || zoneToken
111
145
  ? {
112
146
  headers: {
113
- ...(basicAuth ? { Authorization: `Basic ${btoa(basicAuth)}` } : {}),
147
+ ...(authorization ? { Authorization: authorization } : {}),
114
148
  ...(zoneToken ? { [ZoneRpcAuthentication.headerName]: zoneToken } : {}),
115
149
  },
116
150
  }
@@ -134,16 +168,21 @@ export function getClient(options: getClient.Options): getClient.ReturnType {
134
168
  export function createGetClient(options: createGetClient.Options = {}): createGetClient.ReturnType {
135
169
  const { defaultChainId: defaultChainId_option = defaultChainId, rpc } = options
136
170
  const clients = new Map<string, getClient.ReturnType>()
171
+ const zones = new Map((options.zones ?? []).map((zone) => [zone.id, zone]))
137
172
 
138
173
  return (chainId = defaultChainId_option, principal = null) => {
139
- const { basicAuth, url } = resolve(rpc, { chainId, principal })
140
- const cacheKey = JSON.stringify([url, basicAuth, chainId])
174
+ const { basicAuth, bearerAuth, url } = resolveRpc(rpc, {
175
+ chainId,
176
+ principal,
177
+ zone: zones.get(chainId),
178
+ })
179
+ const cacheKey = JSON.stringify([url, basicAuth, bearerAuth, chainId])
141
180
  const existing = clients.get(cacheKey)
142
181
  if (existing) return existing
143
182
 
144
183
  const client = getClient({
145
184
  chainId,
146
- rpc: { basicAuth, url: () => url },
185
+ rpc: { auth: basicAuth ?? bearerAuth, url: () => url },
147
186
  })
148
187
  clients.set(cacheKey, client)
149
188
  return client
@@ -157,6 +196,8 @@ export declare namespace createGetClient {
157
196
  defaultChainId?: ChainId | undefined
158
197
  /** Tempo RPC options applied to every constructed client. */
159
198
  rpc?: getClient.Rpc | undefined
199
+ /** Zone chains whose internal RPC URLs serve as per-chain defaults. */
200
+ zones?: readonly core_Chain[] | undefined
160
201
  }
161
202
 
162
203
  /** Memoized Tempo client resolver. */
@@ -182,26 +223,68 @@ export declare namespace getClient {
182
223
  principal?: Auth.Principal | null | undefined
183
224
  /** Tempo RPC options. */
184
225
  rpc?: Rpc | undefined
226
+ /** Zone chain metadata used for RPC URL resolution. */
227
+ zone?: core_Chain | undefined
185
228
  /** Zone authorization token forwarded to the RPC node. */
186
229
  zoneToken?: string | undefined
187
230
  }
188
231
 
189
232
  /**
190
233
  * Tempo RPC options: either a static config, or a per-request resolver
191
- * function that receives a {@link resolve.Context} and returns the config to
234
+ * function that receives a {@link resolveRpc.Context} and returns the config to
192
235
  * use (e.g. routing anonymous callers to a public, no-auth RPC).
193
236
  */
194
237
  type Rpc =
195
238
  | {
196
- /** Basic auth credentials for RPC requests. */
197
- basicAuth?: string | undefined
239
+ /** Shared or per-chain RPC credentials. Values containing `:` use Basic auth; others use Bearer auth. */
240
+ auth?: Auth.ChainCredential | undefined
241
+ /** Resolves the public Zone RPC URL used with caller-provided authorization. */
242
+ publicZoneUrl?: UrlResolver | undefined
198
243
  /** Resolves the RPC URL for a Tempo chain id. */
199
244
  url?: UrlResolver | undefined
200
245
  }
201
- | ((context: resolve.Context) => {
202
- /** Basic auth credentials for RPC requests, or undefined for none. */
203
- basicAuth?: string | undefined
246
+ | ((context: resolveRpc.Context) => {
247
+ /** Shared or per-chain RPC credentials, or undefined for none. */
248
+ auth?: Auth.ChainCredential | undefined
249
+ /** Public Zone RPC URL used with caller-provided authorization. */
250
+ publicZoneUrl?: string | undefined
204
251
  /** RPC URL to use; falls back to the built-in public host when omitted. */
205
252
  url?: string | undefined
206
253
  })
207
254
  }
255
+
256
+ /** Resolves a shared or per-chain URL for one chain id. */
257
+ export function resolveUrl(value: UrlResolver | undefined, chainId: ChainId) {
258
+ if (typeof value === 'function') return value(chainId)
259
+ const urls = parseUrls(value)
260
+ if (!urls) return undefined
261
+ if (typeof urls === 'string') return urls
262
+ return urls[chainId]
263
+ }
264
+
265
+ function parseUrls(value: UrlResolver | undefined): Record<number, string> | string | undefined {
266
+ if (!value || typeof value === 'function') return undefined
267
+ const urls =
268
+ typeof value === 'string'
269
+ ? (() => {
270
+ try {
271
+ return JSON.parse(value) as unknown
272
+ } catch {
273
+ return value
274
+ }
275
+ })()
276
+ : value
277
+ if (typeof urls === 'string') return urls
278
+ if (
279
+ !urls ||
280
+ typeof urls !== 'object' ||
281
+ Array.isArray(urls) ||
282
+ Object.keys(urls).some((chainId) => {
283
+ const id = Number(chainId)
284
+ return !Number.isSafeInteger(id) || id <= 0 || String(id) !== chainId
285
+ }) ||
286
+ Object.values(urls).some((url) => typeof url !== 'string')
287
+ )
288
+ throw new Error('Expected a URL or a chain-id-to-URL JSON object.')
289
+ return urls as Record<number, string>
290
+ }
@@ -232,7 +232,7 @@ export const eventTypeHeader = 'tempo-event-type'
232
232
  */
233
233
  export function sign(options: sign.Options): string {
234
234
  const timestamp = options.timestamp ?? Math.floor(Date.now() / 1_000)
235
- const v1 = hmac(options.secret, `${timestamp}.${options.body}`)
235
+ const v1 = Signature.hmac(options.secret, `${timestamp}.${options.body}`)
236
236
  return `t=${timestamp},v1=${v1}`
237
237
  }
238
238
 
@@ -253,15 +253,15 @@ export declare namespace sign {
253
253
  * rejects signatures older than `tolerance` seconds (default 300).
254
254
  */
255
255
  export function verify(options: verify.Options): boolean {
256
- const parsed = parseSignature(options.signature)
256
+ const parsed = Signature.parse(options.signature)
257
257
  if (!parsed) return false
258
258
 
259
259
  const tolerance = options.tolerance ?? 300
260
260
  const now = options.now ?? Math.floor(Date.now() / 1_000)
261
261
  if (Math.abs(now - parsed.timestamp) > tolerance) return false
262
262
 
263
- const expected = hmac(options.secret, `${parsed.timestamp}.${options.body}`)
264
- return timingSafeEqual(expected, parsed.v1)
263
+ const expected = Signature.hmac(options.secret, `${parsed.timestamp}.${options.body}`)
264
+ return Signature.timingSafeEqual(expected, parsed.v1)
265
265
  }
266
266
 
267
267
  export declare namespace verify {
@@ -280,28 +280,30 @@ export declare namespace verify {
280
280
  }
281
281
  }
282
282
 
283
- function hmac(secret: string, message: string): string {
284
- return Hash.hmac256(Hex.fromString(secret), Hex.fromString(message)).slice(2)
285
- }
283
+ namespace Signature {
284
+ export function hmac(secret: string, message: string): string {
285
+ return Hash.hmac256(Hex.fromString(secret), Hex.fromString(message)).slice(2)
286
+ }
286
287
 
287
- function parseSignature(signature: string): { timestamp: number; v1: string } | null {
288
- let timestamp: number | undefined
289
- let v1: string | undefined
290
- for (const part of signature.split(',')) {
291
- const [key, value] = part.split('=', 2)
292
- if (key === 't' && value) timestamp = Number(value)
293
- else if (key === 'v1' && value) v1 = value
288
+ export function parse(signature: string): { timestamp: number; v1: string } | null {
289
+ let timestamp: number | undefined
290
+ let v1: string | undefined
291
+ for (const part of signature.split(',')) {
292
+ const [key, value] = part.split('=', 2)
293
+ if (key === 't' && value) timestamp = Number(value)
294
+ else if (key === 'v1' && value) v1 = value
295
+ }
296
+ if (timestamp === undefined || Number.isNaN(timestamp) || !v1) return null
297
+ return { timestamp, v1 }
294
298
  }
295
- if (timestamp === undefined || Number.isNaN(timestamp) || !v1) return null
296
- return { timestamp, v1 }
297
- }
298
299
 
299
- function timingSafeEqual(a: string, b: string): boolean {
300
- if (a.length !== b.length) return false
301
- let mismatch = 0
302
- for (let index = 0; index < a.length; index++)
303
- mismatch |= a.charCodeAt(index) ^ b.charCodeAt(index)
304
- return mismatch === 0
300
+ export function timingSafeEqual(left: string, right: string): boolean {
301
+ if (left.length !== right.length) return false
302
+ let mismatch = 0
303
+ for (let index = 0; index < left.length; index++)
304
+ mismatch |= left.charCodeAt(index) ^ right.charCodeAt(index)
305
+ return mismatch === 0
306
+ }
305
307
  }
306
308
 
307
309
  /** Thrown when a subscriber URL fails SSRF/format validation. */
@@ -1,5 +1,6 @@
1
1
  import { Webhooks } from 'tapimo'
2
2
  import * as TestApp from '../../test/App.js'
3
+ import * as Cursor from './Cursor.js'
3
4
 
4
5
  const apiKeyOwner = { orgId: 'org_1', type: 'api_key' } as const
5
6
  const mppOwner = { payer: 'did:pkh:eip155:1:0xabc', type: 'mpp' } as const
@@ -56,6 +57,42 @@ describe('createSubscription', () => {
56
57
  expect(read).toEqual(subscription)
57
58
  })
58
59
 
60
+ test('commits an initial poller cursor through both insert paths', async () => {
61
+ const db = TestApp.database()
62
+ const direct = await Webhooks.createSubscription(db, createInput(), {
63
+ startBlockNumber: 123,
64
+ })
65
+ const capped = await Webhooks.createSubscription(db, createInput({ owner: mppOwner }), {
66
+ maxPerOwner: 1,
67
+ startBlockNumber: 456,
68
+ })
69
+
70
+ expect(Cursor.decode((await Webhooks.getCursor(db, direct.id))!, ['int']))
71
+ .toMatchInlineSnapshot(`
72
+ [
73
+ 123,
74
+ ]
75
+ `)
76
+ expect(Cursor.decode((await Webhooks.getCursor(db, capped.id))!, ['int']))
77
+ .toMatchInlineSnapshot(`
78
+ [
79
+ 456,
80
+ ]
81
+ `)
82
+ })
83
+
84
+ test('rejects an invalid initial block number before persisting', async () => {
85
+ const db = TestApp.database()
86
+
87
+ for (const startBlockNumber of [-1, 1.5, Number.MAX_SAFE_INTEGER + 1])
88
+ await expect(
89
+ Webhooks.createSubscription(db, createInput(), { startBlockNumber }),
90
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
91
+ `[RangeError: startBlockNumber must be a non-negative safe integer.]`,
92
+ )
93
+ expect(await Webhooks.listSubscriptions(db, apiKeyOwner)).toEqual([])
94
+ })
95
+
59
96
  test('sets expiresAt from ttl for MPP-owned subscriptions', async () => {
60
97
  const db = TestApp.database()
61
98
  const subscription = await Webhooks.createSubscription(
@@ -301,6 +338,28 @@ describe('cursors', () => {
301
338
  await Webhooks.setCursor(db, created.id, '12345:7')
302
339
  expect(await Webhooks.getCursor(db, created.id)).toMatchInlineSnapshot(`"12345:7"`)
303
340
  })
341
+
342
+ test('atomically rejects a stale cursor write', async () => {
343
+ const db = TestApp.database()
344
+ const created = await Webhooks.createSubscription(db, createInput())
345
+ const a = Cursor.encode([100, 1])
346
+ const b = Cursor.encode([100, 2])
347
+ const results = await Promise.all([
348
+ Webhooks.compareAndSetCursor(db, {
349
+ cursor: a,
350
+ expectedCursor: null,
351
+ subscriptionId: created.id,
352
+ }),
353
+ Webhooks.compareAndSetCursor(db, {
354
+ cursor: b,
355
+ expectedCursor: null,
356
+ subscriptionId: created.id,
357
+ }),
358
+ ])
359
+
360
+ expect(results.toSorted((a, b) => Number(a) - Number(b))).toEqual([false, true])
361
+ expect([a, b]).toContain(await Webhooks.getCursor(db, created.id))
362
+ })
304
363
  })
305
364
 
306
365
  describe('recordSuccess / recordFailure', () => {