tapimo 0.7.2 → 0.9.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 (300) hide show
  1. package/README.md +10 -7
  2. package/dist/ApiKey.d.ts +3 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +10 -0
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +7 -3
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +9 -2
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +20117 -19183
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +61 -4
  13. package/dist/App.js.map +1 -1
  14. package/dist/admin/App.d.ts +84 -74
  15. package/dist/admin/App.d.ts.map +1 -1
  16. package/dist/admin/apps/api-keys.d.ts +14 -1
  17. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  18. package/dist/admin/apps/api-keys.js +6 -2
  19. package/dist/admin/apps/api-keys.js.map +1 -1
  20. package/dist/admin/apps/organizations.d.ts +2 -0
  21. package/dist/admin/apps/organizations.d.ts.map +1 -1
  22. package/dist/admin/apps/verified-tokens.d.ts +11 -11
  23. package/dist/admin/ui.generated.d.ts +1 -1
  24. package/dist/admin/ui.generated.js +67 -67
  25. package/dist/admin/ui.generated.js.map +1 -1
  26. package/dist/analytics/Analytics.d.ts +2 -0
  27. package/dist/analytics/Analytics.d.ts.map +1 -1
  28. package/dist/analytics/Analytics.js +3 -0
  29. package/dist/analytics/Analytics.js.map +1 -1
  30. package/dist/apps/data/App.d.ts +11696 -13937
  31. package/dist/apps/data/App.d.ts.map +1 -1
  32. package/dist/apps/data/App.js +4 -8
  33. package/dist/apps/data/App.js.map +1 -1
  34. package/dist/apps/data/routes/activities.d.ts +271 -271
  35. package/dist/apps/data/routes/addresses.d.ts +398 -167
  36. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  37. package/dist/apps/data/routes/balances.d.ts +278 -8
  38. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  39. package/dist/apps/data/routes/balances.js +114 -2
  40. package/dist/apps/data/routes/balances.js.map +1 -1
  41. package/dist/apps/data/routes/blocks.d.ts +123 -123
  42. package/dist/apps/data/routes/coingecko.d.ts +170 -170
  43. package/dist/apps/data/routes/earn.d.ts +498 -6
  44. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  45. package/dist/apps/data/routes/earn.js +876 -4
  46. package/dist/apps/data/routes/earn.js.map +1 -1
  47. package/dist/apps/data/routes/exchanges.d.ts +10 -10
  48. package/dist/apps/data/routes/fee-amm.d.ts +2 -2
  49. package/dist/apps/data/routes/indexer.d.ts +6 -6
  50. package/dist/apps/data/routes/indexer.js +4 -1
  51. package/dist/apps/data/routes/indexer.js.map +1 -1
  52. package/dist/apps/data/routes/receipts.d.ts +235 -235
  53. package/dist/apps/data/routes/rpc.d.ts +31 -31
  54. package/dist/apps/data/routes/rpc.js +4 -1
  55. package/dist/apps/data/routes/rpc.js.map +1 -1
  56. package/dist/apps/data/routes/tokenlist.d.ts +36 -36
  57. package/dist/apps/data/routes/tokens.d.ts +449 -449
  58. package/dist/apps/data/routes/transactions.d.ts +2 -2
  59. package/dist/apps/data/routes/transfers.d.ts +81 -81
  60. package/dist/apps/data/routes/valuation.d.ts +1 -1
  61. package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
  62. package/dist/apps/data/routes/webhooks.d.ts +9 -9
  63. package/dist/apps/data/routes/zones.d.ts +14 -14
  64. package/dist/apps/funding/Access.d.ts +16 -0
  65. package/dist/apps/funding/Access.d.ts.map +1 -0
  66. package/dist/apps/funding/Access.js +22 -0
  67. package/dist/apps/funding/Access.js.map +1 -0
  68. package/dist/apps/{data/routes/funding.d.ts → funding/App.d.ts} +1640 -3217
  69. package/dist/apps/funding/App.d.ts.map +1 -0
  70. package/dist/apps/funding/App.js +61 -0
  71. package/dist/apps/funding/App.js.map +1 -0
  72. package/dist/apps/funding/Inventory.d.ts +5 -0
  73. package/dist/apps/funding/Inventory.d.ts.map +1 -0
  74. package/dist/apps/funding/Inventory.js +25 -0
  75. package/dist/apps/funding/Inventory.js.map +1 -0
  76. package/dist/apps/funding/ProviderAttempts.d.ts +5 -0
  77. package/dist/apps/funding/ProviderAttempts.d.ts.map +1 -0
  78. package/dist/apps/funding/ProviderAttempts.js +24 -0
  79. package/dist/apps/funding/ProviderAttempts.js.map +1 -0
  80. package/dist/apps/funding/index.d.ts +2 -0
  81. package/dist/apps/funding/index.d.ts.map +1 -0
  82. package/dist/apps/funding/index.js +2 -0
  83. package/dist/apps/funding/index.js.map +1 -0
  84. package/dist/apps/funding/routes/chains.d.ts +169 -0
  85. package/dist/apps/funding/routes/chains.d.ts.map +1 -0
  86. package/dist/apps/funding/routes/chains.js +80 -0
  87. package/dist/apps/funding/routes/chains.js.map +1 -0
  88. package/dist/apps/funding/routes/deposit-addresses.d.ts +1997 -0
  89. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -0
  90. package/dist/apps/funding/routes/deposit-addresses.js +778 -0
  91. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -0
  92. package/dist/apps/funding/routes/providers.d.ts +91 -0
  93. package/dist/apps/funding/routes/providers.d.ts.map +1 -0
  94. package/dist/apps/funding/routes/providers.js +56 -0
  95. package/dist/apps/funding/routes/providers.js.map +1 -0
  96. package/dist/apps/funding/routes/quotes.d.ts +426 -0
  97. package/dist/apps/funding/routes/quotes.d.ts.map +1 -0
  98. package/dist/apps/funding/routes/quotes.js +188 -0
  99. package/dist/apps/funding/routes/quotes.js.map +1 -0
  100. package/dist/apps/funding/routes/transfers.d.ts +1999 -0
  101. package/dist/apps/funding/routes/transfers.d.ts.map +1 -0
  102. package/dist/apps/funding/routes/transfers.js +614 -0
  103. package/dist/apps/funding/routes/transfers.js.map +1 -0
  104. package/dist/apps/index.d.ts +1 -0
  105. package/dist/apps/index.d.ts.map +1 -1
  106. package/dist/apps/index.js +1 -0
  107. package/dist/apps/index.js.map +1 -1
  108. package/dist/apps/management/App.d.ts +430 -165
  109. package/dist/apps/management/App.d.ts.map +1 -1
  110. package/dist/apps/management/routes/api-keys.d.ts +298 -21
  111. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  112. package/dist/apps/management/routes/api-keys.js +75 -1
  113. package/dist/apps/management/routes/api-keys.js.map +1 -1
  114. package/dist/apps/management/routes/billing.d.ts +6 -6
  115. package/dist/apps/management/routes/faucet.d.ts +35 -35
  116. package/dist/apps/management/routes/invitations.d.ts +122 -122
  117. package/dist/apps/management/routes/invite-links.d.ts +38 -38
  118. package/dist/apps/management/routes/members.d.ts +69 -69
  119. package/dist/apps/management/routes/orgs.d.ts +99 -99
  120. package/dist/apps/management/routes/projects.d.ts +25 -25
  121. package/dist/apps/management/routes/scopes.d.ts +1 -1
  122. package/dist/apps/management/routes/usage.d.ts +72 -72
  123. package/dist/apps/management/routes/verified-token-requests.d.ts +77 -77
  124. package/dist/apps/management/routes/webhooks.d.ts +128 -128
  125. package/dist/apps/mcp.d.ts +2 -3
  126. package/dist/apps/mcp.d.ts.map +1 -1
  127. package/dist/apps/mcp.js +16 -14
  128. package/dist/apps/mcp.js.map +1 -1
  129. package/dist/apps/metadata.d.ts +4 -0
  130. package/dist/apps/metadata.d.ts.map +1 -1
  131. package/dist/apps/metadata.js +10 -0
  132. package/dist/apps/metadata.js.map +1 -1
  133. package/dist/apps/mpp/App.d.ts +44 -44
  134. package/dist/cloudflare.d.ts +50 -0
  135. package/dist/cloudflare.d.ts.map +1 -1
  136. package/dist/cloudflare.js +178 -0
  137. package/dist/cloudflare.js.map +1 -1
  138. package/dist/db/Db.d.ts +2 -0
  139. package/dist/db/Db.d.ts.map +1 -1
  140. package/dist/db/Db.js +45 -0
  141. package/dist/db/Db.js.map +1 -1
  142. package/dist/db/Schema.d.ts +12 -0
  143. package/dist/db/Schema.d.ts.map +1 -1
  144. package/dist/db/Schema.js +20 -0
  145. package/dist/db/Schema.js.map +1 -1
  146. package/dist/db/tables/fundingDepositAddresses.d.ts +13 -0
  147. package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -1
  148. package/dist/db/tables/fundingDepositAddresses.js +12 -0
  149. package/dist/db/tables/fundingDepositAddresses.js.map +1 -1
  150. package/dist/db/tables/fundingDepositRequestObservations.d.ts +45 -0
  151. package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +1 -0
  152. package/dist/db/tables/fundingDepositRequestObservations.js +46 -0
  153. package/dist/db/tables/fundingDepositRequestObservations.js.map +1 -0
  154. package/dist/db/tables/fundingDeposits.d.ts +74 -1
  155. package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
  156. package/dist/db/tables/fundingDeposits.js +126 -0
  157. package/dist/db/tables/fundingDeposits.js.map +1 -1
  158. package/dist/internal/Auth.d.ts +15 -11
  159. package/dist/internal/Auth.d.ts.map +1 -1
  160. package/dist/internal/Auth.js +52 -17
  161. package/dist/internal/Auth.js.map +1 -1
  162. package/dist/internal/Cache.js +1 -1
  163. package/dist/internal/Cache.js.map +1 -1
  164. package/dist/internal/EdgeCache.d.ts +2 -2
  165. package/dist/internal/EdgeCache.d.ts.map +1 -1
  166. package/dist/internal/EdgeCache.js +10 -4
  167. package/dist/internal/EdgeCache.js.map +1 -1
  168. package/dist/internal/IpAllowlist.d.ts +15 -0
  169. package/dist/internal/IpAllowlist.d.ts.map +1 -0
  170. package/dist/internal/IpAllowlist.js +27 -0
  171. package/dist/internal/IpAllowlist.js.map +1 -0
  172. package/dist/internal/OpenApi.d.ts +1 -1
  173. package/dist/internal/OpenApi.js +1 -1
  174. package/dist/internal/OpenApi.js.map +1 -1
  175. package/dist/internal/Tidx.d.ts +6 -0
  176. package/dist/internal/Tidx.d.ts.map +1 -1
  177. package/dist/internal/Tidx.js +13 -3
  178. package/dist/internal/Tidx.js.map +1 -1
  179. package/dist/internal/Viem.d.ts +8 -0
  180. package/dist/internal/Viem.d.ts.map +1 -1
  181. package/dist/internal/Viem.js +12 -5
  182. package/dist/internal/Viem.js.map +1 -1
  183. package/dist/internal/funding/Deposit.d.ts +42 -0
  184. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  185. package/dist/internal/funding/Deposit.js +37 -5
  186. package/dist/internal/funding/Deposit.js.map +1 -1
  187. package/dist/internal/funding/Evidence.d.ts +1 -5
  188. package/dist/internal/funding/Evidence.d.ts.map +1 -1
  189. package/dist/internal/funding/Evidence.js +4 -3
  190. package/dist/internal/funding/Evidence.js.map +1 -1
  191. package/dist/internal/funding/Provider.d.ts +102 -0
  192. package/dist/internal/funding/Provider.d.ts.map +1 -1
  193. package/dist/internal/funding/Provider.js +5 -0
  194. package/dist/internal/funding/Provider.js.map +1 -1
  195. package/dist/internal/funding/Reconciliation.d.ts +16 -2
  196. package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
  197. package/dist/internal/funding/Reconciliation.js +348 -54
  198. package/dist/internal/funding/Reconciliation.js.map +1 -1
  199. package/dist/internal/funding/SourceObservation.d.ts +108 -0
  200. package/dist/internal/funding/SourceObservation.d.ts.map +1 -0
  201. package/dist/internal/funding/SourceObservation.js +143 -0
  202. package/dist/internal/funding/SourceObservation.js.map +1 -0
  203. package/dist/internal/funding/Subsidy.d.ts +2 -2
  204. package/dist/internal/funding/Subsidy.d.ts.map +1 -1
  205. package/dist/internal/funding/Subsidy.js +1 -1
  206. package/dist/internal/funding/Subsidy.js.map +1 -1
  207. package/dist/internal/funding/index.d.ts +1 -0
  208. package/dist/internal/funding/index.d.ts.map +1 -1
  209. package/dist/internal/funding/index.js +1 -0
  210. package/dist/internal/funding/index.js.map +1 -1
  211. package/dist/internal/funding/providers/relay.d.ts +43 -1
  212. package/dist/internal/funding/providers/relay.d.ts.map +1 -1
  213. package/dist/internal/funding/providers/relay.js +438 -27
  214. package/dist/internal/funding/providers/relay.js.map +1 -1
  215. package/package.json +3 -3
  216. package/src/ApiKey.test.ts +35 -0
  217. package/src/ApiKey.ts +27 -0
  218. package/src/ApiKeys.test.ts +29 -0
  219. package/src/ApiKeys.ts +11 -3
  220. package/src/App.test.ts +55 -5
  221. package/src/App.ts +79 -5
  222. package/src/Client.test-d.ts +203 -28
  223. package/src/admin/apps/api-keys.test.ts +25 -1
  224. package/src/admin/apps/api-keys.ts +6 -2
  225. package/src/admin/ui.generated.ts +67 -67
  226. package/src/analytics/Analytics.ts +4 -0
  227. package/src/apps/composition.test.ts +130 -3
  228. package/src/apps/data/App.test.ts +0 -12
  229. package/src/apps/data/App.ts +4 -8
  230. package/src/apps/data/routes/balances.test.ts +42 -0
  231. package/src/apps/data/routes/balances.ts +218 -85
  232. package/src/apps/data/routes/earn.test.ts +363 -0
  233. package/src/apps/data/routes/earn.ts +1141 -3
  234. package/src/apps/data/routes/indexer.ts +2 -1
  235. package/src/apps/data/routes/rpc.ts +2 -0
  236. package/src/apps/data/routes/tokens.test.ts +6 -8
  237. package/src/apps/funding/Access.ts +26 -0
  238. package/src/apps/funding/App.test.ts +78 -0
  239. package/src/apps/funding/App.ts +78 -0
  240. package/src/apps/funding/Inventory.ts +30 -0
  241. package/src/apps/funding/ProviderAttempts.ts +26 -0
  242. package/src/apps/funding/index.ts +1 -0
  243. package/src/apps/funding/routes/chains.test.ts +78 -0
  244. package/src/apps/funding/routes/chains.ts +101 -0
  245. package/src/apps/funding/routes/deposit-addresses.test.ts +1649 -0
  246. package/src/apps/funding/routes/deposit-addresses.ts +932 -0
  247. package/src/apps/funding/routes/providers.test.ts +165 -0
  248. package/src/apps/funding/routes/providers.ts +73 -0
  249. package/src/apps/funding/routes/quotes.test.ts +511 -0
  250. package/src/apps/funding/routes/quotes.ts +205 -0
  251. package/src/apps/funding/routes/transfers.test.ts +1236 -0
  252. package/src/apps/funding/routes/transfers.ts +704 -0
  253. package/src/apps/index.ts +1 -0
  254. package/src/apps/management/routes/api-keys.test.ts +98 -0
  255. package/src/apps/management/routes/api-keys.ts +96 -1
  256. package/src/apps/mcp.test.ts +17 -2
  257. package/src/apps/mcp.ts +18 -13
  258. package/src/apps/metadata.ts +12 -0
  259. package/src/apps/mpp/internal/Policy.test.ts +7 -1
  260. package/src/cloudflare.ts +279 -0
  261. package/src/db/Db.ts +71 -0
  262. package/src/db/Schema.ts +24 -0
  263. package/src/db/tables/fundingDepositAddresses.ts +28 -0
  264. package/src/db/tables/fundingDepositRequestObservations.test.ts +106 -0
  265. package/src/db/tables/fundingDepositRequestObservations.ts +99 -0
  266. package/src/db/tables/fundingDeposits.test.ts +239 -0
  267. package/src/db/tables/fundingDeposits.ts +214 -1
  268. package/src/internal/Auth.test.ts +205 -5
  269. package/src/internal/Auth.ts +63 -19
  270. package/src/internal/Cache.test.ts +37 -3
  271. package/src/internal/Cache.ts +1 -1
  272. package/src/internal/EdgeCache.test.ts +7 -7
  273. package/src/internal/EdgeCache.ts +13 -4
  274. package/src/internal/IpAllowlist.test.ts +52 -0
  275. package/src/internal/IpAllowlist.ts +39 -0
  276. package/src/internal/Log.test.ts +7 -1
  277. package/src/internal/OpenApi.ts +1 -1
  278. package/src/internal/Tidx.test.ts +28 -0
  279. package/src/internal/Tidx.ts +19 -3
  280. package/src/internal/Viem.test.ts +28 -0
  281. package/src/internal/Viem.ts +21 -5
  282. package/src/internal/funding/Deposit.ts +74 -5
  283. package/src/internal/funding/Evidence.test.ts +2 -2
  284. package/src/internal/funding/Evidence.ts +4 -9
  285. package/src/internal/funding/Provider.ts +115 -0
  286. package/src/internal/funding/Reconciliation.local.test.ts +7 -0
  287. package/src/internal/funding/Reconciliation.test.ts +1364 -109
  288. package/src/internal/funding/Reconciliation.ts +467 -88
  289. package/src/internal/funding/SourceObservation.test.ts +301 -0
  290. package/src/internal/funding/SourceObservation.ts +267 -0
  291. package/src/internal/funding/Subsidy.ts +2 -2
  292. package/src/internal/funding/index.test.ts +1 -0
  293. package/src/internal/funding/index.ts +1 -0
  294. package/src/internal/funding/providers/relay.test.ts +94 -4
  295. package/src/internal/funding/providers/relay.ts +533 -27
  296. package/dist/apps/data/routes/funding.d.ts.map +0 -1
  297. package/dist/apps/data/routes/funding.js +0 -1557
  298. package/dist/apps/data/routes/funding.js.map +0 -1
  299. package/src/apps/data/routes/funding.test.ts +0 -2994
  300. package/src/apps/data/routes/funding.ts +0 -1821
@@ -11,7 +11,10 @@ import type * as EarnRates from './internal/EarnRates.js'
11
11
  import * as Exchanges from './apps/data/routes/exchanges.js'
12
12
  import * as Faucet from './apps/management/routes/faucet.js'
13
13
  import * as FeeAmm from './apps/data/routes/fee-amm.js'
14
- import * as Funding from './apps/data/routes/funding.js'
14
+ import * as FundingChains from './apps/funding/routes/chains.js'
15
+ import * as FundingDepositAddresses from './apps/funding/routes/deposit-addresses.js'
16
+ import * as FundingQuotes from './apps/funding/routes/quotes.js'
17
+ import * as FundingTransfers from './apps/funding/routes/transfers.js'
15
18
  import type * as FundingDepositAddress from './internal/funding/DepositAddress.js'
16
19
  import * as Indexer from './apps/data/routes/indexer.js'
17
20
  import * as InviteLinks from './apps/management/routes/invite-links.js'
@@ -141,7 +144,7 @@ describe('narrows responses by status', () => {
141
144
  }
142
145
  case 403: {
143
146
  const json = await res.json()
144
- expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden'>()
147
+ expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden' | 'api_key_ip_forbidden'>()
145
148
  expectTypeOf(json.error.message).toEqualTypeOf<string>()
146
149
  void json
147
150
  return
@@ -357,6 +360,61 @@ describe('narrows responses by status', () => {
357
360
  }
358
361
  })
359
362
 
363
+ test('GET /v1/earn/vaults/:vaultId/earnings/:address', async () => {
364
+ const client = Client.create()
365
+ const res = await client.v1.earn.vaults[':vaultId'].earnings[':address'].$get({
366
+ param: {
367
+ address: `0x${'bb'.repeat(20)}`,
368
+ vaultId: `0x${'aa'.repeat(20)}`,
369
+ },
370
+ })
371
+
372
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
373
+
374
+ if (res.status === 200) {
375
+ const json = await res.json()
376
+ expectTypeOf(json).toEqualTypeOf<z.output<typeof Earn.schema.getEarnVaultEarnings.Response>>()
377
+ expectTypeOf(json.account).toEqualTypeOf<`0x${string}`>()
378
+ expectTypeOf(json.assetToken).toEqualTypeOf<`0x${string}`>()
379
+ expectTypeOf(json.currentValue).toEqualTypeOf<string>()
380
+ expectTypeOf(json.id).toEqualTypeOf<`0x${string}`>()
381
+ expectTypeOf(json.period).toEqualTypeOf<'30d' | 'active' | 'lifetime'>()
382
+ expectTypeOf(json.status).toEqualTypeOf<
383
+ 'complete' | 'incomplete_cost_basis' | 'pending_redemption'
384
+ >()
385
+ if (json.status === 'complete' && json.period === 'active')
386
+ expectTypeOf(json.activeEarnings).toEqualTypeOf<string>()
387
+ if (json.status === 'complete' && json.period === 'lifetime')
388
+ expectTypeOf(json.lifetimeEarnings).toEqualTypeOf<string>()
389
+ if (json.status === 'complete' && json.period === '30d')
390
+ expectTypeOf(json.windowEarnings).toEqualTypeOf<string>()
391
+ void json
392
+ return
393
+ }
394
+ if (res.status === 400) {
395
+ const json = await res.json()
396
+ expectTypeOf(json.error.code).toEqualTypeOf<
397
+ Access400<
398
+ 'chain_id_invalid' | 'chain_id_unsupported' | 'earnings_invalid' | 'query_invalid'
399
+ >
400
+ >()
401
+ void json
402
+ return
403
+ }
404
+ if (res.status === 404) {
405
+ const json = await res.json()
406
+ expectTypeOf(json.error.code).toEqualTypeOf<'earn_vault_not_found'>()
407
+ void json
408
+ return
409
+ }
410
+ if (res.status === 502) {
411
+ const json = await res.json()
412
+ expectTypeOf(json.error.code).toEqualTypeOf<'upstream_error'>()
413
+ void json
414
+ return
415
+ }
416
+ })
417
+
360
418
  test('GET /v1/me', async () => {
361
419
  const client = Client.create()
362
420
  const res = await client.v1.me.$get()
@@ -580,7 +638,7 @@ describe('narrows responses by status', () => {
580
638
  case 403: {
581
639
  const json = await res.json()
582
640
  expectTypeOf(json.error.code).toEqualTypeOf<
583
- 'api_key_forbidden' | 'billing_source_disabled' | 'forbidden'
641
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'billing_source_disabled' | 'forbidden'
584
642
  >()
585
643
  void json
586
644
  return
@@ -867,7 +925,7 @@ describe('narrows responses by status', () => {
867
925
  const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects[
868
926
  ':projectId{prj_[A-Za-z0-9_-]+}'
869
927
  ]['api-keys'].$post({
870
- json: { scopes: ['data:read'] },
928
+ json: { allowedIps: ['203.0.113.0/24'], scopes: ['data:read'] },
871
929
  param: { orgId: 'org_test', projectId: 'prj_test' },
872
930
  })
873
931
 
@@ -878,6 +936,7 @@ describe('narrows responses by status', () => {
878
936
  const json = await res.json()
879
937
  expectTypeOf(json.token).toEqualTypeOf<string>()
880
938
  expectTypeOf(json.id).toEqualTypeOf<string>()
939
+ expectTypeOf(json.allowedIps).toEqualTypeOf<readonly string[]>()
881
940
  void json
882
941
  return
883
942
  }
@@ -905,6 +964,7 @@ describe('narrows responses by status', () => {
905
964
  const json = await res.json()
906
965
  expectTypeOf(json.data[0]!.id).toEqualTypeOf<string>()
907
966
  expectTypeOf(json.data[0]!.environment).toEqualTypeOf<'production' | 'sandbox'>()
967
+ expectTypeOf(json.data[0]!.allowedIps).toEqualTypeOf<readonly string[]>()
908
968
  // Absent on org-wide keys minted without project attribution.
909
969
  expectTypeOf(json.data[0]!.projectId).toEqualTypeOf<string | undefined>()
910
970
  void json
@@ -913,6 +973,24 @@ describe('narrows responses by status', () => {
913
973
  }
914
974
  })
915
975
 
976
+ test('PATCH /v1/orgs/:orgId/projects/:projectId/api-keys/:keyId', async () => {
977
+ const client = Client.create()
978
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects[
979
+ ':projectId{prj_[A-Za-z0-9_-]+}'
980
+ ]['api-keys'][':keyId{key_[A-Za-z0-9_-]+}'].$patch({
981
+ json: { allowedIps: [] },
982
+ param: { keyId: 'key_test', orgId: 'org_test', projectId: 'prj_test' },
983
+ })
984
+
985
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
986
+
987
+ if (res.status === 200) {
988
+ const json = await res.json()
989
+ expectTypeOf(json.allowedIps).toEqualTypeOf<readonly string[]>()
990
+ void json
991
+ }
992
+ })
993
+
916
994
  test('DELETE /v1/orgs/:orgId/projects/:projectId/api-keys/:keyId', async () => {
917
995
  const client = Client.create()
918
996
  const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects[
@@ -1116,7 +1194,7 @@ describe('narrows responses by status', () => {
1116
1194
  }
1117
1195
  case 403: {
1118
1196
  const json = await res.json()
1119
- expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden'>()
1197
+ expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden' | 'api_key_ip_forbidden'>()
1120
1198
  expectTypeOf(json.error.message).toEqualTypeOf<string>()
1121
1199
  void json
1122
1200
  return
@@ -1680,6 +1758,56 @@ describe('narrows responses by status', () => {
1680
1758
  }
1681
1759
  })
1682
1760
 
1761
+ test('GET /v1/addresses/:address/balances/:token', async () => {
1762
+ const client = Client.create()
1763
+ const res = await client.v1.addresses[':address'].balances[':token'].$get({
1764
+ param: {
1765
+ address: '0x0000000000000000000000000000000000000000',
1766
+ token: '0x20c0000000000000000000000000000000000000',
1767
+ },
1768
+ query: {},
1769
+ })
1770
+
1771
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
1772
+
1773
+ switch (res.status) {
1774
+ case 200: {
1775
+ const json = await res.json()
1776
+ expectTypeOf(json.amount).toEqualTypeOf<string>()
1777
+ expectTypeOf(json.formatted).toEqualTypeOf<string>()
1778
+ expectTypeOf(json.token).toEqualTypeOf<z.output<typeof Tokens.schema.Token>>()
1779
+ expectTypeOf(json.valuation).toEqualTypeOf<
1780
+ z.output<typeof Balances.schema.getAddressBalances.Balance>['valuation']
1781
+ >()
1782
+ void json
1783
+ return
1784
+ }
1785
+ case 400: {
1786
+ const json = await res.json()
1787
+ expectTypeOf(json.error.code).toEqualTypeOf<
1788
+ Access400<'address_invalid' | 'query_invalid'>
1789
+ >()
1790
+ expectTypeOf(json.error.message).toEqualTypeOf<string>()
1791
+ void json
1792
+ return
1793
+ }
1794
+ case 404: {
1795
+ const json = await res.json()
1796
+ expectTypeOf(json.error.code).toEqualTypeOf<'token_not_found'>()
1797
+ expectTypeOf(json.error.message).toEqualTypeOf<string>()
1798
+ void json
1799
+ return
1800
+ }
1801
+ case 502: {
1802
+ const json = await res.json()
1803
+ expectTypeOf(json.error.code).toEqualTypeOf<'upstream_error'>()
1804
+ expectTypeOf(json.error.message).toEqualTypeOf<string>()
1805
+ void json
1806
+ return
1807
+ }
1808
+ }
1809
+ })
1810
+
1683
1811
  test('GET /v1/addresses/:address/valuation', async () => {
1684
1812
  const client = Client.create()
1685
1813
  const res = await client.v1.addresses[':address'].valuation.$get({
@@ -1810,7 +1938,9 @@ describe('narrows responses by status', () => {
1810
1938
  | undefined
1811
1939
  >()
1812
1940
  expectTypeOf(json.data[0]!.sourceAmount).toEqualTypeOf<
1813
- z.output<typeof Funding.schema.quoteFunding.Response>['data'][number]['sourceAmount']
1941
+ z.output<
1942
+ typeof FundingQuotes.schema.quoteFunding.Response
1943
+ >['data'][number]['sourceAmount']
1814
1944
  >()
1815
1945
  // @ts-expect-error token references do not contain quantities
1816
1946
  void json.data[0]!.sourceToken.amount
@@ -1855,7 +1985,7 @@ describe('narrows responses by status', () => {
1855
1985
  const json = await res.json()
1856
1986
  expectTypeOf(json.data[0]!.tokens[0]!.symbol).toEqualTypeOf<
1857
1987
  z.output<
1858
- typeof Funding.schema.getFundingChains.Response
1988
+ typeof FundingChains.schema.getFundingChains.Response
1859
1989
  >['data'][number]['tokens'][number]['symbol']
1860
1990
  >()
1861
1991
  expectTypeOf(json.data[0]!.addressFormat).toEqualTypeOf<'base58' | 'base58check' | 'hex'>()
@@ -1921,7 +2051,9 @@ describe('narrows responses by status', () => {
1921
2051
  const json = await res.json()
1922
2052
  expectTypeOf(json.id).toEqualTypeOf<string>()
1923
2053
  expectTypeOf(json.status).toEqualTypeOf<
1924
- z.output<typeof Funding.schema.createFundingDepositAddress.Response>['status']
2054
+ z.output<
2055
+ typeof FundingDepositAddresses.schema.createFundingDepositAddress.Response
2056
+ >['status']
1925
2057
  >()
1926
2058
  expectTypeOf(json.subsidize).toEqualTypeOf<boolean>()
1927
2059
  if ('quote' in json) {
@@ -1964,7 +2096,7 @@ describe('narrows responses by status', () => {
1964
2096
  case 200: {
1965
2097
  const json = await res.json()
1966
2098
  expectTypeOf(json.status).toEqualTypeOf<
1967
- z.output<typeof Funding.schema.DepositAddress>['status']
2099
+ z.output<typeof FundingDepositAddresses.schema.DepositAddress>['status']
1968
2100
  >()
1969
2101
  expectTypeOf(json.sourceChain.kind).toEqualTypeOf<'evm' | 'solana' | 'tron'>()
1970
2102
  expectTypeOf(json.subsidize).toEqualTypeOf<boolean>()
@@ -1982,22 +2114,17 @@ describe('narrows responses by status', () => {
1982
2114
  }
1983
2115
  })
1984
2116
 
1985
- test('GET /v1/funding/deposit-addresses/:id/deposits', async () => {
2117
+ test('POST /v1/funding/deposit-addresses/:id/reconcile', async () => {
1986
2118
  const client = Client.create()
1987
2119
  const res = await client.v1.funding['deposit-addresses'][
1988
2120
  ':id{fda_[A-Za-z0-9_-]+}'
1989
- ].deposits.$get({ param: { id: 'fda_test' }, query: {} })
2121
+ ].reconcile.$post({ param: { id: 'fda_test' } })
1990
2122
 
1991
- expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PublicAccessStatus>()
2123
+ expectTypeOf(res.status).toEqualTypeOf<202 | 400 | 401 | 403 | 404 | 409 | 429 | 501 | 502>()
1992
2124
 
1993
2125
  switch (res.status) {
1994
- case 200: {
1995
- const json = await res.json()
1996
- expectTypeOf(json.data[0]!.status).toEqualTypeOf<
1997
- z.output<typeof Funding.schema.Deposit>['status']
1998
- >()
1999
- expectTypeOf(json.nextCursor).toEqualTypeOf<string | null>()
2000
- void json
2126
+ case 202: {
2127
+ expectTypeOf(await res.text()).toEqualTypeOf<string>()
2001
2128
  return
2002
2129
  }
2003
2130
  case 404: {
@@ -2006,6 +2133,49 @@ describe('narrows responses by status', () => {
2006
2133
  void json
2007
2134
  return
2008
2135
  }
2136
+ case 409: {
2137
+ const json = await res.json()
2138
+ expectTypeOf(json.error.code).toEqualTypeOf<'funding_deposit_address_not_active'>()
2139
+ void json
2140
+ return
2141
+ }
2142
+ case 501: {
2143
+ const json = await res.json()
2144
+ expectTypeOf(json.error.code).toEqualTypeOf<'not_implemented'>()
2145
+ void json
2146
+ return
2147
+ }
2148
+ case 502: {
2149
+ const json = await res.json()
2150
+ expectTypeOf(json.error.code).toEqualTypeOf<'upstream_error'>()
2151
+ void json
2152
+ return
2153
+ }
2154
+ }
2155
+ })
2156
+
2157
+ test('GET /v1/funding/deposits', async () => {
2158
+ const client = Client.create()
2159
+ void client.v1.funding.deposits.$get({
2160
+ query: { depositAddress: 'TJRabPrwbZy45sbavfcjinPJC18kjpRTv8' },
2161
+ })
2162
+ const res = await client.v1.funding.deposits.$get({
2163
+ query: { recipient: `0x${'11'.repeat(20)}` },
2164
+ })
2165
+
2166
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 502 | PublicAccessStatus>()
2167
+
2168
+ switch (res.status) {
2169
+ case 200: {
2170
+ const json = await res.json()
2171
+ expectTypeOf(json.data[0]!.recipient).toEqualTypeOf<string>()
2172
+ expectTypeOf(json.data[0]!.status).toEqualTypeOf<
2173
+ z.output<typeof FundingDepositAddresses.schema.Deposit>['status']
2174
+ >()
2175
+ expectTypeOf(json.nextCursor).toEqualTypeOf<string | null>()
2176
+ void json
2177
+ return
2178
+ }
2009
2179
  }
2010
2180
  })
2011
2181
 
@@ -2020,12 +2190,15 @@ describe('narrows responses by status', () => {
2020
2190
  switch (res.status) {
2021
2191
  case 200: {
2022
2192
  const json = await res.json()
2193
+ expectTypeOf(json.detectionTrigger).toEqualTypeOf<
2194
+ 'chain' | 'manual' | 'poll' | 'webhook' | undefined
2195
+ >()
2023
2196
  expectTypeOf(json.destinationAmountRequired).toEqualTypeOf<
2024
- z.output<typeof Funding.schema.Deposit>['destinationAmountRequired']
2197
+ z.output<typeof FundingDepositAddresses.schema.Deposit>['destinationAmountRequired']
2025
2198
  >()
2026
2199
  expectTypeOf(json.sourceTransferIndex).toEqualTypeOf<number | undefined>()
2027
2200
  expectTypeOf(json.statusReason).toEqualTypeOf<
2028
- z.output<typeof Funding.schema.Deposit>['statusReason']
2201
+ z.output<typeof FundingDepositAddresses.schema.Deposit>['statusReason']
2029
2202
  >()
2030
2203
  // @ts-expect-error provider request identifiers remain private
2031
2204
  void json.providerRequestIds
@@ -2052,7 +2225,7 @@ describe('narrows responses by status', () => {
2052
2225
  const json = await res.json()
2053
2226
  expectTypeOf(json.data[0]!.id).toEqualTypeOf<string>()
2054
2227
  expectTypeOf(json.data[0]!.status).toEqualTypeOf<
2055
- z.output<typeof Funding.schema.Transfer>['status']
2228
+ z.output<typeof FundingTransfers.schema.Transfer>['status']
2056
2229
  >()
2057
2230
  expectTypeOf(json.data[0]!.version).toEqualTypeOf<number>()
2058
2231
  // Transfer reads never expose the executable action.
@@ -2060,7 +2233,7 @@ describe('narrows responses by status', () => {
2060
2233
  void json.data[0]!.action
2061
2234
  // `meta` (opt-in `include=totalCount` count) is optional.
2062
2235
  expectTypeOf(json.meta).toEqualTypeOf<
2063
- z.output<typeof Funding.schema.listFundingTransfers.Response>['meta']
2236
+ z.output<typeof FundingTransfers.schema.listFundingTransfers.Response>['meta']
2064
2237
  >()
2065
2238
  expectTypeOf(json.nextCursor).toEqualTypeOf<string | null>()
2066
2239
  void json
@@ -2102,7 +2275,7 @@ describe('narrows responses by status', () => {
2102
2275
  expectTypeOf(json.action.type).toEqualTypeOf<'evm:calls'>()
2103
2276
  expectTypeOf(json.id).toEqualTypeOf<string>()
2104
2277
  expectTypeOf(json.status).toEqualTypeOf<
2105
- z.output<typeof Funding.schema.createFundingTransfer.Response>['status']
2278
+ z.output<typeof FundingTransfers.schema.createFundingTransfer.Response>['status']
2106
2279
  >()
2107
2280
  void json
2108
2281
  return
@@ -2191,10 +2364,10 @@ describe('narrows responses by status', () => {
2191
2364
  const json = await res.json()
2192
2365
  expectTypeOf(json.id).toEqualTypeOf<string>()
2193
2366
  expectTypeOf(json.status).toEqualTypeOf<
2194
- z.output<typeof Funding.schema.getFundingTransfer.Response>['status']
2367
+ z.output<typeof FundingTransfers.schema.getFundingTransfer.Response>['status']
2195
2368
  >()
2196
2369
  expectTypeOf(json.statusReason).toEqualTypeOf<
2197
- z.output<typeof Funding.schema.getFundingTransfer.Response>['statusReason']
2370
+ z.output<typeof FundingTransfers.schema.getFundingTransfer.Response>['statusReason']
2198
2371
  >()
2199
2372
  // @ts-expect-error `action` is a creation-only field
2200
2373
  void json.action
@@ -2944,7 +3117,7 @@ describe('narrows responses by status', () => {
2944
3117
  }
2945
3118
  case 403: {
2946
3119
  const json = await res.json()
2947
- expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden'>()
3120
+ expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden' | 'api_key_ip_forbidden'>()
2948
3121
  void json
2949
3122
  return
2950
3123
  }
@@ -3120,7 +3293,9 @@ describe('narrows responses by status', () => {
3120
3293
  }
3121
3294
  if (res.status === 403) {
3122
3295
  const json = await res.json()
3123
- expectTypeOf(json.error.code).toEqualTypeOf<'api_key_forbidden' | 'limit_exceeded'>()
3296
+ expectTypeOf(json.error.code).toEqualTypeOf<
3297
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'limit_exceeded'
3298
+ >()
3124
3299
  }
3125
3300
  })
3126
3301
 
@@ -24,6 +24,7 @@ describe('POST /api-keys', () => {
24
24
  expect(body.createdBy).toBe(TestAdmin.identity.email)
25
25
  expect(TestAdmin.redact(body)).toMatchInlineSnapshot(`
26
26
  {
27
+ "allowedIps": [],
27
28
  "createdAt": "<createdAt>",
28
29
  "createdBy": "admin@tempo.xyz",
29
30
  "environment": "production",
@@ -290,6 +291,23 @@ describe('DELETE /api-keys/:id', () => {
290
291
  })
291
292
 
292
293
  describe('PATCH /api-keys/:id', () => {
294
+ test('preserves the allowlist when omitted', async () => {
295
+ const { client, store } = TestAdmin.setup()
296
+ const { record } = await core_ApiKeys.mint(store, {
297
+ allowedIps: ['203.0.113.0/24'],
298
+ name: 'Restricted',
299
+ scopes: ['data:read'],
300
+ })
301
+
302
+ const response = await client['api-keys'][':id'].$patch({
303
+ json: { name: 'Renamed' },
304
+ param: { id: record.id },
305
+ })
306
+
307
+ expect(response.status).toBe(200)
308
+ expect((await core_ApiKeys.get(store, record.id))?.allowedIps).toEqual(['203.0.113.0/24'])
309
+ })
310
+
293
311
  test('renames and associates a one-off key without changing its token', async () => {
294
312
  const { client, db, store } = TestAdmin.setup()
295
313
  const organization = await Organizations.create(db, { name: 'Tempo' })
@@ -299,12 +317,18 @@ describe('PATCH /api-keys/:id', () => {
299
317
  })
300
318
 
301
319
  const response = await client['api-keys'][':id'].$patch({
302
- json: { name: 'Explorer', orgId: organization.id, projectId: 'prj_real' },
320
+ json: {
321
+ allowedIps: ['203.0.113.0/24'],
322
+ name: 'Explorer',
323
+ orgId: organization.id,
324
+ projectId: 'prj_real',
325
+ },
303
326
  param: { id: record.id },
304
327
  })
305
328
  expect(response.status).toBe(200)
306
329
  const body = await TestApp.json(response, core_ApiKeys.schema.Record)
307
330
  expect(body.name).toBe('Explorer')
331
+ expect(body.allowedIps).toEqual(['203.0.113.0/24'])
308
332
  expect(body.orgId).toBe(organization.id)
309
333
  expect(body.projectId).toBe('prj_real')
310
334
 
@@ -1,6 +1,7 @@
1
1
  import { Hono } from 'hono'
2
2
  import * as z from 'zod/mini'
3
3
 
4
+ import * as core_ApiKey from '../../ApiKey.js'
4
5
  import * as ApiKeys from '../../ApiKeys.js'
5
6
  import * as Db from '../../db/Db.js'
6
7
  import * as Organizations from '../../db/tables/organizations.js'
@@ -111,6 +112,9 @@ export namespace schema {
111
112
  /** Request body updating a key; omitted fields keep their value. */
112
113
  export const Body = Schema.describe(
113
114
  z.object({
115
+ allowedIps: z
116
+ .optional(core_ApiKey.schema.AllowedIps)
117
+ .check(z.describe('Replacement client IP/CIDR allowlist. An empty list clears it.')),
114
118
  name: z.optional(Name).check(z.describe('New human-readable key name.')),
115
119
  orgId: z
116
120
  .optional(z.string())
@@ -163,7 +167,7 @@ export namespace schema {
163
167
  * returning the one-time token.
164
168
  * - `GET /` lists key records (metadata only), optionally filtered by `orgId`.
165
169
  * - `DELETE /:id` revokes a key by id (`404` if absent).
166
- * - `PATCH /:id` updates a key's name or project, or assigns its first organization.
170
+ * - `PATCH /:id` updates a key's allowlist, name, or project, or assigns its first organization.
167
171
  * - `POST /backfill` rebuilds the id and org index entries for every record.
168
172
  */
169
173
  export function apiKeys() {
@@ -307,7 +311,7 @@ export function apiKeys() {
307
311
  message: 'Invalid request body',
308
312
  }),
309
313
  OpenApi.describeRoute({
310
- description: 'Update a key name or project, or assign its first organization. The token is unchanged.', // prettier-ignore
314
+ description: 'Update a key allowlist, name, or project, or assign its first organization. The token is unchanged.', // prettier-ignore
311
315
  operationId: 'updateApiKey',
312
316
  responses: OpenApi.responses({
313
317
  errors: {