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
@@ -0,0 +1,930 @@
1
+ import { Hex } from 'ox'
2
+
3
+ import * as Db from '../../db/Db.js'
4
+ import * as FundingDepositAddresses from '../../db/tables/fundingDepositAddresses.js'
5
+ import * as FundingDeposits from '../../db/tables/fundingDeposits.js'
6
+ import type * as Metrics from '../../Metrics.js'
7
+ import * as Value from '../Value.js'
8
+ import * as Deposit from './Deposit.js'
9
+ import * as Provider from './Provider.js'
10
+ import * as Subsidy from './Subsidy.js'
11
+
12
+ const defaultBatchSize = 25
13
+ const defaultLeaseMs = 2 * 60_000
14
+ const defaultPollIntervalMs = 60_000
15
+ const maximumPages = 100
16
+
17
+ /** Verified token transfer returned by an authoritative chain reader. */
18
+ export type TransferEvidence = {
19
+ /** Token quantity in base units. */
20
+ amount: string
21
+ /** Verified sender account, when the chain exposes it. */
22
+ sender?: string | undefined
23
+ /** Verified transaction reference. */
24
+ transactionHash: string
25
+ /** Transfer position within the transaction. */
26
+ transferIndex: number
27
+ }
28
+
29
+ /** Authoritative chain-evidence reader used during deposit reconciliation. */
30
+ export type VerifyTransfers = (
31
+ parameters: VerifyTransfers.Parameters,
32
+ ) => Promise<readonly TransferEvidence[]>
33
+
34
+ /** Parameters passed to an authoritative chain-evidence reader. */
35
+ export declare namespace VerifyTransfers {
36
+ type Parameters = {
37
+ /** Account that must receive the token transfer. */
38
+ recipient: string
39
+ /** Chain containing the transaction. */
40
+ chain: Provider.ChainRef
41
+ /** Token that must be transferred. */
42
+ token: Provider.TokenRef
43
+ /** Provider-discovered transaction reference to verify. */
44
+ transactionHash: string
45
+ }
46
+ }
47
+
48
+ /** Creates a reusable-address reconciliation tracker. */
49
+ export function createTracker(options: createTracker.Options): createTracker.Tracker {
50
+ const now = options.now ?? (() => new Date())
51
+ const batchSize = options.batchSize ?? defaultBatchSize
52
+ const leaseMs = options.leaseMs ?? defaultLeaseMs
53
+ const pollIntervalMs = options.pollIntervalMs ?? defaultPollIntervalMs
54
+
55
+ const record = (outcome: string, providerId: string) => {
56
+ options.metrics?.count('funding_deposit_reconciliation_count', 1, {
57
+ outcome,
58
+ provider: providerId,
59
+ })
60
+ }
61
+
62
+ return {
63
+ async reconcile(message) {
64
+ const database = Db.get(options.db)
65
+ const startedAt = now()
66
+ const claimed = await claim(database, message, {
67
+ leaseUntil: new Date(startedAt.getTime() + leaseMs).toISOString(),
68
+ now: startedAt.toISOString(),
69
+ })
70
+ if (!claimed) return { type: 'busy' }
71
+
72
+ const provider = options.providers.find((candidate) => candidate.id === claimed.providerId)
73
+ if (!provider || !Provider.canListDepositAddressRequests(provider)) {
74
+ await fail(database, claimed, startedAt, pollIntervalMs)
75
+ record('provider_unavailable', claimed.providerId)
76
+ return { type: 'provider_unavailable' }
77
+ }
78
+
79
+ const heartbeat = maintainLease(database, claimed, { leaseMs, now })
80
+ try {
81
+ await heartbeat.ready()
82
+ const requests = await listRequests(provider, {
83
+ address: claimed,
84
+ requestId: message.requestId,
85
+ signal: options.signal,
86
+ })
87
+ heartbeat.assert()
88
+ let created = 0
89
+ let updated = 0
90
+ const pendingRequestIds = new Set(requests.pendingRequestIds)
91
+ for (const request of requests.requests) {
92
+ const result = await reconcileRequest(database, {
93
+ address: claimed,
94
+ metrics: options.metrics,
95
+ request,
96
+ subsidies: options.subsidies,
97
+ verifyTransfers: options.verifyTransfers,
98
+ })
99
+ heartbeat.assert()
100
+ created += result.created
101
+ updated += result.updated
102
+ if (result.terminal) pendingRequestIds.delete(request.id)
103
+ else pendingRequestIds.add(request.id)
104
+ }
105
+
106
+ const leaseFailure = await heartbeat.stop()
107
+ if (leaseFailure !== undefined) throw leaseFailure
108
+ const completedAt = now()
109
+ const stored = await FundingDepositAddresses.completePoll(database, {
110
+ id: claimed.id,
111
+ lastPolledAt: completedAt.toISOString(),
112
+ nextPollAt: new Date(completedAt.getTime() + pollIntervalMs).toISOString(),
113
+ pollLeaseVersion: claimed.pollLeaseVersion,
114
+ providerRequestIds: claimed.providerRequestIds,
115
+ providerState: reconciliationState(claimed.providerState, requests, [
116
+ ...pendingRequestIds,
117
+ ]),
118
+ })
119
+ if (!stored) return { type: 'stale' }
120
+ record('completed', claimed.providerId)
121
+ options.metrics?.histogram(
122
+ 'funding_deposit_reconciliation_duration_ms',
123
+ completedAt.getTime() - startedAt.getTime(),
124
+ { provider: claimed.providerId },
125
+ )
126
+ return { created, type: 'completed', updated }
127
+ } catch (cause) {
128
+ const leaseFailure = await heartbeat.stop()
129
+ await fail(database, claimed, now(), pollIntervalMs)
130
+ record('failed', claimed.providerId)
131
+ throw leaseFailure ?? cause
132
+ } finally {
133
+ options.metrics?.flush()
134
+ }
135
+ },
136
+
137
+ async tick() {
138
+ const database = Db.get(options.db)
139
+ const startedAt = now()
140
+ const leaseUntil = new Date(startedAt.getTime() + leaseMs).toISOString()
141
+ let claimed = 0
142
+ let failed = 0
143
+ for (const provider of options.providers) {
144
+ if (!Provider.canListDepositAddressRequests(provider)) continue
145
+ const records = await FundingDepositAddresses.claimDue(database, {
146
+ leaseUntil,
147
+ limit: Math.max(0, batchSize - claimed),
148
+ now: startedAt.toISOString(),
149
+ providerId: provider.id,
150
+ })
151
+ for (const address of records) {
152
+ claimed += 1
153
+ options.metrics?.histogram(
154
+ 'funding_deposit_poll_lag_ms',
155
+ Math.max(0, startedAt.getTime() - new Date(address.nextPollAt).getTime()),
156
+ { provider: provider.id },
157
+ )
158
+ try {
159
+ await options.dispatch({
160
+ addressId: address.id,
161
+ pollLeaseVersion: address.pollLeaseVersion,
162
+ type: 'funding:deposit-address:reconcile',
163
+ })
164
+ record('enqueued', provider.id)
165
+ } catch {
166
+ failed += 1
167
+ await fail(database, address, startedAt, pollIntervalMs)
168
+ record('enqueue_failed', provider.id)
169
+ }
170
+ }
171
+ if (claimed >= batchSize) break
172
+ }
173
+ options.metrics?.flush()
174
+ return { claimed, failed }
175
+ },
176
+ }
177
+ }
178
+
179
+ export declare namespace createTracker {
180
+ /** Dependencies and bounds for deposit reconciliation. */
181
+ type Options = {
182
+ /** Maximum addresses claimed by one scheduled tick. */
183
+ batchSize?: number | undefined
184
+ /** Authoritative database or per-invocation database factory. */
185
+ db: Db.Source
186
+ /** Durable reconciliation queue transport. */
187
+ dispatch: (message: Provider.Webhook.receive.Dispatchable) => Promise<void>
188
+ /** Duration of one reconciliation lease. */
189
+ leaseMs?: number | undefined
190
+ /** Optional bounded operational metrics sink. */
191
+ metrics?: Metrics.Metrics | undefined
192
+ /** Clock used for scheduling and tests. */
193
+ now?: (() => Date) | undefined
194
+ /** Delay before a successfully reconciled address is polled again. */
195
+ pollIntervalMs?: number | undefined
196
+ /** Configured funding provider integrations. */
197
+ providers: readonly Provider.Provider[]
198
+ /** Optional cancellation signal for provider reads. */
199
+ signal?: AbortSignal | undefined
200
+ /** Optional pathUSD-funded subsidy settler. */
201
+ subsidies?: Subsidy.Settler | undefined
202
+ /** Authoritative source and Tempo transfer verifier. */
203
+ verifyTransfers: VerifyTransfers
204
+ }
205
+
206
+ /** Result of reconciling one queue message. */
207
+ type ReconcileResult =
208
+ | { type: 'busy' | 'provider_unavailable' | 'stale' }
209
+ | { created: number; type: 'completed'; updated: number }
210
+
211
+ /** Scheduled and queue-driven reusable-address tracker. */
212
+ type Tracker = {
213
+ /** Reconciles one address from provider discovery and verified chain evidence. */
214
+ reconcile(message: Provider.Webhook.receive.Dispatchable): Promise<ReconcileResult>
215
+ /** Claims and enqueues one bounded batch of due reusable addresses. */
216
+ tick(): Promise<{ claimed: number; failed: number }>
217
+ }
218
+ }
219
+
220
+ type ClaimOptions = {
221
+ leaseUntil: string
222
+ now: string
223
+ }
224
+
225
+ async function claim(
226
+ db: Db.Db,
227
+ message: Provider.Webhook.receive.Dispatchable,
228
+ options: ClaimOptions,
229
+ ) {
230
+ if (message.pollLeaseVersion === undefined)
231
+ return FundingDepositAddresses.claim(db, {
232
+ id: message.addressId,
233
+ leaseUntil: options.leaseUntil,
234
+ now: options.now,
235
+ })
236
+ const current = await FundingDepositAddresses.get(db, message.addressId)
237
+ if (
238
+ !current?.pollLeaseUntil ||
239
+ current.pollLeaseUntil <= options.now ||
240
+ current.pollLeaseVersion !== message.pollLeaseVersion
241
+ )
242
+ return undefined
243
+ return current
244
+ }
245
+
246
+ async function fail(
247
+ db: Db.Db,
248
+ address: FundingDepositAddresses.Record,
249
+ now: Date,
250
+ pollIntervalMs: number,
251
+ ) {
252
+ const delay = Math.min(pollIntervalMs * 2 ** address.pollFailureCount, 15 * 60_000)
253
+ return FundingDepositAddresses.failPoll(db, {
254
+ id: address.id,
255
+ nextPollAt: new Date(now.getTime() + delay).toISOString(),
256
+ pollLeaseVersion: address.pollLeaseVersion,
257
+ })
258
+ }
259
+
260
+ type MaintainLeaseOptions = {
261
+ leaseMs: number
262
+ now: () => Date
263
+ }
264
+
265
+ function maintainLease(
266
+ db: Db.Db,
267
+ address: FundingDepositAddresses.Record,
268
+ options: MaintainLeaseOptions,
269
+ ) {
270
+ let failure: unknown
271
+ let stopped = false
272
+ const extend = async () => {
273
+ if (stopped || failure !== undefined) return
274
+ const renewed = await FundingDepositAddresses.renewPoll(db, {
275
+ id: address.id,
276
+ leaseUntil: new Date(options.now().getTime() + options.leaseMs).toISOString(),
277
+ pollLeaseVersion: address.pollLeaseVersion,
278
+ })
279
+ if (!renewed) failure = new StaleLeaseError()
280
+ }
281
+ const captureFailure = (cause: unknown) => {
282
+ failure = cause
283
+ }
284
+ let renewal = extend().catch(captureFailure)
285
+ const timer = setInterval(
286
+ () => {
287
+ renewal = renewal.then(extend).catch(captureFailure)
288
+ },
289
+ Math.max(1, Math.floor(options.leaseMs / 2)),
290
+ )
291
+
292
+ return {
293
+ assert() {
294
+ if (failure !== undefined) throw failure
295
+ },
296
+ async ready() {
297
+ await renewal
298
+ if (failure !== undefined) throw failure
299
+ },
300
+ async stop() {
301
+ if (!stopped) {
302
+ stopped = true
303
+ clearInterval(timer)
304
+ }
305
+ await renewal
306
+ return failure
307
+ },
308
+ }
309
+ }
310
+
311
+ type Requests = {
312
+ highWaterRequestIds: readonly string[]
313
+ highWaterUpdatedAt?: string | undefined
314
+ pendingRequestIds: readonly string[]
315
+ requests: readonly Provider.listDepositAddressRequests.ReturnType['requests'][number][]
316
+ }
317
+
318
+ type ListRequestsOptions = {
319
+ address: FundingDepositAddresses.Record
320
+ requestId?: string | undefined
321
+ signal?: AbortSignal | undefined
322
+ }
323
+
324
+ async function listRequests(
325
+ provider: Provider.Provider & {
326
+ listDepositAddressRequests: NonNullable<Provider.Provider['listDepositAddressRequests']>
327
+ },
328
+ options: ListRequestsOptions,
329
+ ): Promise<Requests> {
330
+ const highWater = readHighWater(options.address.providerState)
331
+ const highWaterRequestIds = new Set(highWater.requestIds)
332
+ const pendingRequestIds = new Set(highWater.pendingRequestIds)
333
+ const requests: Provider.listDepositAddressRequests.ReturnType['requests'][number][] = []
334
+ let continuation: string | undefined
335
+ for (let page = 0; page < maximumPages; page++) {
336
+ const result = await provider.listDepositAddressRequests(
337
+ { address: options.address.address, ...(continuation ? { continuation } : {}) },
338
+ options.signal ?? new AbortController().signal,
339
+ )
340
+ requests.push(
341
+ ...result.requests.filter(
342
+ (request) =>
343
+ !highWater.updatedAt ||
344
+ request.updatedAt > highWater.updatedAt ||
345
+ (request.updatedAt === highWater.updatedAt &&
346
+ (!highWaterRequestIds.has(request.id) || pendingRequestIds.has(request.id))),
347
+ ),
348
+ )
349
+ const reached = result.requests.some(
350
+ (request) => highWater.updatedAt && request.updatedAt < highWater.updatedAt,
351
+ )
352
+ continuation = result.continuation
353
+ if (!continuation || reached) break
354
+ if (page === maximumPages - 1) throw new PaginationLimitError()
355
+ }
356
+
357
+ const observed = new Set(requests.map((request) => request.id))
358
+ for (const requestId of unique([
359
+ ...highWater.pendingRequestIds,
360
+ ...(options.requestId ? [options.requestId] : []),
361
+ ])) {
362
+ if (observed.has(requestId)) continue
363
+ const result = await provider.listDepositAddressRequests(
364
+ { address: options.address.address, requestId },
365
+ options.signal ?? new AbortController().signal,
366
+ )
367
+ requests.push(...result.requests)
368
+ }
369
+
370
+ const addressRequests = requests.filter(
371
+ (request) => !highWater.pendingRequestIds.includes(request.id),
372
+ )
373
+ const newest = addressRequests.reduce<string | undefined>(
374
+ (value, request) => (!value || request.updatedAt > value ? request.updatedAt : value),
375
+ highWater.updatedAt,
376
+ )
377
+ return {
378
+ highWaterRequestIds: newest
379
+ ? unique([
380
+ ...(newest === highWater.updatedAt ? highWater.requestIds : []),
381
+ ...addressRequests
382
+ .filter((request) => request.updatedAt === newest)
383
+ .map((request) => request.id),
384
+ ])
385
+ : [],
386
+ highWaterUpdatedAt: newest,
387
+ pendingRequestIds: highWater.pendingRequestIds,
388
+ requests,
389
+ }
390
+ }
391
+
392
+ type HighWater = {
393
+ pendingRequestIds: readonly string[]
394
+ requestIds: readonly string[]
395
+ updatedAt?: string | undefined
396
+ }
397
+
398
+ function readHighWater(state: FundingDepositAddresses.Record['providerState']): HighWater {
399
+ if (!state || typeof state !== 'object') return { pendingRequestIds: [], requestIds: [] }
400
+ const reconciliation = state['reconciliation']
401
+ if (!reconciliation || typeof reconciliation !== 'object')
402
+ return { pendingRequestIds: [], requestIds: [] }
403
+ const pendingRequestIds =
404
+ 'pendingRequestIds' in reconciliation && Array.isArray(reconciliation.pendingRequestIds)
405
+ ? reconciliation.pendingRequestIds.filter(
406
+ (value: unknown): value is string => typeof value === 'string',
407
+ )
408
+ : []
409
+ const requestIds =
410
+ 'requestIds' in reconciliation && Array.isArray(reconciliation.requestIds)
411
+ ? reconciliation.requestIds.filter(
412
+ (value: unknown): value is string => typeof value === 'string',
413
+ )
414
+ : []
415
+ return {
416
+ pendingRequestIds,
417
+ requestIds,
418
+ ...('updatedAt' in reconciliation && typeof reconciliation.updatedAt === 'string'
419
+ ? { updatedAt: reconciliation.updatedAt }
420
+ : {}),
421
+ }
422
+ }
423
+
424
+ function reconciliationState(
425
+ state: FundingDepositAddresses.Record['providerState'],
426
+ requests: Requests,
427
+ pendingRequestIds: readonly string[],
428
+ ) {
429
+ const current = state && typeof state === 'object' ? state : {}
430
+ return {
431
+ ...current,
432
+ reconciliation: {
433
+ pendingRequestIds,
434
+ requestIds: requests.highWaterRequestIds,
435
+ ...(requests.highWaterUpdatedAt ? { updatedAt: requests.highWaterUpdatedAt } : {}),
436
+ },
437
+ }
438
+ }
439
+
440
+ type ObservedSourceTransaction = {
441
+ deposits: FundingDeposits.Record[]
442
+ transactionHash: string
443
+ transfers: readonly TransferEvidence[]
444
+ }
445
+
446
+ type VerifiedDeposit = {
447
+ deposit: FundingDeposits.Record
448
+ required: bigint
449
+ sourceAmount: bigint
450
+ }
451
+
452
+ /** Reconciles one provider request against verified chain evidence. */
453
+ export async function reconcileRequest(
454
+ db: Db.Db,
455
+ options: reconcileRequest.Options,
456
+ ): Promise<reconcileRequest.ReturnType> {
457
+ let created = 0
458
+ const observed: ObservedSourceTransaction[] = []
459
+ // Persist provider observations first so transient chain failures do not hide acknowledged deposits.
460
+ for (const transactionHash of unique(options.request.sourceTransactionHashes)) {
461
+ let deposits = await FundingDeposits.listByProviderObservation(db, {
462
+ depositAddressId: options.address.id,
463
+ providerRequestId: options.request.id,
464
+ sourceTransactionHash: transactionHash,
465
+ })
466
+ if (deposits.length === 0)
467
+ deposits = await FundingDeposits.listBySourceTransaction(db, {
468
+ depositAddressId: options.address.id,
469
+ sourceTransactionHash: transactionHash,
470
+ })
471
+ if (deposits.length === 0) {
472
+ deposits = [
473
+ await Deposit.create(db, {
474
+ now: new Date(options.request.createdAt),
475
+ providerRequestId: options.request.id,
476
+ snapshot: {
477
+ depositAddressId: options.address.id,
478
+ destinationChain: options.address.snapshot.destinationChain,
479
+ destinationToken: options.address.snapshot.destinationToken,
480
+ provider: options.address.snapshot.provider,
481
+ recipient: options.address.recipient,
482
+ refundAddress: options.address.refundAddress,
483
+ sourceChain: options.address.snapshot.sourceChain,
484
+ sourceToken: options.address.snapshot.sourceToken,
485
+ sourceTransactionHashes: [transactionHash],
486
+ },
487
+ sourceTransactionHash: transactionHash,
488
+ }),
489
+ ]
490
+ created += 1
491
+ }
492
+ observed.push({ deposits, transactionHash, transfers: [] })
493
+ }
494
+
495
+ const sources = await Promise.all(
496
+ observed.map(
497
+ async (source): Promise<ObservedSourceTransaction> => ({
498
+ ...source,
499
+ transfers: await options.verifyTransfers({
500
+ chain: options.address.snapshot.sourceChain,
501
+ recipient: options.address.address,
502
+ token: options.address.snapshot.sourceToken,
503
+ transactionHash: source.transactionHash,
504
+ }),
505
+ }),
506
+ ),
507
+ )
508
+
509
+ const sourceEvidenceComplete =
510
+ sources.length > 0 && sources.every((source) => source.transfers.length > 0)
511
+ let terminal = sourceEvidenceComplete
512
+ const updatedIds = new Set<string>()
513
+ const verified: VerifiedDeposit[] = []
514
+ for (const source of sources) {
515
+ const transfers = [...source.transfers].sort(
516
+ (left, right) => left.transferIndex - right.transferIndex,
517
+ )
518
+ for (const [providerTransferIndex, transfer] of transfers.entries()) {
519
+ const required = destinationBaseUnits(
520
+ BigInt(transfer.amount),
521
+ options.address.snapshot.sourceToken.decimals,
522
+ options.address.snapshot.destinationToken.decimals,
523
+ )
524
+ const sourceAmount = Value.tokenAmount({
525
+ baseUnits: transfer.amount,
526
+ currency: options.address.snapshot.sourceToken.currency,
527
+ decimals: options.address.snapshot.sourceToken.decimals,
528
+ })
529
+ const destinationAmountRequired = Value.tokenAmount({
530
+ baseUnits: required,
531
+ currency: options.address.snapshot.destinationToken.currency,
532
+ decimals: options.address.snapshot.destinationToken.decimals,
533
+ })
534
+ // Bind the placeholder to transfers in deterministic log order when one transaction contains several deposits.
535
+ let deposit = source.deposits.find((record) =>
536
+ record.providerRequestId === null
537
+ ? record.sourceTransferIndex === transfer.transferIndex
538
+ : record.providerTransferIndex === providerTransferIndex,
539
+ )
540
+ if (!deposit) {
541
+ deposit = await Deposit.create(db, {
542
+ now: new Date(options.request.createdAt),
543
+ providerRequestId: options.request.id,
544
+ providerTransferIndex,
545
+ snapshot: {
546
+ depositAddressId: options.address.id,
547
+ ...(options.address.snapshot.subsidize ? { destinationAmountRequired } : {}),
548
+ destinationChain: options.address.snapshot.destinationChain,
549
+ destinationToken: options.address.snapshot.destinationToken,
550
+ provider: options.address.snapshot.provider,
551
+ recipient: options.address.recipient,
552
+ refundAddress: options.address.refundAddress,
553
+ ...(transfer.sender ? { sender: transfer.sender } : {}),
554
+ sourceAmount,
555
+ sourceChain: options.address.snapshot.sourceChain,
556
+ sourceToken: options.address.snapshot.sourceToken,
557
+ sourceTransactionHashes: [transfer.transactionHash],
558
+ },
559
+ sourceTransactionHash: transfer.transactionHash,
560
+ sourceTransferIndex: transfer.transferIndex,
561
+ })
562
+ source.deposits.push(deposit)
563
+ created += 1
564
+ }
565
+ if (!Deposit.isTerminal(deposit.status)) {
566
+ const result = await Deposit.transition(db, {
567
+ expectedVersion: deposit.version,
568
+ id: deposit.id,
569
+ providerRequestIds: unique([...deposit.providerRequestIds, options.request.id]),
570
+ snapshot: {
571
+ ...deposit.snapshot,
572
+ ...(options.address.snapshot.subsidize ? { destinationAmountRequired } : {}),
573
+ ...(transfer.sender ? { sender: transfer.sender } : {}),
574
+ sourceAmount,
575
+ },
576
+ sourceTransferIndex: transfer.transferIndex,
577
+ status: deposit.status === 'detected' ? 'bridging' : deposit.status,
578
+ })
579
+ if (result.type === 'applied') {
580
+ deposit = result.record
581
+ updatedIds.add(deposit.id)
582
+ }
583
+ }
584
+ verified.push({ deposit, required, sourceAmount: BigInt(transfer.amount) })
585
+ }
586
+ }
587
+ if (verified.length === 0) return { created, terminal: false, updated: updatedIds.size }
588
+ if (!sourceEvidenceComplete) return { created, terminal: false, updated: updatedIds.size }
589
+
590
+ const destinationEvidence = await Promise.all(
591
+ options.request.destinationTransactionHashes.map((transactionHash) =>
592
+ options.verifyTransfers({
593
+ chain: options.address.snapshot.destinationChain,
594
+ recipient: options.address.recipient,
595
+ token: options.address.providerOutputToken,
596
+ transactionHash,
597
+ }),
598
+ ),
599
+ )
600
+ const destinationTransfers = destinationEvidence.flat()
601
+ const providerEvidenceComplete =
602
+ options.request.status === 'success' &&
603
+ destinationEvidence.every((transfers) => transfers.length > 0)
604
+ const providerOutput = destinationTransfers.reduce(
605
+ (total, transfer) => total + BigInt(transfer.amount),
606
+ 0n,
607
+ )
608
+ const totalRequired = verified.reduce((total, entry) => total + entry.required, 0n)
609
+ let allocated = 0n
610
+ let cumulativeRequired = 0n
611
+
612
+ for (const entry of verified) {
613
+ const { required, sourceAmount } = entry
614
+ cumulativeRequired += required
615
+ const nextAllocated =
616
+ totalRequired === 0n ? 0n : (providerOutput * cumulativeRequired) / totalRequired
617
+ const delivered = nextAllocated - allocated
618
+ allocated = nextAllocated
619
+ const { deposit } = entry
620
+ if (Deposit.isTerminal(deposit.status)) continue
621
+
622
+ const settlement = await reconcileSubsidy({
623
+ address: options.address,
624
+ delivered,
625
+ deposit,
626
+ providerEvidenceComplete,
627
+ required,
628
+ sourceAmount,
629
+ subsidies: options.subsidies,
630
+ verifyTransfers: options.verifyTransfers,
631
+ })
632
+ if (settlement.outcome)
633
+ options.metrics?.count('funding_deposit_subsidy_count', 1, {
634
+ outcome: settlement.outcome,
635
+ provider: options.address.providerId,
636
+ })
637
+ if (settlement.status === 'bridging' || settlement.status === 'settling') terminal = false
638
+ const destinationAmount = Value.tokenAmount({
639
+ baseUnits: delivered + settlement.delivered,
640
+ currency: options.address.snapshot.destinationToken.currency,
641
+ decimals: options.address.snapshot.destinationToken.decimals,
642
+ })
643
+ const result = await Deposit.transition(db, {
644
+ expectedVersion: deposit.version,
645
+ id: deposit.id,
646
+ ...(delivered > 0n
647
+ ? {
648
+ providerOutputAmount: Value.tokenAmount({
649
+ baseUnits: delivered,
650
+ currency: options.address.providerOutputToken.currency,
651
+ decimals: options.address.providerOutputToken.decimals,
652
+ }),
653
+ }
654
+ : {}),
655
+ providerRequestIds: unique([...deposit.providerRequestIds, options.request.id]),
656
+ providerTransactionHashes: unique([
657
+ ...deposit.providerTransactionHashes,
658
+ ...options.request.destinationTransactionHashes,
659
+ ]),
660
+ ...(settlement.settlementTransaction
661
+ ? { settlementTransaction: settlement.settlementTransaction }
662
+ : {}),
663
+ ...(settlement.settlementTransactionHash
664
+ ? { settlementTransactionHash: settlement.settlementTransactionHash }
665
+ : {}),
666
+ snapshot: {
667
+ ...deposit.snapshot,
668
+ ...(delivered + settlement.delivered > 0n ? { destinationAmount } : {}),
669
+ ...(settlement.status === 'completed' && !options.address.snapshot.subsidize
670
+ ? { destinationAmountRequired: destinationAmount }
671
+ : {}),
672
+ destinationTransactionHashes: unique([
673
+ ...(deposit.snapshot.destinationTransactionHashes ?? []),
674
+ ...destinationTransfers.map((evidence) => evidence.transactionHash),
675
+ ...settlement.destinationTransactionHashes,
676
+ ]),
677
+ },
678
+ status: settlement.status,
679
+ ...(settlement.statusReason ? { statusReason: settlement.statusReason } : {}),
680
+ ...(settlement.subsidyAmount ? { subsidyAmount: settlement.subsidyAmount } : {}),
681
+ ...(settlement.tempoGasPaid ? { tempoGasPaid: settlement.tempoGasPaid } : {}),
682
+ })
683
+ if (result.type === 'applied') {
684
+ updatedIds.add(deposit.id)
685
+ if (settlement.broadcast && options.subsidies) {
686
+ await options.subsidies.broadcast(settlement.broadcast).catch((cause) => {
687
+ options.metrics?.count('funding_deposit_subsidy_count', 1, {
688
+ outcome: 'broadcast_failed',
689
+ provider: options.address.providerId,
690
+ })
691
+ throw cause
692
+ })
693
+ options.metrics?.count('funding_deposit_subsidy_count', 1, {
694
+ outcome: 'broadcast',
695
+ provider: options.address.providerId,
696
+ })
697
+ }
698
+ }
699
+ }
700
+ return { created, terminal, updated: updatedIds.size }
701
+ }
702
+
703
+ export declare namespace reconcileRequest {
704
+ /** Provider request, address, and settlement dependencies. */
705
+ type Options = {
706
+ /** Reusable deposit address attributed by the provider. */
707
+ address: FundingDepositAddresses.Record
708
+ /** Optional bounded operational metrics sink. */
709
+ metrics?: Metrics.Metrics | undefined
710
+ /** Provider request containing discovered chain transactions. */
711
+ request: Provider.listDepositAddressRequests.ReturnType['requests'][number]
712
+ /** Optional pathUSD-funded subsidy settler. */
713
+ subsidies?: Subsidy.Settler | undefined
714
+ /** Authoritative source and destination transfer verifier. */
715
+ verifyTransfers: VerifyTransfers
716
+ }
717
+
718
+ /** Material changes produced by one provider request. */
719
+ type ReturnType = {
720
+ /** Number of newly detected source transfers. */
721
+ created: number
722
+ /** Whether every deposit from this request reached a terminal state. */
723
+ terminal: boolean
724
+ /** Number of existing or new deposits materially changed. */
725
+ updated: number
726
+ }
727
+ }
728
+
729
+ type ReconcileSubsidyOptions = {
730
+ address: FundingDepositAddresses.Record
731
+ delivered: bigint
732
+ deposit: FundingDeposits.Record
733
+ providerEvidenceComplete: boolean
734
+ required: bigint
735
+ sourceAmount: bigint
736
+ subsidies?: Subsidy.Settler | undefined
737
+ verifyTransfers: VerifyTransfers
738
+ }
739
+
740
+ type ReconcileSubsidyResult = {
741
+ broadcast?: Subsidy.Settler.broadcast.Parameters | undefined
742
+ delivered: bigint
743
+ destinationTransactionHashes: readonly string[]
744
+ outcome?: string | undefined
745
+ settlementTransaction?: string | undefined
746
+ settlementTransactionHash?: string | undefined
747
+ status: Deposit.Status
748
+ statusReason?: Deposit.StatusReason | undefined
749
+ subsidyAmount?: Deposit.Snapshot['destinationAmountRequired'] | undefined
750
+ tempoGasPaid?: string | undefined
751
+ }
752
+
753
+ async function reconcileSubsidy(options: ReconcileSubsidyOptions): Promise<ReconcileSubsidyResult> {
754
+ const empty = { delivered: 0n, destinationTransactionHashes: [] } as const
755
+ if (options.required === 0n)
756
+ return {
757
+ ...empty,
758
+ status: 'action-required',
759
+ statusReason: {
760
+ code: 'source_amount_not_supported',
761
+ message: 'The source amount is smaller than one destination-token base unit.',
762
+ },
763
+ }
764
+ const deficit = options.required > options.delivered ? options.required - options.delivered : 0n
765
+ const subsidyAmount =
766
+ options.deposit.subsidyAmount ??
767
+ Value.tokenAmount({
768
+ baseUnits: deficit,
769
+ currency: options.address.snapshot.destinationToken.currency,
770
+ decimals: options.address.snapshot.destinationToken.decimals,
771
+ })
772
+ if (options.deposit.settlementTransaction && options.deposit.settlementTransactionHash) {
773
+ if (!options.subsidies)
774
+ return {
775
+ ...empty,
776
+ outcome: 'unavailable',
777
+ status: 'action-required',
778
+ statusReason: {
779
+ code: 'subsidy_failed',
780
+ message: 'Tempo subsidy settlement is unavailable.',
781
+ },
782
+ subsidyAmount,
783
+ }
784
+ const hash = options.deposit.settlementTransactionHash as Hex.Hex
785
+ const status = await options.subsidies.status({ hash })
786
+ if (status.type === 'reverted')
787
+ return {
788
+ ...empty,
789
+ outcome: 'reverted',
790
+ status: 'action-required',
791
+ statusReason: {
792
+ code: 'subsidy_failed',
793
+ message: 'Tempo could not deliver the required subsidy.',
794
+ },
795
+ subsidyAmount,
796
+ tempoGasPaid: status.tempoGasPaid,
797
+ }
798
+ if (status.type === 'pending')
799
+ return {
800
+ ...empty,
801
+ broadcast: {
802
+ hash,
803
+ transaction: options.deposit.settlementTransaction as Hex.Hex,
804
+ },
805
+ outcome: 'pending',
806
+ status: 'settling',
807
+ subsidyAmount,
808
+ }
809
+
810
+ const transfers = await options.verifyTransfers({
811
+ chain: options.address.snapshot.destinationChain,
812
+ recipient: options.address.recipient,
813
+ token: options.address.snapshot.destinationToken,
814
+ transactionHash: hash,
815
+ })
816
+ const delivered = transfers.reduce((total, transfer) => total + BigInt(transfer.amount), 0n)
817
+ return {
818
+ delivered,
819
+ destinationTransactionHashes: transfers.map((transfer) => transfer.transactionHash),
820
+ outcome: options.delivered + delivered >= options.required ? 'completed' : 'underfilled',
821
+ status: options.delivered + delivered >= options.required ? 'completed' : 'settling',
822
+ subsidyAmount,
823
+ tempoGasPaid: status.tempoGasPaid,
824
+ }
825
+ }
826
+
827
+ if (options.delivered >= options.required) return { ...empty, status: 'completed' }
828
+ if (!options.address.snapshot.subsidize) {
829
+ if (!options.providerEvidenceComplete) return { ...empty, status: 'bridging' }
830
+ if (options.delivered > 0n) return { ...empty, status: 'completed' }
831
+ return {
832
+ ...empty,
833
+ status: 'action-required',
834
+ statusReason: {
835
+ code: 'delivery_failed',
836
+ message: 'The provider completed without delivering destination funds.',
837
+ },
838
+ }
839
+ }
840
+ if (!options.providerEvidenceComplete) return { ...empty, status: 'bridging' }
841
+ if (!options.subsidies)
842
+ return {
843
+ ...empty,
844
+ outcome: 'unavailable',
845
+ status: 'action-required',
846
+ statusReason: {
847
+ code: 'subsidy_failed',
848
+ message: 'Tempo subsidy settlement is unavailable.',
849
+ },
850
+ }
851
+ if (
852
+ !Subsidy.supports(options.subsidies.policy, {
853
+ amount: options.sourceAmount.toString(),
854
+ destinationToken: options.address.snapshot.destinationToken,
855
+ sourceToken: options.address.snapshot.sourceToken,
856
+ })
857
+ )
858
+ return {
859
+ ...empty,
860
+ outcome: 'unsupported',
861
+ status: 'action-required',
862
+ statusReason: {
863
+ code: 'source_amount_not_supported',
864
+ message: 'The source amount is outside the subsidized deposit limit.',
865
+ },
866
+ }
867
+
868
+ const prepared = await options.subsidies
869
+ .prepare({
870
+ amount: deficit,
871
+ depositId: options.deposit.id,
872
+ recipient: options.address.recipient as Hex.Hex,
873
+ token: options.address.snapshot.destinationToken.address as Hex.Hex,
874
+ })
875
+ .catch((cause) => {
876
+ if (cause instanceof Subsidy.BalanceUnavailableError) return undefined
877
+ if (cause instanceof Subsidy.LiquidityUnavailableError) return null
878
+ throw cause
879
+ })
880
+ if (prepared === null)
881
+ return {
882
+ ...empty,
883
+ outcome: 'liquidity_unavailable',
884
+ status: 'settling',
885
+ subsidyAmount,
886
+ }
887
+ if (!prepared)
888
+ return {
889
+ ...empty,
890
+ outcome: 'balance_unavailable',
891
+ status: 'action-required',
892
+ statusReason: {
893
+ code: 'subsidy_balance_unavailable',
894
+ message: 'Tempo lacks enough pathUSD for the required subsidy.',
895
+ },
896
+ subsidyAmount,
897
+ }
898
+ return {
899
+ ...empty,
900
+ broadcast: prepared,
901
+ outcome: 'prepared',
902
+ settlementTransaction: prepared.transaction,
903
+ settlementTransactionHash: prepared.hash,
904
+ status: 'settling',
905
+ subsidyAmount,
906
+ }
907
+ }
908
+
909
+ function destinationBaseUnits(amount: bigint, sourceDecimals: number, destinationDecimals: number) {
910
+ if (destinationDecimals >= sourceDecimals)
911
+ return amount * 10n ** BigInt(destinationDecimals - sourceDecimals)
912
+ const divisor = 10n ** BigInt(sourceDecimals - destinationDecimals)
913
+ // Destination tokens cannot represent finer source precision, so retain only
914
+ // the amount expressible in destination base units.
915
+ return amount / divisor
916
+ }
917
+
918
+ function unique(values: readonly string[]) {
919
+ return [...new Set(values)]
920
+ }
921
+
922
+ /** Provider pagination exceeded the bounded reconciliation limit. */
923
+ export class PaginationLimitError extends Error {
924
+ override name = 'Funding.Reconciliation.PaginationLimitError'
925
+ }
926
+
927
+ /** The reconciliation lease was claimed by another worker. */
928
+ export class StaleLeaseError extends Error {
929
+ override name = 'Funding.Reconciliation.StaleLeaseError'
930
+ }