tapimo 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (443) hide show
  1. package/dist/App.d.ts +6396 -4575
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +39 -4
  4. package/dist/App.js.map +1 -1
  5. package/dist/Assets.d.ts +15 -0
  6. package/dist/Assets.d.ts.map +1 -1
  7. package/dist/Assets.js +7 -0
  8. package/dist/Assets.js.map +1 -1
  9. package/dist/Scope.d.ts +2 -0
  10. package/dist/Scope.d.ts.map +1 -1
  11. package/dist/Scope.js +17 -0
  12. package/dist/Scope.js.map +1 -1
  13. package/dist/admin/App.d.ts +176 -78
  14. package/dist/admin/App.d.ts.map +1 -1
  15. package/dist/admin/apps/api-keys.d.ts +84 -4
  16. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  17. package/dist/admin/apps/api-keys.js +54 -0
  18. package/dist/admin/apps/api-keys.js.map +1 -1
  19. package/dist/admin/apps/earn-vaults.d.ts +123 -9
  20. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  21. package/dist/admin/apps/earn-vaults.js +60 -7
  22. package/dist/admin/apps/earn-vaults.js.map +1 -1
  23. package/dist/admin/apps/organizations.d.ts.map +1 -1
  24. package/dist/admin/apps/organizations.js +4 -2
  25. package/dist/admin/apps/organizations.js.map +1 -1
  26. package/dist/admin/apps/verified-tokens.d.ts +90 -90
  27. package/dist/admin/ui.generated.d.ts +1 -1
  28. package/dist/admin/ui.generated.js +71 -71
  29. package/dist/admin/ui.generated.js.map +1 -1
  30. package/dist/apps/Zones.d.ts +16 -16
  31. package/dist/apps/Zones.js +4 -4
  32. package/dist/apps/data/App.d.ts +1699 -749
  33. package/dist/apps/data/App.d.ts.map +1 -1
  34. package/dist/apps/data/App.js +58 -9
  35. package/dist/apps/data/App.js.map +1 -1
  36. package/dist/apps/data/ZoneSelection.d.ts +62 -0
  37. package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
  38. package/dist/apps/data/ZoneSelection.js +44 -0
  39. package/dist/apps/data/ZoneSelection.js.map +1 -0
  40. package/dist/apps/data/routes/activities.d.ts +2417 -50
  41. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  42. package/dist/apps/data/routes/activities.js +1896 -1293
  43. package/dist/apps/data/routes/activities.js.map +1 -1
  44. package/dist/apps/data/routes/addresses.d.ts +471 -340
  45. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  46. package/dist/apps/data/routes/balances.d.ts +12 -12
  47. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  48. package/dist/apps/data/routes/balances.js +44 -17
  49. package/dist/apps/data/routes/balances.js.map +1 -1
  50. package/dist/apps/data/routes/blocks.d.ts +42 -42
  51. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  52. package/dist/apps/data/routes/blocks.js +22 -12
  53. package/dist/apps/data/routes/blocks.js.map +1 -1
  54. package/dist/apps/data/routes/coingecko.d.ts +179 -179
  55. package/dist/apps/data/routes/earn.d.ts +144 -19
  56. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  57. package/dist/apps/data/routes/earn.js +160 -28
  58. package/dist/apps/data/routes/earn.js.map +1 -1
  59. package/dist/apps/data/routes/exchanges.d.ts +719 -13
  60. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  61. package/dist/apps/data/routes/exchanges.js +16 -13
  62. package/dist/apps/data/routes/exchanges.js.map +1 -1
  63. package/dist/apps/data/routes/fee-amm.d.ts +2 -2
  64. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  65. package/dist/apps/data/routes/fee-amm.js +9 -11
  66. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  67. package/dist/apps/data/routes/indexer.d.ts +34 -34
  68. package/dist/apps/data/routes/receipts.d.ts +363 -263
  69. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  70. package/dist/apps/data/routes/receipts.js +29 -11
  71. package/dist/apps/data/routes/receipts.js.map +1 -1
  72. package/dist/apps/data/routes/rpc.js +24 -10
  73. package/dist/apps/data/routes/rpc.js.map +1 -1
  74. package/dist/apps/data/routes/tokenlist.d.ts +13 -13
  75. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  76. package/dist/apps/data/routes/tokenlist.js +16 -15
  77. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  78. package/dist/apps/data/routes/tokens.d.ts +112 -98
  79. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  80. package/dist/apps/data/routes/tokens.js +85 -35
  81. package/dist/apps/data/routes/tokens.js.map +1 -1
  82. package/dist/apps/data/routes/transactions.d.ts +7 -2
  83. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  84. package/dist/apps/data/routes/transactions.js +38 -18
  85. package/dist/apps/data/routes/transactions.js.map +1 -1
  86. package/dist/apps/data/routes/transfers.d.ts +1 -1
  87. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  88. package/dist/apps/data/routes/transfers.js +25 -21
  89. package/dist/apps/data/routes/transfers.js.map +1 -1
  90. package/dist/apps/data/routes/valuation.d.ts +1 -1
  91. package/dist/apps/data/routes/valuation.d.ts.map +1 -1
  92. package/dist/apps/data/routes/valuation.js +12 -7
  93. package/dist/apps/data/routes/valuation.js.map +1 -1
  94. package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
  95. package/dist/apps/data/routes/webhooks.d.ts +15 -15
  96. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  97. package/dist/apps/data/routes/webhooks.js +2 -2
  98. package/dist/apps/data/routes/webhooks.js.map +1 -1
  99. package/dist/apps/data/routes/zones.d.ts +32 -32
  100. package/dist/apps/data/routes/zones.js +1 -1
  101. package/dist/apps/funding/App.d.ts +38 -27
  102. package/dist/apps/funding/App.d.ts.map +1 -1
  103. package/dist/apps/funding/routes/chains.d.ts.map +1 -1
  104. package/dist/apps/funding/routes/chains.js +5 -4
  105. package/dist/apps/funding/routes/chains.js.map +1 -1
  106. package/dist/apps/funding/routes/deposit-addresses.d.ts +16 -16
  107. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  108. package/dist/apps/funding/routes/deposit-addresses.js +24 -19
  109. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  110. package/dist/apps/funding/routes/providers.d.ts +13 -13
  111. package/dist/apps/funding/routes/providers.d.ts.map +1 -1
  112. package/dist/apps/funding/routes/providers.js +3 -2
  113. package/dist/apps/funding/routes/providers.js.map +1 -1
  114. package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
  115. package/dist/apps/funding/routes/quotes.js +2 -2
  116. package/dist/apps/funding/routes/quotes.js.map +1 -1
  117. package/dist/apps/funding/routes/transfers.d.ts +60 -48
  118. package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
  119. package/dist/apps/funding/routes/transfers.js +27 -19
  120. package/dist/apps/funding/routes/transfers.js.map +1 -1
  121. package/dist/apps/management/App.d.ts +4558 -3700
  122. package/dist/apps/management/App.d.ts.map +1 -1
  123. package/dist/apps/management/Billing.d.ts.map +1 -1
  124. package/dist/apps/management/Billing.js +19 -6
  125. package/dist/apps/management/Billing.js.map +1 -1
  126. package/dist/apps/management/routes/api-keys.d.ts +786 -175
  127. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  128. package/dist/apps/management/routes/api-keys.js +312 -34
  129. package/dist/apps/management/routes/api-keys.js.map +1 -1
  130. package/dist/apps/management/routes/billing.d.ts +103 -30
  131. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  132. package/dist/apps/management/routes/billing.js +91 -32
  133. package/dist/apps/management/routes/billing.js.map +1 -1
  134. package/dist/apps/management/routes/faucet.d.ts +35 -35
  135. package/dist/apps/management/routes/faucet.d.ts.map +1 -1
  136. package/dist/apps/management/routes/faucet.js +23 -12
  137. package/dist/apps/management/routes/faucet.js.map +1 -1
  138. package/dist/apps/management/routes/invitations.d.ts +46 -13
  139. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  140. package/dist/apps/management/routes/invitations.js +79 -29
  141. package/dist/apps/management/routes/invitations.js.map +1 -1
  142. package/dist/apps/management/routes/invite-links.d.ts +120 -75
  143. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  144. package/dist/apps/management/routes/invite-links.js +100 -41
  145. package/dist/apps/management/routes/invite-links.js.map +1 -1
  146. package/dist/apps/management/routes/me.d.ts +5 -5
  147. package/dist/apps/management/routes/me.d.ts.map +1 -1
  148. package/dist/apps/management/routes/me.js +14 -10
  149. package/dist/apps/management/routes/me.js.map +1 -1
  150. package/dist/apps/management/routes/members.d.ts +99 -78
  151. package/dist/apps/management/routes/members.d.ts.map +1 -1
  152. package/dist/apps/management/routes/members.js +37 -18
  153. package/dist/apps/management/routes/members.js.map +1 -1
  154. package/dist/apps/management/routes/orgs.d.ts +48 -8
  155. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  156. package/dist/apps/management/routes/orgs.js +48 -19
  157. package/dist/apps/management/routes/orgs.js.map +1 -1
  158. package/dist/apps/management/routes/projects.d.ts +108 -46
  159. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  160. package/dist/apps/management/routes/projects.js +72 -21
  161. package/dist/apps/management/routes/projects.js.map +1 -1
  162. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  163. package/dist/apps/management/routes/scopes.js +8 -5
  164. package/dist/apps/management/routes/scopes.js.map +1 -1
  165. package/dist/apps/management/routes/usage.d.ts +82 -82
  166. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  167. package/dist/apps/management/routes/usage.js +41 -31
  168. package/dist/apps/management/routes/usage.js.map +1 -1
  169. package/dist/apps/management/routes/verified-token-requests.d.ts +35 -7
  170. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  171. package/dist/apps/management/routes/verified-token-requests.js +36 -17
  172. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  173. package/dist/apps/management/routes/webhooks.d.ts +200 -183
  174. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  175. package/dist/apps/management/routes/webhooks.js +80 -35
  176. package/dist/apps/management/routes/webhooks.js.map +1 -1
  177. package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
  178. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  179. package/dist/apps/mpp/internal/Adapter.js +12 -0
  180. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  181. package/dist/db/Db.d.ts +2 -0
  182. package/dist/db/Db.d.ts.map +1 -1
  183. package/dist/db/Db.js +52 -1
  184. package/dist/db/Db.js.map +1 -1
  185. package/dist/db/Schema.d.ts +26 -3
  186. package/dist/db/Schema.d.ts.map +1 -1
  187. package/dist/db/Schema.js +24 -5
  188. package/dist/db/Schema.js.map +1 -1
  189. package/dist/db/tables/earnVaults.d.ts +5 -1
  190. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  191. package/dist/db/tables/earnVaults.js +5 -0
  192. package/dist/db/tables/earnVaults.js.map +1 -1
  193. package/dist/db/tables/fundingCatalog.d.ts +4 -2
  194. package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
  195. package/dist/db/tables/fundingCatalog.js +5 -1
  196. package/dist/db/tables/fundingCatalog.js.map +1 -1
  197. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
  198. package/dist/db/tables/webhookDeliveries.js +10 -0
  199. package/dist/db/tables/webhookDeliveries.js.map +1 -1
  200. package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
  201. package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
  202. package/dist/db/tables/webhookQueueCompletions.js +32 -0
  203. package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
  204. package/dist/db/tables/webhookQueueEvents.d.ts +14 -20
  205. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  206. package/dist/db/tables/webhookQueueEvents.js +68 -47
  207. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  208. package/dist/db/tables/webhookSubscriptions.d.ts +16 -5
  209. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  210. package/dist/db/tables/webhookSubscriptions.js +29 -5
  211. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  212. package/dist/handlers/internal/utils.d.ts.map +1 -1
  213. package/dist/handlers/internal/utils.js +9 -0
  214. package/dist/handlers/internal/utils.js.map +1 -1
  215. package/dist/internal/Auth.d.ts +11 -2
  216. package/dist/internal/Auth.d.ts.map +1 -1
  217. package/dist/internal/Auth.js +19 -6
  218. package/dist/internal/Auth.js.map +1 -1
  219. package/dist/internal/Cache.d.ts.map +1 -1
  220. package/dist/internal/Cache.js +11 -7
  221. package/dist/internal/Cache.js.map +1 -1
  222. package/dist/internal/EarnVaults.d.ts +43 -4
  223. package/dist/internal/EarnVaults.d.ts.map +1 -1
  224. package/dist/internal/EarnVaults.js +167 -0
  225. package/dist/internal/EarnVaults.js.map +1 -1
  226. package/dist/internal/Fetch.d.ts +23 -0
  227. package/dist/internal/Fetch.d.ts.map +1 -0
  228. package/dist/internal/Fetch.js +26 -0
  229. package/dist/internal/Fetch.js.map +1 -0
  230. package/dist/internal/Log.d.ts +3 -1
  231. package/dist/internal/Log.d.ts.map +1 -1
  232. package/dist/internal/Log.js +16 -3
  233. package/dist/internal/Log.js.map +1 -1
  234. package/dist/internal/OpenApi.d.ts +30 -24
  235. package/dist/internal/OpenApi.d.ts.map +1 -1
  236. package/dist/internal/OpenApi.js +140 -41
  237. package/dist/internal/OpenApi.js.map +1 -1
  238. package/dist/internal/Response.d.ts +14 -9
  239. package/dist/internal/Response.d.ts.map +1 -1
  240. package/dist/internal/Response.js +16 -5
  241. package/dist/internal/Response.js.map +1 -1
  242. package/dist/internal/Schema.d.ts +11 -10
  243. package/dist/internal/Schema.d.ts.map +1 -1
  244. package/dist/internal/Schema.js +14 -9
  245. package/dist/internal/Schema.js.map +1 -1
  246. package/dist/internal/Store.d.ts +28 -6
  247. package/dist/internal/Store.d.ts.map +1 -1
  248. package/dist/internal/Store.js +121 -25
  249. package/dist/internal/Store.js.map +1 -1
  250. package/dist/internal/Tidx.d.ts +2 -0
  251. package/dist/internal/Tidx.d.ts.map +1 -1
  252. package/dist/internal/Tidx.js +23 -6
  253. package/dist/internal/Tidx.js.map +1 -1
  254. package/dist/internal/Timeout.d.ts +36 -0
  255. package/dist/internal/Timeout.d.ts.map +1 -0
  256. package/dist/internal/Timeout.js +37 -0
  257. package/dist/internal/Timeout.js.map +1 -0
  258. package/dist/internal/Timing.d.ts +9 -0
  259. package/dist/internal/Timing.d.ts.map +1 -1
  260. package/dist/internal/Timing.js +7 -0
  261. package/dist/internal/Timing.js.map +1 -1
  262. package/dist/internal/WebhookDestination.d.ts.map +1 -1
  263. package/dist/internal/WebhookDestination.js +3 -0
  264. package/dist/internal/WebhookDestination.js.map +1 -1
  265. package/dist/internal/Webhooks.d.ts +29 -12
  266. package/dist/internal/Webhooks.d.ts.map +1 -1
  267. package/dist/internal/Webhooks.js +37 -20
  268. package/dist/internal/Webhooks.js.map +1 -1
  269. package/dist/internal/funding/Action.d.ts +9 -0
  270. package/dist/internal/funding/Action.d.ts.map +1 -1
  271. package/dist/internal/funding/Action.js +16 -8
  272. package/dist/internal/funding/Action.js.map +1 -1
  273. package/dist/internal/funding/Catalog.d.ts +9 -2
  274. package/dist/internal/funding/Catalog.d.ts.map +1 -1
  275. package/dist/internal/funding/Catalog.js +19 -8
  276. package/dist/internal/funding/Catalog.js.map +1 -1
  277. package/dist/internal/funding/Deposit.d.ts +2 -2
  278. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  279. package/dist/internal/funding/Deposit.js +9 -8
  280. package/dist/internal/funding/Deposit.js.map +1 -1
  281. package/dist/internal/funding/DepositAddress.d.ts +4 -4
  282. package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
  283. package/dist/internal/funding/DepositAddress.js +9 -8
  284. package/dist/internal/funding/DepositAddress.js.map +1 -1
  285. package/dist/internal/funding/Provider.d.ts +68 -13
  286. package/dist/internal/funding/Provider.d.ts.map +1 -1
  287. package/dist/internal/funding/Provider.js +42 -20
  288. package/dist/internal/funding/Provider.js.map +1 -1
  289. package/dist/internal/funding/Transfer.d.ts +13 -12
  290. package/dist/internal/funding/Transfer.d.ts.map +1 -1
  291. package/dist/internal/funding/Transfer.js +23 -21
  292. package/dist/internal/funding/Transfer.js.map +1 -1
  293. package/dist/internal/funding/providers/stargate.d.ts +38 -0
  294. package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
  295. package/dist/internal/funding/providers/stargate.js +277 -0
  296. package/dist/internal/funding/providers/stargate.js.map +1 -0
  297. package/dist/internal/index.d.ts +1 -0
  298. package/dist/internal/index.d.ts.map +1 -1
  299. package/dist/internal/index.js +1 -0
  300. package/dist/internal/index.js.map +1 -1
  301. package/dist/providers/index.d.ts +7 -0
  302. package/dist/providers/index.d.ts.map +1 -1
  303. package/dist/providers/index.js +3 -0
  304. package/dist/providers/index.js.map +1 -1
  305. package/package.json +3 -3
  306. package/src/App.test.ts +148 -0
  307. package/src/App.ts +45 -4
  308. package/src/Assets.test.ts +18 -0
  309. package/src/Assets.ts +22 -0
  310. package/src/Client.test-d.ts +311 -16
  311. package/src/Scope.test.ts +20 -0
  312. package/src/Scope.ts +16 -0
  313. package/src/admin/apps/api-keys.test.ts +75 -0
  314. package/src/admin/apps/api-keys.ts +64 -0
  315. package/src/admin/apps/earn-vaults.test.ts +143 -0
  316. package/src/admin/apps/earn-vaults.ts +84 -7
  317. package/src/admin/apps/organizations.ts +6 -2
  318. package/src/admin/ui/src/lib/api-keys.ts +19 -0
  319. package/src/admin/ui/src/routes/api-keys.tsx +125 -2
  320. package/src/admin/ui.generated.ts +71 -71
  321. package/src/apps/Zones.test.ts +4 -4
  322. package/src/apps/Zones.ts +4 -4
  323. package/src/apps/composition.test.ts +1 -1
  324. package/src/apps/data/App.test.ts +72 -0
  325. package/src/apps/data/App.ts +58 -10
  326. package/src/apps/data/ZoneSelection.test.ts +196 -0
  327. package/src/apps/data/ZoneSelection.ts +108 -0
  328. package/src/apps/data/routes/activities.test.ts +1843 -2
  329. package/src/apps/data/routes/activities.ts +2211 -1388
  330. package/src/apps/data/routes/balances.ts +134 -98
  331. package/src/apps/data/routes/blocks.test.ts +533 -0
  332. package/src/apps/data/routes/blocks.ts +36 -17
  333. package/src/apps/data/routes/earn.test.ts +187 -25
  334. package/src/apps/data/routes/earn.ts +228 -32
  335. package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
  336. package/src/apps/data/routes/exchanges.test.ts +31 -1
  337. package/src/apps/data/routes/exchanges.ts +19 -15
  338. package/src/apps/data/routes/fee-amm.ts +18 -11
  339. package/src/apps/data/routes/receipts.ts +48 -17
  340. package/src/apps/data/routes/rpc.test.ts +75 -0
  341. package/src/apps/data/routes/rpc.ts +23 -9
  342. package/src/apps/data/routes/tokenlist.ts +21 -18
  343. package/src/apps/data/routes/tokens.test.ts +607 -0
  344. package/src/apps/data/routes/tokens.ts +312 -231
  345. package/src/apps/data/routes/transactions.ts +69 -30
  346. package/src/apps/data/routes/transfers.test.ts +424 -3
  347. package/src/apps/data/routes/transfers.ts +57 -36
  348. package/src/apps/data/routes/valuation.ts +94 -78
  349. package/src/apps/data/routes/webhooks.ts +6 -2
  350. package/src/apps/data/routes/zones.test.ts +21 -15
  351. package/src/apps/data/routes/zones.ts +1 -1
  352. package/src/apps/funding/routes/chains.test.ts +211 -7
  353. package/src/apps/funding/routes/chains.ts +19 -12
  354. package/src/apps/funding/routes/deposit-addresses.test.ts +416 -0
  355. package/src/apps/funding/routes/deposit-addresses.ts +101 -84
  356. package/src/apps/funding/routes/providers.ts +9 -5
  357. package/src/apps/funding/routes/quotes.test.ts +42 -0
  358. package/src/apps/funding/routes/quotes.ts +8 -5
  359. package/src/apps/funding/routes/transfers.test.ts +430 -40
  360. package/src/apps/funding/routes/transfers.ts +76 -59
  361. package/src/apps/management/Billing.test.ts +26 -0
  362. package/src/apps/management/Billing.ts +24 -7
  363. package/src/apps/management/routes/api-keys.test.ts +398 -0
  364. package/src/apps/management/routes/api-keys.ts +481 -145
  365. package/src/apps/management/routes/billing.test.ts +209 -0
  366. package/src/apps/management/routes/billing.ts +254 -177
  367. package/src/apps/management/routes/faucet.test.ts +39 -0
  368. package/src/apps/management/routes/faucet.ts +75 -41
  369. package/src/apps/management/routes/invitations.test.ts +216 -0
  370. package/src/apps/management/routes/invitations.ts +186 -109
  371. package/src/apps/management/routes/invite-links.test.ts +263 -1
  372. package/src/apps/management/routes/invite-links.ts +295 -214
  373. package/src/apps/management/routes/me.test.ts +49 -0
  374. package/src/apps/management/routes/me.ts +42 -32
  375. package/src/apps/management/routes/members.test.ts +124 -1
  376. package/src/apps/management/routes/members.ts +81 -51
  377. package/src/apps/management/routes/orgs.test.ts +176 -0
  378. package/src/apps/management/routes/orgs.ts +101 -59
  379. package/src/apps/management/routes/projects.test.ts +183 -0
  380. package/src/apps/management/routes/projects.ts +124 -60
  381. package/src/apps/management/routes/scopes.test.ts +44 -0
  382. package/src/apps/management/routes/scopes.ts +37 -28
  383. package/src/apps/management/routes/usage.test.ts +92 -0
  384. package/src/apps/management/routes/usage.ts +186 -151
  385. package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
  386. package/src/apps/management/routes/verified-token-requests.ts +166 -133
  387. package/src/apps/management/routes/webhooks.test.ts +234 -0
  388. package/src/apps/management/routes/webhooks.ts +191 -78
  389. package/src/apps/mpp/internal/Adapter.ts +13 -1
  390. package/src/db/Db.test.ts +41 -0
  391. package/src/db/Db.ts +75 -1
  392. package/src/db/Schema.ts +33 -5
  393. package/src/db/tables/earnVaults.test.ts +22 -0
  394. package/src/db/tables/earnVaults.ts +11 -1
  395. package/src/db/tables/fundingCatalog.test.ts +16 -2
  396. package/src/db/tables/fundingCatalog.ts +9 -3
  397. package/src/db/tables/webhookDeliveries.ts +13 -0
  398. package/src/db/tables/webhookQueueCompletions.ts +55 -0
  399. package/src/db/tables/webhookQueueEvents.ts +95 -61
  400. package/src/db/tables/webhookSubscriptions.ts +45 -6
  401. package/src/handlers/internal/utils.test.ts +53 -0
  402. package/src/handlers/internal/utils.ts +15 -0
  403. package/src/internal/Auth.ts +35 -9
  404. package/src/internal/Cache.ts +14 -7
  405. package/src/internal/EarnVaults.capabilities.test.ts +33 -0
  406. package/src/internal/EarnVaults.test.ts +79 -0
  407. package/src/internal/EarnVaults.ts +277 -0
  408. package/src/internal/Fetch.test.ts +46 -0
  409. package/src/internal/Fetch.ts +56 -0
  410. package/src/internal/Log.test.ts +21 -0
  411. package/src/internal/Log.ts +20 -5
  412. package/src/internal/OpenApi.ts +177 -51
  413. package/src/internal/Response.test.ts +95 -0
  414. package/src/internal/Response.ts +41 -3
  415. package/src/internal/Schema.test.ts +18 -0
  416. package/src/internal/Schema.ts +19 -9
  417. package/src/internal/Store.test.ts +364 -0
  418. package/src/internal/Store.ts +153 -27
  419. package/src/internal/Tidx.test.ts +21 -1
  420. package/src/internal/Tidx.ts +23 -6
  421. package/src/internal/Timeout.test.ts +35 -0
  422. package/src/internal/Timeout.ts +73 -0
  423. package/src/internal/Timing.ts +16 -0
  424. package/src/internal/WebhookDestination.ts +3 -0
  425. package/src/internal/Webhooks.test.ts +122 -8
  426. package/src/internal/Webhooks.ts +59 -29
  427. package/src/internal/funding/Action.test.ts +41 -1
  428. package/src/internal/funding/Action.ts +69 -41
  429. package/src/internal/funding/Catalog.test.ts +34 -0
  430. package/src/internal/funding/Catalog.ts +28 -11
  431. package/src/internal/funding/Deposit.ts +71 -64
  432. package/src/internal/funding/DepositAddress.ts +50 -43
  433. package/src/internal/funding/Provider.test.ts +73 -0
  434. package/src/internal/funding/Provider.ts +246 -170
  435. package/src/internal/funding/Transfer.ts +133 -110
  436. package/src/internal/funding/providers/index.test.ts +22 -0
  437. package/src/internal/funding/providers/relay.test.ts +2 -2
  438. package/src/internal/funding/providers/stargate.test.ts +163 -0
  439. package/src/internal/funding/providers/stargate.ts +409 -0
  440. package/src/internal/index.test.ts +1 -0
  441. package/src/internal/index.ts +1 -0
  442. package/src/providers/index.test.ts +1 -0
  443. package/src/providers/index.ts +9 -0
@@ -3,6 +3,7 @@ import { Mpp as PublicMpp } from 'tapimo/mpp'
3
3
  import type * as z from 'zod/mini'
4
4
 
5
5
  import * as Activities from './apps/data/routes/activities.js'
6
+ import * as ApiKeys from './apps/management/routes/api-keys.js'
6
7
  import * as Balances from './apps/data/routes/balances.js'
7
8
  import * as Billing from './apps/management/routes/billing.js'
8
9
  import * as Blocks from './apps/data/routes/blocks.js'
@@ -82,6 +83,50 @@ test('returns typed client', async () => {
82
83
  })
83
84
 
84
85
  describe('narrows responses by status', () => {
86
+ test('POST /v1/orgs/:orgId/projects/:projectId/api-keys/:keyId/rotate', async () => {
87
+ const client = Client.create()
88
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects[
89
+ ':projectId{prj_[A-Za-z0-9_-]+}'
90
+ ]['api-keys'][':keyId{key_[A-Za-z0-9_-]+}'].rotate.$post({
91
+ param: { keyId: 'key_test', orgId: 'org_test', projectId: 'prj_test' },
92
+ })
93
+
94
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
95
+
96
+ if (res.status === 200) {
97
+ const json = await res.json()
98
+ expectTypeOf(json).toEqualTypeOf<z.output<typeof ApiKeys.schema.rotateApiKey.Response>>()
99
+ }
100
+ })
101
+
102
+ test('POST /v1/orgs/:orgId/api-keys/:keyId/rotate', async () => {
103
+ const client = Client.create()
104
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['api-keys'][
105
+ ':keyId{key_[A-Za-z0-9_-]+}'
106
+ ].rotate.$post({ param: { keyId: 'key_test', orgId: 'org_test' } })
107
+
108
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
109
+
110
+ if (res.status === 200) {
111
+ const json = await res.json()
112
+ expectTypeOf(json).toEqualTypeOf<z.output<typeof ApiKeys.schema.rotateApiKey.Response>>()
113
+ }
114
+ })
115
+
116
+ test('DELETE /v1/orgs/:orgId/api-keys/:keyId', async () => {
117
+ const client = Client.create()
118
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['api-keys'][
119
+ ':keyId{key_[A-Za-z0-9_-]+}'
120
+ ].$delete({ param: { keyId: 'key_test', orgId: 'org_test' } })
121
+
122
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 429 | 502>()
123
+
124
+ if (res.status === 200) {
125
+ const json = await res.json()
126
+ expectTypeOf(json).toEqualTypeOf<z.output<typeof ApiKeys.schema.revokeApiKey.Response>>()
127
+ }
128
+ })
129
+
85
130
  test('POST /v1/mpp/validate', async () => {
86
131
  const client = Client.create()
87
132
  const res = await client.v1.mpp.validate.$post({ json: mppInput })
@@ -173,7 +218,7 @@ describe('narrows responses by status', () => {
173
218
  'apy.window': '24h',
174
219
  capability: 'deposit',
175
220
  'engine.type': 'erc4626',
176
- include: 'access,apy,capabilities,token.logoUri,tvl,zone',
221
+ include: 'access,apy,capabilities,token.logoUri,tvl,zone,zones',
177
222
  },
178
223
  })
179
224
 
@@ -205,6 +250,8 @@ describe('narrows responses by status', () => {
205
250
  expectTypeOf(json.data[0]!.vaultAddress).toEqualTypeOf<`0x${string}`>()
206
251
  expectTypeOf(json.data[0]!.verified).toEqualTypeOf<boolean>()
207
252
  expectTypeOf(json.data[0]!.zone?.chainId).toEqualTypeOf<number | undefined>()
253
+ expectTypeOf(json.data[0]!.zones?.[0]?.deploymentBlock).toEqualTypeOf<number | undefined>()
254
+ expectTypeOf(json.data[0]!.zones?.[0]?.earnRouter).toEqualTypeOf<`0x${string}` | undefined>()
208
255
  expectTypeOf(json.meta?.valuation?.basis).toEqualTypeOf<'nominal' | undefined>()
209
256
  void json
210
257
  return
@@ -226,7 +273,10 @@ describe('narrows responses by status', () => {
226
273
  test('GET /v1/earn/vaults/verified', async () => {
227
274
  const client = Client.create()
228
275
  const res = await client.v1.earn.vaults.verified.$get({
229
- query: { 'apy.window': '7d', include: 'access,apy,capabilities,token.logoUri,tvl,zone' },
276
+ query: {
277
+ 'apy.window': '7d',
278
+ include: 'access,apy,capabilities,token.logoUri,tvl,zone,zones',
279
+ },
230
280
  })
231
281
 
232
282
  expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 502 | PaidAccessStatus>()
@@ -243,6 +293,7 @@ describe('narrows responses by status', () => {
243
293
  expectTypeOf(json.data[0]!.tvl).toEqualTypeOf<VaultValue | null | undefined>()
244
294
  expectTypeOf(json.data[0]!.tvl?.formatted).toEqualTypeOf<string | undefined>()
245
295
  expectTypeOf(json.data[0]!.verified).toEqualTypeOf<true>()
296
+ expectTypeOf(json.data[0]!.zones?.[0]?.chainId).toEqualTypeOf<number | undefined>()
246
297
  expectTypeOf(json.meta?.valuation?.source).toEqualTypeOf<string | undefined>()
247
298
  void json
248
299
  return
@@ -968,6 +1019,46 @@ describe('narrows responses by status', () => {
968
1019
  void json
969
1020
  return
970
1021
  }
1022
+ case 403: {
1023
+ const json = await res.json()
1024
+ expectTypeOf(json.error.code).toEqualTypeOf<
1025
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1026
+ >()
1027
+ void json
1028
+ return
1029
+ }
1030
+ }
1031
+ })
1032
+
1033
+ test('DELETE /v1/orgs/:orgId', async () => {
1034
+ const client = Client.create()
1035
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].$delete({
1036
+ param: { orgId: 'org_test' },
1037
+ })
1038
+
1039
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 409 | 502 | PublicAccessStatus>()
1040
+
1041
+ switch (res.status) {
1042
+ case 403: {
1043
+ const json = await res.json()
1044
+ expectTypeOf(json.error.code).toEqualTypeOf<
1045
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1046
+ >()
1047
+ void json
1048
+ return
1049
+ }
1050
+ case 404: {
1051
+ const json = await res.json()
1052
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1053
+ void json
1054
+ return
1055
+ }
1056
+ case 409: {
1057
+ const json = await res.json()
1058
+ expectTypeOf(json.error.code).toEqualTypeOf<'sponsorships_unreported'>()
1059
+ void json
1060
+ return
1061
+ }
971
1062
  }
972
1063
  })
973
1064
 
@@ -1035,10 +1126,21 @@ describe('narrows responses by status', () => {
1035
1126
 
1036
1127
  expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1037
1128
 
1038
- if (res.status === 200) {
1039
- const json = await res.json()
1040
- expectTypeOf(json.allowedIps).toEqualTypeOf<readonly string[]>()
1041
- void json
1129
+ switch (res.status) {
1130
+ case 200: {
1131
+ const json = await res.json()
1132
+ expectTypeOf(json.allowedIps).toEqualTypeOf<readonly string[]>()
1133
+ void json
1134
+ return
1135
+ }
1136
+ case 403: {
1137
+ const json = await res.json()
1138
+ expectTypeOf(json.error.code).toEqualTypeOf<
1139
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1140
+ >()
1141
+ void json
1142
+ return
1143
+ }
1042
1144
  }
1043
1145
  })
1044
1146
 
@@ -1053,6 +1155,14 @@ describe('narrows responses by status', () => {
1053
1155
  expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1054
1156
 
1055
1157
  switch (res.status) {
1158
+ case 403: {
1159
+ const json = await res.json()
1160
+ expectTypeOf(json.error.code).toEqualTypeOf<
1161
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1162
+ >()
1163
+ void json
1164
+ return
1165
+ }
1056
1166
  case 404: {
1057
1167
  const json = await res.json()
1058
1168
  expectTypeOf(json.error.code).toEqualTypeOf<
@@ -1117,6 +1227,12 @@ describe('narrows responses by status', () => {
1117
1227
  void json
1118
1228
  return
1119
1229
  }
1230
+ case 404: {
1231
+ const json = await res.json()
1232
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1233
+ void json
1234
+ return
1235
+ }
1120
1236
  }
1121
1237
  })
1122
1238
 
@@ -1129,6 +1245,20 @@ describe('narrows responses by status', () => {
1129
1245
  expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 409 | 502 | PublicAccessStatus>()
1130
1246
 
1131
1247
  switch (res.status) {
1248
+ case 403: {
1249
+ const json = await res.json()
1250
+ expectTypeOf(json.error.code).toEqualTypeOf<
1251
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1252
+ >()
1253
+ void json
1254
+ return
1255
+ }
1256
+ case 404: {
1257
+ const json = await res.json()
1258
+ expectTypeOf(json.error.code).toEqualTypeOf<'member_not_found' | 'organization_not_found'>()
1259
+ void json
1260
+ return
1261
+ }
1132
1262
  case 409: {
1133
1263
  const json = await res.json()
1134
1264
  expectTypeOf(json.error.code).toEqualTypeOf<'last_owner'>()
@@ -1138,6 +1268,87 @@ describe('narrows responses by status', () => {
1138
1268
  }
1139
1269
  })
1140
1270
 
1271
+ test('DELETE /v1/orgs/:orgId/members/:userId', async () => {
1272
+ const client = Client.create()
1273
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].members[
1274
+ ':userId{usr_[A-Za-z0-9_-]+}'
1275
+ ].$delete({ param: { orgId: 'org_test', userId: 'usr_test' } })
1276
+
1277
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 409 | 502 | PublicAccessStatus>()
1278
+
1279
+ switch (res.status) {
1280
+ case 200: {
1281
+ const json = await res.json()
1282
+ expectTypeOf(json.userId).toEqualTypeOf<string>()
1283
+ void json
1284
+ return
1285
+ }
1286
+ case 404: {
1287
+ const json = await res.json()
1288
+ expectTypeOf(json.error.code).toEqualTypeOf<'member_not_found' | 'organization_not_found'>()
1289
+ void json
1290
+ return
1291
+ }
1292
+ case 409: {
1293
+ const json = await res.json()
1294
+ expectTypeOf(json.error.code).toEqualTypeOf<'last_owner'>()
1295
+ void json
1296
+ return
1297
+ }
1298
+ }
1299
+ })
1300
+
1301
+ test('POST /v1/orgs/:orgId/invitations', async () => {
1302
+ const client = Client.create()
1303
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].invitations.$post({
1304
+ json: { email: 'dev@example.com', role: 'member' },
1305
+ param: { orgId: 'org_test' },
1306
+ })
1307
+
1308
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1309
+
1310
+ switch (res.status) {
1311
+ case 200: {
1312
+ const json = await res.json()
1313
+ expectTypeOf(json.email).toEqualTypeOf<string>()
1314
+ expectTypeOf(json.role).toEqualTypeOf<'admin' | 'member' | 'owner'>()
1315
+ void json
1316
+ return
1317
+ }
1318
+ case 403: {
1319
+ const json = await res.json()
1320
+ expectTypeOf(json.error.code).toEqualTypeOf<
1321
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1322
+ >()
1323
+ void json
1324
+ return
1325
+ }
1326
+ case 404: {
1327
+ const json = await res.json()
1328
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1329
+ void json
1330
+ return
1331
+ }
1332
+ }
1333
+ })
1334
+
1335
+ test('DELETE /v1/orgs/:orgId/invitations/:invitationId', async () => {
1336
+ const client = Client.create()
1337
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].invitations[
1338
+ ':invitationId{inv_[A-Za-z0-9_-]+}'
1339
+ ].$delete({ param: { invitationId: 'inv_test', orgId: 'org_test' } })
1340
+
1341
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1342
+
1343
+ if (res.status === 404) {
1344
+ const json = await res.json()
1345
+ expectTypeOf(json.error.code).toEqualTypeOf<
1346
+ 'invitation_not_found' | 'organization_not_found'
1347
+ >()
1348
+ void json
1349
+ }
1350
+ })
1351
+
1141
1352
  test('POST /v1/orgs/:orgId/invite-links', async () => {
1142
1353
  const client = Client.create()
1143
1354
  const orgLinks = client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['invite-links']
@@ -1157,13 +1368,57 @@ describe('narrows responses by status', () => {
1157
1368
  >()
1158
1369
  expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
1159
1370
 
1160
- if (res.status === 200) {
1161
- const json = await res.json()
1162
- expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<readonly string[] | null>()
1163
- expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<
1164
- z.output<typeof InviteLinks.schema.InviteLink>['allowedEmailDomains']
1165
- >()
1166
- void json
1371
+ switch (res.status) {
1372
+ case 200: {
1373
+ const json = await res.json()
1374
+ expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<readonly string[] | null>()
1375
+ expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<
1376
+ z.output<typeof InviteLinks.schema.InviteLink>['allowedEmailDomains']
1377
+ >()
1378
+ void json
1379
+ return
1380
+ }
1381
+ case 403: {
1382
+ const json = await res.json()
1383
+ expectTypeOf(json.error.code).toEqualTypeOf<'forbidden'>()
1384
+ void json
1385
+ return
1386
+ }
1387
+ case 404: {
1388
+ const json = await res.json()
1389
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1390
+ void json
1391
+ return
1392
+ }
1393
+ }
1394
+ })
1395
+
1396
+ test('PATCH /v1/orgs/:orgId/invite-links/:inviteLinkId', async () => {
1397
+ const client = Client.create()
1398
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['invite-links'][
1399
+ ':inviteLinkId{iln_[A-Za-z0-9_-]+}'
1400
+ ].$patch({
1401
+ json: { enabled: false },
1402
+ param: { inviteLinkId: 'iln_test', orgId: 'org_test' },
1403
+ })
1404
+
1405
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
1406
+
1407
+ switch (res.status) {
1408
+ case 403: {
1409
+ const json = await res.json()
1410
+ expectTypeOf(json.error.code).toEqualTypeOf<'forbidden'>()
1411
+ void json
1412
+ return
1413
+ }
1414
+ case 404: {
1415
+ const json = await res.json()
1416
+ expectTypeOf(json.error.code).toEqualTypeOf<
1417
+ 'invite_link_not_found' | 'organization_not_found'
1418
+ >()
1419
+ void json
1420
+ return
1421
+ }
1167
1422
  }
1168
1423
  })
1169
1424
 
@@ -1500,14 +1755,18 @@ describe('narrows responses by status', () => {
1500
1755
  param: {
1501
1756
  transactionHash: '0x4845ae2098724ab26a5d89370dce5124d044be6a5acc164afc348662de67d474',
1502
1757
  },
1503
- query: { include: 'token.logoUri,token.verified' },
1758
+ query: {
1759
+ chainId: '4217',
1760
+ include: 'zones,token.logoUri,token.verified',
1761
+ },
1504
1762
  })
1505
1763
 
1506
- expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
1764
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 409 | 502 | PaidAccessStatus>()
1507
1765
 
1508
1766
  switch (res.status) {
1509
1767
  case 200: {
1510
1768
  const json = await res.json()
1769
+ expectTypeOf(json.chainId).toEqualTypeOf<number>()
1511
1770
  expectTypeOf(json.data[0]!.type).toEqualTypeOf<
1512
1771
  z.output<
1513
1772
  typeof Activities.schema.getTransactionActivities.Response
@@ -1550,6 +1809,13 @@ describe('narrows responses by status', () => {
1550
1809
  void json
1551
1810
  return
1552
1811
  }
1812
+ case 409: {
1813
+ const json = await res.json()
1814
+ expectTypeOf(json.error.code).toEqualTypeOf<'transaction_ambiguous'>()
1815
+ expectTypeOf(json.error.message).toEqualTypeOf<string>()
1816
+ void json
1817
+ return
1818
+ }
1553
1819
  case 502: {
1554
1820
  const json = await res.json()
1555
1821
  expectTypeOf(json.error.code).toEqualTypeOf<'upstream_error'>()
@@ -2342,6 +2608,7 @@ describe('narrows responses by status', () => {
2342
2608
  amount: '1000000',
2343
2609
  destinationToken: '0x20c000000000000000000000b9537d11c60e8b50',
2344
2610
  mode: 'exactSource',
2611
+ provider: 'stargate',
2345
2612
  recipient: `0x${'11'.repeat(20)}`,
2346
2613
  sender: `0x${'22'.repeat(20)}`,
2347
2614
  sourceChain: 'eip155:8453',
@@ -2604,6 +2871,30 @@ describe('narrows responses by status', () => {
2604
2871
  }
2605
2872
  })
2606
2873
 
2874
+ test('QUERY /v1/exchange/quotes', async () => {
2875
+ const client = Client.create()
2876
+ const res = await client.v1.exchange.quotes.$query({
2877
+ json: {
2878
+ account: '0x1111111111111111111111111111111111111111',
2879
+ amount: '1000000',
2880
+ destinationToken: '0x20c000000000000000000000b9537d11c60e8b50',
2881
+ mode: 'exactSource',
2882
+ slippageBps: 50,
2883
+ sourceToken: '0x20c0000000000000000000008f5425160ebe5525',
2884
+ },
2885
+ query: { include: 'token.logoUri,token.verified' },
2886
+ })
2887
+
2888
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
2889
+ if (res.status === 200) {
2890
+ const json = await res.json()
2891
+ expectTypeOf(json.destinationAmount).toEqualTypeOf<ValuedTokenAmount>()
2892
+ expectTypeOf(json.sourceAmount).toEqualTypeOf<ValuedTokenAmount>()
2893
+ expectTypeOf(json.destinationToken.logoUri).toEqualTypeOf<string | undefined>()
2894
+ expectTypeOf(json.sourceToken.verified).toEqualTypeOf<boolean | undefined>()
2895
+ }
2896
+ })
2897
+
2607
2898
  test('POST /v1/exchange/quotes/execute', async () => {
2608
2899
  const client = Client.create()
2609
2900
  const res = await client.v1.exchange.quotes.execute.$post({
@@ -3292,7 +3583,10 @@ describe('narrows responses by status', () => {
3292
3583
  const client = Client.create()
3293
3584
  const res = await client.v1.addresses[':address'].activities.$get({
3294
3585
  param: { address: '0x0000000000000000000000000000000000000000' },
3295
- query: { include: 'token.logoUri,token.verified' },
3586
+ query: {
3587
+ chainId: '4217',
3588
+ include: 'zones,token.logoUri,token.verified',
3589
+ },
3296
3590
  })
3297
3591
 
3298
3592
  expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 502 | PaidAccessStatus>()
@@ -3300,6 +3594,7 @@ describe('narrows responses by status', () => {
3300
3594
  switch (res.status) {
3301
3595
  case 200: {
3302
3596
  const json = await res.json()
3597
+ expectTypeOf(json.data[0]!.chainId).toEqualTypeOf<number | undefined>()
3303
3598
  expectTypeOf(json.data[0]!.type).toEqualTypeOf<
3304
3599
  z.output<typeof Activities.schema.getAddressActivities.Response>['data'][number]['type']
3305
3600
  >()
package/src/Scope.test.ts CHANGED
@@ -52,3 +52,23 @@ describe('extend', () => {
52
52
  ).toThrowErrorMatchingInlineSnapshot(`[Error: Duplicate scope \`data:read\`.]`)
53
53
  })
54
54
  })
55
+
56
+ describe('expandAliases', () => {
57
+ test('adds the current scope for a legacy Zone read scope', () => {
58
+ expect(
59
+ Scope.expandAliases(['data:read', 'zone:1424310001:read', 'zone:1424310001:write']),
60
+ ).toEqual([
61
+ 'data:read',
62
+ 'zone:1424310001:read',
63
+ 'zone:1424310001:write',
64
+ 'zone:1424310003:read',
65
+ ])
66
+ })
67
+
68
+ test('does not duplicate an existing current scope', () => {
69
+ expect(Scope.expandAliases(['zone:1424310001:read', 'zone:1424310003:read'])).toEqual([
70
+ 'zone:1424310001:read',
71
+ 'zone:1424310003:read',
72
+ ])
73
+ })
74
+ })
package/src/Scope.ts CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  import * as z from 'zod/mini'
8
8
 
9
+ import * as Schema from './internal/Schema.js'
10
+
9
11
  /**
10
12
  * Wildcard scope. A key whose `scopes` contains this value satisfies every
11
13
  * required scope, so it never needs re-provisioning when new scopes are added.
@@ -154,6 +156,20 @@ export function includes(catalog: Catalog, scope: string): scope is Id {
154
156
  return schema.Zone.safeParse(scope).success || catalog.some((entry) => entry.scope === scope)
155
157
  }
156
158
 
159
+ /** Adds current read scopes granted by legacy Zone read scopes. */
160
+ export function expandAliases(scopes: readonly string[]): readonly string[] {
161
+ const aliases = new Set<string>()
162
+ for (const scope of scopes) {
163
+ const match = /^zone:([1-9]\d*):read$/.exec(scope)
164
+ if (!match) continue
165
+ const chainId = Number(match[1])
166
+ const resolved = Schema.resolveChainId(chainId)
167
+ if (resolved !== chainId) aliases.add(`zone:${resolved}:read`)
168
+ }
169
+ for (const scope of scopes) aliases.delete(scope)
170
+ return aliases.size ? [...scopes, ...aliases] : scopes
171
+ }
172
+
157
173
  /** Returns the self-issuable identifiers in a scope catalog. */
158
174
  export function selfServeFrom(catalog: Catalog): readonly Id[] {
159
175
  return catalog
@@ -299,6 +299,81 @@ describe('DELETE /api-keys/:id', () => {
299
299
  })
300
300
  })
301
301
 
302
+ describe('POST /api-keys/:id/rotate', () => {
303
+ test('mints a replacement with the source access and attribution', async () => {
304
+ const { client, store } = await setup()
305
+ const { record: source, token: sourceToken } = await core_ApiKeys.mint(store, {
306
+ allowedIps: ['203.0.113.0/24'],
307
+ billingActive: true,
308
+ createdBy: 'customer@example.com',
309
+ environment: 'sandbox',
310
+ expiresAt: '2100-01-01T00:00:00.000Z',
311
+ name: 'Privy Zones',
312
+ orgId: 'org_privy',
313
+ projectId: 'prj_privy',
314
+ rateLimits: { '*': { limit: 10_000, period: 'minute' } },
315
+ scopes: ['zone:421700001:read', 'zone:421700001:write'],
316
+ })
317
+
318
+ const response = await client['api-keys'][':id'].rotate.$post({
319
+ param: { id: source.id },
320
+ })
321
+ const body = await TestApp.json(response, ApiKeys.schema.rotateApiKey.Response)
322
+
323
+ expect(response.status).toBe(200)
324
+ expect(body).toMatchObject({
325
+ allowedIps: source.allowedIps,
326
+ billingActive: source.billingActive,
327
+ createdBy: TestAdmin.identity.email,
328
+ environment: source.environment,
329
+ expiresAt: source.expiresAt,
330
+ name: source.name,
331
+ orgId: source.orgId,
332
+ projectId: source.projectId,
333
+ rateLimits: source.rateLimits,
334
+ scopes: source.scopes,
335
+ })
336
+ expect(body.id).not.toBe(source.id)
337
+ expect(body.token).not.toBe(sourceToken)
338
+ expect(await core_ApiKeys.resolve(store, sourceToken)).not.toBeNull()
339
+ expect(await core_ApiKeys.resolve(store, body.token)).toMatchObject({
340
+ id: body.id,
341
+ scopes: source.scopes,
342
+ })
343
+ })
344
+
345
+ test('unknown id → 404', async () => {
346
+ const { client } = await setup()
347
+ const response = await client['api-keys'][':id'].rotate.$post({
348
+ param: { id: 'key_missing' },
349
+ })
350
+
351
+ expect(response.status).toMatchInlineSnapshot(`404`)
352
+ })
353
+
354
+ test('keeps a rotated one-off key assignable to an organization', async () => {
355
+ const { client, db, store } = await setup()
356
+ const organization = await Organizations.create(db, { name: 'Tempo' })
357
+ const { record: source } = await core_ApiKeys.mint(store, {
358
+ name: 'One-off',
359
+ scopes: ['data:read'],
360
+ })
361
+
362
+ const rotateResponse = await client['api-keys'][':id'].rotate.$post({
363
+ param: { id: source.id },
364
+ })
365
+ const replacement = await TestApp.json(rotateResponse, ApiKeys.schema.rotateApiKey.Response)
366
+ expect(replacement.orgId).toBe(replacement.id)
367
+
368
+ const updateResponse = await client['api-keys'][':id'].$patch({
369
+ json: { orgId: organization.id },
370
+ param: { id: replacement.id },
371
+ })
372
+ expect(updateResponse.status).toBe(200)
373
+ expect((await core_ApiKeys.get(store, replacement.id))?.orgId).toBe(organization.id)
374
+ })
375
+ })
376
+
302
377
  describe('PATCH /api-keys/:id', () => {
303
378
  test('preserves the allowlist when omitted', async () => {
304
379
  const { client, store } = TestAdmin.setup()
@@ -173,6 +173,24 @@ export namespace schema {
173
173
  .object({ id: z.string().check(z.describe('Revoked key id.')) })
174
174
  .check(z.describe('API-key revocation result.'))
175
175
  }
176
+
177
+ /** Schemas for the rotateApiKey operation. */
178
+ export namespace rotateApiKey {
179
+ /** Path parameters for rotating a key. */
180
+ export const Params = z
181
+ .object({
182
+ id: z
183
+ .string()
184
+ .check(
185
+ z.describe('Stable id of the key to rotate.'),
186
+ z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
187
+ ),
188
+ })
189
+ .check(z.describe('Path parameters for rotating an API key.'))
190
+
191
+ /** Response: the replacement record plus its one-time plaintext token. */
192
+ export const Response = createApiKey.Response
193
+ }
176
194
  }
177
195
 
178
196
  /**
@@ -183,6 +201,7 @@ export namespace schema {
183
201
  * - `GET /` lists key records (metadata only), optionally filtered by `orgId`.
184
202
  * - `DELETE /:id` revokes a key by id (`404` if absent).
185
203
  * - `PATCH /:id` updates a key's allowlist, name, or project, or assigns its first organization.
204
+ * - `POST /:id/rotate` mints a replacement with the source key's access and attribution.
186
205
  * - `POST /backfill` rebuilds the id and org index entries for every record.
187
206
  */
188
207
  export function apiKeys() {
@@ -315,6 +334,51 @@ export function apiKeys() {
315
334
  return c.json(Response.validated(schema.revokeApiKey.Response, { id }))
316
335
  },
317
336
  )
337
+ .post(
338
+ '/:id/rotate',
339
+ OpenApi.validate('param', schema.rotateApiKey.Params, {
340
+ code: 'param_invalid',
341
+ message: 'Invalid path parameters',
342
+ }),
343
+ OpenApi.describeRoute({
344
+ description: 'Create a replacement that preserves the source key access and attribution. The source key remains active.', // prettier-ignore
345
+ operationId: 'rotateAdminApiKey',
346
+ responses: OpenApi.responses({
347
+ errors: { 404: 'API key not found.' },
348
+ success: {
349
+ description: 'Replacement key (includes the one-time token).',
350
+ schema: schema.rotateApiKey.Response,
351
+ },
352
+ }),
353
+ summary: 'Rotate API key',
354
+ tags: ['API keys'],
355
+ }),
356
+ async (c) => {
357
+ const { id } = c.req.valid('param')
358
+ const store = c.get('kv').store
359
+ const source = await ApiKeys.get(store, id)
360
+ if (!source)
361
+ return Response.error(c, {
362
+ code: 'not_found',
363
+ message: 'API key not found.',
364
+ status: 404,
365
+ })
366
+
367
+ const { record, token } = await ApiKeys.mint(store, {
368
+ allowedIps: source.allowedIps,
369
+ createdBy: c.get('identity')!.email,
370
+ environment: source.environment,
371
+ scopes: source.scopes,
372
+ ...(source.billingActive === undefined ? {} : { billingActive: source.billingActive }),
373
+ ...(source.expiresAt === undefined ? {} : { expiresAt: source.expiresAt }),
374
+ ...(source.name === undefined ? {} : { name: source.name }),
375
+ ...(source.orgId === source.id ? {} : { orgId: source.orgId }),
376
+ ...(source.projectId === undefined ? {} : { projectId: source.projectId }),
377
+ ...(source.rateLimits === undefined ? {} : { rateLimits: source.rateLimits }),
378
+ })
379
+ return c.json(Response.validated(schema.rotateApiKey.Response, { ...record, token }), 200)
380
+ },
381
+ )
318
382
  .patch(
319
383
  '/:id',
320
384
  OpenApi.validate('param', schema.updateApiKey.Params, {