tapimo 0.0.1 → 0.1.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 (274) hide show
  1. package/README.md +13 -3
  2. package/dist/ApiKey.d.ts +12 -11
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +10 -12
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +139 -0
  7. package/dist/ApiKeys.d.ts.map +1 -0
  8. package/dist/ApiKeys.js +166 -0
  9. package/dist/ApiKeys.js.map +1 -0
  10. package/dist/App.d.ts +920 -910
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +36 -12
  13. package/dist/App.js.map +1 -1
  14. package/dist/Handler.d.ts +86 -0
  15. package/dist/Handler.d.ts.map +1 -0
  16. package/dist/Handler.js +83 -0
  17. package/dist/Handler.js.map +1 -0
  18. package/dist/Scope.d.ts +4 -1
  19. package/dist/Scope.d.ts.map +1 -1
  20. package/dist/Scope.js +5 -1
  21. package/dist/Scope.js.map +1 -1
  22. package/dist/Webhooks.d.ts +3 -5
  23. package/dist/Webhooks.d.ts.map +1 -1
  24. package/dist/Webhooks.js +9 -2
  25. package/dist/Webhooks.js.map +1 -1
  26. package/dist/admin/Access.d.ts +1 -3
  27. package/dist/admin/Access.d.ts.map +1 -1
  28. package/dist/admin/Access.js +1 -3
  29. package/dist/admin/Access.js.map +1 -1
  30. package/dist/admin/App.d.ts +49 -160
  31. package/dist/admin/App.d.ts.map +1 -1
  32. package/dist/admin/App.js +2 -4
  33. package/dist/admin/App.js.map +1 -1
  34. package/dist/admin/apps/api-keys.d.ts +7 -5
  35. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  36. package/dist/admin/apps/api-keys.js +8 -9
  37. package/dist/admin/apps/api-keys.js.map +1 -1
  38. package/dist/admin/apps/scopes.d.ts +3 -0
  39. package/dist/admin/apps/scopes.d.ts.map +1 -1
  40. package/dist/admin/apps/verified-tokens.d.ts +101 -215
  41. package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
  42. package/dist/admin/apps/verified-tokens.js +17 -38
  43. package/dist/admin/apps/verified-tokens.js.map +1 -1
  44. package/dist/admin/ui.generated.d.ts +1 -1
  45. package/dist/admin/ui.generated.js +13 -13
  46. package/dist/admin/ui.generated.js.map +1 -1
  47. package/dist/apps/balances.d.ts +43 -43
  48. package/dist/apps/coingecko.d.ts +176 -176
  49. package/dist/apps/coingecko.js +1 -1
  50. package/dist/apps/coingecko.js.map +1 -1
  51. package/dist/apps/receipts.d.ts +43 -43
  52. package/dist/apps/tokenlist.d.ts +36 -36
  53. package/dist/apps/tokens.d.ts +454 -454
  54. package/dist/apps/transactions.d.ts +43 -43
  55. package/dist/apps/transfers.d.ts +29 -29
  56. package/dist/apps/webhooks.d.ts +5 -2
  57. package/dist/apps/webhooks.d.ts.map +1 -1
  58. package/dist/apps/webhooks.js +38 -34
  59. package/dist/apps/webhooks.js.map +1 -1
  60. package/dist/{Cli.d.ts → cli/Cli.d.ts} +13 -2
  61. package/dist/cli/Cli.d.ts.map +1 -0
  62. package/dist/cli/Cli.js +19 -0
  63. package/dist/cli/Cli.js.map +1 -0
  64. package/dist/cli/bin.d.ts +3 -0
  65. package/dist/cli/bin.d.ts.map +1 -0
  66. package/dist/cli/bin.js +4 -0
  67. package/dist/cli/bin.js.map +1 -0
  68. package/dist/cli/commands/admin.d.ts +15 -0
  69. package/dist/cli/commands/admin.d.ts.map +1 -0
  70. package/dist/cli/commands/admin.js +60 -0
  71. package/dist/cli/commands/admin.js.map +1 -0
  72. package/dist/cloudflare.d.ts +7 -0
  73. package/dist/cloudflare.d.ts.map +1 -1
  74. package/dist/cloudflare.js +9 -0
  75. package/dist/cloudflare.js.map +1 -1
  76. package/dist/db/Db.d.ts +103 -0
  77. package/dist/db/Db.d.ts.map +1 -0
  78. package/dist/db/Db.js +274 -0
  79. package/dist/db/Db.js.map +1 -0
  80. package/dist/db/Schema.d.ts +88 -0
  81. package/dist/db/Schema.d.ts.map +1 -0
  82. package/dist/db/Schema.js +130 -0
  83. package/dist/db/Schema.js.map +1 -0
  84. package/dist/db/tables/organizations.d.ts +79 -0
  85. package/dist/db/tables/organizations.d.ts.map +1 -0
  86. package/dist/db/tables/organizations.js +81 -0
  87. package/dist/db/tables/organizations.js.map +1 -0
  88. package/dist/db/tables/verifiedTokens.d.ts +53 -0
  89. package/dist/db/tables/verifiedTokens.d.ts.map +1 -0
  90. package/dist/db/tables/verifiedTokens.js +74 -0
  91. package/dist/db/tables/verifiedTokens.js.map +1 -0
  92. package/dist/db/tables/webhookDeliveries.d.ts +71 -0
  93. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -0
  94. package/dist/db/tables/webhookDeliveries.js +119 -0
  95. package/dist/db/tables/webhookDeliveries.js.map +1 -0
  96. package/dist/db/tables/webhookSubscriptions.d.ts +158 -0
  97. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -0
  98. package/dist/db/tables/webhookSubscriptions.js +272 -0
  99. package/dist/db/tables/webhookSubscriptions.js.map +1 -0
  100. package/dist/handlers/internal/executionError.d.ts +25 -0
  101. package/dist/handlers/internal/executionError.d.ts.map +1 -0
  102. package/dist/handlers/internal/executionError.js +184 -0
  103. package/dist/handlers/internal/executionError.js.map +1 -0
  104. package/dist/handlers/internal/multisig.d.ts +237 -0
  105. package/dist/handlers/internal/multisig.d.ts.map +1 -0
  106. package/dist/handlers/internal/multisig.js +567 -0
  107. package/dist/handlers/internal/multisig.js.map +1 -0
  108. package/dist/handlers/internal/requestListener.d.ts +124 -0
  109. package/dist/handlers/internal/requestListener.d.ts.map +1 -0
  110. package/dist/handlers/internal/requestListener.js +173 -0
  111. package/dist/handlers/internal/requestListener.js.map +1 -0
  112. package/dist/handlers/internal/sponsorship.d.ts +83 -0
  113. package/dist/handlers/internal/sponsorship.d.ts.map +1 -0
  114. package/dist/handlers/internal/sponsorship.js +103 -0
  115. package/dist/handlers/internal/sponsorship.js.map +1 -0
  116. package/dist/handlers/internal/types.d.ts +284 -0
  117. package/dist/handlers/internal/types.d.ts.map +1 -0
  118. package/dist/handlers/internal/types.js +2 -0
  119. package/dist/handlers/internal/types.js.map +1 -0
  120. package/dist/handlers/internal/utils.d.ts +34 -0
  121. package/dist/handlers/internal/utils.d.ts.map +1 -0
  122. package/dist/handlers/internal/utils.js +131 -0
  123. package/dist/handlers/internal/utils.js.map +1 -0
  124. package/dist/handlers/relay.d.ts +119 -0
  125. package/dist/handlers/relay.d.ts.map +1 -0
  126. package/dist/handlers/relay.js +1264 -0
  127. package/dist/handlers/relay.js.map +1 -0
  128. package/dist/index.d.ts +4 -2
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +4 -2
  131. package/dist/index.js.map +1 -1
  132. package/dist/internal/Auth.d.ts +16 -10
  133. package/dist/internal/Auth.d.ts.map +1 -1
  134. package/dist/internal/Auth.js +78 -13
  135. package/dist/internal/Auth.js.map +1 -1
  136. package/dist/internal/RpcSchema.d.ts +10 -0
  137. package/dist/internal/RpcSchema.d.ts.map +1 -0
  138. package/dist/internal/RpcSchema.js +2 -0
  139. package/dist/internal/RpcSchema.js.map +1 -0
  140. package/dist/internal/Store.d.ts +42 -3
  141. package/dist/internal/Store.d.ts.map +1 -1
  142. package/dist/internal/Store.js +87 -8
  143. package/dist/internal/Store.js.map +1 -1
  144. package/dist/internal/VerifiedTokens.d.ts +15 -34
  145. package/dist/internal/VerifiedTokens.d.ts.map +1 -1
  146. package/dist/internal/VerifiedTokens.js +115 -159
  147. package/dist/internal/VerifiedTokens.js.map +1 -1
  148. package/dist/internal/Viem.d.ts +81 -7
  149. package/dist/internal/Viem.d.ts.map +1 -1
  150. package/dist/internal/Webhooks.d.ts +49 -35
  151. package/dist/internal/Webhooks.d.ts.map +1 -1
  152. package/dist/internal/Webhooks.js +92 -205
  153. package/dist/internal/Webhooks.js.map +1 -1
  154. package/package.json +10 -5
  155. package/src/ApiKey.test.ts +3 -3
  156. package/src/ApiKey.ts +10 -12
  157. package/src/ApiKeys.test.ts +175 -0
  158. package/src/ApiKeys.ts +205 -0
  159. package/src/App.test-d.ts +1 -1
  160. package/src/App.test.ts +10768 -351
  161. package/src/App.ts +79 -36
  162. package/src/Client.test-d.ts +1 -1
  163. package/src/Handler.ts +154 -0
  164. package/src/Scope.ts +5 -1
  165. package/src/Webhooks.test.ts +8 -7
  166. package/src/Webhooks.ts +11 -5
  167. package/src/admin/Access.ts +1 -3
  168. package/src/admin/App.ts +19 -24
  169. package/src/admin/apps/api-keys.test.ts +19 -18
  170. package/src/admin/apps/api-keys.ts +8 -9
  171. package/src/admin/apps/scopes.test.ts +4 -0
  172. package/src/admin/apps/verified-tokens.test.ts +3 -30
  173. package/src/admin/apps/verified-tokens.ts +17 -36
  174. package/src/admin/ui.generated.ts +13 -13
  175. package/src/apps/balances.test.ts +4 -3
  176. package/src/apps/blocks.test.ts +1 -1
  177. package/src/apps/coingecko.ts +1 -1
  178. package/src/apps/exchanges.test.ts +1 -1
  179. package/src/apps/indexer.test.ts +2 -2
  180. package/src/apps/receipts.test.ts +1 -1
  181. package/src/apps/rpc.test.ts +100 -10
  182. package/src/apps/tokenlist.test.ts +5 -7
  183. package/src/apps/tokens.test.ts +4 -3
  184. package/src/apps/transactions.test.ts +1 -1
  185. package/src/apps/transfers.test.ts +1 -1
  186. package/src/apps/verified-tokens.test.ts +24 -12
  187. package/src/apps/webhooks.test.ts +131 -144
  188. package/src/apps/webhooks.ts +45 -47
  189. package/src/{Cli.test.ts → cli/Cli.test.ts} +10 -9
  190. package/src/{Cli.ts → cli/Cli.ts} +16 -9
  191. package/src/cli/bin.ts +4 -0
  192. package/src/cli/commands/admin.test.ts +71 -0
  193. package/src/cli/commands/admin.ts +60 -0
  194. package/src/cloudflare.ts +10 -0
  195. package/src/db/Db.test.ts +84 -0
  196. package/src/db/Db.ts +383 -0
  197. package/src/db/Schema.ts +164 -0
  198. package/src/db/tables/organizations.test.ts +124 -0
  199. package/src/db/tables/organizations.ts +127 -0
  200. package/src/db/tables/verifiedTokens.ts +111 -0
  201. package/src/db/tables/webhookDeliveries.ts +159 -0
  202. package/src/db/tables/webhookSubscriptions.ts +358 -0
  203. package/src/handlers/internal/executionError.ts +205 -0
  204. package/src/handlers/internal/multisig.localnet.test.ts +146 -0
  205. package/src/handlers/internal/multisig.test.ts +744 -0
  206. package/src/handlers/internal/multisig.ts +858 -0
  207. package/src/handlers/internal/relay.localnet.test.ts +2035 -0
  208. package/src/handlers/internal/requestListener.ts +273 -0
  209. package/src/handlers/internal/sponsorship.ts +186 -0
  210. package/src/handlers/internal/types.ts +378 -0
  211. package/src/handlers/internal/utils.ts +153 -0
  212. package/src/handlers/relay.ts +1605 -0
  213. package/src/index.ts +4 -2
  214. package/src/internal/Auth.test.ts +78 -20
  215. package/src/internal/Auth.ts +98 -20
  216. package/src/internal/RateLimit.test.ts +1 -1
  217. package/src/internal/RpcSchema.ts +10 -0
  218. package/src/internal/Store.test.ts +179 -7
  219. package/src/internal/Store.ts +136 -11
  220. package/src/internal/VerifiedTokens.test.ts +99 -115
  221. package/src/internal/VerifiedTokens.ts +123 -175
  222. package/src/internal/Viem.ts +2 -1
  223. package/src/internal/Webhooks.test.ts +107 -107
  224. package/src/internal/Webhooks.ts +102 -220
  225. package/dist/ApiKeySource.d.ts +0 -166
  226. package/dist/ApiKeySource.d.ts.map +0 -1
  227. package/dist/ApiKeySource.js +0 -234
  228. package/dist/ApiKeySource.js.map +0 -1
  229. package/dist/Cli.d.ts.map +0 -1
  230. package/dist/Cli.js +0 -13
  231. package/dist/Cli.js.map +0 -1
  232. package/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +0 -1
  233. package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
  234. package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
  235. package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
  236. package/seeds/31318/verified-tokens.json +0 -30
  237. package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
  238. package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +0 -1
  239. package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +0 -1
  240. package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +0 -4
  241. package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +0 -30
  242. package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +0 -1
  243. package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +0 -1
  244. package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +0 -1
  245. package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +0 -11
  246. package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +0 -1
  247. package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +0 -1
  248. package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
  249. package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +0 -1
  250. package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
  251. package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +0 -1
  252. package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +0 -5
  253. package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +0 -1
  254. package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +0 -1
  255. package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +0 -1
  256. package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +0 -1
  257. package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +0 -1
  258. package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +0 -1
  259. package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +0 -1
  260. package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +0 -1
  261. package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
  262. package/seeds/4217/verified-tokens.json +0 -177
  263. package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
  264. package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
  265. package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
  266. package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
  267. package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +0 -1
  268. package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +0 -1
  269. package/seeds/42431/verified-tokens.json +0 -44
  270. package/seeds/openrpc/README.md +0 -27
  271. package/seeds/openrpc/execution-apis.json +0 -8989
  272. package/src/ApiKeySource.test-d.ts +0 -11
  273. package/src/ApiKeySource.test.ts +0 -295
  274. package/src/ApiKeySource.ts +0 -303
@@ -1,4 +1,4 @@
1
- import { Schema } from 'cadent'
1
+ import { Schema } from 'tapimo'
2
2
  import { Value as core_Value } from 'ox'
3
3
 
4
4
  import * as TestApp from '../../test/App.js'
@@ -12,9 +12,10 @@ import * as Tokens from './tokens.js'
12
12
  // verified tokens the bundle used to provide; a test can still override
13
13
  // `verifiedTokens`.
14
14
  const runtime = Runtime.get()
15
- const verified = TestApp.verifiedStore(runtime.chainId)
15
+ const db = TestApp.database()
16
+ await TestApp.verifiedSeed(db, runtime.chainId)
16
17
  function app(options: TestApp.create.Options = {}) {
17
- return TestApp.client({ verifiedTokens: { store: verified }, ...options })
18
+ return TestApp.client({ db, ...options })
18
19
  }
19
20
 
20
21
  async function holderWithBalance(client: ReturnType<typeof app>) {
@@ -1,4 +1,4 @@
1
- import { Schema } from 'cadent'
1
+ import { Schema } from 'tapimo'
2
2
  import { Hex } from 'ox'
3
3
  import { zeroHash } from 'viem'
4
4
 
@@ -1048,7 +1048,7 @@ async function loadDexBalances(
1048
1048
  account: dexAccount,
1049
1049
  token: token as ViemAddress,
1050
1050
  })
1051
- balances.set(token, balance)
1051
+ balances.set(token, balance.amount)
1052
1052
  } catch {
1053
1053
  failed = true
1054
1054
  balances.set(token, 0n)
@@ -1,5 +1,5 @@
1
1
  import type * as z from 'zod/mini'
2
- import { Schema } from 'cadent'
2
+ import { Schema } from 'tapimo'
3
3
 
4
4
  import * as TestApp from '../../test/App.js'
5
5
  import * as Exchanges from './exchanges.js'
@@ -1,4 +1,4 @@
1
- import { RateLimit, Store } from 'cadent'
1
+ import { RateLimit, Store } from 'tapimo'
2
2
  import * as TestApp from '../../test/App.js'
3
3
  import * as Mppx from '../../test/Mppx.js'
4
4
  import * as Runtime from '../../test/runtime.js'
@@ -117,7 +117,7 @@ describe('GET /indexer/query', () => {
117
117
  getClient: () => Tempo.client,
118
118
  recipient: Tempo.accounts[2].address,
119
119
  },
120
- secretKey: 'secret_test_key',
120
+ secretKey: 'secret_test_key_0123456789abcdef',
121
121
  },
122
122
  })
123
123
  await exhaustQuota(RateLimit.memory({ store: rateLimitStore }), 'public:anonymous', {
@@ -1,4 +1,4 @@
1
- import { Schema } from 'cadent'
1
+ import { Schema } from 'tapimo'
2
2
  import { Hex } from 'ox'
3
3
  import { zeroHash } from 'viem'
4
4
 
@@ -227,16 +227,14 @@ describe('POST /rpc', () => {
227
227
  try {
228
228
  const app = TestApp.create({
229
229
  auth: {
230
- source: TestApp.source({
231
- keys: [
232
- {
233
- id: 'key_indexer_only',
234
- orgId: 'org_test',
235
- scopes: ['indexer:query'],
236
- token: 'secret_indexer_key',
237
- },
238
- ],
239
- }),
230
+ keys: [
231
+ {
232
+ id: 'key_indexer_only',
233
+ orgId: 'org_test',
234
+ scopes: ['indexer:query'],
235
+ token: 'secret_indexer_key',
236
+ },
237
+ ],
240
238
  },
241
239
  })
242
240
  const response = await app.fetch(
@@ -266,6 +264,98 @@ describe('POST /rpc', () => {
266
264
  })
267
265
  })
268
266
 
267
+ describe('POST /rpc/relay', () => {
268
+ test('rejects anonymous callers', async () => {
269
+ const app = TestApp.create()
270
+
271
+ const response = await app.fetch(
272
+ new Request('http://tempo-api.test/rpc/relay', {
273
+ body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: 'eth_chainId' }),
274
+ method: 'POST',
275
+ }),
276
+ )
277
+ const body = (await response.json()) as Record<string, unknown>
278
+ const { requestId, ...stable } = body
279
+
280
+ expect(response.status).toMatchInlineSnapshot(`401`)
281
+ expect(typeof requestId).toMatchInlineSnapshot(`"string"`)
282
+ expect(stable).toMatchInlineSnapshot(`
283
+ {
284
+ "error": {
285
+ "code": "api_key_missing",
286
+ "message": "Missing API key",
287
+ },
288
+ }
289
+ `)
290
+ })
291
+
292
+ test('rejects keys missing the relay scope', async () => {
293
+ // The shared test key holds the data/indexer scopes only.
294
+ const app = TestApp.create()
295
+
296
+ const response = await app.fetch(
297
+ new Request('http://tempo-api.test/rpc/relay', {
298
+ body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: 'eth_chainId' }),
299
+ headers: { 'tempo-api-key': TestApp.key.token },
300
+ method: 'POST',
301
+ }),
302
+ )
303
+ const body = (await response.json()) as Record<string, unknown>
304
+ const { requestId, ...stable } = body
305
+
306
+ expect(response.status).toMatchInlineSnapshot(`403`)
307
+ expect(typeof requestId).toMatchInlineSnapshot(`"string"`)
308
+ expect(stable).toMatchInlineSnapshot(`
309
+ {
310
+ "error": {
311
+ "code": "api_key_forbidden",
312
+ "message": "API key missing required scope",
313
+ },
314
+ }
315
+ `)
316
+ })
317
+
318
+ test('proxies for keys holding rpc-relay', async () => {
319
+ const fetch = mockRpc()
320
+
321
+ try {
322
+ const app = TestApp.create({
323
+ auth: {
324
+ keys: [
325
+ {
326
+ id: 'key_relay',
327
+ orgId: 'org_test',
328
+ scopes: ['rpc-relay'],
329
+ token: 'secret_relay_key',
330
+ },
331
+ ],
332
+ },
333
+ rpc: { url: () => 'https://internal.rpc.test/json-rpc' },
334
+ })
335
+
336
+ const response = await app.fetch(
337
+ new Request('http://tempo-api.test/rpc/relay', {
338
+ body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: 'eth_chainId' }),
339
+ headers: { 'tempo-api-key': 'secret_relay_key' },
340
+ method: 'POST',
341
+ }),
342
+ )
343
+
344
+ expect(response.status).toMatchInlineSnapshot(`200`)
345
+ expect(await response.json()).toMatchInlineSnapshot(`
346
+ {
347
+ "id": 1,
348
+ "jsonrpc": "2.0",
349
+ "result": "0xa5bf",
350
+ }
351
+ `)
352
+ expect(fetch.calls[0]?.url).toMatchInlineSnapshot(`"https://internal.rpc.test/json-rpc"`)
353
+ } finally {
354
+ fetch.restore()
355
+ }
356
+ })
357
+ })
358
+
269
359
  function mockRpc() {
270
360
  const original = globalThis.fetch
271
361
  const calls: {
@@ -1,5 +1,3 @@
1
- import { Store } from 'cadent'
2
-
3
1
  import * as TestApp from '../../test/App.js'
4
2
  import * as Runtime from '../../test/runtime.js'
5
3
  import * as VerifiedTokens from '../internal/VerifiedTokens.js'
@@ -11,7 +9,7 @@ const reader = {
11
9
  orgId: 'org_test',
12
10
  scopes: ['data:read'],
13
11
  token: 'secret_reader',
14
- } satisfies TestApp.source.Key
12
+ } satisfies TestApp.kvStore.Key
15
13
 
16
14
  /** A known list published into the store before exercising the read endpoint. */
17
15
  const seedList = [
@@ -27,11 +25,11 @@ function as(key: { token: string }) {
27
25
 
28
26
  /** Client whose verified-token store holds a published {@link seedList} snapshot. */
29
27
  async function seeded() {
30
- const store = Store.memory()
31
- await VerifiedTokens.replace(store, chainId, seedList)
28
+ const db = TestApp.database()
29
+ await VerifiedTokens.replace(db, chainId, seedList)
32
30
  return TestApp.client({
33
- auth: { source: TestApp.source({ keys: [reader] }) },
34
- verifiedTokens: { store },
31
+ auth: { keys: [reader] },
32
+ db,
35
33
  })
36
34
  }
37
35
 
@@ -1,4 +1,4 @@
1
- import { Schema } from 'cadent'
1
+ import { Schema } from 'tapimo'
2
2
 
3
3
  import * as TestApp from '../../test/App.js'
4
4
  import * as Runtime from '../../test/runtime.js'
@@ -10,9 +10,10 @@ import * as Tokens from './tokens.js'
10
10
  // verified tokens the bundle used to provide; a test can still override
11
11
  // `verifiedTokens`.
12
12
  const runtime = Runtime.get()
13
- const verified = TestApp.verifiedStore(runtime.chainId)
13
+ const db = TestApp.database()
14
+ await TestApp.verifiedSeed(db, runtime.chainId)
14
15
  function app(options: TestApp.create.Options = {}) {
15
- return TestApp.client({ verifiedTokens: { store: verified }, ...options })
16
+ return TestApp.client({ db, ...options })
16
17
  }
17
18
 
18
19
  const verifiedTokenCount = 6
@@ -1,4 +1,4 @@
1
- import { Schema } from 'cadent'
1
+ import { Schema } from 'tapimo'
2
2
  import { Hex } from 'ox'
3
3
  import { zeroHash } from 'viem'
4
4
 
@@ -1,5 +1,5 @@
1
1
  import type * as z from 'zod/mini'
2
- import { Schema } from 'cadent'
2
+ import { Schema } from 'tapimo'
3
3
 
4
4
  import * as TestApp from '../../test/App.js'
5
5
  import * as Runtime from '../../test/runtime.js'
@@ -1,22 +1,15 @@
1
- import { Store } from 'cadent'
2
-
3
1
  import * as TestApp from '../../test/App.js'
4
2
  import * as Runtime from '../../test/runtime.js'
5
3
  import * as VerifiedTokens from '../internal/VerifiedTokens.js'
6
4
  import * as Verified from './verified-tokens.js'
7
5
 
8
- // Mutations live in the admin API (`cadent/admin`) and are covered in
9
- // `../admin/apps/verified-tokens.test.ts`; these tests cover the public reads,
10
- // seeded by publishing a snapshot through the same core module the admin
11
- // writes use.
12
-
13
6
  /** Reader key for the data routes. */
14
7
  const reader = {
15
8
  id: 'key_reader',
16
9
  orgId: 'org_test',
17
10
  scopes: ['data:read'],
18
11
  token: 'secret_reader',
19
- } satisfies TestApp.source.Key
12
+ } satisfies TestApp.kvStore.Key
20
13
 
21
14
  /** An address not present in the seed list. */
22
15
  const unknownAddress = '0x20c00000000000000000000000000000000000ff'
@@ -36,11 +29,11 @@ function as(key: { token: string }) {
36
29
 
37
30
  /** Client whose verified-token store holds a published {@link seedList} snapshot. */
38
31
  async function seeded() {
39
- const store = Store.memory()
40
- await VerifiedTokens.replace(store, chainId, seedList)
32
+ const db = TestApp.database()
33
+ await VerifiedTokens.replace(db, chainId, seedList)
41
34
  return TestApp.client({
42
- auth: { source: TestApp.source({ keys: [reader] }) },
43
- verifiedTokens: { store },
35
+ auth: { keys: [reader] },
36
+ db,
44
37
  })
45
38
  }
46
39
 
@@ -55,6 +48,25 @@ describe('GET /verified-tokens', () => {
55
48
  expect(body.data[1]?.logoUri).toBeUndefined()
56
49
  })
57
50
 
51
+ test('reads through `db.cached` when configured', async () => {
52
+ // Seed only the cached source: the list serving from it proves the
53
+ // snapshot path resolves `cached`, not `source`. `refreshMs: 0` forces a
54
+ // head check against this app's database (the per-isolate snapshot cell
55
+ // is keyed by chain id, so a prior test's cell could otherwise satisfy
56
+ // the read).
57
+ const cached = TestApp.database()
58
+ await VerifiedTokens.replace(cached, chainId, seedList)
59
+ const client = TestApp.client({
60
+ auth: { keys: [reader] },
61
+ db: { cached, source: TestApp.database() },
62
+ verifiedTokens: { refreshMs: 0 },
63
+ })
64
+ const response = await client.v1['verified-tokens'].$get({ query: {} }, as(reader))
65
+ expect(response.status).toBe(200)
66
+ const body = await TestApp.json(response, Verified.schema.listVerifiedTokens.Response)
67
+ expect(body.data.map((token) => token.address)).toEqual(seedList.map((token) => token.address))
68
+ })
69
+
58
70
  test('filters by currency (case-insensitive)', async () => {
59
71
  const response = await (
60
72
  await seeded()