tapimo 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (689) hide show
  1. package/dist/ApiKeys.d.ts +24 -7
  2. package/dist/ApiKeys.d.ts.map +1 -1
  3. package/dist/ApiKeys.js +17 -5
  4. package/dist/ApiKeys.js.map +1 -1
  5. package/dist/App.d.ts +12104 -7861
  6. package/dist/App.d.ts.map +1 -1
  7. package/dist/App.js +191 -128
  8. package/dist/App.js.map +1 -1
  9. package/dist/Assets.d.ts +10 -0
  10. package/dist/Assets.d.ts.map +1 -1
  11. package/dist/Assets.js +17 -4
  12. package/dist/Assets.js.map +1 -1
  13. package/dist/Scope.d.ts +19 -8
  14. package/dist/Scope.d.ts.map +1 -1
  15. package/dist/Scope.js +25 -9
  16. package/dist/Scope.js.map +1 -1
  17. package/dist/Webhooks.d.ts +1 -1
  18. package/dist/admin/App.d.ts +601 -20
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +12 -2
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +94 -11
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +141 -32
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +1069 -0
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -0
  28. package/dist/admin/apps/earn-vaults.js +409 -0
  29. package/dist/admin/apps/earn-vaults.js.map +1 -0
  30. package/dist/admin/apps/verified-tokens.d.ts +166 -166
  31. package/dist/admin/ui.generated.d.ts +1 -1
  32. package/dist/admin/ui.generated.d.ts.map +1 -1
  33. package/dist/admin/ui.generated.js +151 -95
  34. package/dist/admin/ui.generated.js.map +1 -1
  35. package/dist/analytics/Analytics.d.ts +2 -0
  36. package/dist/analytics/Analytics.d.ts.map +1 -1
  37. package/dist/analytics/Analytics.js +18 -2
  38. package/dist/analytics/Analytics.js.map +1 -1
  39. package/dist/analytics/tables/requestEvents.d.ts +22 -1
  40. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  41. package/dist/analytics/tables/requestEvents.js +59 -39
  42. package/dist/analytics/tables/requestEvents.js.map +1 -1
  43. package/dist/apps/Zones.d.ts +8335 -0
  44. package/dist/apps/Zones.d.ts.map +1 -0
  45. package/dist/apps/Zones.js +38 -0
  46. package/dist/apps/Zones.js.map +1 -0
  47. package/dist/apps/data/App.d.ts +14377 -10165
  48. package/dist/apps/data/App.d.ts.map +1 -1
  49. package/dist/apps/data/App.js +91 -19
  50. package/dist/apps/data/App.js.map +1 -1
  51. package/dist/apps/data/FxOracle.d.ts +1 -1
  52. package/dist/apps/data/FxOracle.d.ts.map +1 -1
  53. package/dist/apps/data/index.d.ts +0 -1
  54. package/dist/apps/data/index.d.ts.map +1 -1
  55. package/dist/apps/data/index.js +0 -1
  56. package/dist/apps/data/index.js.map +1 -1
  57. package/dist/apps/data/routes/activities.d.ts +32 -32
  58. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  59. package/dist/apps/data/routes/activities.js +130 -65
  60. package/dist/apps/data/routes/activities.js.map +1 -1
  61. package/dist/apps/data/routes/addresses.d.ts +312 -312
  62. package/dist/apps/data/routes/balances.d.ts +18 -18
  63. package/dist/apps/data/routes/balances.js +5 -5
  64. package/dist/apps/data/routes/balances.js.map +1 -1
  65. package/dist/apps/data/routes/coingecko.d.ts +176 -176
  66. package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
  67. package/dist/apps/data/routes/coingecko.js +62 -35
  68. package/dist/apps/data/routes/coingecko.js.map +1 -1
  69. package/dist/apps/data/routes/earn.d.ts +2144 -0
  70. package/dist/apps/data/routes/earn.d.ts.map +1 -0
  71. package/dist/apps/data/routes/earn.js +947 -0
  72. package/dist/apps/data/routes/earn.js.map +1 -0
  73. package/dist/apps/data/routes/exchanges.d.ts +1231 -324
  74. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  75. package/dist/apps/data/routes/exchanges.js +656 -193
  76. package/dist/apps/data/routes/exchanges.js.map +1 -1
  77. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  78. package/dist/apps/data/routes/fee-amm.js +59 -8
  79. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  80. package/dist/apps/data/routes/funding.d.ts +4092 -387
  81. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  82. package/dist/apps/data/routes/funding.js +1403 -256
  83. package/dist/apps/data/routes/funding.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +5 -5
  85. package/dist/apps/data/routes/indexer.d.ts.map +1 -1
  86. package/dist/apps/data/routes/indexer.js +19 -2
  87. package/dist/apps/data/routes/indexer.js.map +1 -1
  88. package/dist/apps/data/routes/receipts.d.ts +265 -265
  89. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  90. package/dist/apps/data/routes/receipts.js +11 -11
  91. package/dist/apps/data/routes/receipts.js.map +1 -1
  92. package/dist/apps/data/routes/rpc.d.ts +5 -5
  93. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  94. package/dist/apps/data/routes/rpc.js +211 -22
  95. package/dist/apps/data/routes/rpc.js.map +1 -1
  96. package/dist/apps/data/routes/tokenlist.d.ts +36 -36
  97. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  98. package/dist/apps/data/routes/tokenlist.js +49 -9
  99. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  100. package/dist/apps/data/routes/tokens.d.ts +116 -88
  101. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  102. package/dist/apps/data/routes/tokens.js +198 -91
  103. package/dist/apps/data/routes/tokens.js.map +1 -1
  104. package/dist/apps/data/routes/transactions.d.ts +55 -55
  105. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  106. package/dist/apps/data/routes/transactions.js +78 -39
  107. package/dist/apps/data/routes/transactions.js.map +1 -1
  108. package/dist/apps/data/routes/transfers.d.ts +78 -29
  109. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  110. package/dist/apps/data/routes/transfers.js +165 -67
  111. package/dist/apps/data/routes/transfers.js.map +1 -1
  112. package/dist/apps/data/routes/valuation.d.ts +10 -10
  113. package/dist/apps/data/routes/valuation.js +2 -2
  114. package/dist/apps/data/routes/valuation.js.map +1 -1
  115. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
  116. package/dist/apps/data/routes/verified-tokens.js +34 -9
  117. package/dist/apps/data/routes/verified-tokens.js.map +1 -1
  118. package/dist/apps/data/routes/webhooks.d.ts +5 -3
  119. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  120. package/dist/apps/data/routes/webhooks.js +175 -65
  121. package/dist/apps/data/routes/webhooks.js.map +1 -1
  122. package/dist/apps/data/routes/zones.d.ts +281 -0
  123. package/dist/apps/data/routes/zones.d.ts.map +1 -0
  124. package/dist/apps/data/routes/zones.js +252 -0
  125. package/dist/apps/data/routes/zones.js.map +1 -0
  126. package/dist/apps/docs/reference.js +6 -5
  127. package/dist/apps/docs/reference.js.map +1 -1
  128. package/dist/apps/index.d.ts +2 -1
  129. package/dist/apps/index.d.ts.map +1 -1
  130. package/dist/apps/index.js +2 -1
  131. package/dist/apps/index.js.map +1 -1
  132. package/dist/apps/management/App.d.ts +670 -670
  133. package/dist/apps/management/Billing.d.ts +8 -0
  134. package/dist/apps/management/Billing.d.ts.map +1 -1
  135. package/dist/apps/management/Billing.js +12 -0
  136. package/dist/apps/management/Billing.js.map +1 -1
  137. package/dist/apps/management/Error.d.ts +12 -0
  138. package/dist/apps/management/Error.d.ts.map +1 -0
  139. package/dist/apps/management/Error.js +10 -0
  140. package/dist/apps/management/Error.js.map +1 -0
  141. package/dist/apps/management/routes/api-keys.d.ts +5 -5
  142. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  143. package/dist/apps/management/routes/api-keys.js +2 -8
  144. package/dist/apps/management/routes/api-keys.js.map +1 -1
  145. package/dist/apps/management/routes/billing.d.ts +119 -119
  146. package/dist/apps/management/routes/faucet.d.ts +35 -35
  147. package/dist/apps/management/routes/invitations.d.ts +62 -62
  148. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  149. package/dist/apps/management/routes/invitations.js +4 -10
  150. package/dist/apps/management/routes/invitations.js.map +1 -1
  151. package/dist/apps/management/routes/invite-links.d.ts +30 -30
  152. package/dist/apps/management/routes/me.d.ts +6 -6
  153. package/dist/apps/management/routes/members.d.ts +78 -78
  154. package/dist/apps/management/routes/orgs.d.ts +48 -48
  155. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  156. package/dist/apps/management/routes/orgs.js +2 -8
  157. package/dist/apps/management/routes/orgs.js.map +1 -1
  158. package/dist/apps/management/routes/projects.d.ts +9 -9
  159. package/dist/apps/management/routes/scopes.js +2 -2
  160. package/dist/apps/management/routes/scopes.js.map +1 -1
  161. package/dist/apps/management/routes/usage.d.ts +80 -80
  162. package/dist/apps/management/routes/verified-token-requests.d.ts +36 -36
  163. package/dist/apps/management/routes/webhooks.d.ts +50 -50
  164. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  165. package/dist/apps/management/routes/webhooks.js +15 -3
  166. package/dist/apps/management/routes/webhooks.js.map +1 -1
  167. package/dist/apps/mpp/App.d.ts +55 -56
  168. package/dist/apps/mpp/App.d.ts.map +1 -1
  169. package/dist/apps/mpp/App.js +192 -27
  170. package/dist/apps/mpp/App.js.map +1 -1
  171. package/dist/apps/mpp/Mpp.d.ts +0 -20
  172. package/dist/apps/mpp/Mpp.d.ts.map +1 -1
  173. package/dist/apps/mpp/Mpp.js +0 -24
  174. package/dist/apps/mpp/Mpp.js.map +1 -1
  175. package/dist/apps/mpp/internal/Adapter.d.ts +40 -0
  176. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -0
  177. package/dist/apps/mpp/internal/Adapter.js +66 -0
  178. package/dist/apps/mpp/internal/Adapter.js.map +1 -0
  179. package/dist/apps/mpp/internal/Error.d.ts +4 -0
  180. package/dist/apps/mpp/internal/Error.d.ts.map +1 -0
  181. package/dist/apps/mpp/internal/Error.js +41 -0
  182. package/dist/apps/mpp/internal/Error.js.map +1 -0
  183. package/dist/apps/mpp/internal/Idempotency.d.ts +33 -0
  184. package/dist/apps/mpp/internal/Idempotency.d.ts.map +1 -0
  185. package/dist/apps/mpp/internal/Idempotency.js +28 -0
  186. package/dist/apps/mpp/internal/Idempotency.js.map +1 -0
  187. package/dist/apps/mpp/internal/Policy.d.ts +46 -0
  188. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -0
  189. package/dist/apps/mpp/internal/Policy.js +57 -0
  190. package/dist/apps/mpp/internal/Policy.js.map +1 -0
  191. package/dist/apps/mpp/internal/ScreenManager.d.ts +27 -0
  192. package/dist/apps/mpp/internal/ScreenManager.d.ts.map +1 -0
  193. package/dist/apps/mpp/internal/ScreenManager.js +18 -0
  194. package/dist/apps/mpp/internal/ScreenManager.js.map +1 -0
  195. package/dist/apps/mpp/internal/Screening.d.ts +35 -0
  196. package/dist/apps/mpp/internal/Screening.d.ts.map +1 -0
  197. package/dist/apps/mpp/internal/Screening.js +20 -0
  198. package/dist/apps/mpp/internal/Screening.js.map +1 -0
  199. package/dist/apps/mpp/internal/Sponsorship.d.ts +36 -0
  200. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -0
  201. package/dist/apps/mpp/internal/Sponsorship.js +103 -0
  202. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -0
  203. package/dist/apps/mpp/internal/Utils.d.ts +7 -0
  204. package/dist/apps/mpp/internal/Utils.d.ts.map +1 -0
  205. package/dist/apps/mpp/internal/Utils.js +24 -0
  206. package/dist/apps/mpp/internal/Utils.js.map +1 -0
  207. package/dist/apps/relay/App.js +184 -24
  208. package/dist/apps/relay/App.js.map +1 -1
  209. package/dist/apps/relay/Sponsorships.d.ts +4 -0
  210. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  211. package/dist/apps/relay/Sponsorships.js +16 -7
  212. package/dist/apps/relay/Sponsorships.js.map +1 -1
  213. package/dist/db/Db.d.ts +20 -0
  214. package/dist/db/Db.d.ts.map +1 -1
  215. package/dist/db/Db.js +342 -0
  216. package/dist/db/Db.js.map +1 -1
  217. package/dist/db/Schema.d.ts +921 -1
  218. package/dist/db/Schema.d.ts.map +1 -1
  219. package/dist/db/Schema.js +269 -1
  220. package/dist/db/Schema.js.map +1 -1
  221. package/dist/db/tables/earnVaults.d.ts +68 -0
  222. package/dist/db/tables/earnVaults.d.ts.map +1 -0
  223. package/dist/db/tables/earnVaults.js +72 -0
  224. package/dist/db/tables/earnVaults.js.map +1 -0
  225. package/dist/db/tables/fundingCatalog.d.ts +56 -0
  226. package/dist/db/tables/fundingCatalog.d.ts.map +1 -0
  227. package/dist/db/tables/fundingCatalog.js +85 -0
  228. package/dist/db/tables/fundingCatalog.js.map +1 -0
  229. package/dist/db/tables/fundingDepositAddresses.d.ts +159 -0
  230. package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -0
  231. package/dist/db/tables/fundingDepositAddresses.js +206 -0
  232. package/dist/db/tables/fundingDepositAddresses.js.map +1 -0
  233. package/dist/db/tables/fundingDeposits.d.ts +115 -0
  234. package/dist/db/tables/fundingDeposits.d.ts.map +1 -0
  235. package/dist/db/tables/fundingDeposits.js +100 -0
  236. package/dist/db/tables/fundingDeposits.js.map +1 -0
  237. package/dist/db/tables/fundingIdempotency.d.ts +91 -0
  238. package/dist/db/tables/fundingIdempotency.d.ts.map +1 -0
  239. package/dist/db/tables/fundingIdempotency.js +103 -0
  240. package/dist/db/tables/fundingIdempotency.js.map +1 -0
  241. package/dist/db/tables/fundingTransferEvents.d.ts +12 -0
  242. package/dist/db/tables/fundingTransferEvents.d.ts.map +1 -0
  243. package/dist/db/tables/fundingTransferEvents.js +18 -0
  244. package/dist/db/tables/fundingTransferEvents.js.map +1 -0
  245. package/dist/db/tables/fundingTransferTransactions.d.ts +15 -0
  246. package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -0
  247. package/dist/db/tables/fundingTransferTransactions.js +27 -0
  248. package/dist/db/tables/fundingTransferTransactions.js.map +1 -0
  249. package/dist/db/tables/fundingTransfers.d.ts +82 -0
  250. package/dist/db/tables/fundingTransfers.d.ts.map +1 -0
  251. package/dist/db/tables/fundingTransfers.js +89 -0
  252. package/dist/db/tables/fundingTransfers.js.map +1 -0
  253. package/dist/db/tables/organizations.d.ts +8 -0
  254. package/dist/db/tables/organizations.d.ts.map +1 -1
  255. package/dist/db/tables/organizations.js +35 -0
  256. package/dist/db/tables/organizations.js.map +1 -1
  257. package/dist/db/tables/projects.d.ts +8 -0
  258. package/dist/db/tables/projects.d.ts.map +1 -1
  259. package/dist/db/tables/projects.js +16 -0
  260. package/dist/db/tables/projects.js.map +1 -1
  261. package/dist/db/tables/requestUsage.d.ts +13 -0
  262. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  263. package/dist/db/tables/requestUsage.js +16 -0
  264. package/dist/db/tables/requestUsage.js.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.d.ts +4 -2
  266. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  267. package/dist/db/tables/sponsoredTransactions.js +14 -4
  268. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  269. package/dist/db/tables/users.d.ts +8 -0
  270. package/dist/db/tables/users.d.ts.map +1 -1
  271. package/dist/db/tables/users.js +16 -0
  272. package/dist/db/tables/users.js.map +1 -1
  273. package/dist/db/tables/verifiedTokens.d.ts +14 -7
  274. package/dist/db/tables/verifiedTokens.d.ts.map +1 -1
  275. package/dist/db/tables/verifiedTokens.js +9 -7
  276. package/dist/db/tables/verifiedTokens.js.map +1 -1
  277. package/dist/db/tables/webhookSubscriptions.d.ts +31 -1
  278. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  279. package/dist/db/tables/webhookSubscriptions.js +24 -3
  280. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  281. package/dist/handlers/relay.js +108 -108
  282. package/dist/handlers/relay.js.map +1 -1
  283. package/dist/internal/Auth.d.ts +26 -0
  284. package/dist/internal/Auth.d.ts.map +1 -1
  285. package/dist/internal/Auth.js +35 -2
  286. package/dist/internal/Auth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts.map +1 -1
  288. package/dist/internal/Cache.js +16 -10
  289. package/dist/internal/Cache.js.map +1 -1
  290. package/dist/internal/Cursor.js +1 -1
  291. package/dist/internal/Cursor.js.map +1 -1
  292. package/dist/internal/EarnRates.d.ts +89 -0
  293. package/dist/internal/EarnRates.d.ts.map +1 -0
  294. package/dist/internal/EarnRates.js +266 -0
  295. package/dist/internal/EarnRates.js.map +1 -0
  296. package/dist/internal/EarnVaults.d.ts +171 -0
  297. package/dist/internal/EarnVaults.d.ts.map +1 -0
  298. package/dist/internal/EarnVaults.js +547 -0
  299. package/dist/internal/EarnVaults.js.map +1 -0
  300. package/dist/internal/EdgeCache.d.ts +9 -2
  301. package/dist/internal/EdgeCache.d.ts.map +1 -1
  302. package/dist/internal/EdgeCache.js +36 -9
  303. package/dist/internal/EdgeCache.js.map +1 -1
  304. package/dist/internal/Id.d.ts +11 -0
  305. package/dist/internal/Id.d.ts.map +1 -1
  306. package/dist/internal/Id.js +13 -0
  307. package/dist/internal/Id.js.map +1 -1
  308. package/dist/internal/Idempotency.d.ts +83 -0
  309. package/dist/internal/Idempotency.d.ts.map +1 -0
  310. package/dist/internal/Idempotency.js +113 -0
  311. package/dist/internal/Idempotency.js.map +1 -0
  312. package/dist/internal/Log.d.ts +64 -9
  313. package/dist/internal/Log.d.ts.map +1 -1
  314. package/dist/internal/Log.js +29 -7
  315. package/dist/internal/Log.js.map +1 -1
  316. package/dist/internal/MetricSink.d.ts.map +1 -1
  317. package/dist/internal/MetricSink.js +47 -1
  318. package/dist/internal/MetricSink.js.map +1 -1
  319. package/dist/internal/OpenApi.d.ts +1 -1
  320. package/dist/internal/OpenApi.d.ts.map +1 -1
  321. package/dist/internal/OpenApi.js +3 -0
  322. package/dist/internal/OpenApi.js.map +1 -1
  323. package/dist/internal/Provider.d.ts +14 -0
  324. package/dist/internal/Provider.d.ts.map +1 -0
  325. package/dist/internal/Provider.js +5 -0
  326. package/dist/internal/Provider.js.map +1 -0
  327. package/dist/internal/Schema.d.ts +8 -3
  328. package/dist/internal/Schema.d.ts.map +1 -1
  329. package/dist/internal/Schema.js +24 -13
  330. package/dist/internal/Schema.js.map +1 -1
  331. package/dist/internal/Store.d.ts +6 -0
  332. package/dist/internal/Store.d.ts.map +1 -1
  333. package/dist/internal/Store.js +35 -0
  334. package/dist/internal/Store.js.map +1 -1
  335. package/dist/internal/Tidx.d.ts +43 -24
  336. package/dist/internal/Tidx.d.ts.map +1 -1
  337. package/dist/internal/Tidx.js +79 -11
  338. package/dist/internal/Tidx.js.map +1 -1
  339. package/dist/internal/Viem.d.ts +82 -65
  340. package/dist/internal/Viem.d.ts.map +1 -1
  341. package/dist/internal/Viem.js +83 -12
  342. package/dist/internal/Viem.js.map +1 -1
  343. package/dist/internal/WebhookDestination.d.ts.map +1 -1
  344. package/dist/internal/WebhookDestination.js +34 -28
  345. package/dist/internal/WebhookDestination.js.map +1 -1
  346. package/dist/internal/Webhooks.d.ts +9 -0
  347. package/dist/internal/Webhooks.d.ts.map +1 -1
  348. package/dist/internal/Webhooks.js +15 -10
  349. package/dist/internal/Webhooks.js.map +1 -1
  350. package/dist/internal/exchange/Provider.d.ts +219 -0
  351. package/dist/internal/exchange/Provider.d.ts.map +1 -0
  352. package/dist/internal/exchange/Provider.js +117 -0
  353. package/dist/internal/exchange/Provider.js.map +1 -0
  354. package/dist/internal/exchange/index.d.ts +2 -0
  355. package/dist/internal/exchange/index.d.ts.map +1 -0
  356. package/dist/internal/exchange/index.js +2 -0
  357. package/dist/internal/exchange/index.js.map +1 -0
  358. package/dist/internal/exchange/providers/uniswap.d.ts +57 -0
  359. package/dist/internal/exchange/providers/uniswap.d.ts.map +1 -0
  360. package/dist/internal/exchange/providers/uniswap.js +553 -0
  361. package/dist/internal/exchange/providers/uniswap.js.map +1 -0
  362. package/dist/internal/funding/Action.d.ts +55 -0
  363. package/dist/internal/funding/Action.d.ts.map +1 -0
  364. package/dist/internal/funding/Action.js +74 -0
  365. package/dist/internal/funding/Action.js.map +1 -0
  366. package/dist/internal/funding/Catalog.d.ts +107 -0
  367. package/dist/internal/funding/Catalog.d.ts.map +1 -0
  368. package/dist/internal/funding/Catalog.js +270 -0
  369. package/dist/internal/funding/Catalog.js.map +1 -0
  370. package/dist/internal/funding/Chain.d.ts +76 -0
  371. package/dist/internal/funding/Chain.d.ts.map +1 -0
  372. package/dist/internal/funding/Chain.js +38 -0
  373. package/dist/internal/funding/Chain.js.map +1 -0
  374. package/dist/internal/funding/Deposit.d.ts +366 -0
  375. package/dist/internal/funding/Deposit.d.ts.map +1 -0
  376. package/dist/internal/funding/Deposit.js +286 -0
  377. package/dist/internal/funding/Deposit.js.map +1 -0
  378. package/dist/internal/funding/DepositAddress.d.ts +345 -0
  379. package/dist/internal/funding/DepositAddress.d.ts.map +1 -0
  380. package/dist/internal/funding/DepositAddress.js +189 -0
  381. package/dist/internal/funding/DepositAddress.js.map +1 -0
  382. package/dist/internal/funding/Evidence.d.ts +52 -0
  383. package/dist/internal/funding/Evidence.d.ts.map +1 -0
  384. package/dist/internal/funding/Evidence.js +314 -0
  385. package/dist/internal/funding/Evidence.js.map +1 -0
  386. package/dist/internal/funding/Provider.d.ts +1186 -0
  387. package/dist/internal/funding/Provider.d.ts.map +1 -0
  388. package/dist/internal/funding/Provider.js +1081 -0
  389. package/dist/internal/funding/Provider.js.map +1 -0
  390. package/dist/internal/funding/Reconciliation.d.ts +113 -0
  391. package/dist/internal/funding/Reconciliation.d.ts.map +1 -0
  392. package/dist/internal/funding/Reconciliation.js +676 -0
  393. package/dist/internal/funding/Reconciliation.js.map +1 -0
  394. package/dist/internal/funding/Route.d.ts +21 -0
  395. package/dist/internal/funding/Route.d.ts.map +1 -0
  396. package/dist/internal/funding/Route.js +5 -0
  397. package/dist/internal/funding/Route.js.map +1 -0
  398. package/dist/internal/funding/Subsidy.d.ts +113 -0
  399. package/dist/internal/funding/Subsidy.d.ts.map +1 -0
  400. package/dist/internal/funding/Subsidy.js +138 -0
  401. package/dist/internal/funding/Subsidy.js.map +1 -0
  402. package/dist/internal/funding/Token.d.ts +41 -0
  403. package/dist/internal/funding/Token.d.ts.map +1 -0
  404. package/dist/internal/funding/Token.js +22 -0
  405. package/dist/internal/funding/Token.js.map +1 -0
  406. package/dist/internal/funding/Transfer.d.ts +643 -0
  407. package/dist/internal/funding/Transfer.d.ts.map +1 -0
  408. package/dist/internal/funding/Transfer.js +332 -0
  409. package/dist/internal/funding/Transfer.js.map +1 -0
  410. package/dist/internal/funding/index.d.ts +13 -0
  411. package/dist/internal/funding/index.d.ts.map +1 -0
  412. package/dist/internal/funding/index.js +13 -0
  413. package/dist/internal/funding/index.js.map +1 -0
  414. package/dist/internal/funding/providers/across.d.ts +21 -0
  415. package/dist/internal/funding/providers/across.d.ts.map +1 -0
  416. package/dist/internal/funding/providers/across.js +117 -0
  417. package/dist/internal/funding/providers/across.js.map +1 -0
  418. package/dist/internal/funding/providers/relay.d.ts +46 -0
  419. package/dist/internal/funding/providers/relay.d.ts.map +1 -0
  420. package/dist/internal/funding/providers/relay.js +464 -0
  421. package/dist/internal/funding/providers/relay.js.map +1 -0
  422. package/dist/internal/funding/providers/rhino.d.ts +15 -0
  423. package/dist/internal/funding/providers/rhino.d.ts.map +1 -0
  424. package/dist/internal/funding/providers/rhino.js +116 -0
  425. package/dist/internal/funding/providers/rhino.js.map +1 -0
  426. package/dist/internal/funding/providers/squid.d.ts +19 -0
  427. package/dist/internal/funding/providers/squid.d.ts.map +1 -0
  428. package/dist/internal/funding/providers/squid.js +120 -0
  429. package/dist/internal/funding/providers/squid.js.map +1 -0
  430. package/dist/internal/funding/providers/symbiosis.d.ts +20 -0
  431. package/dist/internal/funding/providers/symbiosis.d.ts.map +1 -0
  432. package/dist/internal/funding/providers/symbiosis.js +176 -0
  433. package/dist/internal/funding/providers/symbiosis.js.map +1 -0
  434. package/dist/internal/index.d.ts +5 -1
  435. package/dist/internal/index.d.ts.map +1 -1
  436. package/dist/internal/index.js +5 -1
  437. package/dist/internal/index.js.map +1 -1
  438. package/dist/internal/webhookDestinations/url.js +61 -57
  439. package/dist/internal/webhookDestinations/url.js.map +1 -1
  440. package/dist/providers/index.d.ts +43 -0
  441. package/dist/providers/index.d.ts.map +1 -0
  442. package/dist/providers/index.js +19 -0
  443. package/dist/providers/index.js.map +1 -0
  444. package/package.json +9 -4
  445. package/src/ApiKeys.test.ts +11 -7
  446. package/src/ApiKeys.ts +37 -9
  447. package/src/App.test.ts +85 -10
  448. package/src/App.ts +224 -137
  449. package/src/Assets.ts +29 -4
  450. package/src/Client.test-d.ts +650 -30
  451. package/src/Scope.test.ts +19 -0
  452. package/src/Scope.ts +28 -11
  453. package/src/Webhooks.test.ts +25 -0
  454. package/src/Webhooks.ts +1 -1
  455. package/src/admin/App.test.ts +9 -2
  456. package/src/admin/App.ts +32 -9
  457. package/src/admin/apps/api-keys.test.ts +167 -23
  458. package/src/admin/apps/api-keys.ts +166 -28
  459. package/src/admin/apps/earn-vaults.test.ts +338 -0
  460. package/src/admin/apps/earn-vaults.ts +572 -0
  461. package/src/admin/apps/scopes.test.ts +16 -1
  462. package/src/admin/ui/plugin.ts +2 -2
  463. package/src/admin/ui/src/components/EarnVaultForm.tsx +137 -0
  464. package/src/admin/ui/src/components/MobileProfile.tsx +2 -2
  465. package/src/admin/ui/src/components/Page.tsx +1 -1
  466. package/src/admin/ui/src/components/ThemeToggle.tsx +1 -1
  467. package/src/admin/ui/src/lib/api-keys.ts +37 -7
  468. package/src/admin/ui/src/lib/client.ts +1 -1
  469. package/src/admin/ui/src/lib/config.ts +1 -1
  470. package/src/admin/ui/src/lib/early-access.ts +8 -9
  471. package/src/admin/ui/src/lib/earn-vaults.ts +207 -0
  472. package/src/admin/ui/src/lib/format.ts +13 -0
  473. package/src/admin/ui/src/lib/organizations.test.ts +14 -4
  474. package/src/admin/ui/src/lib/organizations.ts +7 -1
  475. package/src/admin/ui/src/lib/response.ts +22 -0
  476. package/src/admin/ui/src/lib/scopes.test.ts +19 -11
  477. package/src/admin/ui/src/lib/scopes.ts +28 -7
  478. package/src/admin/ui/src/lib/verified-tokens.ts +10 -9
  479. package/src/admin/ui/src/routeTree.gen.ts +70 -7
  480. package/src/admin/ui/src/router.tsx +2 -2
  481. package/src/admin/ui/src/routes/__root.tsx +9 -8
  482. package/src/admin/ui/src/routes/api-keys.tsx +475 -64
  483. package/src/admin/ui/src/routes/early-access.tsx +5 -12
  484. package/src/admin/ui/src/routes/earn.vaults.tsx +348 -0
  485. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +154 -0
  486. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +190 -0
  487. package/src/admin/ui/src/routes/organizations.tsx +4 -7
  488. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +56 -54
  489. package/src/admin/ui/src/routes/verified-tokens.tsx +4 -4
  490. package/src/admin/ui/vite.config.ts +4 -1
  491. package/src/admin/ui.generated.ts +189 -95
  492. package/src/analytics/Analytics.test.ts +69 -10
  493. package/src/analytics/Analytics.ts +20 -1
  494. package/src/analytics/tables/requestEvents.ts +79 -37
  495. package/src/apps/Zones.test.ts +33 -0
  496. package/src/apps/Zones.ts +40 -0
  497. package/src/apps/composition.test.ts +84 -1
  498. package/src/apps/data/App.test.ts +38 -9
  499. package/src/apps/data/App.ts +96 -33
  500. package/src/apps/data/FxOracle.ts +1 -1
  501. package/src/apps/data/index.ts +0 -1
  502. package/src/apps/data/routes/activities.test.ts +82 -6
  503. package/src/apps/data/routes/activities.ts +131 -71
  504. package/src/apps/data/routes/balances.test.ts +50 -37
  505. package/src/apps/data/routes/balances.ts +5 -5
  506. package/src/apps/data/routes/blocks.test.ts +2 -0
  507. package/src/apps/data/routes/coingecko.test.ts +22 -0
  508. package/src/apps/data/routes/coingecko.ts +84 -48
  509. package/src/apps/data/routes/earn.test.ts +1108 -0
  510. package/src/apps/data/routes/earn.ts +1391 -0
  511. package/src/apps/data/routes/exchanges.test.ts +82 -33
  512. package/src/apps/data/routes/exchanges.ts +842 -227
  513. package/src/apps/data/routes/fee-amm.test.ts +4 -6
  514. package/src/apps/data/routes/fee-amm.ts +69 -12
  515. package/src/apps/data/routes/funding.test.ts +2712 -221
  516. package/src/apps/data/routes/funding.ts +1604 -387
  517. package/src/apps/data/routes/indexer.test.ts +43 -34
  518. package/src/apps/data/routes/indexer.ts +19 -2
  519. package/src/apps/data/routes/receipts.test.ts +5 -3
  520. package/src/apps/data/routes/receipts.ts +13 -11
  521. package/src/apps/data/routes/rpc.test.ts +446 -28
  522. package/src/apps/data/routes/rpc.ts +243 -25
  523. package/src/apps/data/routes/tokenlist.test.ts +15 -0
  524. package/src/apps/data/routes/tokenlist.ts +88 -22
  525. package/src/apps/data/routes/tokens.ts +262 -86
  526. package/src/apps/data/routes/transactions.test.ts +2 -0
  527. package/src/apps/data/routes/transactions.ts +77 -42
  528. package/src/apps/data/routes/transfers.test.ts +166 -4
  529. package/src/apps/data/routes/transfers.ts +216 -78
  530. package/src/apps/data/routes/valuation.test.ts +62 -9
  531. package/src/apps/data/routes/valuation.ts +2 -2
  532. package/src/apps/data/routes/verified-tokens.test.ts +51 -0
  533. package/src/apps/data/routes/verified-tokens.ts +52 -15
  534. package/src/apps/data/routes/webhooks.test.ts +432 -33
  535. package/src/apps/data/routes/webhooks.ts +189 -79
  536. package/src/apps/data/routes/zones.test.ts +473 -0
  537. package/src/apps/data/routes/zones.ts +338 -0
  538. package/src/apps/docs/reference.ts +8 -6
  539. package/src/apps/index.ts +2 -1
  540. package/src/apps/management/Billing.test.ts +29 -0
  541. package/src/apps/management/Billing.ts +23 -0
  542. package/src/apps/management/Error.ts +12 -0
  543. package/src/apps/management/routes/api-keys.test.ts +5 -3
  544. package/src/apps/management/routes/api-keys.ts +2 -9
  545. package/src/apps/management/routes/invitations.ts +4 -11
  546. package/src/apps/management/routes/orgs.ts +2 -9
  547. package/src/apps/management/routes/scopes.test.ts +7 -2
  548. package/src/apps/management/routes/scopes.ts +2 -2
  549. package/src/apps/management/routes/webhooks.test.ts +6 -1
  550. package/src/apps/management/routes/webhooks.ts +15 -3
  551. package/src/apps/mpp/App.ts +276 -29
  552. package/src/apps/mpp/Mpp.test.ts +631 -26
  553. package/src/apps/mpp/Mpp.ts +0 -42
  554. package/src/apps/mpp/internal/Adapter.ts +108 -3
  555. package/src/apps/mpp/internal/Error.test.ts +33 -0
  556. package/src/apps/mpp/internal/Error.ts +44 -6
  557. package/src/apps/mpp/internal/Idempotency.test.ts +213 -0
  558. package/src/apps/mpp/internal/Idempotency.ts +59 -5
  559. package/src/apps/mpp/internal/Policy.test.ts +122 -0
  560. package/src/apps/mpp/internal/Policy.ts +98 -0
  561. package/src/apps/mpp/internal/ScreenManager.test.ts +68 -0
  562. package/src/apps/mpp/internal/ScreenManager.ts +41 -0
  563. package/src/apps/mpp/internal/Screening.ts +40 -3
  564. package/src/apps/mpp/internal/Sponsorship.ts +144 -0
  565. package/src/apps/mpp/internal/Utils.ts +30 -0
  566. package/src/apps/relay/App.test.ts +495 -64
  567. package/src/apps/relay/App.ts +234 -24
  568. package/src/apps/relay/Sponsorships.test.ts +51 -0
  569. package/src/apps/relay/Sponsorships.ts +19 -7
  570. package/src/db/Db.ts +439 -0
  571. package/src/db/Schema.ts +325 -2
  572. package/src/db/tables/earnVaults.test.ts +185 -0
  573. package/src/db/tables/earnVaults.ts +151 -0
  574. package/src/db/tables/fundingCatalog.test.ts +108 -0
  575. package/src/db/tables/fundingCatalog.ts +157 -0
  576. package/src/db/tables/fundingDepositAddresses.test.ts +580 -0
  577. package/src/db/tables/fundingDepositAddresses.ts +376 -0
  578. package/src/db/tables/fundingDeposits.test.ts +261 -0
  579. package/src/db/tables/fundingDeposits.ts +229 -0
  580. package/src/db/tables/fundingIdempotency.test.ts +182 -0
  581. package/src/db/tables/fundingIdempotency.ts +180 -0
  582. package/src/db/tables/fundingTransferEvents.ts +28 -0
  583. package/src/db/tables/fundingTransferTransactions.test.ts +69 -0
  584. package/src/db/tables/fundingTransferTransactions.ts +37 -0
  585. package/src/db/tables/fundingTransfers.test.ts +89 -0
  586. package/src/db/tables/fundingTransfers.ts +153 -0
  587. package/src/db/tables/organizations.test.ts +88 -0
  588. package/src/db/tables/organizations.ts +42 -1
  589. package/src/db/tables/projects.ts +16 -0
  590. package/src/db/tables/requestUsage.ts +23 -0
  591. package/src/db/tables/sponsoredTransactions.test.ts +52 -2
  592. package/src/db/tables/sponsoredTransactions.ts +18 -6
  593. package/src/db/tables/users.ts +16 -0
  594. package/src/db/tables/verifiedTokens.ts +19 -14
  595. package/src/db/tables/webhookSubscriptions.ts +58 -3
  596. package/src/handlers/relay.test.ts +2 -0
  597. package/src/handlers/relay.ts +95 -99
  598. package/src/internal/Auth.test.ts +48 -0
  599. package/src/internal/Auth.ts +61 -2
  600. package/src/internal/Cache.ts +13 -9
  601. package/src/internal/Cursor.test.ts +2 -2
  602. package/src/internal/Cursor.ts +1 -1
  603. package/src/internal/EarnRates.test.ts +125 -0
  604. package/src/internal/EarnRates.ts +409 -0
  605. package/src/internal/EarnVaults.test.ts +195 -0
  606. package/src/internal/EarnVaults.ts +876 -0
  607. package/src/internal/EdgeCache.test.ts +37 -5
  608. package/src/internal/EdgeCache.ts +39 -7
  609. package/src/internal/Id.ts +14 -0
  610. package/src/internal/Idempotency.test.ts +109 -0
  611. package/src/internal/Idempotency.ts +237 -0
  612. package/src/internal/Log.test-d.ts +41 -8
  613. package/src/internal/Log.test.ts +189 -8
  614. package/src/internal/Log.ts +124 -17
  615. package/src/internal/MetricSink.test.ts +244 -4
  616. package/src/internal/MetricSink.ts +51 -1
  617. package/src/internal/OpenApi.ts +3 -0
  618. package/src/internal/Provider.test.ts +17 -0
  619. package/src/internal/Provider.ts +17 -0
  620. package/src/internal/Schema.test.ts +13 -0
  621. package/src/internal/Schema.ts +41 -24
  622. package/src/internal/Store.test.ts +25 -0
  623. package/src/internal/Store.ts +46 -0
  624. package/src/internal/Tidx.local.test.ts +78 -3
  625. package/src/internal/Tidx.test.ts +212 -18
  626. package/src/internal/Tidx.ts +112 -32
  627. package/src/internal/VerifiedTokens.test.ts +15 -0
  628. package/src/internal/Viem.test.ts +170 -17
  629. package/src/internal/Viem.ts +111 -28
  630. package/src/internal/WebhookDestination.ts +25 -23
  631. package/src/internal/Webhooks.test.ts +59 -0
  632. package/src/internal/Webhooks.ts +34 -10
  633. package/src/internal/exchange/Provider.test.ts +216 -0
  634. package/src/internal/exchange/Provider.ts +326 -0
  635. package/src/internal/exchange/index.test.ts +6 -0
  636. package/src/internal/exchange/index.ts +1 -0
  637. package/src/internal/exchange/providers/uniswap.test.ts +122 -0
  638. package/src/internal/exchange/providers/uniswap.ts +682 -0
  639. package/src/internal/funding/Action.test.ts +138 -0
  640. package/src/internal/funding/Action.ts +117 -0
  641. package/src/internal/funding/Catalog.test.ts +311 -0
  642. package/src/internal/funding/Catalog.ts +347 -0
  643. package/src/internal/funding/Chain.test.ts +79 -0
  644. package/src/internal/funding/Chain.ts +120 -0
  645. package/src/internal/funding/Deposit.test.ts +26 -0
  646. package/src/internal/funding/Deposit.ts +453 -0
  647. package/src/internal/funding/DepositAddress.test.ts +18 -0
  648. package/src/internal/funding/DepositAddress.ts +312 -0
  649. package/src/internal/funding/Evidence.test.ts +297 -0
  650. package/src/internal/funding/Evidence.ts +430 -0
  651. package/src/internal/funding/Provider.test.ts +1328 -0
  652. package/src/internal/funding/Provider.ts +1796 -0
  653. package/src/internal/funding/Reconciliation.local.test.ts +504 -0
  654. package/src/internal/funding/Reconciliation.test.ts +2020 -0
  655. package/src/internal/funding/Reconciliation.ts +930 -0
  656. package/src/internal/funding/Route.test.ts +66 -0
  657. package/src/internal/funding/Route.ts +29 -0
  658. package/src/internal/funding/Subsidy.local.test.ts +152 -0
  659. package/src/internal/funding/Subsidy.test.ts +75 -0
  660. package/src/internal/funding/Subsidy.ts +260 -0
  661. package/src/internal/funding/Token.test.ts +47 -0
  662. package/src/internal/funding/Token.ts +59 -0
  663. package/src/internal/funding/Transfer.test.ts +369 -0
  664. package/src/internal/funding/Transfer.ts +522 -0
  665. package/src/internal/funding/index.test.ts +20 -0
  666. package/src/internal/funding/index.ts +12 -0
  667. package/src/internal/funding/providers/across.ts +149 -0
  668. package/src/{apps/data/FundingQuoteProviders.test.ts → internal/funding/providers/index.test.ts} +178 -157
  669. package/src/internal/funding/providers/relay.test.ts +474 -0
  670. package/src/internal/funding/providers/relay.ts +559 -0
  671. package/src/internal/funding/providers/rhino.ts +139 -0
  672. package/src/internal/funding/providers/squid.ts +151 -0
  673. package/src/internal/funding/providers/symbiosis.ts +221 -0
  674. package/src/internal/index.test.ts +5 -1
  675. package/src/internal/index.ts +5 -1
  676. package/src/internal/webhookDestinations/url.ts +49 -45
  677. package/src/providers/index.test.ts +14 -0
  678. package/src/providers/index.ts +54 -0
  679. package/dist/apps/data/FundingQuoteProviders.d.ts +0 -174
  680. package/dist/apps/data/FundingQuoteProviders.d.ts.map +0 -1
  681. package/dist/apps/data/FundingQuoteProviders.js +0 -775
  682. package/dist/apps/data/FundingQuoteProviders.js.map +0 -1
  683. package/dist/internal/FundingQuotes.d.ts +0 -864
  684. package/dist/internal/FundingQuotes.d.ts.map +0 -1
  685. package/dist/internal/FundingQuotes.js +0 -672
  686. package/dist/internal/FundingQuotes.js.map +0 -1
  687. package/src/apps/data/FundingQuoteProviders.ts +0 -1043
  688. package/src/internal/FundingQuotes.test.ts +0 -456
  689. package/src/internal/FundingQuotes.ts +0 -944
@@ -1,3 +1,5 @@
1
+ /** @module-tag localnet */
2
+
1
3
  import { nanoid } from 'nanoid'
2
4
  import { Hash, Hex, Secp256k1 } from 'ox'
3
5
  import { ZoneRpcAuthentication } from 'ox/tempo'
@@ -14,6 +16,7 @@ import * as TestStripe from '../../../test/Stripe.js'
14
16
  import * as BillingSettings from '../../db/tables/billingSettings.js'
15
17
  import type * as Db from '../../db/Db.js'
16
18
  import * as Fees from '../../internal/Fees.js'
19
+ import type * as Log from '../../internal/Log.js'
17
20
  import * as Organizations from '../../db/tables/organizations.js'
18
21
  import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js'
19
22
  import * as StripeCustomers from '../../db/tables/stripeCustomers.js'
@@ -28,10 +31,10 @@ const feePayerAccount = Tempo.accounts[10]!
28
31
  const senderAccount = Tempo.accounts[9]!
29
32
  const zone = runtime.zone.chainId
30
33
  const zoneScope = `zone:${zone}:read` as const
31
- const zoneOptions = {
34
+ const zoneOptions = TestApp.zone({
32
35
  chainId: zone,
33
- forwardRpcUrl: runtime.zone.forwardRpcUrl,
34
- }
36
+ rpcUrl: runtime.zone.publicZoneUrl,
37
+ })
35
38
 
36
39
  /** Super admin secret configured on the end-to-end billing app. */
37
40
  const superAdminSecret = 'tempo:sk:a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1'
@@ -255,8 +258,7 @@ describe('behavior: Zone chain routing', () => {
255
258
  try {
256
259
  const api = TestApp.create({
257
260
  auth: { keys },
258
- rpc: ({ chainId }) =>
259
- chainId === zone ? { basicAuth: 'rpc-secret', url: server.url } : {},
261
+ rpc: ({ chainId }) => (chainId === zone ? { auth: 'rpc:secret', url: server.url } : {}),
260
262
  zones: [zoneOptions],
261
263
  })
262
264
  const body = await request(api, {
@@ -266,7 +268,7 @@ describe('behavior: Zone chain routing', () => {
266
268
  })
267
269
 
268
270
  expect(body).toMatchObject({ result: Hex.fromNumber(zone) })
269
- expect(authorization).toEqual(['Basic cnBjLXNlY3JldA=='])
271
+ expect(authorization).toEqual(['Basic cnBjOnNlY3JldA=='])
270
272
  } finally {
271
273
  await server.closeAsync()
272
274
  }
@@ -368,8 +370,10 @@ describe('behavior: Zone chain routing', () => {
368
370
  })
369
371
 
370
372
  test('requires Zone authorization for an embedded signed transaction', async () => {
373
+ const entries: Log.Entry[] = []
371
374
  const api = TestApp.create({
372
375
  auth: { keys },
376
+ logger: (entry) => void entries.push(entry),
373
377
  relay: { feePayer: { account: feePayerAccount } },
374
378
  zones: [zoneOptions],
375
379
  })
@@ -396,6 +400,7 @@ describe('behavior: Zone chain routing', () => {
396
400
  const authorized = await request(api, { ...rpc, zoneToken: token() })
397
401
 
398
402
  expect(refused).toMatchObject({ error: { data: { code: 'api_key_forbidden' } } })
403
+ expectSponsorshipCode({ code: 'api_key_forbidden', entry: entries[0] })
399
404
  expect(authorized).toMatchObject({ result: expect.stringMatching(/^0x/) })
400
405
  })
401
406
  })
@@ -450,7 +455,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
450
455
  `)
451
456
  })
452
457
 
453
- test('behavior: non-mainnet production keys record billable rows', async () => {
458
+ test('behavior: non-mainnet production keys record non-billable rows', async () => {
454
459
  const db = TestApp.database()
455
460
  const app = TestApp.create({
456
461
  auth: { keys },
@@ -466,7 +471,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
466
471
  expect(body.error).toBeUndefined()
467
472
 
468
473
  const [row] = await SponsoredTransactions.listPending(db)
469
- expect(row?.billable).toBe(true)
474
+ expect(row?.billable).toBe(false)
470
475
  expect(row?.environment).toMatchInlineSnapshot(`"production"`)
471
476
  })
472
477
 
@@ -509,7 +514,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
509
514
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
510
515
  })
511
516
 
512
- test('behavior: keys without project attribution are refused', async () => {
517
+ test('behavior: organization-attributed keys sponsor without a project', async () => {
513
518
  const db = TestApp.database()
514
519
  const app = TestApp.create({
515
520
  auth: { keys },
@@ -522,26 +527,273 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
522
527
  params: [await signSponsorable()],
523
528
  token: 'secret_unattributed',
524
529
  })
525
- expect(body.result).toBeUndefined()
526
- expect(body.error?.code).toBe(-32602)
530
+ expect(body.error).toBeUndefined()
531
+ expect(Transaction.deserialize(body.result as `0x76${string}`).feePayerSignature).toBeDefined()
532
+
533
+ const [row] = await SponsoredTransactions.listPending(db)
534
+ expect(row?.orgId).toMatchInlineSnapshot(`"org_1"`)
535
+ expect(row?.projectId).toBeNull()
536
+ })
537
+
538
+ test('behavior: batches aggregate sponsorship rejections without retaining payloads', async () => {
539
+ const db = TestApp.database()
540
+ const entries: Log.Entry[] = []
541
+ const app = TestApp.create({
542
+ auth: { keys },
543
+ db,
544
+ logger: (entry) => void entries.push(entry),
545
+ relay: { feePayer: { account: feePayerAccount } },
546
+ })
547
+ const transactions = await Promise.all([
548
+ signSponsorable({ chainId: 999_999, nonce: 0 }),
549
+ signSponsorable({ chainId: 999_999, nonce: 1 }),
550
+ ])
551
+
552
+ const response = await app.fetch(
553
+ new Request('http://tempo-api.test/rpc/sponsor', {
554
+ body: JSON.stringify(
555
+ transactions.map((transaction, index) => ({
556
+ id: index + 1,
557
+ jsonrpc: '2.0',
558
+ method: 'eth_signRawTransaction',
559
+ params: [transaction],
560
+ })),
561
+ ),
562
+ headers: {
563
+ 'content-type': 'application/json',
564
+ 'tempo-api-key': 'secret_sponsor',
565
+ },
566
+ method: 'POST',
567
+ }),
568
+ )
569
+ const body = await response.json()
570
+
571
+ expect(body).toMatchObject([
572
+ { error: { data: { code: 'chain_id_unsupported' } } },
573
+ { error: { data: { code: 'chain_id_unsupported' } } },
574
+ ])
575
+ expect(entries).toHaveLength(1)
576
+ expect(entries[0]?.rpc).toStrictEqual({
577
+ code: -32602,
578
+ dataCode: 'chain_id_unsupported',
579
+ errors: 2,
580
+ })
581
+ expect(entries[0]?.sponsorship).toStrictEqual({
582
+ chainId: 999_999,
583
+ method: 'eth_signRawTransaction',
584
+ outcome: 'rejected',
585
+ reason: 'chain_id_unsupported',
586
+ rejections: 2,
587
+ })
588
+ expect(JSON.stringify(entries[0])).not.toContain(transactions[0])
589
+ expect(JSON.stringify(entries[0])).not.toContain(transactions[1])
590
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
591
+ })
592
+
593
+ test('behavior: invalid batch items never enable payload hashes', async () => {
594
+ const db = TestApp.database()
595
+ const entries: Log.Entry[] = []
596
+ const app = TestApp.create({
597
+ auth: { keys },
598
+ db,
599
+ logger: (entry) => void entries.push(entry),
600
+ relay: { feePayer: { account: feePayerAccount } },
601
+ })
602
+ const serialized = await signSponsorable({ chainId: 999_999 })
603
+
604
+ const response = await app.fetch(
605
+ new Request('http://tempo-api.test/rpc/sponsor', {
606
+ body: JSON.stringify([
607
+ null,
608
+ {
609
+ id: 2,
610
+ jsonrpc: '2.0',
611
+ method: 'eth_signRawTransaction',
612
+ params: [serialized],
613
+ },
614
+ ]),
615
+ headers: {
616
+ 'content-type': 'application/json',
617
+ 'tempo-api-key': 'secret_sponsor',
618
+ },
619
+ method: 'POST',
620
+ }),
621
+ )
622
+ const body = await response.json()
623
+
624
+ expect(body).toMatchObject([
625
+ { error: { code: -32600 } },
626
+ { error: { data: { code: 'chain_id_unsupported' } } },
627
+ ])
628
+ expect(entries[0]?.sponsorship).toStrictEqual({
629
+ chainId: 999_999,
630
+ method: 'eth_signRawTransaction',
631
+ outcome: 'rejected',
632
+ reason: 'chain_id_unsupported',
633
+ rejections: 1,
634
+ })
635
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
636
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
637
+ })
638
+
639
+ test('behavior: batch diagnostics use only rejected request methods', async () => {
640
+ const db = TestApp.database()
641
+ const entries: Log.Entry[] = []
642
+ const app = TestApp.create({
643
+ auth: { keys },
644
+ db,
645
+ logger: (entry) => void entries.push(entry),
646
+ relay: { feePayer: { account: feePayerAccount } },
647
+ })
648
+ const serialized = await signSponsorable({ chainId: 999_999 })
649
+
650
+ const response = await app.fetch(
651
+ new Request('http://tempo-api.test/rpc/sponsor', {
652
+ body: JSON.stringify([
653
+ {
654
+ id: 1,
655
+ jsonrpc: '2.0',
656
+ method: 'eth_fillTransaction',
657
+ params: [],
658
+ },
659
+ {
660
+ id: 2,
661
+ jsonrpc: '2.0',
662
+ method: 'eth_signRawTransaction',
663
+ params: [serialized],
664
+ },
665
+ ]),
666
+ headers: {
667
+ 'content-type': 'application/json',
668
+ 'tempo-api-key': 'secret_sponsor',
669
+ },
670
+ method: 'POST',
671
+ }),
672
+ )
673
+ const body = await response.json()
674
+
675
+ expect(body).toMatchObject([
676
+ { error: { data: { code: 'internal_error' } } },
677
+ { error: { data: { code: 'chain_id_unsupported' } } },
678
+ ])
679
+ expect(entries[0]?.sponsorship).toStrictEqual({
680
+ chainId: 999_999,
681
+ method: 'eth_signRawTransaction',
682
+ outcome: 'rejected',
683
+ reason: 'chain_id_unsupported',
684
+ rejections: 1,
685
+ })
686
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
687
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
688
+ })
689
+
690
+ test('behavior: duplicate batch ids suppress request attribution', async () => {
691
+ const db = TestApp.database()
692
+ const entries: Log.Entry[] = []
693
+ const app = TestApp.create({
694
+ auth: { keys },
695
+ db,
696
+ logger: (entry) => void entries.push(entry),
697
+ relay: { feePayer: { account: feePayerAccount } },
698
+ })
699
+ const serialized = await signSponsorable({ chainId: 999_999 })
700
+
701
+ const response = await app.fetch(
702
+ new Request('http://tempo-api.test/rpc/sponsor/999999', {
703
+ body: JSON.stringify([
704
+ {
705
+ id: 1,
706
+ jsonrpc: '2.0',
707
+ method: 'eth_chainId',
708
+ },
709
+ {
710
+ id: 1,
711
+ jsonrpc: '2.0',
712
+ method: 'eth_signRawTransaction',
713
+ params: [serialized],
714
+ },
715
+ ]),
716
+ headers: {
717
+ 'content-type': 'application/json',
718
+ 'tempo-api-key': 'secret_sponsor',
719
+ },
720
+ method: 'POST',
721
+ }),
722
+ )
723
+ const body = await response.json()
724
+
725
+ expect(body).toMatchObject([
726
+ { error: { data: { code: 'chain_id_unsupported' } } },
727
+ { error: { data: { code: 'chain_id_unsupported' } } },
728
+ ])
729
+ expect(entries[0]?.sponsorship).toStrictEqual({
730
+ chainId: 999_999,
731
+ outcome: 'rejected',
732
+ reason: 'chain_id_unsupported',
733
+ rejections: 2,
734
+ })
735
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
527
736
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
528
737
  })
529
738
 
530
739
  test('behavior: super admin principals are refused', async () => {
531
740
  const db = TestApp.database()
741
+ const entries: Log.Entry[] = []
532
742
  const app = TestApp.create({
533
743
  auth: { keys, superAdmin: { secret: 'super-admin-secret' } },
534
744
  db,
745
+ logger: (entry) => void entries.push(entry),
535
746
  relay: { feePayer: { account: feePayerAccount } },
536
747
  })
748
+ const serialized = await signSponsorable()
537
749
 
538
750
  const body = await relayRequest(app, {
539
751
  method: 'eth_signRawTransaction',
540
- params: [await signSponsorable()],
752
+ params: [serialized],
541
753
  token: 'super-admin-secret',
542
754
  })
543
755
  expect(body.result).toBeUndefined()
544
- expect(body.error?.code).toBe(-32602)
756
+ expect(body.error).toStrictEqual({
757
+ code: -32602,
758
+ data: { code: 'api_key_required' },
759
+ message: 'Sponsorship rejected.',
760
+ })
761
+ expectSponsorshipCode({ code: 'api_key_required', entry: entries[0] })
762
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
763
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
764
+ })
765
+
766
+ test('behavior: sponsorship policy invariants return internal errors', async () => {
767
+ const db = TestApp.database()
768
+ const entries: Log.Entry[] = []
769
+ const app = TestApp.create({
770
+ auth: {
771
+ keys,
772
+ overrides: {
773
+ 'ALL /rpc/sponsor': { apiKey: { scopes: [] } },
774
+ },
775
+ },
776
+ db,
777
+ logger: (entry) => void entries.push(entry),
778
+ relay: { feePayer: { account: feePayerAccount } },
779
+ })
780
+ const serialized = await signSponsorable()
781
+
782
+ const body = await relayRequest(app, {
783
+ method: 'eth_signRawTransaction',
784
+ params: [serialized],
785
+ token: 'secret_unscoped',
786
+ })
787
+
788
+ expect(body.error).toStrictEqual({
789
+ code: -32603,
790
+ data: { code: 'internal_error' },
791
+ message: 'Internal error',
792
+ })
793
+ expect(entries[0]?.level).toBe('error')
794
+ expectSponsorshipCode({ code: 'internal_error', entry: entries[0] })
795
+ expect(entries[0]?.sponsorship?.internalErrors).toBe(1)
796
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
545
797
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
546
798
  })
547
799
 
@@ -625,30 +877,49 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
625
877
 
626
878
  test('behavior: sponsorship is refused for chains this deployment does not serve', async () => {
627
879
  const db = TestApp.database()
880
+ const entries: Log.Entry[] = []
628
881
  const app = TestApp.create({
629
882
  auth: { keys },
630
883
  db,
884
+ logger: (entry) => void entries.push(entry),
631
885
  relay: { feePayer: { account: feePayerAccount } },
632
886
  })
887
+ const serialized = await senderAccount.signTransaction({
888
+ chainId: 999_999,
889
+ feePayer: true,
890
+ gas: 100_000n,
891
+ maxFeePerGas: 1_000_000n,
892
+ maxPriorityFeePerGas: 0n,
893
+ nonce: 0,
894
+ to: Tempo.accounts[8]!.address,
895
+ value: 0n,
896
+ })
633
897
 
634
898
  const body = await relayRequest(app, {
635
899
  method: 'eth_signRawTransaction',
636
- params: [
637
- await senderAccount.signTransaction({
638
- chainId: 999_999,
639
- feePayer: true,
640
- gas: 100_000n,
641
- maxFeePerGas: 1_000_000n,
642
- maxPriorityFeePerGas: 0n,
643
- nonce: 0,
644
- to: Tempo.accounts[8]!.address,
645
- value: 0n,
646
- }),
647
- ],
900
+ params: [serialized],
648
901
  token: 'secret_sponsor',
649
902
  })
650
903
  expect(body.result).toBeUndefined()
651
- expect(body.error?.code).toBe(-32602)
904
+ expect(body.error).toStrictEqual({
905
+ code: -32602,
906
+ data: { code: 'chain_id_unsupported' },
907
+ message: 'Unsupported chain id.',
908
+ })
909
+ expect(entries[0]?.rpc).toStrictEqual({
910
+ code: -32602,
911
+ dataCode: 'chain_id_unsupported',
912
+ errors: 1,
913
+ })
914
+ expect(entries[0]?.sponsorship).toStrictEqual({
915
+ chainId: 999_999,
916
+ method: 'eth_signRawTransaction',
917
+ outcome: 'rejected',
918
+ payloadHash: Hash.keccak256(serialized),
919
+ reason: 'chain_id_unsupported',
920
+ rejections: 1,
921
+ })
922
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
652
923
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
653
924
  })
654
925
  })
@@ -669,15 +940,6 @@ describe('behavior: mainnet billing gate', () => {
669
940
  nonce: '0x0',
670
941
  } as const
671
942
 
672
- function createApp(db: Db.Source = TestApp.database()) {
673
- return TestApp.create({
674
- auth: { keys },
675
- db,
676
- relay: { feePayer: { account: feePayerAccount } },
677
- supportedChainIds: [Viem.chainId.mainnet],
678
- })
679
- }
680
-
681
943
  /** Activates billing for the org so the gate reaches the limit checks. */
682
944
  async function activate(db: ReturnType<typeof TestApp.database>, orgId = 'org_1') {
683
945
  await StripeCustomers.create(db, { orgId, stripeCustomerId: `cus_gate_${orgId}` })
@@ -695,18 +957,23 @@ describe('behavior: mainnet billing gate', () => {
695
957
  const overCapFees = { gas: 1_000_000n, maxFeePerGas: 2_000_000_000_000n } as const
696
958
 
697
959
  test('behavior: refuses mainnet sponsorship without a billing source', async () => {
698
- const body = await relayRequest(createApp(), {
699
- method: 'eth_signRawTransaction',
700
- params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
701
- token: 'secret_sponsor_prod',
702
- })
960
+ const entries: Log.Entry[] = []
961
+ const body = await relayRequest(
962
+ createMainnetApp({ logger: (entry) => void entries.push(entry) }),
963
+ {
964
+ method: 'eth_signRawTransaction',
965
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
966
+ token: 'secret_sponsor_prod',
967
+ },
968
+ )
703
969
  expect(body.error?.code).toBe(-32602)
704
970
  expect(body.error?.message).toBe('Billing required.')
705
971
  expect(body.error?.data).toStrictEqual({ code: 'billing_required' })
972
+ expectSponsorshipCode({ code: 'billing_required', entry: entries[0] })
706
973
  })
707
974
 
708
975
  test('behavior: returns the billing reason for sponsor fills', async () => {
709
- const body = await relayRequest(createApp(), {
976
+ const body = await relayRequest(createMainnetApp(), {
710
977
  method: 'eth_fillTransaction',
711
978
  params: [fill],
712
979
  token: 'secret_sponsor_prod',
@@ -718,6 +985,91 @@ describe('behavior: mainnet billing gate', () => {
718
985
  })
719
986
  })
720
987
 
988
+ test('behavior: error capabilities retain sponsor fill attribution', async () => {
989
+ const entries: Log.Entry[] = []
990
+ const body = await relayRequest(
991
+ createMainnetApp({ logger: (entry) => void entries.push(entry) }),
992
+ {
993
+ method: 'eth_fillTransaction',
994
+ params: [
995
+ {
996
+ ...fill,
997
+ capabilities: { balanceDiffs: false, errors: true },
998
+ },
999
+ ],
1000
+ token: 'secret_sponsor_prod',
1001
+ },
1002
+ )
1003
+ type Result = {
1004
+ capabilities?: {
1005
+ error?: { errorName?: string | undefined; message?: string | undefined } | undefined
1006
+ sponsored?: boolean | undefined
1007
+ }
1008
+ }
1009
+ const result = body.result as unknown as Result | undefined
1010
+
1011
+ expect(body.error).toBeUndefined()
1012
+ expect(result?.capabilities).toMatchObject({
1013
+ error: { errorName: 'unknown', message: 'Billing required.' },
1014
+ sponsored: false,
1015
+ })
1016
+ expect(entries[0]?.level).toBe('warn')
1017
+ expect(entries[0]?.rpc).toBeUndefined()
1018
+ expect(entries[0]?.sponsorship).toStrictEqual({
1019
+ chainId: Viem.chainId.mainnet,
1020
+ method: 'eth_fillTransaction',
1021
+ outcome: 'rejected',
1022
+ reason: 'billing_required',
1023
+ rejections: 1,
1024
+ })
1025
+ })
1026
+
1027
+ test('behavior: error capabilities hide sponsorship policy invariants', async () => {
1028
+ const entries: Log.Entry[] = []
1029
+ const app = TestApp.create({
1030
+ auth: {
1031
+ keys,
1032
+ overrides: {
1033
+ 'ALL /rpc/sponsor': { apiKey: { scopes: [] } },
1034
+ },
1035
+ },
1036
+ db: TestApp.database(),
1037
+ logger: (entry) => void entries.push(entry),
1038
+ relay: { feePayer: { account: feePayerAccount } },
1039
+ supportedChainIds: [Viem.chainId.mainnet],
1040
+ })
1041
+
1042
+ const body = await relayRequest(app, {
1043
+ method: 'eth_fillTransaction',
1044
+ params: [
1045
+ {
1046
+ ...fill,
1047
+ capabilities: { balanceDiffs: false, errors: true },
1048
+ },
1049
+ ],
1050
+ token: 'secret_unscoped',
1051
+ })
1052
+
1053
+ expect(body.error).toBeUndefined()
1054
+ expect(body.result).toMatchObject({
1055
+ capabilities: {
1056
+ error: { errorName: 'unknown', message: 'Internal error' },
1057
+ sponsored: false,
1058
+ },
1059
+ })
1060
+ expect(JSON.stringify(body)).not.toContain('ineligible API key')
1061
+ expect(entries[0]?.level).toBe('error')
1062
+ expect(entries[0]?.rpc).toBeUndefined()
1063
+ expect(entries[0]?.sponsorship).toStrictEqual({
1064
+ chainId: Viem.chainId.mainnet,
1065
+ internalErrors: 1,
1066
+ method: 'eth_fillTransaction',
1067
+ outcome: 'rejected',
1068
+ reason: 'internal_error',
1069
+ rejections: 1,
1070
+ })
1071
+ })
1072
+
721
1073
  test('behavior: relay fills still fall back to self-payment', async () => {
722
1074
  const server = await Relay.createServer(
723
1075
  RequestListener.fromFetchHandler(async (request) => {
@@ -766,7 +1118,7 @@ describe('behavior: mainnet billing gate', () => {
766
1118
  test('behavior: refuses mainnet sponsorship while billing is inactive', async () => {
767
1119
  const db = TestApp.database()
768
1120
  await StripeCustomers.create(db, { orgId: 'org_1', stripeCustomerId: 'cus_gate' })
769
- const body = await relayRequest(createApp(db), {
1121
+ const body = await relayRequest(createMainnetApp({ db }), {
770
1122
  method: 'eth_signRawTransaction',
771
1123
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
772
1124
  token: 'secret_sponsor_prod',
@@ -777,24 +1129,29 @@ describe('behavior: mainnet billing gate', () => {
777
1129
 
778
1130
  test('behavior: past-due billing refuses with its own reason', async () => {
779
1131
  const db = TestApp.database()
1132
+ const entries: Log.Entry[] = []
780
1133
  await activate(db)
781
1134
  // An unpaid invoice parked the org; the caller must settle it, not attach a card.
782
1135
  await StripeCustomers.setStatus(db, 'org_1', 'past_due')
783
- const body = await relayRequest(createApp(db), {
784
- method: 'eth_signRawTransaction',
785
- params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
786
- token: 'secret_sponsor_prod',
787
- })
1136
+ const body = await relayRequest(
1137
+ createMainnetApp({ db, logger: (entry) => void entries.push(entry) }),
1138
+ {
1139
+ method: 'eth_signRawTransaction',
1140
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
1141
+ token: 'secret_sponsor_prod',
1142
+ },
1143
+ )
788
1144
  expect(body.error?.code).toBe(-32602)
789
1145
  expect(body.error?.message).toBe('Billing past due.')
790
1146
  expect(body.error?.data).toStrictEqual({ code: 'billing_past_due' })
1147
+ expectSponsorshipCode({ code: 'billing_past_due', entry: entries[0] })
791
1148
  })
792
1149
 
793
1150
  test('behavior: active billing opens mainnet sponsorship and records it', async () => {
794
1151
  const db = TestApp.database()
795
1152
  await activate(db)
796
1153
 
797
- const body = await relayRequest(createApp(db), {
1154
+ const body = await relayRequest(createMainnetApp({ db }), {
798
1155
  method: 'eth_signRawTransaction',
799
1156
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
800
1157
  token: 'secret_sponsor_prod',
@@ -813,15 +1170,44 @@ describe('behavior: mainnet billing gate', () => {
813
1170
 
814
1171
  test('behavior: a sandbox key never sponsors mainnet, even with active billing', async () => {
815
1172
  const db = TestApp.database()
1173
+ const entries: Log.Entry[] = []
816
1174
  await activate(db) // org_1 is active…
817
- const body = await relayRequest(createApp(db), {
1175
+ const app = TestApp.create({
1176
+ auth: { keys },
1177
+ db,
1178
+ logger: (entry) => void entries.push(entry),
1179
+ relay: { feePayer: { account: feePayerAccount } },
1180
+ supportedChainIds: [Viem.chainId.mainnet],
1181
+ })
1182
+ const serialized = await signSponsorable({
1183
+ chainId: Viem.chainId.mainnet,
1184
+ ...halfDollarFees,
1185
+ })
1186
+ const body = await relayRequest(app, {
818
1187
  method: 'eth_signRawTransaction',
819
- params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
1188
+ params: [serialized],
820
1189
  token: 'secret_sponsor', // …but this key is sandbox.
821
1190
  })
822
1191
  // Refused for the environment, before the billing check reveals a reason.
823
- expect(body.error?.code).toBe(-32602)
824
- expect(body.error?.message).toBe('Sponsorship rejected.')
1192
+ expect(body.error).toStrictEqual({
1193
+ code: -32602,
1194
+ data: { code: 'production_api_key_required' },
1195
+ message: 'Sponsorship rejected.',
1196
+ })
1197
+ expect(entries[0]?.rpc).toStrictEqual({
1198
+ code: -32602,
1199
+ dataCode: 'production_api_key_required',
1200
+ errors: 1,
1201
+ })
1202
+ expect(entries[0]?.sponsorship).toStrictEqual({
1203
+ chainId: Viem.chainId.mainnet,
1204
+ method: 'eth_signRawTransaction',
1205
+ outcome: 'rejected',
1206
+ payloadHash: Hash.keccak256(serialized),
1207
+ reason: 'production_api_key_required',
1208
+ rejections: 1,
1209
+ })
1210
+ expect(JSON.stringify(entries[0])).not.toContain(serialized)
825
1211
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
826
1212
  })
827
1213
 
@@ -829,7 +1215,7 @@ describe('behavior: mainnet billing gate', () => {
829
1215
  const db = TestApp.database()
830
1216
  // org_1 is active; the production wildcard key belongs to org_2, which has nothing.
831
1217
  await activate(db)
832
- const body = await relayRequest(createApp(db), {
1218
+ const body = await relayRequest(createMainnetApp({ db }), {
833
1219
  method: 'eth_signRawTransaction',
834
1220
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
835
1221
  token: 'secret_wildcard_prod',
@@ -840,15 +1226,20 @@ describe('behavior: mainnet billing gate', () => {
840
1226
 
841
1227
  test('behavior: refuses a transaction over the platform fee cap', async () => {
842
1228
  const db = TestApp.database()
1229
+ const entries: Log.Entry[] = []
843
1230
  await activate(db)
844
- const body = await relayRequest(createApp(db), {
845
- method: 'eth_signRawTransaction',
846
- params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...overCapFees })],
847
- token: 'secret_sponsor_prod',
848
- })
1231
+ const body = await relayRequest(
1232
+ createMainnetApp({ db, logger: (entry) => void entries.push(entry) }),
1233
+ {
1234
+ method: 'eth_signRawTransaction',
1235
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...overCapFees })],
1236
+ token: 'secret_sponsor_prod',
1237
+ },
1238
+ )
849
1239
  expect(body.error?.code).toBe(-32602)
850
1240
  expect(body.error?.message).toBe('Transaction fee limit exceeded.')
851
1241
  expect(body.error?.data).toStrictEqual({ code: 'tx_fee_limit_exceeded' })
1242
+ expectSponsorshipCode({ code: 'tx_fee_limit_exceeded', entry: entries[0] })
852
1243
  })
853
1244
 
854
1245
  test('behavior: the org fee limit tightens the platform cap but never loosens it', async () => {
@@ -856,7 +1247,7 @@ describe('behavior: mainnet billing gate', () => {
856
1247
  await activate(db)
857
1248
  // Tighter than the platform default: $0.50 envelopes now refuse.
858
1249
  await BillingSettings.upsert(db, { orgId: 'org_1', txFeeLimit: '0.10' })
859
- const app = createApp(db)
1250
+ const app = createMainnetApp({ db })
860
1251
  const tightened = await relayRequest(app, {
861
1252
  method: 'eth_signRawTransaction',
862
1253
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
@@ -876,6 +1267,7 @@ describe('behavior: mainnet billing gate', () => {
876
1267
 
877
1268
  test('behavior: refuses fee tokens the verified list does not resolve to USD', async () => {
878
1269
  const db = TestApp.database()
1270
+ const entries: Log.Entry[] = []
879
1271
  await activate(db)
880
1272
  // EURC is verified yet non-USD; fee math reads micro-USD, so it refuses.
881
1273
  const eurc = `0x${'e0'.repeat(20)}` as const
@@ -883,7 +1275,7 @@ describe('behavior: mainnet billing gate', () => {
883
1275
  tokens: [{ address: eurc, currency: 'EUR', decimals: 6, name: 'Euro Coin', symbol: 'EURC' }],
884
1276
  })
885
1277
 
886
- const app = createApp(db)
1278
+ const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
887
1279
  const request = async (feeToken: `0x${string}`) =>
888
1280
  await relayRequest(app, {
889
1281
  method: 'eth_signRawTransaction',
@@ -893,9 +1285,11 @@ describe('behavior: mainnet billing gate', () => {
893
1285
  const nonUsd = await request(eurc)
894
1286
  expect(nonUsd.error?.message).toBe('Fee token unsupported.')
895
1287
  expect(nonUsd.error?.data).toStrictEqual({ code: 'fee_token_unsupported' })
1288
+ expectSponsorshipCode({ code: 'fee_token_unsupported', entry: entries[0] })
896
1289
  // Tokens absent from the verified list refuse the same way.
897
1290
  const unverified = await request(`0x${'ab'.repeat(20)}`)
898
1291
  expect(unverified.error?.data).toStrictEqual({ code: 'fee_token_unsupported' })
1292
+ expectSponsorshipCode({ code: 'fee_token_unsupported', entry: entries[1] })
899
1293
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
900
1294
  })
901
1295
 
@@ -903,7 +1297,7 @@ describe('behavior: mainnet billing gate', () => {
903
1297
  const db = TestApp.database()
904
1298
  await activate(db)
905
1299
 
906
- const body = await relayRequest(createApp(db), {
1300
+ const body = await relayRequest(createMainnetApp({ db }), {
907
1301
  method: 'eth_signRawTransaction',
908
1302
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
909
1303
  token: 'secret_sponsor_prod',
@@ -915,6 +1309,7 @@ describe('behavior: mainnet billing gate', () => {
915
1309
 
916
1310
  test('behavior: refuses sponsorship over the period spend limit; raising restores', async () => {
917
1311
  const db = TestApp.database()
1312
+ const entries: Log.Entry[] = []
918
1313
  await activate(db)
919
1314
  await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '1' })
920
1315
  // $0.90 already finalized this window; a $0.50 cap would overshoot $1.
@@ -934,7 +1329,7 @@ describe('behavior: mainnet billing gate', () => {
934
1329
  finalizedAt: new Date().toISOString(),
935
1330
  })
936
1331
 
937
- const app = createApp(db)
1332
+ const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
938
1333
  const request = async () =>
939
1334
  await relayRequest(app, {
940
1335
  method: 'eth_signRawTransaction',
@@ -944,6 +1339,7 @@ describe('behavior: mainnet billing gate', () => {
944
1339
  const refused = await request()
945
1340
  expect(refused.error?.message).toBe('Spend limit exceeded.')
946
1341
  expect(refused.error?.data).toStrictEqual({ code: 'spend_limit_exceeded' })
1342
+ expectSponsorshipCode({ code: 'spend_limit_exceeded', entry: entries[0] })
947
1343
 
948
1344
  await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '10' })
949
1345
  const restored = await request()
@@ -968,7 +1364,7 @@ describe('behavior: mainnet billing gate', () => {
968
1364
  transactionHash: `0x${'34'.repeat(32)}`,
969
1365
  })
970
1366
 
971
- const body = await relayRequest(createApp(db), {
1367
+ const body = await relayRequest(createMainnetApp({ db }), {
972
1368
  method: 'eth_signRawTransaction',
973
1369
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
974
1370
  token: 'secret_sponsor_prod',
@@ -985,7 +1381,7 @@ describe('behavior: mainnet billing gate', () => {
985
1381
  await activate(seed)
986
1382
  // Limit fits exactly two $0.50 sponsorships.
987
1383
  await BillingSettings.upsert(seed, { orgId: 'org_1', spendLimit: '1' })
988
- const app = createApp(db)
1384
+ const app = createMainnetApp({ db })
989
1385
  // Distinct nonces → distinct envelopes → distinct rows, fired together.
990
1386
  const results = await Promise.all(
991
1387
  Array.from({ length: 6 }, async (_, nonce) =>
@@ -1339,3 +1735,38 @@ describe.runIf(TestStripe.secretKey)(
1339
1735
  )
1340
1736
  },
1341
1737
  )
1738
+
1739
+ function createMainnetApp(options: createMainnetApp.Options = {}) {
1740
+ return TestApp.create({
1741
+ auth: { keys },
1742
+ db: options.db ?? TestApp.database(),
1743
+ ...(options.logger ? { logger: options.logger } : {}),
1744
+ relay: { feePayer: { account: feePayerAccount } },
1745
+ supportedChainIds: [Viem.chainId.mainnet],
1746
+ })
1747
+ }
1748
+
1749
+ declare namespace createMainnetApp {
1750
+ /** Mainnet sponsorship test app options. */
1751
+ type Options = {
1752
+ /** Database source. */
1753
+ db?: Db.Source | undefined
1754
+ /** Structured request log sink. */
1755
+ logger?: Log.Emit | undefined
1756
+ }
1757
+ }
1758
+
1759
+ function expectSponsorshipCode(options: expectSponsorshipCode.Options) {
1760
+ expect(options.entry?.rpc?.dataCode).toBe(options.code)
1761
+ expect(options.entry?.sponsorship?.reason).toBe(options.code)
1762
+ }
1763
+
1764
+ declare namespace expectSponsorshipCode {
1765
+ /** Expected canonical sponsorship code. */
1766
+ type Options = {
1767
+ /** Expected client and internal code. */
1768
+ code: Log.SponsorshipReason
1769
+ /** Structured request log entry. */
1770
+ entry: Log.Entry | undefined
1771
+ }
1772
+ }