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,13 +1,27 @@
1
- import { createFileRoute } from '@tanstack/react-router'
2
- import { type ReactNode, useState } from 'react'
1
+ import { useInfiniteQuery } from '@tanstack/react-query'
2
+ import { createFileRoute, useNavigate } from '@tanstack/react-router'
3
+ import { type ReactNode, useEffect, useId, useState } from 'react'
3
4
  import { Button, cx, Fields, Input, Rows, Select, useCopy } from 'regen-ui'
4
- import { Check, ChevronRight, Copy as CopyIcon, Plus, Trash2, X } from 'lucide-react'
5
+ import {
6
+ Check,
7
+ ChevronRight,
8
+ Copy as CopyIcon,
9
+ Pencil,
10
+ Plus,
11
+ Search,
12
+ Trash2,
13
+ TriangleAlert,
14
+ X,
15
+ } from 'lucide-react'
5
16
 
6
- import { Card, Notice, Page } from '../components/Page'
7
- import { Checkbox } from '../components/Checkbox'
8
- import { Dialog } from '../components/Dialog'
9
- import * as ApiKeys from '../lib/api-keys'
10
- import * as Scopes from '../lib/scopes'
17
+ import { Card, Notice, Page } from '../components/Page.js'
18
+ import { Checkbox } from '../components/Checkbox.js'
19
+ import { Dialog } from '../components/Dialog.js'
20
+ import * as ApiKeys from '../lib/api-keys.js'
21
+ import * as Config from '../lib/config.js'
22
+ import * as Format from '../lib/format.js'
23
+ import * as Organizations from '../lib/organizations.js'
24
+ import * as Scopes from '../lib/scopes.js'
11
25
 
12
26
  export const Route = createFileRoute('/api-keys')({
13
27
  validateSearch: ApiKeys.search,
@@ -22,10 +36,18 @@ export const Route = createFileRoute('/api-keys')({
22
36
 
23
37
  function RouteComponent() {
24
38
  const filters = Route.useSearch()
39
+ const navigate = useNavigate({ from: Route.fullPath })
25
40
  const [open, setOpen] = useState(false)
26
- const [environment, setEnvironment] = useState<'production' | 'sandbox'>('production')
41
+ const [query, setQuery] = useState(filters.query ?? '')
42
+ const environment = filters.environment ?? 'production'
43
+ const config = Config.use()
27
44
  const keys = ApiKeys.get.useQuery(filters)
28
45
  const provision = ApiKeys.provision.useMutation()
46
+ const records = (keys.data?.data ?? []).filter(
47
+ (record) => record.environment === environment && matches(record, filters.query),
48
+ )
49
+
50
+ useEffect(() => setQuery(filters.query ?? ''), [filters.query])
29
51
 
30
52
  function onSubmit(form: FormData) {
31
53
  const field = (key: string) => {
@@ -33,19 +55,29 @@ function RouteComponent() {
33
55
  return typeof value === 'string' ? value.trim() : ''
34
56
  }
35
57
  const name = field('name')
58
+ if (!name) {
59
+ alert('Enter a name that identifies what uses this key.')
60
+ return
61
+ }
62
+ const orgId = filters.orgId ?? field('orgId')
36
63
  const rateLimit = field('rateLimit')
37
64
  const perMinute = rateLimit ? Number(rateLimit) : undefined
38
65
  const environment = field('environment') === 'sandbox' ? 'sandbox' : 'production'
39
- const zoneChainId = field('zoneChainId')
40
- const pendingZoneScope = zoneChainId ? Scopes.fromZoneChainId(zoneChainId) : undefined
41
- if (zoneChainId && !pendingZoneScope) {
66
+ const pendingZoneScopes = (['read', 'write'] as const).map((access) => {
67
+ const chainId = field(`zoneChainId_${access}`)
68
+ return {
69
+ chainId,
70
+ scope: chainId ? Scopes.fromZoneChainId(chainId, access) : undefined,
71
+ }
72
+ })
73
+ if (pendingZoneScopes.some(({ chainId, scope }) => chainId && !scope)) {
42
74
  alert('Enter a positive integer Zone chain ID.')
43
75
  return
44
76
  }
45
77
  const scopes = [
46
78
  ...new Set([
47
79
  ...form.getAll('scopes').filter((v): v is string => typeof v === 'string'),
48
- ...(pendingZoneScope ? [pendingZoneScope] : []),
80
+ ...pendingZoneScopes.flatMap(({ scope }) => (scope ? [scope] : [])),
49
81
  ]),
50
82
  ]
51
83
  if (scopes.length === 0) {
@@ -55,11 +87,11 @@ function RouteComponent() {
55
87
  provision.mutate(
56
88
  {
57
89
  environment,
58
- scopes: scopes as ApiKeys.provision.Input['scopes'],
59
- ...(filters.orgId ? { orgId: filters.orgId } : {}),
60
- ...(name ? { name } : {}),
61
- ...(perMinute === undefined ? {} : { rateLimits: { '*': { perMinute } } }),
90
+ name,
91
+ ...(orgId ? { orgId } : {}),
62
92
  ...(filters.projectId ? { projectId: filters.projectId } : {}),
93
+ ...(perMinute === undefined ? {} : { rateLimits: { '*': { perMinute } } }),
94
+ scopes: scopes as ApiKeys.provision.Input['scopes'],
63
95
  },
64
96
  { onError: (error) => alert(error.message), onSuccess: () => setOpen(false) },
65
97
  )
@@ -84,7 +116,17 @@ function RouteComponent() {
84
116
  { label: 'Production', value: 'production' },
85
117
  { label: 'Sandbox', value: 'sandbox' },
86
118
  ]}
87
- onChange={(value) => setEnvironment(value as 'production' | 'sandbox')}
119
+ onChange={(value) =>
120
+ void navigate({
121
+ search: {
122
+ ...(value === 'sandbox' ? { environment: 'sandbox' as const } : {}),
123
+ ...(filters.orgId ? { orgId: filters.orgId } : {}),
124
+ ...(filters.projectId ? { projectId: filters.projectId } : {}),
125
+ ...(filters.query ? { query: filters.query } : {}),
126
+ },
127
+ to: '/api-keys',
128
+ })
129
+ }
88
130
  value={environment}
89
131
  />
90
132
  <Dialog.Trigger
@@ -101,13 +143,42 @@ function RouteComponent() {
101
143
  {provision.data ? (
102
144
  <TokenBanner onDismiss={() => provision.reset()} token={provision.data.token} />
103
145
  ) : null}
146
+ <form
147
+ className="flex gap-2"
148
+ onSubmit={(event) => {
149
+ event.preventDefault()
150
+ const next = query.trim()
151
+ void navigate({
152
+ search: {
153
+ ...(environment === 'sandbox' ? { environment } : {}),
154
+ ...(filters.orgId ? { orgId: filters.orgId } : {}),
155
+ ...(filters.projectId ? { projectId: filters.projectId } : {}),
156
+ ...(next ? { query: next } : {}),
157
+ },
158
+ to: '/api-keys',
159
+ })
160
+ }}
161
+ >
162
+ <div className="min-w-0 flex-1">
163
+ <Input
164
+ aria-label="Search API keys"
165
+ onChange={(event) => setQuery(event.target.value)}
166
+ placeholder="Name, key ID, organization, project, creator, or scope"
167
+ value={query}
168
+ />
169
+ </div>
170
+ <Button type="submit">
171
+ <Search className="size-4" />
172
+ Search
173
+ </Button>
174
+ </form>
104
175
  <KeyList
176
+ currentUser={config.data?.auth.identity?.email}
105
177
  environment={environment}
106
178
  error={keys.error}
107
- keys={(keys.data?.data ?? []).filter(
108
- (key) => (key.environment ?? 'production') === environment,
109
- )}
179
+ keys={records}
110
180
  loading={keys.isPending}
181
+ query={filters.query}
111
182
  />
112
183
  <Dialog.Popup className="flex max-h-[calc(100dvh-2rem)] flex-col overflow-hidden">
113
184
  <ProvisionForm
@@ -202,10 +273,11 @@ function ProvisionForm(props: {
202
273
  </div>
203
274
  ) : null}
204
275
  <Fields
205
- className="min-h-0 flex-1 gap-6 [grid-template-rows:auto_auto_auto_minmax(0,1fr)]"
276
+ className="min-h-0 flex-1 gap-6 [grid-template-rows:auto_auto_auto_auto_minmax(0,1fr)]"
206
277
  variant="default"
207
278
  >
208
- <Input label="Name" name="name" placeholder="e.g. production-api" />
279
+ <OrganizationAutocomplete orgId={props.orgId} />
280
+ <Input label="Name" name="name" placeholder="e.g. Explorer testnet" required />
209
281
  <div className="flex flex-col gap-2">
210
282
  <span className="label-13 text-foreground-secondary">Environment</span>
211
283
  <select
@@ -235,9 +307,14 @@ function ProvisionForm(props: {
235
307
  ) : (
236
308
  <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain border border-border">
237
309
  <Rows variant="surface">
238
- {(scopes.data?.data ?? []).map((entry) =>
239
- entry.scope === Scopes.zoneTemplate ? (
240
- <ZoneScopeRow description={entry.description} key={entry.scope} />
310
+ {(scopes.data?.data ?? []).map((entry) => {
311
+ const zoneAccess = Scopes.accessFromTemplate(entry.scope)
312
+ return zoneAccess ? (
313
+ <ZoneScopeRow
314
+ access={zoneAccess}
315
+ description={entry.description}
316
+ key={entry.scope}
317
+ />
241
318
  ) : (
242
319
  <Rows.Row
243
320
  key={entry.scope}
@@ -257,8 +334,8 @@ function ProvisionForm(props: {
257
334
  </span>
258
335
  </span>
259
336
  </Rows.Row>
260
- ),
261
- )}
337
+ )
338
+ })}
262
339
  </Rows>
263
340
  </div>
264
341
  )}
@@ -275,10 +352,152 @@ function ProvisionForm(props: {
275
352
  )
276
353
  }
277
354
 
278
- function ZoneScopeRow(props: { description: string }) {
355
+ function OrganizationAutocomplete(props: { orgId?: string | undefined }) {
356
+ const inputId = useId()
357
+ const hintId = useId()
358
+ const listId = useId()
359
+ const [activeIndex, setActiveIndex] = useState(-1)
360
+ const [dismissed, setDismissed] = useState(false)
361
+ const [focused, setFocused] = useState(false)
362
+ const [value, setValue] = useState(props.orgId ?? '')
363
+ const debouncedValue = useDebouncedValue(value, 300)
364
+ const searchableValue = Organizations.lookupQuery(value)
365
+ const query = searchableValue ? Organizations.lookupQuery(debouncedValue) : undefined
366
+ const organizations = useInfiniteQuery({
367
+ ...Organizations.list.options({ query }),
368
+ enabled: Boolean(query && !props.orgId),
369
+ })
370
+ const records =
371
+ query && searchableValue === query
372
+ ? (organizations.data?.pages.flatMap((page) => page.data) ?? [])
373
+ : []
374
+ const normalizedValue = value.trim()
375
+ const open = Boolean(focused && searchableValue && !dismissed)
376
+ const message = (() => {
377
+ if (normalizedValue.length < 3) return 'Type at least 3 characters to search.'
378
+ if (searchableValue !== query || organizations.isFetching) return 'Searching organizations…'
379
+ if (organizations.error) return organizations.error.message
380
+ return 'No organizations found.'
381
+ })()
382
+
383
+ useEffect(() => setActiveIndex(records.length ? 0 : -1), [query, records.length])
384
+
385
+ if (props.orgId) return <Input label="Organization" name="orgId" readOnly value={props.orgId} />
386
+
387
+ return (
388
+ <div className="flex min-w-0 flex-col gap-2">
389
+ <div className="relative">
390
+ <Input
391
+ aria-activedescendant={open && activeIndex >= 0 ? `${listId}-${activeIndex}` : undefined}
392
+ aria-autocomplete="list"
393
+ aria-controls={listId}
394
+ aria-describedby={hintId}
395
+ aria-expanded={open}
396
+ autoComplete="off"
397
+ id={inputId}
398
+ label="Organization (optional)"
399
+ name="orgId"
400
+ onBlur={() => setFocused(false)}
401
+ onChange={(event) => {
402
+ setDismissed(false)
403
+ setValue(event.target.value)
404
+ }}
405
+ onFocus={() => {
406
+ setDismissed(false)
407
+ setFocused(true)
408
+ }}
409
+ onKeyDown={(event) => {
410
+ if (event.key === 'Escape' && open) {
411
+ event.preventDefault()
412
+ event.stopPropagation()
413
+ setDismissed(true)
414
+ return
415
+ }
416
+ if (!open || records.length === 0) return
417
+ if (event.key === 'ArrowDown') {
418
+ event.preventDefault()
419
+ setActiveIndex((index) => (index + 1) % records.length)
420
+ return
421
+ }
422
+ if (event.key === 'ArrowUp') {
423
+ event.preventDefault()
424
+ setActiveIndex((index) => (index <= 0 ? records.length - 1 : index - 1))
425
+ return
426
+ }
427
+ const organization = records[activeIndex]
428
+ if (event.key === 'Enter' && organization) {
429
+ event.preventDefault()
430
+ setDismissed(true)
431
+ setValue(organization.id)
432
+ }
433
+ }}
434
+ placeholder="Search name or paste org_…"
435
+ role="combobox"
436
+ value={value}
437
+ />
438
+ {open ? (
439
+ <div
440
+ aria-describedby={hintId}
441
+ className="absolute top-full z-10 mt-1 max-h-64 w-full overflow-auto border border-border bg-surface py-1 shadow-lg"
442
+ id={listId}
443
+ role="listbox"
444
+ >
445
+ {records.length ? (
446
+ records.map((organization, index) => (
447
+ <div
448
+ aria-selected={index === activeIndex}
449
+ className={cx(
450
+ 'flex cursor-pointer flex-col gap-1 px-3 py-2 hover:bg-secondary-hover',
451
+ index === activeIndex ? 'bg-secondary-hover' : undefined,
452
+ )}
453
+ id={`${listId}-${index}`}
454
+ key={organization.id}
455
+ onClick={() => {
456
+ setDismissed(true)
457
+ setValue(organization.id)
458
+ }}
459
+ onMouseDown={(event) => event.preventDefault()}
460
+ onMouseMove={() => setActiveIndex(index)}
461
+ role="option"
462
+ >
463
+ <span className="truncate text-label-14 text-foreground">
464
+ {organization.name}
465
+ </span>
466
+ <span className="truncate font-mono text-label-12 text-foreground-secondary">
467
+ {organization.id}
468
+ </span>
469
+ </div>
470
+ ))
471
+ ) : (
472
+ <div className="px-3 py-2 text-label-13 text-foreground-secondary" role="status">
473
+ {message}
474
+ </div>
475
+ )}
476
+ </div>
477
+ ) : null}
478
+ </div>
479
+ <p className="text-label-12 text-foreground-secondary" id={hintId}>
480
+ Search by name, ID, or member email. Leave blank for a one-off key.
481
+ </p>
482
+ </div>
483
+ )
484
+ }
485
+
486
+ function useDebouncedValue(value: string, delay: number) {
487
+ const [debouncedValue, setDebouncedValue] = useState(value)
488
+
489
+ useEffect(() => {
490
+ const timeout = setTimeout(() => setDebouncedValue(value), delay)
491
+ return () => clearTimeout(timeout)
492
+ }, [delay, value])
493
+
494
+ return debouncedValue
495
+ }
496
+
497
+ function ZoneScopeRow(options: ZoneScopeRow.Props) {
279
498
  const [chainId, setChainId] = useState('')
280
499
  const [selected, setSelected] = useState<readonly string[]>([])
281
- const scope = Scopes.fromZoneChainId(chainId)
500
+ const scope = Scopes.fromZoneChainId(chainId, options.access)
282
501
  const duplicate = scope ? selected.includes(scope) : false
283
502
  const error =
284
503
  chainId && !scope
@@ -296,8 +515,10 @@ function ZoneScopeRow(props: { description: string }) {
296
515
  return (
297
516
  <Rows.Row className="min-h-[56px] flex-col items-stretch py-3" style={{ height: 'auto' }}>
298
517
  <span className="flex min-w-0 flex-col gap-0.5">
299
- <span className="text-label-13 text-foreground">{Scopes.zoneTemplate}</span>
300
- <span className="text-label-12 text-foreground-secondary">{props.description}</span>
518
+ <span className="text-label-13 text-foreground">
519
+ {Scopes.zoneTemplates[options.access]}
520
+ </span>
521
+ <span className="text-label-12 text-foreground-secondary">{options.description}</span>
301
522
  </span>
302
523
  <div className="flex items-start gap-2 max-sm:flex-col">
303
524
  <div className="min-w-0 flex-1 max-sm:w-full">
@@ -306,7 +527,7 @@ function ZoneScopeRow(props: { description: string }) {
306
527
  autoComplete="off"
307
528
  error={error}
308
529
  inputMode="numeric"
309
- name="zoneChainId"
530
+ name={`zoneChainId_${options.access}`}
310
531
  onChange={(event) => setChainId(event.target.value)}
311
532
  onKeyDown={(event) => {
312
533
  if (event.key !== 'Enter') return
@@ -316,7 +537,7 @@ function ZoneScopeRow(props: { description: string }) {
316
537
  pattern="[0-9]*"
317
538
  placeholder="421700001"
318
539
  prefix="zone:"
319
- suffix=":read"
540
+ suffix={`:${options.access}`}
320
541
  value={chainId}
321
542
  />
322
543
  </div>
@@ -356,11 +577,20 @@ function ZoneScopeRow(props: { description: string }) {
356
577
  )
357
578
  }
358
579
 
580
+ declare namespace ZoneScopeRow {
581
+ type Props = {
582
+ access: Scopes.ZoneAccess
583
+ description: string
584
+ }
585
+ }
586
+
359
587
  function KeyList(props: {
588
+ currentUser?: string | undefined
360
589
  environment: 'production' | 'sandbox'
361
590
  error: Error | null
362
591
  keys: readonly ApiKeys.ApiKey[]
363
592
  loading: boolean
593
+ query?: string | undefined
364
594
  }) {
365
595
  return (
366
596
  <Card>
@@ -369,11 +599,15 @@ function KeyList(props: {
369
599
  ) : props.error ? (
370
600
  <Notice>{props.error.message}</Notice>
371
601
  ) : props.keys.length === 0 ? (
372
- <Notice>No {props.environment} keys yet.</Notice>
602
+ <Notice>
603
+ {props.query
604
+ ? `No ${props.environment} keys match “${props.query}”.`
605
+ : `No ${props.environment} keys yet.`}
606
+ </Notice>
373
607
  ) : (
374
608
  <Rows variant="surface">
375
609
  {props.keys.map((key) => (
376
- <KeyRow key={key.id} record={key} />
610
+ <KeyRow currentUser={props.currentUser} key={key.id} record={key} />
377
611
  ))}
378
612
  </Rows>
379
613
  )}
@@ -381,17 +615,11 @@ function KeyList(props: {
381
615
  )
382
616
  }
383
617
 
384
- function KeyRow(props: { record: ApiKeys.ApiKey }) {
385
- const { record } = props
618
+ function KeyRow(props: { currentUser?: string | undefined; record: ApiKeys.ApiKey }) {
619
+ const { currentUser, record } = props
386
620
  const [expanded, setExpanded] = useState(false)
387
- const revoke = ApiKeys.revoke.useMutation()
388
621
  const perMinute = record.rateLimits?.['*']?.perMinute
389
622
 
390
- function onRevoke() {
391
- if (!confirm(`Revoke key ${record.name ?? record.id}? This can't be undone.`)) return
392
- revoke.mutate(record.id, { onError: (error) => alert(error.message) })
393
- }
394
-
395
623
  return (
396
624
  <>
397
625
  <Rows.Row
@@ -399,18 +627,25 @@ function KeyRow(props: { record: ApiKeys.ApiKey }) {
399
627
  onClick={() => setExpanded((value) => !value)}
400
628
  style={{ height: 'auto' }}
401
629
  >
402
- <span className="flex min-w-0 flex-1 items-baseline gap-2">
403
- <span className="truncate text-label-14 text-foreground">
404
- {record.name ?? 'Unnamed key'}
630
+ <span className="flex min-w-0 flex-1 flex-col gap-0.5">
631
+ <span className="flex min-w-0 items-baseline gap-2">
632
+ <span className="truncate text-label-14 text-foreground">
633
+ {record.name ?? 'Unnamed key'}
634
+ </span>
635
+ {record.environment === 'sandbox' ? (
636
+ <span className="shrink-0 rounded-none bg-warning-subtle px-2 py-0.5 text-label-12 font-normal text-warning">
637
+ sandbox
638
+ </span>
639
+ ) : null}
405
640
  </span>
406
- {record.environment === 'sandbox' ? (
407
- <span className="shrink-0 rounded-none bg-warning-subtle px-2 py-0.5 text-label-12 font-normal text-warning">
408
- sandbox
641
+ {record.organizationName ? (
642
+ <span className="truncate text-label-12 text-foreground-secondary">
643
+ {record.organizationName}
409
644
  </span>
410
645
  ) : null}
411
646
  </span>
412
647
  <span className="shrink-0 text-label-12 text-foreground-secondary">
413
- {formatDate(record.createdAt)}
648
+ {Format.date(record.createdAt)}
414
649
  </span>
415
650
  <ChevronRight
416
651
  aria-hidden
@@ -427,9 +662,11 @@ function KeyRow(props: { record: ApiKeys.ApiKey }) {
427
662
  {perMinute === undefined ? 'Inherited' : `${perMinute} req/min`}
428
663
  </Detail>
429
664
  <Detail label="Token">···{record.tokenLast4}</Detail>
430
- <Detail label="Provisioned by">{record.createdBy ?? '—'}</Detail>
665
+ <Detail label="Organization">{organization(record)}</Detail>
666
+ <Detail label="Project">{project(record)}</Detail>
667
+ <Detail label="Provisioned by">{record.createdByLabel ?? 'Unknown'}</Detail>
431
668
  {record.expiresAt ? (
432
- <Detail label="Expires">{formatDate(record.expiresAt)}</Detail>
669
+ <Detail label="Expires">{Format.date(record.expiresAt)}</Detail>
433
670
  ) : null}
434
671
  <Detail className="w-full" label="Scopes">
435
672
  {record.scopes.length === 0 ? (
@@ -445,11 +682,9 @@ function KeyRow(props: { record: ApiKeys.ApiKey }) {
445
682
  )}
446
683
  </Detail>
447
684
  </dl>
448
- <div className="flex justify-end border-t border-border px-5 py-3">
449
- <Button loading={revoke.isPending} onClick={onRevoke} size="small" variant="negative">
450
- <Trash2 className="size-4" />
451
- Revoke key
452
- </Button>
685
+ <div className="flex justify-end gap-2 border-t border-border px-5 py-3">
686
+ <EditDialog record={record} />
687
+ <RevokeDialog currentUser={currentUser} record={record} />
453
688
  </div>
454
689
  </Rows.Panel>
455
690
  ) : null}
@@ -457,6 +692,163 @@ function KeyRow(props: { record: ApiKeys.ApiKey }) {
457
692
  )
458
693
  }
459
694
 
695
+ function EditDialog(options: EditDialog.Props) {
696
+ const { record } = options
697
+ const [open, setOpen] = useState(false)
698
+ const update = ApiKeys.update.useMutation()
699
+ return (
700
+ <Dialog.Root onOpenChange={setOpen} open={open}>
701
+ <Dialog.Trigger
702
+ render={
703
+ <Button size="small">
704
+ <Pencil className="size-4" />
705
+ Edit
706
+ </Button>
707
+ }
708
+ />
709
+ <Dialog.Popup>
710
+ <Dialog.Title>Edit API key</Dialog.Title>
711
+ <Dialog.Description>
712
+ {record.orgId === record.id
713
+ ? 'Update its name or associate it with an organization. New activity may take about a minute to appear there.'
714
+ : 'Use a name that identifies the service or integration using this key.'}
715
+ </Dialog.Description>
716
+ <form
717
+ className="mt-6 flex flex-col gap-6"
718
+ key={open ? 'open' : 'closed'}
719
+ onSubmit={(event) => {
720
+ event.preventDefault()
721
+ const form = new FormData(event.currentTarget)
722
+ const name = form.get('name')
723
+ const orgId = form.get('orgId')
724
+ if (typeof name !== 'string' || !name.trim()) return
725
+ update.mutate(
726
+ {
727
+ id: record.id,
728
+ input: {
729
+ name: name.trim(),
730
+ ...(typeof orgId === 'string' && orgId.trim() ? { orgId: orgId.trim() } : {}),
731
+ },
732
+ },
733
+ {
734
+ onError: (error) => alert(error.message),
735
+ onSuccess: () => setOpen(false),
736
+ },
737
+ )
738
+ }}
739
+ >
740
+ <Input
741
+ autoFocus
742
+ defaultValue={record.name ?? ''}
743
+ label="Name"
744
+ name="name"
745
+ placeholder="e.g. Explorer testnet"
746
+ required
747
+ />
748
+ {record.orgId === record.id ? <OrganizationAutocomplete /> : null}
749
+ <div className="flex justify-end gap-2">
750
+ <Dialog.Close render={<Button type="button">Cancel</Button>} />
751
+ <Button loading={update.isPending} type="submit" variant="primary">
752
+ Save changes
753
+ </Button>
754
+ </div>
755
+ </form>
756
+ </Dialog.Popup>
757
+ </Dialog.Root>
758
+ )
759
+ }
760
+
761
+ declare namespace EditDialog {
762
+ type Props = {
763
+ record: ApiKeys.ApiKey
764
+ }
765
+ }
766
+
767
+ function RevokeDialog(props: { currentUser?: string | undefined; record: ApiKeys.ApiKey }) {
768
+ const { currentUser, record } = props
769
+ const [confirmation, setConfirmation] = useState('')
770
+ const [open, setOpen] = useState(false)
771
+ const revoke = ApiKeys.revoke.useMutation()
772
+ const expected = record.name ?? record.id
773
+ const creator = record.createdByLabel
774
+ const differentCreator =
775
+ !!creator && !!currentUser && creator.toLowerCase() !== currentUser.toLowerCase()
776
+
777
+ return (
778
+ <Dialog.Root
779
+ onOpenChange={(value) => {
780
+ setOpen(value)
781
+ if (!value) setConfirmation('')
782
+ }}
783
+ open={open}
784
+ >
785
+ <Dialog.Trigger
786
+ render={
787
+ <Button size="small" variant="negative">
788
+ <Trash2 className="size-4" />
789
+ Revoke key
790
+ </Button>
791
+ }
792
+ />
793
+ <Dialog.Popup>
794
+ <Dialog.Title>Revoke {record.name ?? 'API key'}?</Dialog.Title>
795
+ <Dialog.Description>
796
+ Requests using this key will fail immediately. This action cannot be undone.
797
+ </Dialog.Description>
798
+ <dl className="mt-5 grid grid-cols-2 gap-4 border border-border bg-secondary p-4">
799
+ <Detail className="col-span-2" label="Key ID">
800
+ <code className="break-all">{record.id}</code>
801
+ </Detail>
802
+ <Detail label="Environment">{record.environment}</Detail>
803
+ <Detail label="Organization">{organization(record)}</Detail>
804
+ <Detail label="Project">{project(record)}</Detail>
805
+ <Detail label="Provisioned by">{creator ?? 'Unknown'}</Detail>
806
+ <Detail label="Rate limit">
807
+ {record.rateLimits?.['*']?.perMinute === undefined
808
+ ? 'Inherited'
809
+ : `${record.rateLimits['*']!.perMinute} req/min`}
810
+ </Detail>
811
+ </dl>
812
+ {differentCreator ? (
813
+ <div className="mt-4 flex gap-3 border border-warning bg-warning-subtle p-3 text-warning">
814
+ <TriangleAlert className="mt-0.5 size-4 shrink-0" />
815
+ <p className="text-copy-13">
816
+ This key was provisioned by {creator}. Confirm it is no longer in use before revoking
817
+ it.
818
+ </p>
819
+ </div>
820
+ ) : null}
821
+ <div className="mt-5">
822
+ <Input
823
+ autoComplete="off"
824
+ label={`Type “${expected}” to confirm`}
825
+ onChange={(event) => setConfirmation(event.target.value)}
826
+ value={confirmation}
827
+ />
828
+ </div>
829
+ {revoke.error ? (
830
+ <p className="mt-3 text-copy-13 text-negative">{revoke.error.message}</p>
831
+ ) : null}
832
+ <div className="mt-6 flex justify-end gap-2">
833
+ <Dialog.Close render={<Button type="button">Cancel</Button>} />
834
+ <Button
835
+ disabled={confirmation !== expected}
836
+ loading={revoke.isPending}
837
+ onClick={() =>
838
+ revoke.mutate(record.id, {
839
+ onSuccess: () => setOpen(false),
840
+ })
841
+ }
842
+ variant="negative"
843
+ >
844
+ Revoke key
845
+ </Button>
846
+ </div>
847
+ </Dialog.Popup>
848
+ </Dialog.Root>
849
+ )
850
+ }
851
+
460
852
  function Detail(props: { children: ReactNode; className?: string; label: ReactNode }) {
461
853
  return (
462
854
  <div className={cx('flex min-w-0 flex-col gap-1', props.className)}>
@@ -466,10 +858,29 @@ function Detail(props: { children: ReactNode; className?: string; label: ReactNo
466
858
  )
467
859
  }
468
860
 
469
- function formatDate(iso: string) {
470
- return new Date(iso).toLocaleDateString(undefined, {
471
- day: 'numeric',
472
- month: 'short',
473
- year: 'numeric',
474
- })
861
+ function matches(record: ApiKeys.ApiKey, query?: string) {
862
+ const normalized = query?.trim().toLowerCase()
863
+ if (!normalized) return true
864
+ return [
865
+ record.createdBy,
866
+ record.createdByLabel,
867
+ record.id,
868
+ record.name,
869
+ record.organizationName,
870
+ record.orgId,
871
+ record.projectId,
872
+ record.projectName,
873
+ record.tokenLast4,
874
+ ...record.scopes,
875
+ ].some((value) => value?.toLowerCase().includes(normalized))
876
+ }
877
+
878
+ function organization(record: ApiKeys.ApiKey) {
879
+ if (!record.organizationName) return '-'
880
+ return `${record.organizationName} (${record.orgId})`
881
+ }
882
+
883
+ function project(record: ApiKeys.ApiKey) {
884
+ if (!record.projectId || !record.projectName) return '-'
885
+ return `${record.projectName} (${record.projectId})`
475
886
  }