tapimo 0.15.1 → 0.18.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 (709) hide show
  1. package/README.md +137 -0
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +4 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +37 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +163 -10
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +13085 -11974
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +46 -15
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +1 -1
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +1 -1
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +893 -191
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +5 -1
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +70 -70
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +8 -3
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +66 -27
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  28. package/dist/admin/apps/earn-vaults.js +36 -7
  29. package/dist/admin/apps/earn-vaults.js.map +1 -1
  30. package/dist/admin/apps/organizations.d.ts +25 -25
  31. package/dist/admin/apps/organizations.d.ts.map +1 -1
  32. package/dist/admin/apps/organizations.js +5 -4
  33. package/dist/admin/apps/organizations.js.map +1 -1
  34. package/dist/admin/apps/route-policies.d.ts +632 -0
  35. package/dist/admin/apps/route-policies.d.ts.map +1 -0
  36. package/dist/admin/apps/route-policies.js +257 -0
  37. package/dist/admin/apps/route-policies.js.map +1 -0
  38. package/dist/admin/apps/routes-support.js +39 -3
  39. package/dist/admin/apps/routes-support.js.map +1 -1
  40. package/dist/admin/apps/routes.d.ts +529 -76
  41. package/dist/admin/apps/routes.d.ts.map +1 -1
  42. package/dist/admin/apps/routes.js +82 -1
  43. package/dist/admin/apps/routes.js.map +1 -1
  44. package/dist/admin/apps/verified-tokens.d.ts +157 -157
  45. package/dist/admin/index.d.ts +0 -1
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +0 -1
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/admin/ui.generated.d.ts +1 -1
  50. package/dist/admin/ui.generated.d.ts.map +1 -1
  51. package/dist/admin/ui.generated.js +205 -201
  52. package/dist/admin/ui.generated.js.map +1 -1
  53. package/dist/analytics/Analytics.d.ts.map +1 -1
  54. package/dist/analytics/Analytics.js +65 -1
  55. package/dist/analytics/Analytics.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  57. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  58. package/dist/analytics/tables/requestEvents.js +58 -59
  59. package/dist/analytics/tables/requestEvents.js.map +1 -1
  60. package/dist/apps/data/App.d.ts +2709 -2670
  61. package/dist/apps/data/App.d.ts.map +1 -1
  62. package/dist/apps/data/routes/activities.d.ts +357 -357
  63. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  64. package/dist/apps/data/routes/activities.js +50 -0
  65. package/dist/apps/data/routes/activities.js.map +1 -1
  66. package/dist/apps/data/routes/addresses.d.ts +248 -248
  67. package/dist/apps/data/routes/balances.d.ts +22 -22
  68. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  69. package/dist/apps/data/routes/balances.js +5 -7
  70. package/dist/apps/data/routes/balances.js.map +1 -1
  71. package/dist/apps/data/routes/blocks.d.ts +125 -125
  72. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  73. package/dist/apps/data/routes/earn.d.ts +103 -12
  74. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  75. package/dist/apps/data/routes/earn.js +456 -220
  76. package/dist/apps/data/routes/earn.js.map +1 -1
  77. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  78. package/dist/apps/data/routes/exchanges.js +267 -97
  79. package/dist/apps/data/routes/exchanges.js.map +1 -1
  80. package/dist/apps/data/routes/fee-amm.d.ts +109 -127
  81. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.js +83 -54
  83. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +43 -43
  85. package/dist/apps/data/routes/receipts.d.ts +235 -235
  86. package/dist/apps/data/routes/rpc.d.ts +30 -30
  87. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  88. package/dist/apps/data/routes/tokens.js +11 -6
  89. package/dist/apps/data/routes/tokens.js.map +1 -1
  90. package/dist/apps/data/routes/transactions.d.ts +2 -0
  91. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  92. package/dist/apps/data/routes/transactions.js +30 -22
  93. package/dist/apps/data/routes/transactions.js.map +1 -1
  94. package/dist/apps/data/routes/transfers.d.ts +77 -77
  95. package/dist/apps/data/routes/valuation.d.ts +32 -32
  96. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  97. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  98. package/dist/apps/data/routes/webhooks.js +1 -1
  99. package/dist/apps/data/routes/webhooks.js.map +1 -1
  100. package/dist/apps/data/routes/zones.d.ts +31 -31
  101. package/dist/apps/management/App.d.ts +2909 -2064
  102. package/dist/apps/management/App.d.ts.map +1 -1
  103. package/dist/apps/management/App.js +2 -0
  104. package/dist/apps/management/App.js.map +1 -1
  105. package/dist/apps/management/Billing.d.ts +2 -4
  106. package/dist/apps/management/Billing.d.ts.map +1 -1
  107. package/dist/apps/management/Billing.js +65 -26
  108. package/dist/apps/management/Billing.js.map +1 -1
  109. package/dist/apps/management/routes/api-keys.d.ts +257 -245
  110. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  111. package/dist/apps/management/routes/api-keys.js +70 -11
  112. package/dist/apps/management/routes/api-keys.js.map +1 -1
  113. package/dist/apps/management/routes/billing.d.ts +84 -84
  114. package/dist/apps/management/routes/cli.d.ts +912 -0
  115. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  116. package/dist/apps/management/routes/cli.js +416 -0
  117. package/dist/apps/management/routes/cli.js.map +1 -0
  118. package/dist/apps/management/routes/faucet.d.ts +8 -8
  119. package/dist/apps/management/routes/invitations.d.ts +138 -138
  120. package/dist/apps/management/routes/invite-links.d.ts +172 -172
  121. package/dist/apps/management/routes/members.d.ts +16 -16
  122. package/dist/apps/management/routes/orgs.d.ts +104 -104
  123. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  124. package/dist/apps/management/routes/orgs.js +8 -2
  125. package/dist/apps/management/routes/orgs.js.map +1 -1
  126. package/dist/apps/management/routes/projects.d.ts +125 -125
  127. package/dist/apps/management/routes/usage.d.ts +8 -8
  128. package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
  129. package/dist/apps/management/routes/webhooks.d.ts +485 -485
  130. package/dist/apps/mpp/App.d.ts +44 -44
  131. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  132. package/dist/apps/mpp/internal/Policy.js +4 -2
  133. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  134. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  135. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  136. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  137. package/dist/apps/relay/App.d.ts +8 -0
  138. package/dist/apps/relay/App.d.ts.map +1 -1
  139. package/dist/apps/relay/App.js +16 -4
  140. package/dist/apps/relay/App.js.map +1 -1
  141. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  142. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  143. package/dist/apps/relay/Sponsorships.js +71 -60
  144. package/dist/apps/relay/Sponsorships.js.map +1 -1
  145. package/dist/apps/routes/Access.d.ts +53 -0
  146. package/dist/apps/routes/Access.d.ts.map +1 -1
  147. package/dist/apps/routes/Access.js +121 -0
  148. package/dist/apps/routes/Access.js.map +1 -1
  149. package/dist/apps/routes/App.d.ts +397 -158
  150. package/dist/apps/routes/App.d.ts.map +1 -1
  151. package/dist/apps/routes/App.js.map +1 -1
  152. package/dist/apps/routes/routes/chains.d.ts +25 -25
  153. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  154. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  155. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  156. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  157. package/dist/apps/routes/routes/quotes.d.ts +171 -81
  158. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  159. package/dist/apps/routes/routes/quotes.js +101 -27
  160. package/dist/apps/routes/routes/quotes.js.map +1 -1
  161. package/dist/apps/routes/routes/transfers.d.ts +532 -480
  162. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/transfers.js +182 -37
  164. package/dist/apps/routes/routes/transfers.js.map +1 -1
  165. package/dist/cli/ApiKeys.d.ts +120 -0
  166. package/dist/cli/ApiKeys.d.ts.map +1 -0
  167. package/dist/cli/ApiKeys.js +138 -0
  168. package/dist/cli/ApiKeys.js.map +1 -0
  169. package/dist/cli/Cli.d.ts +92 -34
  170. package/dist/cli/Cli.d.ts.map +1 -1
  171. package/dist/cli/Cli.js +188 -11
  172. package/dist/cli/Cli.js.map +1 -1
  173. package/dist/cli/Credentials.d.ts +95 -0
  174. package/dist/cli/Credentials.d.ts.map +1 -0
  175. package/dist/cli/Credentials.js +110 -0
  176. package/dist/cli/Credentials.js.map +1 -0
  177. package/dist/cli/Spec.d.ts +59 -0
  178. package/dist/cli/Spec.d.ts.map +1 -0
  179. package/dist/cli/Spec.js +77 -0
  180. package/dist/cli/Spec.js.map +1 -0
  181. package/dist/cli/bin.js +5 -1
  182. package/dist/cli/bin.js.map +1 -1
  183. package/dist/cli/commands/admin.d.ts +5 -5
  184. package/dist/cli/commands/admin.d.ts.map +1 -1
  185. package/dist/cli/commands/auth.d.ts +73 -0
  186. package/dist/cli/commands/auth.d.ts.map +1 -0
  187. package/dist/cli/commands/auth.js +204 -0
  188. package/dist/cli/commands/auth.js.map +1 -0
  189. package/dist/cli/commands/keys.d.ts +17 -0
  190. package/dist/cli/commands/keys.d.ts.map +1 -0
  191. package/dist/cli/commands/keys.js +109 -0
  192. package/dist/cli/commands/keys.js.map +1 -0
  193. package/dist/cloudflare.d.ts +27 -2
  194. package/dist/cloudflare.d.ts.map +1 -1
  195. package/dist/cloudflare.js +144 -17
  196. package/dist/cloudflare.js.map +1 -1
  197. package/dist/db/Db.d.ts +23 -0
  198. package/dist/db/Db.d.ts.map +1 -1
  199. package/dist/db/Db.js +413 -1
  200. package/dist/db/Db.js.map +1 -1
  201. package/dist/db/Schema.d.ts +44 -1
  202. package/dist/db/Schema.d.ts.map +1 -1
  203. package/dist/db/Schema.js +56 -3
  204. package/dist/db/Schema.js.map +1 -1
  205. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  206. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  207. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  208. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  209. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  210. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  211. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  212. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  213. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  214. package/dist/db/tables/authAccounts.js +1 -0
  215. package/dist/db/tables/authAccounts.js.map +1 -1
  216. package/dist/db/tables/earnVaults.d.ts +5 -1
  217. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  218. package/dist/db/tables/earnVaults.js +12 -1
  219. package/dist/db/tables/earnVaults.js.map +1 -1
  220. package/dist/db/tables/organizations.d.ts +4 -2
  221. package/dist/db/tables/organizations.d.ts.map +1 -1
  222. package/dist/db/tables/organizations.js +8 -34
  223. package/dist/db/tables/organizations.js.map +1 -1
  224. package/dist/db/tables/requestUsage.d.ts +5 -1
  225. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  226. package/dist/db/tables/requestUsage.js +10 -2
  227. package/dist/db/tables/requestUsage.js.map +1 -1
  228. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  229. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  230. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  231. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  232. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  233. package/dist/db/tables/rewardRuns.js +4 -0
  234. package/dist/db/tables/rewardRuns.js.map +1 -1
  235. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  236. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  237. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  238. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  239. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  240. package/dist/db/tables/routesDepositAddresses.js +84 -31
  241. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  242. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  243. package/dist/db/tables/routesDeposits.js +31 -21
  244. package/dist/db/tables/routesDeposits.js.map +1 -1
  245. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  246. package/dist/db/tables/routesIdempotency.js +2 -0
  247. package/dist/db/tables/routesIdempotency.js.map +1 -1
  248. package/dist/db/tables/routesPolicies.d.ts +58 -0
  249. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  250. package/dist/db/tables/routesPolicies.js +198 -0
  251. package/dist/db/tables/routesPolicies.js.map +1 -0
  252. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  253. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  254. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  255. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  256. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  257. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  258. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  259. package/dist/db/tables/routesTransfers.d.ts +26 -1
  260. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  261. package/dist/db/tables/routesTransfers.js +36 -6
  262. package/dist/db/tables/routesTransfers.js.map +1 -1
  263. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  264. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.js +144 -33
  266. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  267. package/dist/db/tables/users.d.ts +2 -0
  268. package/dist/db/tables/users.d.ts.map +1 -1
  269. package/dist/db/tables/users.js +11 -0
  270. package/dist/db/tables/users.js.map +1 -1
  271. package/dist/handlers/internal/multisig.d.ts +1 -1
  272. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  273. package/dist/handlers/internal/multisig.js +3 -2
  274. package/dist/handlers/internal/multisig.js.map +1 -1
  275. package/dist/handlers/relay.d.ts +2 -0
  276. package/dist/handlers/relay.d.ts.map +1 -1
  277. package/dist/handlers/relay.js +34 -15
  278. package/dist/handlers/relay.js.map +1 -1
  279. package/dist/internal/Auth.d.ts +57 -6
  280. package/dist/internal/Auth.d.ts.map +1 -1
  281. package/dist/internal/Auth.js +182 -78
  282. package/dist/internal/Auth.js.map +1 -1
  283. package/dist/internal/BetterAuth.d.ts +22 -0
  284. package/dist/internal/BetterAuth.d.ts.map +1 -1
  285. package/dist/internal/BetterAuth.js +17 -14
  286. package/dist/internal/BetterAuth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts +5 -0
  288. package/dist/internal/Cache.d.ts.map +1 -1
  289. package/dist/internal/Cache.js +3 -1
  290. package/dist/internal/Cache.js.map +1 -1
  291. package/dist/internal/CliAuth.d.ts +243 -0
  292. package/dist/internal/CliAuth.d.ts.map +1 -0
  293. package/dist/internal/CliAuth.js +249 -0
  294. package/dist/internal/CliAuth.js.map +1 -0
  295. package/dist/internal/EarnSharePrices.d.ts +1 -1
  296. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  297. package/dist/internal/EarnSharePrices.js +7 -3
  298. package/dist/internal/EarnSharePrices.js.map +1 -1
  299. package/dist/internal/EarnVaults.d.ts +47 -0
  300. package/dist/internal/EarnVaults.d.ts.map +1 -1
  301. package/dist/internal/EarnVaults.js +188 -4
  302. package/dist/internal/EarnVaults.js.map +1 -1
  303. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  304. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  305. package/dist/internal/EarnWithdrawals.js +189 -0
  306. package/dist/internal/EarnWithdrawals.js.map +1 -0
  307. package/dist/internal/ExecutionContext.d.ts +21 -0
  308. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  309. package/dist/internal/ExecutionContext.js +16 -0
  310. package/dist/internal/ExecutionContext.js.map +1 -0
  311. package/dist/internal/Log.d.ts +7 -3
  312. package/dist/internal/Log.d.ts.map +1 -1
  313. package/dist/internal/Log.js +163 -130
  314. package/dist/internal/Log.js.map +1 -1
  315. package/dist/internal/MetricSink.d.ts.map +1 -1
  316. package/dist/internal/MetricSink.js +26 -1
  317. package/dist/internal/MetricSink.js.map +1 -1
  318. package/dist/internal/RateLimit.d.ts +67 -0
  319. package/dist/internal/RateLimit.d.ts.map +1 -1
  320. package/dist/internal/RateLimit.js +174 -27
  321. package/dist/internal/RateLimit.js.map +1 -1
  322. package/dist/internal/Store.d.ts +6 -0
  323. package/dist/internal/Store.d.ts.map +1 -1
  324. package/dist/internal/Store.js +4 -5
  325. package/dist/internal/Store.js.map +1 -1
  326. package/dist/internal/Timing.d.ts +6 -0
  327. package/dist/internal/Timing.d.ts.map +1 -1
  328. package/dist/internal/Timing.js +21 -1
  329. package/dist/internal/Timing.js.map +1 -1
  330. package/dist/internal/Tron.d.ts +124 -0
  331. package/dist/internal/Tron.d.ts.map +1 -0
  332. package/dist/internal/Tron.js +202 -0
  333. package/dist/internal/Tron.js.map +1 -0
  334. package/dist/internal/Viem.d.ts +4 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Viem.js +25 -6
  337. package/dist/internal/Viem.js.map +1 -1
  338. package/dist/internal/rewards/Read.d.ts +2 -2
  339. package/dist/internal/rewards/Read.d.ts.map +1 -1
  340. package/dist/internal/rewards/Read.js +11 -2
  341. package/dist/internal/rewards/Read.js.map +1 -1
  342. package/dist/internal/routes/Action.d.ts +27 -0
  343. package/dist/internal/routes/Action.d.ts.map +1 -1
  344. package/dist/internal/routes/Action.js +49 -1
  345. package/dist/internal/routes/Action.js.map +1 -1
  346. package/dist/internal/routes/Chain.d.ts +2 -0
  347. package/dist/internal/routes/Chain.d.ts.map +1 -1
  348. package/dist/internal/routes/Chain.js +4 -0
  349. package/dist/internal/routes/Chain.js.map +1 -1
  350. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  351. package/dist/internal/routes/DepositAddress.js +5 -0
  352. package/dist/internal/routes/DepositAddress.js.map +1 -1
  353. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  354. package/dist/internal/routes/Evidence.js +6 -2
  355. package/dist/internal/routes/Evidence.js.map +1 -1
  356. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  357. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  358. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  359. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  360. package/dist/internal/routes/Policy.d.ts +161 -0
  361. package/dist/internal/routes/Policy.d.ts.map +1 -0
  362. package/dist/internal/routes/Policy.js +249 -0
  363. package/dist/internal/routes/Policy.js.map +1 -0
  364. package/dist/internal/routes/Provider.d.ts +66 -3
  365. package/dist/internal/routes/Provider.d.ts.map +1 -1
  366. package/dist/internal/routes/Provider.js +106 -27
  367. package/dist/internal/routes/Provider.js.map +1 -1
  368. package/dist/internal/routes/Quota.d.ts +57 -0
  369. package/dist/internal/routes/Quota.d.ts.map +1 -0
  370. package/dist/internal/routes/Quota.js +144 -0
  371. package/dist/internal/routes/Quota.js.map +1 -0
  372. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  373. package/dist/internal/routes/Reconciliation.js +163 -47
  374. package/dist/internal/routes/Reconciliation.js.map +1 -1
  375. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  376. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  377. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  378. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  379. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  380. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  381. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  382. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  383. package/dist/internal/routes/Subsidy.d.ts +2 -2
  384. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  385. package/dist/internal/routes/Subsidy.js +2 -2
  386. package/dist/internal/routes/Subsidy.js.map +1 -1
  387. package/dist/internal/routes/Transfer.d.ts +229 -1
  388. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  389. package/dist/internal/routes/Transfer.js +644 -7
  390. package/dist/internal/routes/Transfer.js.map +1 -1
  391. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  392. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  393. package/dist/internal/routes/TransferReconciliation.js +83 -159
  394. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  395. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  396. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  397. package/dist/internal/routes/TransferSettlement.js +2 -0
  398. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  399. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  400. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  401. package/dist/internal/routes/TransferSubsidy.js +64 -5
  402. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  403. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  404. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  405. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  406. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  407. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  408. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  409. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  410. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  411. package/dist/internal/routes/index.d.ts +3 -0
  412. package/dist/internal/routes/index.d.ts.map +1 -1
  413. package/dist/internal/routes/index.js +3 -0
  414. package/dist/internal/routes/index.js.map +1 -1
  415. package/dist/internal/routes/providers/across.d.ts +3 -0
  416. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  417. package/dist/internal/routes/providers/across.js +11 -0
  418. package/dist/internal/routes/providers/across.js.map +1 -1
  419. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  420. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  421. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  422. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  423. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  424. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  425. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  426. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  427. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  428. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  429. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  430. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  431. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  432. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  434. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  435. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  436. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/propAmm.js +524 -0
  438. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  439. package/dist/internal/routes/providers/relay.d.ts +3 -0
  440. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  441. package/dist/internal/routes/providers/relay.js +352 -41
  442. package/dist/internal/routes/providers/relay.js.map +1 -1
  443. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  444. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  445. package/dist/internal/routes/providers/rhino.js +11 -0
  446. package/dist/internal/routes/providers/rhino.js.map +1 -1
  447. package/dist/internal/routes/providers/squid.d.ts +3 -0
  448. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  449. package/dist/internal/routes/providers/squid.js +19 -0
  450. package/dist/internal/routes/providers/squid.js.map +1 -1
  451. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  452. package/dist/internal/routes/providers/stargate.js +22 -9
  453. package/dist/internal/routes/providers/stargate.js.map +1 -1
  454. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  455. package/dist/internal/routes/providers/symbiosis.js +13 -17
  456. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  457. package/dist/providers/index.d.ts +14 -0
  458. package/dist/providers/index.d.ts.map +1 -1
  459. package/dist/providers/index.js +6 -0
  460. package/dist/providers/index.js.map +1 -1
  461. package/package.json +16 -6
  462. package/src/ApiKey.ts +7 -3
  463. package/src/ApiKeys.test.ts +652 -8
  464. package/src/ApiKeys.ts +191 -11
  465. package/src/App.test.ts +405 -18
  466. package/src/App.ts +51 -15
  467. package/src/Client.test-d.ts +157 -10
  468. package/src/Client.test.ts +4 -4
  469. package/src/Scope.ts +1 -2
  470. package/src/admin/App.ts +11 -5
  471. package/src/admin/apps/api-keys.test.ts +98 -2
  472. package/src/admin/apps/api-keys.ts +21 -12
  473. package/src/admin/apps/earn-vaults.test.ts +76 -7
  474. package/src/admin/apps/earn-vaults.ts +47 -8
  475. package/src/admin/apps/organizations.test.ts +147 -31
  476. package/src/admin/apps/organizations.ts +5 -4
  477. package/src/admin/apps/route-policies.test.ts +220 -0
  478. package/src/admin/apps/route-policies.ts +322 -0
  479. package/src/admin/apps/routes-support.test.ts +107 -2
  480. package/src/admin/apps/routes-support.ts +43 -3
  481. package/src/admin/apps/routes.test.ts +150 -0
  482. package/src/admin/apps/routes.ts +97 -1
  483. package/src/admin/apps/scopes.test.ts +1 -1
  484. package/src/admin/index.ts +0 -1
  485. package/src/admin/ui/plugin.ts +2 -1
  486. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  487. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  488. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  489. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  490. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  491. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  492. package/src/admin/ui/src/lib/routes.ts +34 -0
  493. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  494. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  495. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  496. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  497. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  498. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  499. package/src/admin/ui/src/routes/organizations.tsx +1 -0
  500. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  501. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  502. package/src/admin/ui/src/routes/routes.tsx +85 -2
  503. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  504. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  505. package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
  506. package/src/admin/ui.generated.ts +258 -202
  507. package/src/analytics/Analytics.test.ts +4 -50
  508. package/src/analytics/Analytics.ts +65 -1
  509. package/src/analytics/tables/requestEvents.test.ts +402 -1
  510. package/src/analytics/tables/requestEvents.ts +62 -93
  511. package/src/apps/data/routes/activities.test.ts +315 -14
  512. package/src/apps/data/routes/activities.ts +60 -0
  513. package/src/apps/data/routes/balances.ts +5 -7
  514. package/src/apps/data/routes/earn.bench.ts +18 -0
  515. package/src/apps/data/routes/earn.local.test.ts +507 -0
  516. package/src/apps/data/routes/earn.test.ts +405 -127
  517. package/src/apps/data/routes/earn.ts +660 -270
  518. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  519. package/src/apps/data/routes/exchanges.test.ts +166 -2
  520. package/src/apps/data/routes/exchanges.ts +308 -101
  521. package/src/apps/data/routes/fee-amm.test.ts +134 -2
  522. package/src/apps/data/routes/fee-amm.ts +122 -60
  523. package/src/apps/data/routes/receipts.test.ts +21 -18
  524. package/src/apps/data/routes/rpc.test.ts +2 -2
  525. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  526. package/src/apps/data/routes/tokens.test.ts +4 -4
  527. package/src/apps/data/routes/tokens.ts +11 -6
  528. package/src/apps/data/routes/transactions.test.ts +29 -0
  529. package/src/apps/data/routes/transactions.ts +33 -22
  530. package/src/apps/data/routes/webhooks.test.ts +12 -3
  531. package/src/apps/data/routes/webhooks.ts +2 -1
  532. package/src/apps/management/App.ts +4 -0
  533. package/src/apps/management/Billing.test.ts +253 -27
  534. package/src/apps/management/Billing.ts +83 -29
  535. package/src/apps/management/routes/api-keys.test.ts +1 -1
  536. package/src/apps/management/routes/api-keys.ts +85 -11
  537. package/src/apps/management/routes/billing.test.ts +68 -4
  538. package/src/apps/management/routes/cli.test.ts +370 -0
  539. package/src/apps/management/routes/cli.ts +533 -0
  540. package/src/apps/management/routes/me.test.ts +14 -4
  541. package/src/apps/management/routes/orgs.test.ts +108 -4
  542. package/src/apps/management/routes/orgs.ts +7 -2
  543. package/src/apps/management/routes/usage.test.ts +2 -2
  544. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  545. package/src/apps/mpp/internal/Policy.ts +6 -2
  546. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  547. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  548. package/src/apps/relay/App.test.ts +85 -1
  549. package/src/apps/relay/App.ts +28 -4
  550. package/src/apps/relay/Sponsorships.test.ts +97 -1
  551. package/src/apps/relay/Sponsorships.ts +77 -66
  552. package/src/apps/routes/Access.test.ts +319 -0
  553. package/src/apps/routes/Access.ts +147 -0
  554. package/src/apps/routes/App.ts +10 -0
  555. package/src/apps/routes/routes/chains.test.ts +3 -2
  556. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  557. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  558. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  559. package/src/apps/routes/routes/quotes.test.ts +81 -8
  560. package/src/apps/routes/routes/quotes.ts +109 -27
  561. package/src/apps/routes/routes/transfers.test.ts +252 -15
  562. package/src/apps/routes/routes/transfers.ts +212 -33
  563. package/src/cli/ApiKeys.test.ts +265 -0
  564. package/src/cli/ApiKeys.ts +189 -0
  565. package/src/cli/Cli.test.ts +188 -0
  566. package/src/cli/Cli.ts +280 -12
  567. package/src/cli/Credentials.test.ts +122 -0
  568. package/src/cli/Credentials.ts +144 -0
  569. package/src/cli/Spec.test.ts +133 -0
  570. package/src/cli/Spec.ts +132 -0
  571. package/src/cli/bin.test.ts +49 -0
  572. package/src/cli/bin.ts +5 -1
  573. package/src/cli/commands/auth.test.ts +138 -0
  574. package/src/cli/commands/auth.ts +254 -0
  575. package/src/cli/commands/keys.test.ts +68 -0
  576. package/src/cli/commands/keys.ts +125 -0
  577. package/src/cloudflare.ts +184 -36
  578. package/src/db/Db.test.ts +877 -0
  579. package/src/db/Db.ts +498 -1
  580. package/src/db/Schema.ts +75 -4
  581. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  582. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  583. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  584. package/src/db/tables/authAccounts.test.ts +30 -0
  585. package/src/db/tables/authAccounts.ts +1 -0
  586. package/src/db/tables/earnVaults.test.ts +34 -0
  587. package/src/db/tables/earnVaults.ts +17 -2
  588. package/src/db/tables/organizations.test.ts +148 -84
  589. package/src/db/tables/organizations.ts +11 -43
  590. package/src/db/tables/requestUsage.ts +13 -2
  591. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  592. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  593. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  594. package/src/db/tables/rewardRuns.ts +4 -0
  595. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  596. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  597. package/src/db/tables/routesDepositAddresses.ts +118 -34
  598. package/src/db/tables/routesDeposits.test.ts +66 -5
  599. package/src/db/tables/routesDeposits.ts +47 -26
  600. package/src/db/tables/routesIdempotency.test.ts +80 -0
  601. package/src/db/tables/routesIdempotency.ts +2 -0
  602. package/src/db/tables/routesPolicies.test.ts +143 -0
  603. package/src/db/tables/routesPolicies.ts +251 -0
  604. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  605. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  606. package/src/db/tables/routesTransfers.test.ts +183 -2
  607. package/src/db/tables/routesTransfers.ts +65 -6
  608. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  609. package/src/db/tables/sponsoredTransactions.ts +182 -38
  610. package/src/db/tables/users.test.ts +51 -0
  611. package/src/db/tables/users.ts +12 -0
  612. package/src/handlers/internal/multisig.store.test.ts +120 -0
  613. package/src/handlers/internal/multisig.test.ts +389 -0
  614. package/src/handlers/internal/multisig.ts +13 -10
  615. package/src/handlers/relay.test.ts +259 -83
  616. package/src/handlers/relay.ts +36 -17
  617. package/src/internal/Auth.test.ts +291 -8
  618. package/src/internal/Auth.ts +227 -96
  619. package/src/internal/BetterAuth.test.ts +58 -22
  620. package/src/internal/BetterAuth.ts +23 -17
  621. package/src/internal/Cache.ts +3 -1
  622. package/src/internal/CliAuth.test.ts +279 -0
  623. package/src/internal/CliAuth.ts +319 -0
  624. package/src/internal/EarnSharePrices.test.ts +25 -0
  625. package/src/internal/EarnSharePrices.ts +9 -2
  626. package/src/internal/EarnVaults.test.ts +67 -0
  627. package/src/internal/EarnVaults.ts +299 -4
  628. package/src/internal/EarnWithdrawals.test.ts +315 -0
  629. package/src/internal/EarnWithdrawals.ts +266 -0
  630. package/src/internal/ExecutionContext.ts +31 -0
  631. package/src/internal/Log.test.ts +210 -0
  632. package/src/internal/Log.ts +180 -142
  633. package/src/internal/MetricSink.test.ts +190 -15
  634. package/src/internal/MetricSink.ts +27 -1
  635. package/src/internal/RateLimit.test.ts +144 -8
  636. package/src/internal/RateLimit.ts +254 -26
  637. package/src/internal/Store.ts +4 -5
  638. package/src/internal/Timing.test.ts +32 -0
  639. package/src/internal/Timing.ts +20 -1
  640. package/src/internal/Tron.test-d.ts +22 -0
  641. package/src/internal/Tron.test.ts +94 -0
  642. package/src/internal/Tron.ts +289 -0
  643. package/src/internal/Viem.rpc.test.ts +76 -0
  644. package/src/internal/Viem.ts +29 -6
  645. package/src/internal/rewards/Read.test.ts +109 -0
  646. package/src/internal/rewards/Read.ts +13 -4
  647. package/src/internal/routes/Action.test.ts +70 -0
  648. package/src/internal/routes/Action.ts +76 -1
  649. package/src/internal/routes/Chain.test.ts +18 -0
  650. package/src/internal/routes/Chain.ts +5 -0
  651. package/src/internal/routes/DepositAddress.ts +5 -0
  652. package/src/internal/routes/Evidence.test.ts +64 -0
  653. package/src/internal/routes/Evidence.ts +11 -3
  654. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  655. package/src/internal/routes/Policy.test.ts +316 -0
  656. package/src/internal/routes/Policy.ts +399 -0
  657. package/src/internal/routes/Provider.test.ts +103 -2
  658. package/src/internal/routes/Provider.ts +149 -27
  659. package/src/internal/routes/Quota.test.ts +149 -0
  660. package/src/internal/routes/Quota.ts +226 -0
  661. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  662. package/src/internal/routes/Reconciliation.test.ts +371 -13
  663. package/src/internal/routes/Reconciliation.ts +193 -42
  664. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  665. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  666. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  667. package/src/internal/routes/SourceObservation.test.ts +221 -0
  668. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  669. package/src/internal/routes/Subsidy.ts +4 -2
  670. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  671. package/src/internal/routes/Transfer.test.ts +130 -1
  672. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  673. package/src/internal/routes/Transfer.ts +866 -8
  674. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  675. package/src/internal/routes/TransferReconciliation.ts +91 -166
  676. package/src/internal/routes/TransferSettlement.ts +48 -0
  677. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  678. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  679. package/src/internal/routes/TransferSubsidy.ts +87 -12
  680. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  681. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  682. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  683. package/src/internal/routes/index.test.ts +3 -0
  684. package/src/internal/routes/index.ts +3 -0
  685. package/src/internal/routes/providers/across.ts +13 -0
  686. package/src/internal/routes/providers/index.test.ts +141 -0
  687. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  688. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  689. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  690. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  691. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  692. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  693. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  694. package/src/internal/routes/providers/propAmm.ts +640 -0
  695. package/src/internal/routes/providers/relay.test.ts +1263 -41
  696. package/src/internal/routes/providers/relay.ts +423 -38
  697. package/src/internal/routes/providers/rhino.ts +14 -1
  698. package/src/internal/routes/providers/squid.ts +21 -0
  699. package/src/internal/routes/providers/stargate.test.ts +105 -1
  700. package/src/internal/routes/providers/stargate.ts +22 -9
  701. package/src/internal/routes/providers/symbiosis.ts +13 -47
  702. package/src/providers/index.test.ts +2 -0
  703. package/src/providers/index.ts +18 -0
  704. package/dist/admin/Access.d.ts +0 -39
  705. package/dist/admin/Access.d.ts.map +0 -1
  706. package/dist/admin/Access.js +0 -73
  707. package/dist/admin/Access.js.map +0 -1
  708. package/src/admin/Access.test.ts +0 -130
  709. package/src/admin/Access.ts +0 -85
@@ -6,6 +6,7 @@ import * as Fees from '../../internal/Fees.js'
6
6
  import * as Id from '../../internal/Id.js'
7
7
  import type * as Db from '../Db.js'
8
8
  import type * as db_Schema from '../Schema.js'
9
+ import * as ApiKeyOwnerTombstones from './apiKeyOwnerTombstones.js'
9
10
  import * as SponsorshipAttributions from './sponsorshipAttributions.js'
10
11
 
11
12
  /** Columns of the `sponsored_transactions` table, derived from `Schema.SponsoredTransaction`. */
@@ -29,6 +30,8 @@ export const failedIntentRecoveryTtlMs = 86_400_000
29
30
  * @returns The stored record.
30
31
  */
31
32
  export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
33
+ if (!db.kysely.isTransaction) return db.transaction((tx) => upsert(tx, input))
34
+ await lockOrganization(db, input.orgId)
32
35
  const record: Record = {
33
36
  apiKeyId: input.apiKeyId,
34
37
  sponsorshipAttributionId: input.sponsorshipAttributionId ?? null,
@@ -43,6 +46,8 @@ export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
43
46
  finalizationAttemptedAt: null,
44
47
  finalizedAt: null,
45
48
  id: Id.generate('stx'),
49
+ meterEventFirstAttemptedAt: null,
50
+ meterReportAttemptedAt: null,
46
51
  meterReportedAt: null,
47
52
  orgId: input.orgId,
48
53
  projectId: input.projectId ?? null,
@@ -50,6 +55,7 @@ export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
50
55
  status: 'pending',
51
56
  transaction: input.transaction,
52
57
  transactionHash: input.transactionHash ?? null,
58
+ transactionHashReconciled: false,
53
59
  }
54
60
  const stored = await db.kysely
55
61
  .insertInto('sponsored_transactions')
@@ -64,12 +70,9 @@ export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
64
70
  eb.ref('sponsored_transactions.feeMax'),
65
71
  eb.ref('excluded.feeMax'),
66
72
  ),
67
- // A raw submission fills the intent's hash; a duplicate intent never
68
- // clears an already-known hash.
69
- transactionHash: eb.fn.coalesce(
70
- eb.ref('excluded.transactionHash'),
71
- eb.ref('sponsored_transactions.transactionHash'),
72
- ),
73
+ // A raw submission fills an intent or refreshes a submitted hash,
74
+ // but never replaces a finalized or reconciled hash.
75
+ transactionHash: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'finalized' OR ${eb.ref('sponsored_transactions.transactionHashReconciled')} THEN ${eb.ref('sponsored_transactions.transactionHash')} ELSE coalesce(${eb.ref('excluded.transactionHash')}, ${eb.ref('sponsored_transactions.transactionHash')}) END`,
73
76
  createdAt: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'failed' THEN ${eb.ref('excluded.createdAt')} ELSE ${eb.ref('sponsored_transactions.createdAt')} END`,
74
77
  finalizedAt: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'failed' THEN NULL ELSE ${eb.ref('sponsored_transactions.finalizedAt')} END`,
75
78
  status: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'failed' THEN 'pending' ELSE ${eb.ref('sponsored_transactions.status')} END`,
@@ -227,30 +230,51 @@ export declare namespace claimPending {
227
230
  }
228
231
 
229
232
  /**
230
- * Lists active hash-less fill intents, oldest first, for reconciliation.
233
+ * Lists pending sponsorships, oldest first, for sign-payload reconciliation.
231
234
  *
232
235
  * @param db - The database.
233
236
  * @param options - Paging options.
234
- * @returns The fill intents.
237
+ * @returns The reconciliation candidates.
235
238
  */
236
- export function listIntents(db: Db.Db, options: listIntents.Options = {}): Promise<Record[]> {
237
- let query = db.kysely
239
+ export async function listReconciliationCandidates(
240
+ db: Db.Db,
241
+ options: listReconciliationCandidates.Options = {},
242
+ ): Promise<Record[]> {
243
+ let intents = db.kysely
238
244
  .selectFrom('sponsored_transactions')
239
245
  .selectAll()
240
246
  .where('status', '=', 'pending')
241
247
  .where('transactionHash', 'is', null)
242
248
  .orderBy('createdAt', 'asc')
243
249
  .orderBy('id', 'asc')
244
- if (options.limit !== undefined) query = query.limit(options.limit)
245
- return query.execute()
250
+ let submitted = db.kysely
251
+ .selectFrom('sponsored_transactions')
252
+ .selectAll()
253
+ .where('status', '=', 'pending')
254
+ .where('transactionHash', 'is not', null)
255
+ .where('transactionHashReconciled', '=', false)
256
+ .orderBy('createdAt', 'asc')
257
+ .orderBy('id', 'asc')
258
+ if (options.limit !== undefined) {
259
+ intents = intents.limit(options.limit)
260
+ submitted = submitted.limit(options.limit)
261
+ }
262
+ const [records_intent, records_submitted] = await Promise.all([
263
+ intents.execute(),
264
+ submitted.execute(),
265
+ ])
266
+ return [...records_intent, ...records_submitted]
246
267
  }
247
268
 
248
- export declare namespace listIntents {
249
- /** Options for {@link listIntents}. */
250
- type Options = listPending.Options
269
+ export declare namespace listReconciliationCandidates {
270
+ /** Options for {@link listReconciliationCandidates}. */
271
+ type Options = {
272
+ /** Maximum rows per transaction-hash state. */
273
+ limit?: number | undefined
274
+ }
251
275
  }
252
276
 
253
- /** Lists the oldest recoverable failed-intent timestamp for each chain. */
277
+ /** Lists the oldest recoverable failed sponsorship timestamp for each chain. */
254
278
  export function listRecoveryWindows(
255
279
  db: Db.Db,
256
280
  options: listRecoveryWindows.Options,
@@ -261,7 +285,6 @@ export function listRecoveryWindows(
261
285
  .select((eb) => eb.fn.min<string>('createdAt').as('createdAt'))
262
286
  .where('finalizedAt', '>=', options.failedSince)
263
287
  .where('status', '=', 'failed')
264
- .where('transactionHash', 'is', null)
265
288
  .groupBy('chainId')
266
289
  .execute()
267
290
  }
@@ -282,7 +305,7 @@ export declare namespace listRecoveryWindows {
282
305
  }
283
306
  }
284
307
 
285
- /** Lists pending and recoverable failed intents matching candidate sign payloads. */
308
+ /** Lists pending intents and recoverable failed sponsorships matching candidate sign payloads. */
286
309
  export function listRecoverableIntents(
287
310
  db: Db.Db,
288
311
  options: listRecoverableIntents.Options,
@@ -294,11 +317,10 @@ export function listRecoverableIntents(
294
317
  .where('signPayload', 'in', [...options.signPayloads])
295
318
  .where((eb) =>
296
319
  eb.or([
297
- eb('status', '=', 'pending'),
320
+ eb.and([eb('status', '=', 'pending'), eb('transactionHash', 'is', null)]),
298
321
  eb.and([eb('finalizedAt', '>=', options.failedSince), eb('status', '=', 'failed')]),
299
322
  ]),
300
323
  )
301
- .where('transactionHash', 'is', null)
302
324
  .execute()
303
325
  }
304
326
 
@@ -313,12 +335,12 @@ export declare namespace listRecoverableIntents {
313
335
  }
314
336
 
315
337
  /**
316
- * Fills a reconciled intent's transaction hash and reopens failed intents.
317
- * A no-op once another pass already assigned the hash.
338
+ * Assigns a reconciled transaction hash and reopens failed sponsorships.
339
+ * A no-op once another pass resolved an active sponsorship.
318
340
  *
319
341
  * @param db - The database.
320
342
  * @param id - The sponsored-transaction id (`stx_…`).
321
- * @param transactionHash - The matched on-chain transaction hash.
343
+ * @param transactionHash - The matched on-chain transaction hash, which may replace an unmined hash.
322
344
  * @param limit - The active period spend limit, when enforced.
323
345
  */
324
346
  export async function assignTransactionHash(
@@ -330,12 +352,7 @@ export async function assignTransactionHash(
330
352
  try {
331
353
  await db.transaction(async (tx) => {
332
354
  const record = await get(tx, id)
333
- if (
334
- !record ||
335
- record.transactionHash !== null ||
336
- !['failed', 'pending'].includes(record.status)
337
- )
338
- return
355
+ if (!record || !['failed', 'pending'].includes(record.status)) return
339
356
  const failedSince = new Date(Date.now() - failedIntentRecoveryTtlMs).toISOString()
340
357
  if (
341
358
  record.status === 'failed' &&
@@ -360,10 +377,14 @@ export async function assignTransactionHash(
360
377
  finalizedAt: null,
361
378
  status: 'pending',
362
379
  transactionHash,
380
+ transactionHashReconciled: true,
363
381
  })
364
382
  .where('id', '=', id)
365
383
  .where('status', '=', record.status)
366
- .where('transactionHash', 'is', null)
384
+ query =
385
+ record.transactionHash === null
386
+ ? query.where('transactionHash', 'is', null)
387
+ : query.where('transactionHash', '=', record.transactionHash)
367
388
  if (record.status === 'failed')
368
389
  query = query.where((eb) =>
369
390
  eb.exists(
@@ -397,7 +418,6 @@ export async function assignTransactionHash(
397
418
  .set({ finalizedAt: new Date().toISOString() })
398
419
  .where('id', '=', id)
399
420
  .where('status', '=', 'failed')
400
- .where('transactionHash', 'is', null)
401
421
  .execute()
402
422
  throw error
403
423
  }
@@ -412,12 +432,19 @@ export async function assignTransactionHash(
412
432
  * @param input - The finalized fee facts.
413
433
  */
414
434
  export async function finalize(db: Db.Db, id: string, input: finalize.Input): Promise<void> {
415
- await db.kysely
435
+ let query = db.kysely
416
436
  .updateTable('sponsored_transactions')
417
- .set({ feeAmount: input.feeAmount, finalizedAt: input.finalizedAt, status: 'finalized' })
437
+ .set({
438
+ feeAmount: input.feeAmount,
439
+ finalizedAt: input.finalizedAt,
440
+ status: 'finalized',
441
+ ...(input.transactionHash === undefined ? {} : { transactionHashReconciled: true }),
442
+ })
418
443
  .where('id', '=', id)
419
444
  .where('status', '=', 'pending')
420
- .execute()
445
+ if (input.transactionHash !== undefined)
446
+ query = query.where('transactionHash', '=', input.transactionHash)
447
+ await query.execute()
421
448
  }
422
449
 
423
450
  export declare namespace finalize {
@@ -427,6 +454,8 @@ export declare namespace finalize {
427
454
  feeAmount: string
428
455
  /** When the sponsorship finalized (ISO 8601). */
429
456
  finalizedAt: string
457
+ /** Transaction hash whose receipt produced the fee, when fencing concurrent reconciliation. */
458
+ transactionHash?: string | undefined
430
459
  }
431
460
  }
432
461
 
@@ -437,14 +466,33 @@ export declare namespace finalize {
437
466
  * @param db - The database.
438
467
  * @param id - The sponsored-transaction id (`stx_…`).
439
468
  * @param finalizedAt - When the sponsorship was marked failed (ISO 8601).
469
+ * @param options - Optional claimed-hash fence.
440
470
  */
441
- export async function fail(db: Db.Db, id: string, finalizedAt: string): Promise<void> {
442
- await db.kysely
471
+ export async function fail(
472
+ db: Db.Db,
473
+ id: string,
474
+ finalizedAt: string,
475
+ options: fail.Options = {},
476
+ ): Promise<void> {
477
+ let query = db.kysely
443
478
  .updateTable('sponsored_transactions')
444
479
  .set({ finalizedAt, status: 'failed' })
445
480
  .where('id', '=', id)
446
481
  .where('status', '=', 'pending')
447
- .execute()
482
+ if (options.transactionHash !== undefined)
483
+ query =
484
+ options.transactionHash === null
485
+ ? query.where('transactionHash', 'is', null)
486
+ : query.where('transactionHash', '=', options.transactionHash)
487
+ await query.execute()
488
+ }
489
+
490
+ export declare namespace fail {
491
+ /** Optional compare-and-set fence for a claimed sponsorship. */
492
+ type Options = {
493
+ /** Transaction hash observed when finalization claimed the row. */
494
+ transactionHash?: string | null | undefined
495
+ }
448
496
  }
449
497
 
450
498
  /**
@@ -465,6 +513,7 @@ export async function reserve(
465
513
  limit: reserve.Limit,
466
514
  ): Promise<Record> {
467
515
  return db.transaction(async (tx) => {
516
+ await lockOrganization(tx, input.orgId)
468
517
  // `hashtext` maps the org id into the advisory-lock keyspace; the class
469
518
  // namespaces it against other advisory-lock users. Released at tx end.
470
519
  const scope = limit.sponsorshipAttributionId
@@ -524,6 +573,7 @@ export function reservePromotion(
524
573
  options: reservePromotion.Options,
525
574
  ): Promise<reservePromotion.Result> {
526
575
  return db.transaction(async (tx) => {
576
+ await lockOrganization(tx, input.orgId)
527
577
  const scope = `${input.orgId}:${input.sponsorshipAttributionId}`
528
578
  await sql`select pg_advisory_xact_lock(${billingLockClass}, hashtext(${scope}))`.execute(tx.kysely) // prettier-ignore
529
579
  const existing = await tx.kysely
@@ -813,7 +863,7 @@ export declare namespace usage {
813
863
 
814
864
  /**
815
865
  * Lists finalized billable rows not yet reported to the billing meter, oldest
816
- * first, for the metering job.
866
+ * first, optionally scoped to chains.
817
867
  *
818
868
  * @param db - The database.
819
869
  * @param options - Reporting scope.
@@ -834,6 +884,89 @@ export function listUnreported(db: Db.Db, options: listUnreported.Options): Prom
834
884
  return query.execute()
835
885
  }
836
886
 
887
+ /** Claims unreported sponsorships, reserving capacity for Stripe retries and unsent rows. */
888
+ export function claimUnreported(db: Db.Db, options: claimUnreported.Options): Promise<Record[]> {
889
+ return db.transaction(async (tx) => {
890
+ const retries =
891
+ options.limit > 1
892
+ ? await tx.kysely
893
+ .selectFrom('sponsored_transactions')
894
+ .selectAll()
895
+ .where('status', '=', 'finalized')
896
+ .where('billable', '=', true)
897
+ .where('meterReportedAt', 'is', null)
898
+ .where('meterEventFirstAttemptedAt', 'is not', null)
899
+ .orderBy('meterReportAttemptedAt', 'asc')
900
+ .orderBy('finalizedAt', 'asc')
901
+ .orderBy('id', 'asc')
902
+ .limit(Math.floor(options.limit / 2))
903
+ .forUpdate()
904
+ .skipLocked()
905
+ .execute()
906
+ : []
907
+ const fresh = await tx.kysely
908
+ .selectFrom('sponsored_transactions')
909
+ .selectAll()
910
+ .where('status', '=', 'finalized')
911
+ .where('billable', '=', true)
912
+ .where('meterReportedAt', 'is', null)
913
+ .$if(options.limit > 1, (query) => query.where('meterEventFirstAttemptedAt', 'is', null))
914
+ .orderBy(sql`meter_report_attempted_at nulls first`)
915
+ .orderBy('finalizedAt', 'asc')
916
+ .orderBy('id', 'asc')
917
+ .limit(options.limit - retries.length)
918
+ .forUpdate()
919
+ .skipLocked()
920
+ .execute()
921
+ const rows = [...retries, ...fresh]
922
+ if (rows.length === 0) return []
923
+ await tx.kysely
924
+ .updateTable('sponsored_transactions')
925
+ .set({ meterReportAttemptedAt: options.attemptedAt })
926
+ .where(
927
+ 'id',
928
+ 'in',
929
+ rows.map((row) => row.id),
930
+ )
931
+ .execute()
932
+ return rows.map((row) => ({ ...row, meterReportAttemptedAt: options.attemptedAt }))
933
+ })
934
+ }
935
+
936
+ /** Persists the first possible Stripe submission before any network request. */
937
+ export async function beginMeterEvent(db: Db.Db, id: string, at: string): Promise<string> {
938
+ const row = await db.kysely
939
+ .updateTable('sponsored_transactions')
940
+ .set({ meterEventFirstAttemptedAt: sql`coalesce(meter_event_first_attempted_at, ${at})` })
941
+ .where('id', '=', id)
942
+ .where('status', '=', 'finalized')
943
+ .where('meterReportedAt', 'is', null)
944
+ .returning('meterEventFirstAttemptedAt')
945
+ .executeTakeFirstOrThrow()
946
+ return row.meterEventFirstAttemptedAt!
947
+ }
948
+
949
+ /** Clears the retry clock only after Stripe explicitly rejected the event. */
950
+ export async function clearRejectedMeterEventAttempt(db: Db.Db, id: string): Promise<void> {
951
+ await db.kysely
952
+ .updateTable('sponsored_transactions')
953
+ .set({ meterEventFirstAttemptedAt: null })
954
+ .where('id', '=', id)
955
+ .where('status', '=', 'finalized')
956
+ .where('meterReportedAt', 'is', null)
957
+ .execute()
958
+ }
959
+
960
+ export declare namespace claimUnreported {
961
+ /** One bounded reporting pass. */
962
+ type Options = {
963
+ /** Time recorded for each claimed row (ISO 8601). */
964
+ attemptedAt: string
965
+ /** Maximum sponsorships claimed by this pass. */
966
+ limit: number
967
+ }
968
+ }
969
+
837
970
  export declare namespace listUnreported {
838
971
  /** Options for {@link listUnreported}. */
839
972
  type Options = {
@@ -857,10 +990,21 @@ export async function markReported(db: Db.Db, id: string, at: string): Promise<v
857
990
  .updateTable('sponsored_transactions')
858
991
  .set({ meterReportedAt: at })
859
992
  .where('id', '=', id)
993
+ .where('status', '=', 'finalized')
860
994
  .where('meterReportedAt', 'is', null)
861
995
  .execute()
862
996
  }
863
997
 
998
+ /** Holds the deletion fence before any sponsorship row, budget, or policy locks. */
999
+ async function lockOrganization(db: Db.Db, orgId: string): Promise<void> {
1000
+ if (!(await ApiKeyOwnerTombstones.lockActive(db, { orgId }))) throw new OrganizationDeletedError()
1001
+ }
1002
+
1003
+ /** A deleted organization cannot acquire or reopen sponsorship commitments. */
1004
+ export class OrganizationDeletedError extends Error {
1005
+ override name = 'SponsoredTransactions.OrganizationDeletedError'
1006
+ }
1007
+
864
1008
  /** Thrown by {@link reserve} when recording would exceed the org's period spend limit. */
865
1009
  export class PeriodSpendLimitError extends Error {
866
1010
  override name = 'SponsoredTransactions.PeriodSpendLimitError'
@@ -10,6 +10,8 @@ describe('getByEmail', () => {
10
10
  try {
11
11
  const first = await Users.upsertByAddress(db, { address: `0x${'11'.repeat(20)}` })
12
12
  const second = await Users.upsertByAddress(db, { address: `0x${'22'.repeat(20)}` })
13
+ expect(first.termsSharedAt).toBeNull()
14
+ expect(second.termsSharedAt).toBeNull()
13
15
  await db.kysely
14
16
  .updateTable('users')
15
17
  .set({ createdAt: '2026-01-01T00:00:00.000Z' })
@@ -49,6 +51,7 @@ describe('auth field migration compatibility', () => {
49
51
  await expect(Users.get(db, 'usr_legacy_worker')).resolves.toMatchObject({
50
52
  emailVerified: false,
51
53
  name: '',
54
+ termsSharedAt: null,
52
55
  })
53
56
  } finally {
54
57
  await db.close()
@@ -56,6 +59,54 @@ describe('auth field migration compatibility', () => {
56
59
  })
57
60
  })
58
61
 
62
+ describe('recordTermsShared', () => {
63
+ test('records an older user once after sign-in', async () => {
64
+ const db = TestApp.database()
65
+ try {
66
+ const now = new Date().toISOString()
67
+ await db.kysely
68
+ .insertInto('users')
69
+ .values([
70
+ {
71
+ address: null,
72
+ createdAt: now,
73
+ email: 'developer@example.com',
74
+ emailVerified: true,
75
+ id: 'usr_older_terms',
76
+ image: null,
77
+ name: 'Developer',
78
+ updatedAt: now,
79
+ },
80
+ {
81
+ address: null,
82
+ createdAt: now,
83
+ email: 'other@example.com',
84
+ emailVerified: true,
85
+ id: 'usr_other_terms',
86
+ image: null,
87
+ name: 'Other',
88
+ updatedAt: now,
89
+ },
90
+ ])
91
+ .execute()
92
+
93
+ await Users.recordTermsShared(db, 'usr_older_terms')
94
+ const first = await Users.get(db, 'usr_older_terms')
95
+ expect(first).toMatchObject({
96
+ termsSharedAt: expect.any(String),
97
+ })
98
+ expect(await Users.get(db, 'usr_other_terms')).toMatchObject({
99
+ termsSharedAt: null,
100
+ })
101
+
102
+ await Users.recordTermsShared(db, 'usr_older_terms')
103
+ expect((await Users.get(db, 'usr_older_terms'))?.termsSharedAt).toBe(first?.termsSharedAt)
104
+ } finally {
105
+ await db.close()
106
+ }
107
+ })
108
+ })
109
+
59
110
  describe('email migration precondition', () => {
60
111
  test('rejects a blank email', async () => {
61
112
  const db = TestApp.database()
@@ -51,6 +51,7 @@ export function getByEmail(db: Db.Db, email: string): Promise<Record | undefined
51
51
  .where(sql<string>`lower(btrim(email))`, '=', email.trim().toLowerCase())
52
52
  .orderBy('createdAt', 'asc')
53
53
  .orderBy('id', 'asc')
54
+ .limit(1)
54
55
  .executeTakeFirst()
55
56
  }
56
57
 
@@ -119,6 +120,17 @@ export async function upsertByAddress(db: Db.Db, input: upsertByAddress.Input):
119
120
  .executeTakeFirstOrThrow()
120
121
  }
121
122
 
123
+ /** Records the first successful sign-in response that includes terms links. */
124
+ export async function recordTermsShared(db: Db.Db, id: string): Promise<void> {
125
+ const now = new Date().toISOString()
126
+ await db.kysely
127
+ .updateTable('users')
128
+ .set({ termsSharedAt: now, updatedAt: now })
129
+ .where('id', '=', id)
130
+ .where('termsSharedAt', 'is', null)
131
+ .execute()
132
+ }
133
+
122
134
  export declare namespace upsertByAddress {
123
135
  /** Fields accepted when ensuring a user. */
124
136
  type Input = {
@@ -0,0 +1,120 @@
1
+ import { Hex } from 'ox'
2
+ import { createClient, http } from 'viem'
3
+ import { tempoLocalnet } from 'viem/tempo/chains'
4
+
5
+ import * as Handler from '../../Handler.js'
6
+ import * as Log from '../../internal/Log.js'
7
+ import * as StateStore from '../../internal/Store.js'
8
+ import * as Multisig from './multisig.js'
9
+
10
+ describe('fromStore', () => {
11
+ test('requires atomic state', () => {
12
+ const { swap: _, ...state } = StateStore.memory()
13
+ expect(() => Multisig.fromStore(state)).toThrowErrorMatchingInlineSnapshot(
14
+ `[Error: Multisig coordination requires an atomic state store.]`,
15
+ )
16
+ })
17
+
18
+ test('preserves concurrent compare-and-set', async () => {
19
+ const state = StateStore.memory()
20
+ const a = Multisig.fromStore(state)
21
+ const results = await Promise.all([
22
+ a.compareAndSet('operation', null, 'a'),
23
+ a.compareAndSet('operation', null, 'b'),
24
+ ])
25
+ expect({ results }).toMatchInlineSnapshot(`
26
+ {
27
+ "results": [
28
+ true,
29
+ false,
30
+ ],
31
+ }
32
+ `)
33
+ })
34
+
35
+ test('honors absolute expiration', async () => {
36
+ vi.useFakeTimers()
37
+ try {
38
+ const store = Multisig.fromStore(StateStore.memory())
39
+ await store.compareAndSet('lease', null, 'a', { expiresAt: Date.now() + 100 })
40
+ await vi.advanceTimersByTimeAsync(101)
41
+ expect(await store.getItem('lease')).toBeNull()
42
+ expect(await store.compareAndSet('lease', null, 'b')).toBe(true)
43
+ } finally {
44
+ vi.useRealTimers()
45
+ }
46
+ })
47
+ })
48
+
49
+ describe('relay', () => {
50
+ const client = createClient({ chain: tempoLocalnet, transport: http() })
51
+
52
+ test('serves unknown operations without forwarding them to the node', async () => {
53
+ const handler = Handler.relay({
54
+ getClient: () => client,
55
+ multisig: { store: StateStore.memory() },
56
+ })
57
+ const response = await handler.fetch(
58
+ new Request('http://relay/', {
59
+ method: 'POST',
60
+ body: JSON.stringify({
61
+ id: 42,
62
+ jsonrpc: '2.0',
63
+ method: 'multisig_getOperation',
64
+ params: [Hex.random(32)],
65
+ }),
66
+ }),
67
+ )
68
+ expect(await response.json()).toMatchInlineSnapshot(`
69
+ {
70
+ "id": 42,
71
+ "jsonrpc": "2.0",
72
+ "result": null,
73
+ }
74
+ `)
75
+ })
76
+
77
+ test('rejects invalid parameters across the five methods', async () => {
78
+ const handler = Handler.relay({
79
+ getClient: () => client,
80
+ multisig: { store: StateStore.memory() },
81
+ })
82
+ for (const method of [
83
+ 'multisig_approveRawTransaction',
84
+ 'multisig_approveRawTransactionSync',
85
+ 'multisig_approveKeyAuthorization',
86
+ 'multisig_getConfig',
87
+ 'multisig_getOperation',
88
+ ]) {
89
+ const response = await handler.fetch(
90
+ new Request('http://relay/', {
91
+ method: 'POST',
92
+ body: JSON.stringify({ id: 1, jsonrpc: '2.0', method, params: [] }),
93
+ }),
94
+ )
95
+ expect(await response.json()).toMatchObject({ error: { code: -32602 } })
96
+ }
97
+ })
98
+
99
+ test('reports corrupt coordinator state through RPC server-error observability', async () => {
100
+ const state = StateStore.memory()
101
+ const hash = Hex.random(32)
102
+ // Operation lookup keys are part of the persisted Viem coordinator format.
103
+ await state.put(`multisig:v2:multisig:operation:${hash}`, 'invalid')
104
+ const handler = Handler.relay({ getClient: () => client, multisig: { store: state } })
105
+ const response = await handler.fetch(
106
+ new Request('http://relay/', {
107
+ method: 'POST',
108
+ body: JSON.stringify({
109
+ id: 1,
110
+ jsonrpc: '2.0',
111
+ method: 'multisig_getOperation',
112
+ params: [hash],
113
+ }),
114
+ }),
115
+ )
116
+ const body: unknown = await response.json()
117
+ expect(body).toMatchObject({ error: { code: -32603 } })
118
+ expect(Log.rpcErrors(body)).toMatchObject({ serverErrors: 1 })
119
+ })
120
+ })