tapimo 0.7.1 → 0.8.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 (786) hide show
  1. package/README.md +10 -7
  2. package/dist/ApiKey.d.ts +3 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +10 -0
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +29 -8
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +24 -5
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +20680 -15487
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +250 -129
  13. package/dist/App.js.map +1 -1
  14. package/dist/Assets.d.ts +10 -0
  15. package/dist/Assets.d.ts.map +1 -1
  16. package/dist/Assets.js +17 -4
  17. package/dist/Assets.js.map +1 -1
  18. package/dist/Scope.d.ts +19 -8
  19. package/dist/Scope.d.ts.map +1 -1
  20. package/dist/Scope.js +25 -9
  21. package/dist/Scope.js.map +1 -1
  22. package/dist/Webhooks.d.ts +1 -1
  23. package/dist/admin/App.d.ts +667 -76
  24. package/dist/admin/App.d.ts.map +1 -1
  25. package/dist/admin/App.js +12 -2
  26. package/dist/admin/App.js.map +1 -1
  27. package/dist/admin/apps/api-keys.d.ts +107 -11
  28. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  29. package/dist/admin/apps/api-keys.js +145 -32
  30. package/dist/admin/apps/api-keys.js.map +1 -1
  31. package/dist/admin/apps/earn-vaults.d.ts +1069 -0
  32. package/dist/admin/apps/earn-vaults.d.ts.map +1 -0
  33. package/dist/admin/apps/earn-vaults.js +409 -0
  34. package/dist/admin/apps/earn-vaults.js.map +1 -0
  35. package/dist/admin/apps/organizations.d.ts +2 -0
  36. package/dist/admin/apps/organizations.d.ts.map +1 -1
  37. package/dist/admin/apps/verified-tokens.d.ts +74 -74
  38. package/dist/admin/ui.generated.d.ts +1 -1
  39. package/dist/admin/ui.generated.d.ts.map +1 -1
  40. package/dist/admin/ui.generated.js +99 -43
  41. package/dist/admin/ui.generated.js.map +1 -1
  42. package/dist/analytics/Analytics.d.ts +4 -0
  43. package/dist/analytics/Analytics.d.ts.map +1 -1
  44. package/dist/analytics/Analytics.js +21 -2
  45. package/dist/analytics/Analytics.js.map +1 -1
  46. package/dist/analytics/tables/requestEvents.d.ts +22 -1
  47. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  48. package/dist/analytics/tables/requestEvents.js +59 -39
  49. package/dist/analytics/tables/requestEvents.js.map +1 -1
  50. package/dist/apps/Zones.d.ts +8335 -0
  51. package/dist/apps/Zones.d.ts.map +1 -0
  52. package/dist/apps/Zones.js +38 -0
  53. package/dist/apps/Zones.js.map +1 -0
  54. package/dist/apps/data/App.d.ts +5666 -3934
  55. package/dist/apps/data/App.d.ts.map +1 -1
  56. package/dist/apps/data/App.js +90 -22
  57. package/dist/apps/data/App.js.map +1 -1
  58. package/dist/apps/data/FxOracle.d.ts +1 -1
  59. package/dist/apps/data/FxOracle.d.ts.map +1 -1
  60. package/dist/apps/data/index.d.ts +0 -1
  61. package/dist/apps/data/index.d.ts.map +1 -1
  62. package/dist/apps/data/index.js +0 -1
  63. package/dist/apps/data/index.js.map +1 -1
  64. package/dist/apps/data/routes/activities.d.ts +56 -56
  65. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  66. package/dist/apps/data/routes/activities.js +130 -65
  67. package/dist/apps/data/routes/activities.js.map +1 -1
  68. package/dist/apps/data/routes/addresses.d.ts +65 -65
  69. package/dist/apps/data/routes/balances.d.ts +14 -14
  70. package/dist/apps/data/routes/balances.js +5 -5
  71. package/dist/apps/data/routes/balances.js.map +1 -1
  72. package/dist/apps/data/routes/blocks.d.ts +39 -39
  73. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  74. package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
  75. package/dist/apps/data/routes/coingecko.js +62 -35
  76. package/dist/apps/data/routes/coingecko.js.map +1 -1
  77. package/dist/apps/data/routes/earn.d.ts +2574 -0
  78. package/dist/apps/data/routes/earn.d.ts.map +1 -0
  79. package/dist/apps/data/routes/earn.js +1574 -0
  80. package/dist/apps/data/routes/earn.js.map +1 -0
  81. package/dist/apps/data/routes/exchanges.d.ts +1626 -719
  82. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  83. package/dist/apps/data/routes/exchanges.js +656 -193
  84. package/dist/apps/data/routes/exchanges.js.map +1 -1
  85. package/dist/apps/data/routes/fee-amm.d.ts +108 -108
  86. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  87. package/dist/apps/data/routes/fee-amm.js +59 -8
  88. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  89. package/dist/apps/data/routes/indexer.d.ts +35 -35
  90. package/dist/apps/data/routes/indexer.d.ts.map +1 -1
  91. package/dist/apps/data/routes/indexer.js +23 -3
  92. package/dist/apps/data/routes/indexer.js.map +1 -1
  93. package/dist/apps/data/routes/receipts.d.ts +33 -33
  94. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  95. package/dist/apps/data/routes/receipts.js +11 -11
  96. package/dist/apps/data/routes/receipts.js.map +1 -1
  97. package/dist/apps/data/routes/rpc.d.ts +6 -6
  98. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  99. package/dist/apps/data/routes/rpc.js +214 -22
  100. package/dist/apps/data/routes/rpc.js.map +1 -1
  101. package/dist/apps/data/routes/tokenlist.d.ts +1 -1
  102. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  103. package/dist/apps/data/routes/tokenlist.js +39 -8
  104. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  105. package/dist/apps/data/routes/tokens.d.ts +115 -87
  106. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  107. package/dist/apps/data/routes/tokens.js +194 -91
  108. package/dist/apps/data/routes/tokens.js.map +1 -1
  109. package/dist/apps/data/routes/transactions.d.ts +54 -54
  110. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  111. package/dist/apps/data/routes/transactions.js +78 -39
  112. package/dist/apps/data/routes/transactions.js.map +1 -1
  113. package/dist/apps/data/routes/transfers.d.ts +76 -27
  114. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  115. package/dist/apps/data/routes/transfers.js +165 -67
  116. package/dist/apps/data/routes/transfers.js.map +1 -1
  117. package/dist/apps/data/routes/valuation.d.ts +42 -42
  118. package/dist/apps/data/routes/valuation.js +2 -2
  119. package/dist/apps/data/routes/valuation.js.map +1 -1
  120. package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
  121. package/dist/apps/data/routes/webhooks.d.ts +370 -368
  122. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  123. package/dist/apps/data/routes/webhooks.js +161 -59
  124. package/dist/apps/data/routes/webhooks.js.map +1 -1
  125. package/dist/apps/data/routes/zones.d.ts +281 -0
  126. package/dist/apps/data/routes/zones.d.ts.map +1 -0
  127. package/dist/apps/data/routes/zones.js +252 -0
  128. package/dist/apps/data/routes/zones.js.map +1 -0
  129. package/dist/apps/docs/reference.js +6 -5
  130. package/dist/apps/docs/reference.js.map +1 -1
  131. package/dist/apps/funding/Access.d.ts +16 -0
  132. package/dist/apps/funding/Access.d.ts.map +1 -0
  133. package/dist/apps/funding/Access.js +22 -0
  134. package/dist/apps/funding/Access.js.map +1 -0
  135. package/dist/apps/funding/App.d.ts +3183 -0
  136. package/dist/apps/funding/App.d.ts.map +1 -0
  137. package/dist/apps/funding/App.js +46 -0
  138. package/dist/apps/funding/App.js.map +1 -0
  139. package/dist/apps/funding/Inventory.d.ts +5 -0
  140. package/dist/apps/funding/Inventory.d.ts.map +1 -0
  141. package/dist/apps/funding/Inventory.js +25 -0
  142. package/dist/apps/funding/Inventory.js.map +1 -0
  143. package/dist/apps/funding/ProviderAttempts.d.ts +5 -0
  144. package/dist/apps/funding/ProviderAttempts.d.ts.map +1 -0
  145. package/dist/apps/funding/ProviderAttempts.js +24 -0
  146. package/dist/apps/funding/ProviderAttempts.js.map +1 -0
  147. package/dist/apps/funding/index.d.ts +2 -0
  148. package/dist/apps/funding/index.d.ts.map +1 -0
  149. package/dist/apps/funding/index.js +2 -0
  150. package/dist/apps/funding/index.js.map +1 -0
  151. package/dist/apps/funding/routes/chains.d.ts +169 -0
  152. package/dist/apps/funding/routes/chains.d.ts.map +1 -0
  153. package/dist/apps/funding/routes/chains.js +80 -0
  154. package/dist/apps/funding/routes/chains.js.map +1 -0
  155. package/dist/apps/funding/routes/deposit-addresses.d.ts +2388 -0
  156. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -0
  157. package/dist/apps/funding/routes/deposit-addresses.js +860 -0
  158. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -0
  159. package/dist/apps/funding/routes/providers.d.ts +91 -0
  160. package/dist/apps/funding/routes/providers.d.ts.map +1 -0
  161. package/dist/apps/funding/routes/providers.js +56 -0
  162. package/dist/apps/funding/routes/providers.js.map +1 -0
  163. package/dist/apps/{data/routes/funding.d.ts → funding/routes/quotes.d.ts} +26 -396
  164. package/dist/apps/funding/routes/quotes.d.ts.map +1 -0
  165. package/dist/apps/funding/routes/quotes.js +188 -0
  166. package/dist/apps/funding/routes/quotes.js.map +1 -0
  167. package/dist/apps/funding/routes/transfers.d.ts +1999 -0
  168. package/dist/apps/funding/routes/transfers.d.ts.map +1 -0
  169. package/dist/apps/funding/routes/transfers.js +614 -0
  170. package/dist/apps/funding/routes/transfers.js.map +1 -0
  171. package/dist/apps/index.d.ts +3 -1
  172. package/dist/apps/index.d.ts.map +1 -1
  173. package/dist/apps/index.js +3 -1
  174. package/dist/apps/index.js.map +1 -1
  175. package/dist/apps/management/App.d.ts +839 -574
  176. package/dist/apps/management/App.d.ts.map +1 -1
  177. package/dist/apps/management/Billing.d.ts +8 -0
  178. package/dist/apps/management/Billing.d.ts.map +1 -1
  179. package/dist/apps/management/Billing.js +12 -0
  180. package/dist/apps/management/Billing.js.map +1 -1
  181. package/dist/apps/management/Error.d.ts +12 -0
  182. package/dist/apps/management/Error.d.ts.map +1 -0
  183. package/dist/apps/management/Error.js +10 -0
  184. package/dist/apps/management/Error.js.map +1 -0
  185. package/dist/apps/management/routes/api-keys.d.ts +296 -19
  186. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  187. package/dist/apps/management/routes/api-keys.js +77 -9
  188. package/dist/apps/management/routes/api-keys.js.map +1 -1
  189. package/dist/apps/management/routes/billing.d.ts +119 -119
  190. package/dist/apps/management/routes/faucet.d.ts +35 -35
  191. package/dist/apps/management/routes/invitations.d.ts +17 -17
  192. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  193. package/dist/apps/management/routes/invitations.js +4 -10
  194. package/dist/apps/management/routes/invitations.js.map +1 -1
  195. package/dist/apps/management/routes/invite-links.d.ts +38 -38
  196. package/dist/apps/management/routes/me.d.ts +6 -6
  197. package/dist/apps/management/routes/members.d.ts +69 -69
  198. package/dist/apps/management/routes/orgs.d.ts +16 -16
  199. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  200. package/dist/apps/management/routes/orgs.js +2 -8
  201. package/dist/apps/management/routes/orgs.js.map +1 -1
  202. package/dist/apps/management/routes/projects.d.ts +19 -19
  203. package/dist/apps/management/routes/scopes.d.ts +1 -1
  204. package/dist/apps/management/routes/scopes.js +2 -2
  205. package/dist/apps/management/routes/scopes.js.map +1 -1
  206. package/dist/apps/management/routes/usage.d.ts +72 -72
  207. package/dist/apps/management/routes/verified-token-requests.d.ts +18 -18
  208. package/dist/apps/management/routes/webhooks.d.ts +122 -122
  209. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  210. package/dist/apps/management/routes/webhooks.js +15 -3
  211. package/dist/apps/management/routes/webhooks.js.map +1 -1
  212. package/dist/apps/mcp.d.ts +2 -3
  213. package/dist/apps/mcp.d.ts.map +1 -1
  214. package/dist/apps/mcp.js +16 -14
  215. package/dist/apps/mcp.js.map +1 -1
  216. package/dist/apps/metadata.d.ts +4 -0
  217. package/dist/apps/metadata.d.ts.map +1 -1
  218. package/dist/apps/metadata.js +10 -0
  219. package/dist/apps/metadata.js.map +1 -1
  220. package/dist/apps/mpp/App.d.ts +57 -58
  221. package/dist/apps/mpp/App.d.ts.map +1 -1
  222. package/dist/apps/mpp/App.js +192 -27
  223. package/dist/apps/mpp/App.js.map +1 -1
  224. package/dist/apps/mpp/Mpp.d.ts +0 -20
  225. package/dist/apps/mpp/Mpp.d.ts.map +1 -1
  226. package/dist/apps/mpp/Mpp.js +0 -24
  227. package/dist/apps/mpp/Mpp.js.map +1 -1
  228. package/dist/apps/mpp/internal/Adapter.d.ts +40 -0
  229. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -0
  230. package/dist/apps/mpp/internal/Adapter.js +66 -0
  231. package/dist/apps/mpp/internal/Adapter.js.map +1 -0
  232. package/dist/apps/mpp/internal/Error.d.ts +4 -0
  233. package/dist/apps/mpp/internal/Error.d.ts.map +1 -0
  234. package/dist/apps/mpp/internal/Error.js +41 -0
  235. package/dist/apps/mpp/internal/Error.js.map +1 -0
  236. package/dist/apps/mpp/internal/Idempotency.d.ts +33 -0
  237. package/dist/apps/mpp/internal/Idempotency.d.ts.map +1 -0
  238. package/dist/apps/mpp/internal/Idempotency.js +28 -0
  239. package/dist/apps/mpp/internal/Idempotency.js.map +1 -0
  240. package/dist/apps/mpp/internal/Policy.d.ts +46 -0
  241. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -0
  242. package/dist/apps/mpp/internal/Policy.js +57 -0
  243. package/dist/apps/mpp/internal/Policy.js.map +1 -0
  244. package/dist/apps/mpp/internal/ScreenManager.d.ts +27 -0
  245. package/dist/apps/mpp/internal/ScreenManager.d.ts.map +1 -0
  246. package/dist/apps/mpp/internal/ScreenManager.js +18 -0
  247. package/dist/apps/mpp/internal/ScreenManager.js.map +1 -0
  248. package/dist/apps/mpp/internal/Screening.d.ts +35 -0
  249. package/dist/apps/mpp/internal/Screening.d.ts.map +1 -0
  250. package/dist/apps/mpp/internal/Screening.js +20 -0
  251. package/dist/apps/mpp/internal/Screening.js.map +1 -0
  252. package/dist/apps/mpp/internal/Sponsorship.d.ts +36 -0
  253. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -0
  254. package/dist/apps/mpp/internal/Sponsorship.js +103 -0
  255. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -0
  256. package/dist/apps/mpp/internal/Utils.d.ts +7 -0
  257. package/dist/apps/mpp/internal/Utils.d.ts.map +1 -0
  258. package/dist/apps/mpp/internal/Utils.js +24 -0
  259. package/dist/apps/mpp/internal/Utils.js.map +1 -0
  260. package/dist/apps/relay/App.js +183 -23
  261. package/dist/apps/relay/App.js.map +1 -1
  262. package/dist/apps/relay/Sponsorships.d.ts +4 -0
  263. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  264. package/dist/apps/relay/Sponsorships.js +15 -6
  265. package/dist/apps/relay/Sponsorships.js.map +1 -1
  266. package/dist/cloudflare.d.ts +50 -0
  267. package/dist/cloudflare.d.ts.map +1 -1
  268. package/dist/cloudflare.js +178 -0
  269. package/dist/cloudflare.js.map +1 -1
  270. package/dist/db/Db.d.ts +22 -0
  271. package/dist/db/Db.d.ts.map +1 -1
  272. package/dist/db/Db.js +379 -0
  273. package/dist/db/Db.js.map +1 -1
  274. package/dist/db/Schema.d.ts +933 -1
  275. package/dist/db/Schema.d.ts.map +1 -1
  276. package/dist/db/Schema.js +289 -1
  277. package/dist/db/Schema.js.map +1 -1
  278. package/dist/db/tables/earnVaults.d.ts +68 -0
  279. package/dist/db/tables/earnVaults.d.ts.map +1 -0
  280. package/dist/db/tables/earnVaults.js +72 -0
  281. package/dist/db/tables/earnVaults.js.map +1 -0
  282. package/dist/db/tables/fundingCatalog.d.ts +56 -0
  283. package/dist/db/tables/fundingCatalog.d.ts.map +1 -0
  284. package/dist/db/tables/fundingCatalog.js +85 -0
  285. package/dist/db/tables/fundingCatalog.js.map +1 -0
  286. package/dist/db/tables/fundingDepositAddresses.d.ts +172 -0
  287. package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -0
  288. package/dist/db/tables/fundingDepositAddresses.js +218 -0
  289. package/dist/db/tables/fundingDepositAddresses.js.map +1 -0
  290. package/dist/db/tables/fundingDepositRequestObservations.d.ts +45 -0
  291. package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +1 -0
  292. package/dist/db/tables/fundingDepositRequestObservations.js +46 -0
  293. package/dist/db/tables/fundingDepositRequestObservations.js.map +1 -0
  294. package/dist/db/tables/fundingDeposits.d.ts +171 -0
  295. package/dist/db/tables/fundingDeposits.d.ts.map +1 -0
  296. package/dist/db/tables/fundingDeposits.js +182 -0
  297. package/dist/db/tables/fundingDeposits.js.map +1 -0
  298. package/dist/db/tables/fundingIdempotency.d.ts +91 -0
  299. package/dist/db/tables/fundingIdempotency.d.ts.map +1 -0
  300. package/dist/db/tables/fundingIdempotency.js +103 -0
  301. package/dist/db/tables/fundingIdempotency.js.map +1 -0
  302. package/dist/db/tables/fundingTransferEvents.d.ts +12 -0
  303. package/dist/db/tables/fundingTransferEvents.d.ts.map +1 -0
  304. package/dist/db/tables/fundingTransferEvents.js +18 -0
  305. package/dist/db/tables/fundingTransferEvents.js.map +1 -0
  306. package/dist/db/tables/fundingTransferTransactions.d.ts +15 -0
  307. package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -0
  308. package/dist/db/tables/fundingTransferTransactions.js +27 -0
  309. package/dist/db/tables/fundingTransferTransactions.js.map +1 -0
  310. package/dist/db/tables/fundingTransfers.d.ts +82 -0
  311. package/dist/db/tables/fundingTransfers.d.ts.map +1 -0
  312. package/dist/db/tables/fundingTransfers.js +89 -0
  313. package/dist/db/tables/fundingTransfers.js.map +1 -0
  314. package/dist/db/tables/organizations.d.ts +8 -0
  315. package/dist/db/tables/organizations.d.ts.map +1 -1
  316. package/dist/db/tables/organizations.js +16 -0
  317. package/dist/db/tables/organizations.js.map +1 -1
  318. package/dist/db/tables/projects.d.ts +8 -0
  319. package/dist/db/tables/projects.d.ts.map +1 -1
  320. package/dist/db/tables/projects.js +16 -0
  321. package/dist/db/tables/projects.js.map +1 -1
  322. package/dist/db/tables/requestUsage.d.ts +13 -0
  323. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  324. package/dist/db/tables/requestUsage.js +16 -0
  325. package/dist/db/tables/requestUsage.js.map +1 -1
  326. package/dist/db/tables/sponsoredTransactions.d.ts +2 -2
  327. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  328. package/dist/db/tables/sponsoredTransactions.js +1 -1
  329. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  330. package/dist/db/tables/users.d.ts +8 -0
  331. package/dist/db/tables/users.d.ts.map +1 -1
  332. package/dist/db/tables/users.js +16 -0
  333. package/dist/db/tables/users.js.map +1 -1
  334. package/dist/db/tables/verifiedTokens.d.ts +14 -7
  335. package/dist/db/tables/verifiedTokens.d.ts.map +1 -1
  336. package/dist/db/tables/verifiedTokens.js +9 -7
  337. package/dist/db/tables/verifiedTokens.js.map +1 -1
  338. package/dist/db/tables/webhookSubscriptions.d.ts +31 -1
  339. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  340. package/dist/db/tables/webhookSubscriptions.js +24 -3
  341. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  342. package/dist/handlers/relay.js +108 -108
  343. package/dist/handlers/relay.js.map +1 -1
  344. package/dist/internal/Auth.d.ts +37 -11
  345. package/dist/internal/Auth.d.ts.map +1 -1
  346. package/dist/internal/Auth.js +75 -16
  347. package/dist/internal/Auth.js.map +1 -1
  348. package/dist/internal/Cache.d.ts.map +1 -1
  349. package/dist/internal/Cache.js +17 -11
  350. package/dist/internal/Cache.js.map +1 -1
  351. package/dist/internal/Cursor.js +1 -1
  352. package/dist/internal/Cursor.js.map +1 -1
  353. package/dist/internal/EarnRates.d.ts +89 -0
  354. package/dist/internal/EarnRates.d.ts.map +1 -0
  355. package/dist/internal/EarnRates.js +266 -0
  356. package/dist/internal/EarnRates.js.map +1 -0
  357. package/dist/internal/EarnVaults.d.ts +171 -0
  358. package/dist/internal/EarnVaults.d.ts.map +1 -0
  359. package/dist/internal/EarnVaults.js +547 -0
  360. package/dist/internal/EarnVaults.js.map +1 -0
  361. package/dist/internal/EdgeCache.d.ts +10 -3
  362. package/dist/internal/EdgeCache.d.ts.map +1 -1
  363. package/dist/internal/EdgeCache.js +43 -11
  364. package/dist/internal/EdgeCache.js.map +1 -1
  365. package/dist/internal/Id.d.ts +11 -0
  366. package/dist/internal/Id.d.ts.map +1 -1
  367. package/dist/internal/Id.js +13 -0
  368. package/dist/internal/Id.js.map +1 -1
  369. package/dist/internal/Idempotency.d.ts +83 -0
  370. package/dist/internal/Idempotency.d.ts.map +1 -0
  371. package/dist/internal/Idempotency.js +113 -0
  372. package/dist/internal/Idempotency.js.map +1 -0
  373. package/dist/internal/IpAllowlist.d.ts +15 -0
  374. package/dist/internal/IpAllowlist.d.ts.map +1 -0
  375. package/dist/internal/IpAllowlist.js +27 -0
  376. package/dist/internal/IpAllowlist.js.map +1 -0
  377. package/dist/internal/Log.d.ts +64 -9
  378. package/dist/internal/Log.d.ts.map +1 -1
  379. package/dist/internal/Log.js +29 -7
  380. package/dist/internal/Log.js.map +1 -1
  381. package/dist/internal/MetricSink.d.ts.map +1 -1
  382. package/dist/internal/MetricSink.js +47 -1
  383. package/dist/internal/MetricSink.js.map +1 -1
  384. package/dist/internal/OpenApi.d.ts +2 -2
  385. package/dist/internal/OpenApi.d.ts.map +1 -1
  386. package/dist/internal/OpenApi.js +4 -1
  387. package/dist/internal/OpenApi.js.map +1 -1
  388. package/dist/internal/Provider.d.ts +14 -0
  389. package/dist/internal/Provider.d.ts.map +1 -0
  390. package/dist/internal/Provider.js +5 -0
  391. package/dist/internal/Provider.js.map +1 -0
  392. package/dist/internal/Schema.d.ts +6 -1
  393. package/dist/internal/Schema.d.ts.map +1 -1
  394. package/dist/internal/Schema.js +20 -11
  395. package/dist/internal/Schema.js.map +1 -1
  396. package/dist/internal/Store.d.ts +6 -0
  397. package/dist/internal/Store.d.ts.map +1 -1
  398. package/dist/internal/Store.js +35 -0
  399. package/dist/internal/Store.js.map +1 -1
  400. package/dist/internal/Tidx.d.ts +49 -24
  401. package/dist/internal/Tidx.d.ts.map +1 -1
  402. package/dist/internal/Tidx.js +90 -12
  403. package/dist/internal/Tidx.js.map +1 -1
  404. package/dist/internal/Viem.d.ts +90 -65
  405. package/dist/internal/Viem.d.ts.map +1 -1
  406. package/dist/internal/Viem.js +90 -12
  407. package/dist/internal/Viem.js.map +1 -1
  408. package/dist/internal/WebhookDestination.d.ts.map +1 -1
  409. package/dist/internal/WebhookDestination.js +34 -28
  410. package/dist/internal/WebhookDestination.js.map +1 -1
  411. package/dist/internal/Webhooks.d.ts +9 -0
  412. package/dist/internal/Webhooks.d.ts.map +1 -1
  413. package/dist/internal/Webhooks.js +15 -10
  414. package/dist/internal/Webhooks.js.map +1 -1
  415. package/dist/internal/exchange/Provider.d.ts +219 -0
  416. package/dist/internal/exchange/Provider.d.ts.map +1 -0
  417. package/dist/internal/exchange/Provider.js +117 -0
  418. package/dist/internal/exchange/Provider.js.map +1 -0
  419. package/dist/internal/exchange/index.d.ts +2 -0
  420. package/dist/internal/exchange/index.d.ts.map +1 -0
  421. package/dist/internal/exchange/index.js +2 -0
  422. package/dist/internal/exchange/index.js.map +1 -0
  423. package/dist/internal/exchange/providers/uniswap.d.ts +57 -0
  424. package/dist/internal/exchange/providers/uniswap.d.ts.map +1 -0
  425. package/dist/internal/exchange/providers/uniswap.js +553 -0
  426. package/dist/internal/exchange/providers/uniswap.js.map +1 -0
  427. package/dist/internal/funding/Action.d.ts +55 -0
  428. package/dist/internal/funding/Action.d.ts.map +1 -0
  429. package/dist/internal/funding/Action.js +74 -0
  430. package/dist/internal/funding/Action.js.map +1 -0
  431. package/dist/internal/funding/Catalog.d.ts +107 -0
  432. package/dist/internal/funding/Catalog.d.ts.map +1 -0
  433. package/dist/internal/funding/Catalog.js +270 -0
  434. package/dist/internal/funding/Catalog.js.map +1 -0
  435. package/dist/internal/funding/Chain.d.ts +76 -0
  436. package/dist/internal/funding/Chain.d.ts.map +1 -0
  437. package/dist/internal/funding/Chain.js +38 -0
  438. package/dist/internal/funding/Chain.js.map +1 -0
  439. package/dist/internal/funding/Deposit.d.ts +408 -0
  440. package/dist/internal/funding/Deposit.d.ts.map +1 -0
  441. package/dist/internal/funding/Deposit.js +318 -0
  442. package/dist/internal/funding/Deposit.js.map +1 -0
  443. package/dist/internal/funding/DepositAddress.d.ts +345 -0
  444. package/dist/internal/funding/DepositAddress.d.ts.map +1 -0
  445. package/dist/internal/funding/DepositAddress.js +189 -0
  446. package/dist/internal/funding/DepositAddress.js.map +1 -0
  447. package/dist/internal/funding/Evidence.d.ts +48 -0
  448. package/dist/internal/funding/Evidence.d.ts.map +1 -0
  449. package/dist/internal/funding/Evidence.js +315 -0
  450. package/dist/internal/funding/Evidence.js.map +1 -0
  451. package/dist/internal/funding/Provider.d.ts +1288 -0
  452. package/dist/internal/funding/Provider.d.ts.map +1 -0
  453. package/dist/internal/funding/Provider.js +1086 -0
  454. package/dist/internal/funding/Provider.js.map +1 -0
  455. package/dist/internal/funding/Reconciliation.d.ts +127 -0
  456. package/dist/internal/funding/Reconciliation.d.ts.map +1 -0
  457. package/dist/internal/funding/Reconciliation.js +885 -0
  458. package/dist/internal/funding/Reconciliation.js.map +1 -0
  459. package/dist/internal/funding/Route.d.ts +21 -0
  460. package/dist/internal/funding/Route.d.ts.map +1 -0
  461. package/dist/internal/funding/Route.js +5 -0
  462. package/dist/internal/funding/Route.js.map +1 -0
  463. package/dist/internal/funding/SourceObservation.d.ts +108 -0
  464. package/dist/internal/funding/SourceObservation.d.ts.map +1 -0
  465. package/dist/internal/funding/SourceObservation.js +143 -0
  466. package/dist/internal/funding/SourceObservation.js.map +1 -0
  467. package/dist/internal/funding/Subsidy.d.ts +113 -0
  468. package/dist/internal/funding/Subsidy.d.ts.map +1 -0
  469. package/dist/internal/funding/Subsidy.js +138 -0
  470. package/dist/internal/funding/Subsidy.js.map +1 -0
  471. package/dist/internal/funding/Token.d.ts +41 -0
  472. package/dist/internal/funding/Token.d.ts.map +1 -0
  473. package/dist/internal/funding/Token.js +22 -0
  474. package/dist/internal/funding/Token.js.map +1 -0
  475. package/dist/internal/funding/Transfer.d.ts +643 -0
  476. package/dist/internal/funding/Transfer.d.ts.map +1 -0
  477. package/dist/internal/funding/Transfer.js +332 -0
  478. package/dist/internal/funding/Transfer.js.map +1 -0
  479. package/dist/internal/funding/index.d.ts +14 -0
  480. package/dist/internal/funding/index.d.ts.map +1 -0
  481. package/dist/internal/funding/index.js +14 -0
  482. package/dist/internal/funding/index.js.map +1 -0
  483. package/dist/internal/funding/providers/across.d.ts +21 -0
  484. package/dist/internal/funding/providers/across.d.ts.map +1 -0
  485. package/dist/internal/funding/providers/across.js +117 -0
  486. package/dist/internal/funding/providers/across.js.map +1 -0
  487. package/dist/internal/funding/providers/relay.d.ts +88 -0
  488. package/dist/internal/funding/providers/relay.d.ts.map +1 -0
  489. package/dist/internal/funding/providers/relay.js +871 -0
  490. package/dist/internal/funding/providers/relay.js.map +1 -0
  491. package/dist/internal/funding/providers/rhino.d.ts +15 -0
  492. package/dist/internal/funding/providers/rhino.d.ts.map +1 -0
  493. package/dist/internal/funding/providers/rhino.js +116 -0
  494. package/dist/internal/funding/providers/rhino.js.map +1 -0
  495. package/dist/internal/funding/providers/squid.d.ts +19 -0
  496. package/dist/internal/funding/providers/squid.d.ts.map +1 -0
  497. package/dist/internal/funding/providers/squid.js +120 -0
  498. package/dist/internal/funding/providers/squid.js.map +1 -0
  499. package/dist/internal/funding/providers/symbiosis.d.ts +20 -0
  500. package/dist/internal/funding/providers/symbiosis.d.ts.map +1 -0
  501. package/dist/internal/funding/providers/symbiosis.js +176 -0
  502. package/dist/internal/funding/providers/symbiosis.js.map +1 -0
  503. package/dist/internal/index.d.ts +5 -1
  504. package/dist/internal/index.d.ts.map +1 -1
  505. package/dist/internal/index.js +5 -1
  506. package/dist/internal/index.js.map +1 -1
  507. package/dist/internal/webhookDestinations/url.js +61 -57
  508. package/dist/internal/webhookDestinations/url.js.map +1 -1
  509. package/dist/providers/index.d.ts +43 -0
  510. package/dist/providers/index.d.ts.map +1 -0
  511. package/dist/providers/index.js +19 -0
  512. package/dist/providers/index.js.map +1 -0
  513. package/package.json +10 -5
  514. package/src/ApiKey.test.ts +35 -0
  515. package/src/ApiKey.ts +27 -0
  516. package/src/ApiKeys.test.ts +40 -7
  517. package/src/ApiKeys.ts +46 -10
  518. package/src/App.test.ts +108 -15
  519. package/src/App.ts +296 -138
  520. package/src/Assets.ts +29 -4
  521. package/src/Client.test-d.ts +809 -37
  522. package/src/Scope.test.ts +19 -0
  523. package/src/Scope.ts +28 -11
  524. package/src/Webhooks.test.ts +25 -0
  525. package/src/Webhooks.ts +1 -1
  526. package/src/admin/App.test.ts +9 -2
  527. package/src/admin/App.ts +32 -9
  528. package/src/admin/apps/api-keys.test.ts +190 -22
  529. package/src/admin/apps/api-keys.ts +170 -28
  530. package/src/admin/apps/earn-vaults.test.ts +338 -0
  531. package/src/admin/apps/earn-vaults.ts +572 -0
  532. package/src/admin/apps/scopes.test.ts +16 -1
  533. package/src/admin/ui/plugin.ts +2 -2
  534. package/src/admin/ui/src/components/EarnVaultForm.tsx +137 -0
  535. package/src/admin/ui/src/components/MobileProfile.tsx +2 -2
  536. package/src/admin/ui/src/components/Page.tsx +1 -1
  537. package/src/admin/ui/src/components/ThemeToggle.tsx +1 -1
  538. package/src/admin/ui/src/lib/api-keys.ts +37 -7
  539. package/src/admin/ui/src/lib/client.ts +1 -1
  540. package/src/admin/ui/src/lib/config.ts +1 -1
  541. package/src/admin/ui/src/lib/early-access.ts +8 -9
  542. package/src/admin/ui/src/lib/earn-vaults.ts +207 -0
  543. package/src/admin/ui/src/lib/format.ts +13 -0
  544. package/src/admin/ui/src/lib/organizations.test.ts +14 -4
  545. package/src/admin/ui/src/lib/organizations.ts +7 -1
  546. package/src/admin/ui/src/lib/response.ts +22 -0
  547. package/src/admin/ui/src/lib/scopes.test.ts +19 -11
  548. package/src/admin/ui/src/lib/scopes.ts +28 -7
  549. package/src/admin/ui/src/lib/verified-tokens.ts +10 -9
  550. package/src/admin/ui/src/routeTree.gen.ts +70 -7
  551. package/src/admin/ui/src/router.tsx +2 -2
  552. package/src/admin/ui/src/routes/__root.tsx +9 -8
  553. package/src/admin/ui/src/routes/api-keys.tsx +475 -64
  554. package/src/admin/ui/src/routes/early-access.tsx +5 -12
  555. package/src/admin/ui/src/routes/earn.vaults.tsx +348 -0
  556. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +154 -0
  557. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +190 -0
  558. package/src/admin/ui/src/routes/organizations.tsx +4 -7
  559. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +56 -54
  560. package/src/admin/ui/src/routes/verified-tokens.tsx +4 -4
  561. package/src/admin/ui/vite.config.ts +4 -1
  562. package/src/admin/ui.generated.ts +113 -43
  563. package/src/analytics/Analytics.test.ts +69 -10
  564. package/src/analytics/Analytics.ts +24 -1
  565. package/src/analytics/tables/requestEvents.ts +79 -37
  566. package/src/apps/Zones.test.ts +33 -0
  567. package/src/apps/Zones.ts +40 -0
  568. package/src/apps/composition.test.ts +184 -3
  569. package/src/apps/data/App.test.ts +28 -23
  570. package/src/apps/data/App.ts +95 -36
  571. package/src/apps/data/FxOracle.ts +1 -1
  572. package/src/apps/data/index.ts +0 -1
  573. package/src/apps/data/routes/activities.test.ts +82 -6
  574. package/src/apps/data/routes/activities.ts +131 -71
  575. package/src/apps/data/routes/balances.test.ts +50 -37
  576. package/src/apps/data/routes/balances.ts +5 -5
  577. package/src/apps/data/routes/blocks.test.ts +2 -0
  578. package/src/apps/data/routes/coingecko.test.ts +22 -0
  579. package/src/apps/data/routes/coingecko.ts +84 -48
  580. package/src/apps/data/routes/earn.test.ts +1391 -0
  581. package/src/apps/data/routes/earn.ts +2188 -0
  582. package/src/apps/data/routes/exchanges.test.ts +82 -33
  583. package/src/apps/data/routes/exchanges.ts +842 -227
  584. package/src/apps/data/routes/fee-amm.test.ts +4 -6
  585. package/src/apps/data/routes/fee-amm.ts +69 -12
  586. package/src/apps/data/routes/indexer.test.ts +43 -34
  587. package/src/apps/data/routes/indexer.ts +21 -3
  588. package/src/apps/data/routes/receipts.test.ts +5 -3
  589. package/src/apps/data/routes/receipts.ts +13 -11
  590. package/src/apps/data/routes/rpc.test.ts +446 -28
  591. package/src/apps/data/routes/rpc.ts +245 -25
  592. package/src/apps/data/routes/tokenlist.ts +72 -19
  593. package/src/apps/data/routes/tokens.test.ts +6 -8
  594. package/src/apps/data/routes/tokens.ts +258 -86
  595. package/src/apps/data/routes/transactions.test.ts +2 -0
  596. package/src/apps/data/routes/transactions.ts +77 -42
  597. package/src/apps/data/routes/transfers.test.ts +166 -4
  598. package/src/apps/data/routes/transfers.ts +216 -78
  599. package/src/apps/data/routes/valuation.test.ts +62 -9
  600. package/src/apps/data/routes/valuation.ts +2 -2
  601. package/src/apps/data/routes/webhooks.test.ts +386 -43
  602. package/src/apps/data/routes/webhooks.ts +172 -71
  603. package/src/apps/data/routes/zones.test.ts +473 -0
  604. package/src/apps/data/routes/zones.ts +338 -0
  605. package/src/apps/docs/reference.ts +8 -6
  606. package/src/apps/funding/Access.ts +26 -0
  607. package/src/apps/funding/App.test.ts +78 -0
  608. package/src/apps/funding/App.ts +63 -0
  609. package/src/apps/funding/Inventory.ts +30 -0
  610. package/src/apps/funding/ProviderAttempts.ts +26 -0
  611. package/src/apps/funding/index.ts +1 -0
  612. package/src/apps/funding/routes/chains.test.ts +78 -0
  613. package/src/apps/funding/routes/chains.ts +101 -0
  614. package/src/apps/funding/routes/deposit-addresses.test.ts +1628 -0
  615. package/src/apps/funding/routes/deposit-addresses.ts +1015 -0
  616. package/src/apps/funding/routes/providers.test.ts +165 -0
  617. package/src/apps/funding/routes/providers.ts +73 -0
  618. package/src/apps/funding/routes/quotes.test.ts +511 -0
  619. package/src/apps/funding/routes/quotes.ts +205 -0
  620. package/src/apps/funding/routes/transfers.test.ts +1255 -0
  621. package/src/apps/funding/routes/transfers.ts +704 -0
  622. package/src/apps/index.ts +3 -1
  623. package/src/apps/management/Billing.test.ts +29 -0
  624. package/src/apps/management/Billing.ts +23 -0
  625. package/src/apps/management/Error.ts +12 -0
  626. package/src/apps/management/routes/api-keys.test.ts +103 -3
  627. package/src/apps/management/routes/api-keys.ts +98 -10
  628. package/src/apps/management/routes/invitations.ts +4 -11
  629. package/src/apps/management/routes/orgs.ts +2 -9
  630. package/src/apps/management/routes/scopes.test.ts +7 -2
  631. package/src/apps/management/routes/scopes.ts +2 -2
  632. package/src/apps/management/routes/webhooks.test.ts +6 -1
  633. package/src/apps/management/routes/webhooks.ts +15 -3
  634. package/src/apps/mcp.test.ts +17 -2
  635. package/src/apps/mcp.ts +18 -13
  636. package/src/apps/metadata.ts +12 -0
  637. package/src/apps/mpp/App.ts +276 -29
  638. package/src/apps/mpp/Mpp.test.ts +631 -26
  639. package/src/apps/mpp/Mpp.ts +0 -42
  640. package/src/apps/mpp/internal/Adapter.ts +108 -3
  641. package/src/apps/mpp/internal/Error.test.ts +33 -0
  642. package/src/apps/mpp/internal/Error.ts +44 -6
  643. package/src/apps/mpp/internal/Idempotency.test.ts +213 -0
  644. package/src/apps/mpp/internal/Idempotency.ts +59 -5
  645. package/src/apps/mpp/internal/Policy.test.ts +128 -0
  646. package/src/apps/mpp/internal/Policy.ts +98 -0
  647. package/src/apps/mpp/internal/ScreenManager.test.ts +68 -0
  648. package/src/apps/mpp/internal/ScreenManager.ts +41 -0
  649. package/src/apps/mpp/internal/Screening.ts +40 -3
  650. package/src/apps/mpp/internal/Sponsorship.ts +144 -0
  651. package/src/apps/mpp/internal/Utils.ts +30 -0
  652. package/src/apps/relay/App.test.ts +493 -62
  653. package/src/apps/relay/App.ts +233 -23
  654. package/src/apps/relay/Sponsorships.test.ts +49 -0
  655. package/src/apps/relay/Sponsorships.ts +18 -6
  656. package/src/cloudflare.ts +279 -0
  657. package/src/db/Db.ts +501 -0
  658. package/src/db/Schema.ts +349 -2
  659. package/src/db/tables/earnVaults.test.ts +185 -0
  660. package/src/db/tables/earnVaults.ts +151 -0
  661. package/src/db/tables/fundingCatalog.test.ts +108 -0
  662. package/src/db/tables/fundingCatalog.ts +157 -0
  663. package/src/db/tables/fundingDepositAddresses.test.ts +580 -0
  664. package/src/db/tables/fundingDepositAddresses.ts +404 -0
  665. package/src/db/tables/fundingDepositRequestObservations.test.ts +106 -0
  666. package/src/db/tables/fundingDepositRequestObservations.ts +99 -0
  667. package/src/db/tables/fundingDeposits.test.ts +399 -0
  668. package/src/db/tables/fundingDeposits.ts +373 -0
  669. package/src/db/tables/fundingIdempotency.test.ts +182 -0
  670. package/src/db/tables/fundingIdempotency.ts +180 -0
  671. package/src/db/tables/fundingTransferEvents.ts +28 -0
  672. package/src/db/tables/fundingTransferTransactions.test.ts +69 -0
  673. package/src/db/tables/fundingTransferTransactions.ts +37 -0
  674. package/src/db/tables/fundingTransfers.test.ts +89 -0
  675. package/src/db/tables/fundingTransfers.ts +153 -0
  676. package/src/db/tables/organizations.ts +16 -0
  677. package/src/db/tables/projects.ts +16 -0
  678. package/src/db/tables/requestUsage.ts +23 -0
  679. package/src/db/tables/sponsoredTransactions.test.ts +11 -0
  680. package/src/db/tables/sponsoredTransactions.ts +3 -3
  681. package/src/db/tables/users.ts +16 -0
  682. package/src/db/tables/verifiedTokens.ts +19 -14
  683. package/src/db/tables/webhookSubscriptions.ts +58 -3
  684. package/src/handlers/relay.test.ts +2 -0
  685. package/src/handlers/relay.ts +95 -99
  686. package/src/internal/Auth.test.ts +225 -5
  687. package/src/internal/Auth.ts +109 -20
  688. package/src/internal/Cache.test.ts +37 -3
  689. package/src/internal/Cache.ts +14 -10
  690. package/src/internal/Cursor.test.ts +2 -2
  691. package/src/internal/Cursor.ts +1 -1
  692. package/src/internal/EarnRates.test.ts +125 -0
  693. package/src/internal/EarnRates.ts +409 -0
  694. package/src/internal/EarnVaults.test.ts +195 -0
  695. package/src/internal/EarnVaults.ts +876 -0
  696. package/src/internal/EdgeCache.test.ts +26 -7
  697. package/src/internal/EdgeCache.ts +48 -9
  698. package/src/internal/Id.ts +14 -0
  699. package/src/internal/Idempotency.test.ts +109 -0
  700. package/src/internal/Idempotency.ts +237 -0
  701. package/src/internal/IpAllowlist.test.ts +52 -0
  702. package/src/internal/IpAllowlist.ts +39 -0
  703. package/src/internal/Log.test-d.ts +41 -8
  704. package/src/internal/Log.test.ts +196 -9
  705. package/src/internal/Log.ts +124 -17
  706. package/src/internal/MetricSink.test.ts +244 -4
  707. package/src/internal/MetricSink.ts +51 -1
  708. package/src/internal/OpenApi.ts +4 -1
  709. package/src/internal/Provider.test.ts +17 -0
  710. package/src/internal/Provider.ts +17 -0
  711. package/src/internal/Schema.ts +27 -17
  712. package/src/internal/Store.test.ts +25 -0
  713. package/src/internal/Store.ts +46 -0
  714. package/src/internal/Tidx.local.test.ts +78 -3
  715. package/src/internal/Tidx.test.ts +240 -18
  716. package/src/internal/Tidx.ts +129 -33
  717. package/src/internal/VerifiedTokens.test.ts +15 -0
  718. package/src/internal/Viem.test.ts +198 -17
  719. package/src/internal/Viem.ts +127 -28
  720. package/src/internal/WebhookDestination.ts +25 -23
  721. package/src/internal/Webhooks.test.ts +59 -0
  722. package/src/internal/Webhooks.ts +34 -10
  723. package/src/internal/exchange/Provider.test.ts +216 -0
  724. package/src/internal/exchange/Provider.ts +326 -0
  725. package/src/internal/exchange/index.test.ts +6 -0
  726. package/src/internal/exchange/index.ts +1 -0
  727. package/src/internal/exchange/providers/uniswap.test.ts +122 -0
  728. package/src/internal/exchange/providers/uniswap.ts +682 -0
  729. package/src/internal/funding/Action.test.ts +138 -0
  730. package/src/internal/funding/Action.ts +117 -0
  731. package/src/internal/funding/Catalog.test.ts +311 -0
  732. package/src/internal/funding/Catalog.ts +347 -0
  733. package/src/internal/funding/Chain.test.ts +79 -0
  734. package/src/internal/funding/Chain.ts +120 -0
  735. package/src/internal/funding/Deposit.test.ts +26 -0
  736. package/src/internal/funding/Deposit.ts +522 -0
  737. package/src/internal/funding/DepositAddress.test.ts +18 -0
  738. package/src/internal/funding/DepositAddress.ts +312 -0
  739. package/src/internal/funding/Evidence.test.ts +297 -0
  740. package/src/internal/funding/Evidence.ts +425 -0
  741. package/src/internal/funding/Provider.test.ts +1328 -0
  742. package/src/internal/funding/Provider.ts +1911 -0
  743. package/src/internal/funding/Reconciliation.local.test.ts +511 -0
  744. package/src/internal/funding/Reconciliation.test.ts +3037 -0
  745. package/src/internal/funding/Reconciliation.ts +1202 -0
  746. package/src/internal/funding/Route.test.ts +66 -0
  747. package/src/internal/funding/Route.ts +29 -0
  748. package/src/internal/funding/SourceObservation.test.ts +301 -0
  749. package/src/internal/funding/SourceObservation.ts +267 -0
  750. package/src/internal/funding/Subsidy.local.test.ts +152 -0
  751. package/src/internal/funding/Subsidy.test.ts +75 -0
  752. package/src/internal/funding/Subsidy.ts +260 -0
  753. package/src/internal/funding/Token.test.ts +47 -0
  754. package/src/internal/funding/Token.ts +59 -0
  755. package/src/internal/funding/Transfer.test.ts +369 -0
  756. package/src/internal/funding/Transfer.ts +522 -0
  757. package/src/internal/funding/index.test.ts +21 -0
  758. package/src/internal/funding/index.ts +13 -0
  759. package/src/internal/funding/providers/across.ts +149 -0
  760. package/src/{apps/data/FundingQuoteProviders.test.ts → internal/funding/providers/index.test.ts} +178 -157
  761. package/src/internal/funding/providers/relay.test.ts +564 -0
  762. package/src/internal/funding/providers/relay.ts +1060 -0
  763. package/src/internal/funding/providers/rhino.ts +139 -0
  764. package/src/internal/funding/providers/squid.ts +151 -0
  765. package/src/internal/funding/providers/symbiosis.ts +221 -0
  766. package/src/internal/index.test.ts +5 -1
  767. package/src/internal/index.ts +5 -1
  768. package/src/internal/webhookDestinations/url.ts +49 -45
  769. package/src/providers/index.test.ts +14 -0
  770. package/src/providers/index.ts +54 -0
  771. package/dist/apps/data/FundingQuoteProviders.d.ts +0 -174
  772. package/dist/apps/data/FundingQuoteProviders.d.ts.map +0 -1
  773. package/dist/apps/data/FundingQuoteProviders.js +0 -775
  774. package/dist/apps/data/FundingQuoteProviders.js.map +0 -1
  775. package/dist/apps/data/routes/funding.d.ts.map +0 -1
  776. package/dist/apps/data/routes/funding.js +0 -410
  777. package/dist/apps/data/routes/funding.js.map +0 -1
  778. package/dist/internal/FundingQuotes.d.ts +0 -864
  779. package/dist/internal/FundingQuotes.d.ts.map +0 -1
  780. package/dist/internal/FundingQuotes.js +0 -672
  781. package/dist/internal/FundingQuotes.js.map +0 -1
  782. package/src/apps/data/FundingQuoteProviders.ts +0 -1043
  783. package/src/apps/data/routes/funding.test.ts +0 -503
  784. package/src/apps/data/routes/funding.ts +0 -604
  785. package/src/internal/FundingQuotes.test.ts +0 -456
  786. package/src/internal/FundingQuotes.ts +0 -944
@@ -0,0 +1,1911 @@
1
+ import { Address, Base58, Bytes, Hash, Value as core_Value } from 'ox'
2
+ import * as z from 'zod/mini'
3
+
4
+ import * as core_Provider from '../Provider.js'
5
+ import * as Schema from '../Schema.js'
6
+ import * as Value from '../Value.js'
7
+ import * as Action from './Action.js'
8
+ import type * as core_Catalog from './Catalog.js'
9
+ import type * as core_Chain from './Chain.js'
10
+ import type * as core_Route from './Route.js'
11
+ import type * as core_Token from './Token.js'
12
+ import type * as Transfer from './Transfer.js'
13
+
14
+ /** Tempo token used when the caller omits `destinationToken`. */
15
+ const defaultDestinationToken = 'usdce'
16
+
17
+ /** Funding provider schemas. */
18
+ export namespace schema {
19
+ /** Bounded upstream error code safe for structured logs. */
20
+ export const ErrorCode = z.string().check(z.regex(/^[A-Za-z0-9_.:-]{1,64}$/))
21
+
22
+ /** Nested upstream error fields used to extract a stable code. */
23
+ export const Error = z.object({
24
+ code: z.optional(z.string()),
25
+ type: z.optional(z.string()),
26
+ })
27
+
28
+ /** Common upstream error body fields used to extract a stable code. */
29
+ export const ErrorBody = z.object({
30
+ _tag: z.optional(z.string()),
31
+ code: z.optional(z.string()),
32
+ error: z.optional(Error),
33
+ errorCode: z.optional(z.string()),
34
+ errorType: z.optional(z.string()),
35
+ type: z.optional(z.string()),
36
+ })
37
+
38
+ /** Positive decimal amount accepted by funding quote requests. */
39
+ export const PositiveDecimal = z.string().check(z.regex(/^(?=.*[1-9])\d+(\.\d+)?$/))
40
+
41
+ /** Positive base-unit amount accepted by funding quote requests. */
42
+ export const PositiveInteger = z.string().check(z.regex(/^(?=.*[1-9])\d+$/))
43
+
44
+ /** Normalized chain reference passed to funding providers. */
45
+ export const ChainRef = Schema.describe(
46
+ z.object({
47
+ addressFormat: z
48
+ .enum(['base58', 'base58check', 'hex'])
49
+ .check(
50
+ z.describe('Address encoding used by accounts and token identifiers on this chain.'),
51
+ z.meta({ examples: ['hex'] }),
52
+ ),
53
+ id: z.string().check(z.describe('CAIP-2 chain id.'), z.meta({ examples: ['eip155:8453'] })),
54
+ kind: z
55
+ .enum(['evm', 'solana', 'tron'])
56
+ .check(
57
+ z.describe('Chain execution family used for provider routing.'),
58
+ z.meta({ examples: ['evm'] }),
59
+ ),
60
+ name: z
61
+ .string()
62
+ .check(z.describe('Human-readable chain name.'), z.meta({ examples: ['Base'] })),
63
+ }),
64
+ 'A normalized chain reference for funding quotes.',
65
+ )
66
+
67
+ /** Normalized token reference passed to funding providers. */
68
+ export const TokenRef = Schema.describe(
69
+ z.object({
70
+ address: z
71
+ .string()
72
+ .check(
73
+ z.describe('Contract address, mint, or issuer address on the token chain.'),
74
+ z.meta({ examples: ['0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'] }),
75
+ ),
76
+ currency: z
77
+ .string()
78
+ .check(
79
+ z.describe('Monetary denomination represented by this token.'),
80
+ z.meta({ examples: ['USD'] }),
81
+ ),
82
+ decimals: z
83
+ .number()
84
+ .check(
85
+ z.int(),
86
+ z.gte(0),
87
+ z.describe('Number of decimal places this token uses.'),
88
+ z.meta({ examples: [6] }),
89
+ ),
90
+ name: z
91
+ .string()
92
+ .check(z.describe('Human-readable token name.'), z.meta({ examples: ['USD Coin'] })),
93
+ standard: z
94
+ .string()
95
+ .check(z.describe('Token standard on the token chain.'), z.meta({ examples: ['ERC-20'] })),
96
+ symbol: z
97
+ .string()
98
+ .check(z.describe('Short token ticker symbol.'), z.meta({ examples: ['USDC'] })),
99
+ tokenKey: z.string().check(
100
+ z.describe('Stable Tempo token key scoped to the token chain.'),
101
+ z.meta({
102
+ examples: ['eip155:8453/erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'],
103
+ }),
104
+ ),
105
+ verified: z
106
+ .boolean()
107
+ .check(
108
+ z.describe('Whether Tempo recognizes this token in its funding quote inventory.'),
109
+ z.meta({ examples: [true] }),
110
+ ),
111
+ }),
112
+ 'A normalized token reference for funding quotes.',
113
+ )
114
+
115
+ /** Provider identity embedded in funding resources. */
116
+ export const ProviderRef = Schema.describe(
117
+ z.object({
118
+ id: z.string().check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
119
+ name: z
120
+ .string()
121
+ .check(z.describe('Human-readable provider name.'), z.meta({ examples: ['Relay'] })),
122
+ }),
123
+ 'Provider metadata embedded in a funding quote.',
124
+ )
125
+
126
+ /** Source amount unit accepted by a funding quote request. */
127
+ export const SourceAmountUnits = z
128
+ ._default(z.enum(['baseUnits', 'decimal']), 'baseUnits')
129
+ .check(
130
+ z.describe('Whether `sourceAmount` is base units or a human-readable decimal.'),
131
+ z.meta({ examples: ['baseUnits', 'decimal'] }),
132
+ )
133
+
134
+ /** Normalized caller request passed to funding providers. */
135
+ export const QuoteRequest = z
136
+ .strictObject({
137
+ destinationToken: z
138
+ .optional(z.string())
139
+ .check(
140
+ z.describe('Tempo destination token symbol, address, or token key. Defaults to USDC.e.'),
141
+ z.meta({ examples: ['usdc.e'] }),
142
+ ),
143
+ provider: z
144
+ .optional(z.string().check(z.minLength(1)))
145
+ .check(
146
+ z.describe(
147
+ 'Only request a quote from this provider. Use an id returned by the funding providers endpoint, or omit it to query every available provider.',
148
+ ),
149
+ z.meta({ examples: ['relay'] }),
150
+ ),
151
+ sourceAmount: PositiveDecimal.check(
152
+ z.describe('Positive source token amount. Base units by default, so 1 USDC is `1000000`.'),
153
+ z.meta({ examples: ['1000000'] }),
154
+ ),
155
+ sourceAmountUnits: SourceAmountUnits,
156
+ sourceChain: z
157
+ .string()
158
+ .check(
159
+ z.minLength(1),
160
+ z.describe(
161
+ 'Source chain alias or stable id, such as `base`, `solana`, or `eip155:8453`.',
162
+ ),
163
+ z.meta({ examples: ['base', 'eip155:8453'] }),
164
+ ),
165
+ sourceToken: z
166
+ .string()
167
+ .check(
168
+ z.minLength(1),
169
+ z.describe(
170
+ 'Source token symbol, contract address, or Tempo token key. Lookup is scoped to `sourceChain`; non-EVM addresses are case-sensitive. An unknown token returns an empty list.',
171
+ ),
172
+ z.meta({ examples: ['usdc', '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'] }),
173
+ ),
174
+ })
175
+ .check(z.describe('Query parameters for live funding quotes into Tempo.'))
176
+
177
+ /** Provider-specific quote status for the requested amount. */
178
+ export const QuoteStatus = z.enum(['available', 'thin', 'unknown', 'unavailable'])
179
+
180
+ /** Machine-readable provider quote quality tier. */
181
+ export const QualityTier = z.enum(['liquid', 'thin', 'unknown', 'unavailable'])
182
+
183
+ /** Quote data returned by a funding provider. */
184
+ export const GetQuoteResult = Schema.describe(
185
+ z.object({
186
+ expiresAt: z.optional(z.iso.datetime()),
187
+ destinationAmountMin: z.optional(Schema.DecimalString),
188
+ destinationAmount: z.optional(Schema.DecimalString),
189
+ quality: z.optional(
190
+ z.object({
191
+ estimatedSeconds: z.optional(z.number().check(z.int(), z.nonnegative())),
192
+ liquiditySource: z.string(),
193
+ sourceDetail: z.optional(z.string()),
194
+ tier: z.optional(QualityTier),
195
+ }),
196
+ ),
197
+ sampledAt: z.iso.datetime(),
198
+ status: QuoteStatus,
199
+ }),
200
+ 'Quote data returned by a funding provider.',
201
+ )
202
+
203
+ /** Executable preparation returned by a funding provider. */
204
+ export const PrepareResult = z.object({
205
+ action: Action.schema.Action,
206
+ correlation: z.object({
207
+ checkEndpoint: z.optional(z.string()),
208
+ requestId: z.string().check(z.minLength(1)),
209
+ }),
210
+ destinationAmount: PositiveInteger,
211
+ destinationAmountMin: PositiveInteger,
212
+ expiresAt: z.optional(z.iso.datetime()),
213
+ fees: z.array(
214
+ z.object({
215
+ amount: Schema.DecimalString,
216
+ side: z.enum(['destination', 'source']),
217
+ }),
218
+ ),
219
+ quality: GetQuoteResult.shape.quality,
220
+ sampledAt: z.iso.datetime(),
221
+ })
222
+
223
+ /** Reusable deposit address provisioned by a funding provider. */
224
+ export const DepositAddressResult = z
225
+ .object({
226
+ address: z
227
+ .string()
228
+ .check(z.minLength(1), z.describe('Reusable source-chain deposit address.')),
229
+ correlation: z
230
+ .object({
231
+ checkEndpoint: z
232
+ .optional(z.string())
233
+ .check(z.describe('Provider status endpoint for the original address request.')),
234
+ requestId: z
235
+ .string()
236
+ .check(z.minLength(1), z.describe('Provider-issued address request identifier.')),
237
+ })
238
+ .check(z.describe('Private provider correlation retained for reconciliation.')),
239
+ destinationAmount: PositiveInteger,
240
+ destinationAmountMin: PositiveInteger,
241
+ expiresAt: z.optional(z.iso.datetime()),
242
+ fees: PrepareResult.shape.fees,
243
+ sampledAt: z.iso.datetime(),
244
+ })
245
+ .check(z.describe('Reusable deposit address and quoted delivery terms returned by a provider.'))
246
+
247
+ /** One provider request discovered for a reusable deposit address. */
248
+ export const DepositAddressRequest = z.object({
249
+ createdAt: z.iso.datetime(),
250
+ destinationTransactionHashes: z.array(z.string()),
251
+ id: z.string().check(z.minLength(1)),
252
+ providerState: z.optional(z.record(z.string(), z.unknown())),
253
+ sourceTransactionHashes: z.array(z.string()),
254
+ status: z.string().check(z.minLength(1)),
255
+ updatedAt: z.iso.datetime(),
256
+ })
257
+
258
+ /** One page of provider requests discovered for a reusable address. */
259
+ export const DepositAddressRequestsResult = z.object({
260
+ continuation: z.optional(z.string().check(z.minLength(1))),
261
+ requests: z.array(DepositAddressRequest),
262
+ })
263
+
264
+ /** Quote quality signals exposed to funding API callers. */
265
+ export const FundingQuoteQuality = Schema.describe(
266
+ z.object({
267
+ estimatedSeconds: z
268
+ .optional(z.number().check(z.int(), z.nonnegative()))
269
+ .check(
270
+ z.describe('Estimated settlement time in seconds, when known.'),
271
+ z.meta({ examples: [2] }),
272
+ ),
273
+ liquiditySource: z
274
+ .string()
275
+ .check(
276
+ z.describe('Provider source for the live quote quality signal.'),
277
+ z.meta({ examples: ['providerQuote'] }),
278
+ ),
279
+ sourceDetail: z
280
+ .optional(z.string())
281
+ .check(
282
+ z.describe('Provider-specific source or endpoint detail for the quality signal.'),
283
+ z.meta({ examples: ['providerEndpoint'] }),
284
+ ),
285
+ tier: z
286
+ .enum(['liquid', 'thin'])
287
+ .check(
288
+ z.describe('Machine-readable quote quality tier for a successful quote.'),
289
+ z.meta({ examples: ['liquid'] }),
290
+ ),
291
+ }),
292
+ 'Machine-readable liquidity, fee, and source signals for a successful quote.',
293
+ )
294
+
295
+ /** Provider quote freshness data exposed to funding API callers. */
296
+ export const QuoteDetails = Schema.describe(
297
+ z.object({
298
+ expiresAt: z
299
+ .optional(z.iso.datetime())
300
+ .check(
301
+ z.describe('Timestamp after which the provider quote is no longer valid.'),
302
+ z.meta({ examples: ['2026-01-01T00:01:00Z'] }),
303
+ ),
304
+ sampledAt: z.iso
305
+ .datetime()
306
+ .check(
307
+ z.describe('Timestamp for the live quote request.'),
308
+ z.meta({ examples: ['2026-01-01T00:00:00Z'] }),
309
+ ),
310
+ }),
311
+ 'Freshness data for a provider funding quote.',
312
+ )
313
+
314
+ /** Successful normalized funding quote returned to callers. */
315
+ export const FundingQuote = Schema.describe(
316
+ z.object({
317
+ destinationAmount: Schema.TokenAmount.check(z.describe('Expected destination amount.')),
318
+ destinationAmountMin: z
319
+ .optional(Schema.TokenAmount)
320
+ .check(
321
+ z.describe(
322
+ 'Provider-derived minimum destination amount. Symbiosis and Squid quotes use a fixed 1% slippage tolerance.',
323
+ ),
324
+ ),
325
+ destinationChain: ChainRef.check(
326
+ z.describe('Destination chain, always Tempo mainnet in V1.'),
327
+ ),
328
+ destinationToken: TokenRef.check(z.describe('Tempo token expected from this quote.')),
329
+ id: z
330
+ .string()
331
+ .check(
332
+ z.describe('Stable deterministic funding quote id.'),
333
+ z.meta({ examples: ['base-usdc-tempo-usdce-relay'] }),
334
+ ),
335
+ provider: ProviderRef,
336
+ quality: FundingQuoteQuality,
337
+ quote: QuoteDetails,
338
+ sourceAmount: Schema.TokenAmount,
339
+ sourceChain: ChainRef.check(z.describe('Chain where the caller currently holds funds.')),
340
+ sourceToken: TokenRef.check(z.describe('Token the caller currently holds.')),
341
+ }),
342
+ 'One successful provider-specific funding quote.',
343
+ )
344
+ }
345
+
346
+ /** Chain metadata declared by a funding route. */
347
+ export type Chain = core_Chain.Chain
348
+
349
+ /** Token metadata declared by a funding route. */
350
+ export type Token = core_Token.Resolved
351
+
352
+ /** Provider ids accepted by funding quote requests. */
353
+ export type ProviderId = string
354
+
355
+ /** Provider-specific quote status for the requested amount. */
356
+ export type QuoteStatus = z.output<typeof schema.QuoteStatus>
357
+
358
+ /** Machine-readable quote quality tier. */
359
+ export type QualityTier = z.output<typeof schema.QualityTier>
360
+
361
+ /** Normalized chain reference passed to funding providers. */
362
+ export type ChainRef = z.output<typeof schema.ChainRef>
363
+
364
+ /** Normalized token amount passed to funding providers. */
365
+ export type TokenAmount = ReturnType<typeof resolveSourceAmount>
366
+
367
+ /** Normalized token reference passed to funding providers. */
368
+ export type TokenRef = z.output<typeof schema.TokenRef>
369
+
370
+ /** A normalized internal candidate passed to funding quote providers. */
371
+ export type QuoteCandidate = ReturnType<typeof createQuoteCandidate>
372
+
373
+ /** A normalized route candidate passed to deposit-address providers. */
374
+ export type DepositAddressCandidate = ReturnType<typeof createDepositAddressCandidate>
375
+
376
+ /** A successful normalized funding quote returned to callers. */
377
+ export type FundingQuote = z.output<typeof schema.FundingQuote>
378
+
379
+ /** Cache policy for a single funding quote request. */
380
+ export type CachePolicy = {
381
+ /** Whether providers should bypass their own quote or inventory caches. */
382
+ bypass: boolean
383
+ }
384
+
385
+ /** Normalized caller request passed to funding providers. */
386
+ export type QuoteRequest = z.output<typeof schema.QuoteRequest>
387
+
388
+ /** Contract of the provider `getQuote` method. */
389
+ export declare namespace getQuote {
390
+ /** Input passed to a funding provider for one curated quote candidate. */
391
+ type Parameters = {
392
+ /** Curated candidate selected for live provider quoting. */
393
+ candidate: QuoteCandidate
394
+ /** Cache policy for provider-side discovery and quote lookups. */
395
+ cache: CachePolicy
396
+ /** Destination chain, always Tempo mainnet in V1. */
397
+ destinationChain: ChainRef
398
+ /** Tempo token expected from this quote. */
399
+ destinationToken: TokenRef
400
+ /** Normalized caller request that produced this quote candidate. */
401
+ request: QuoteRequest
402
+ /** Canonical funding route selected for this quote candidate. */
403
+ route: core_Route.Route
404
+ /** Source amount in base units and display form. */
405
+ sourceAmount: TokenAmount
406
+ /** Chain where the caller currently holds funds. */
407
+ sourceChain: ChainRef
408
+ /** Token the caller currently holds. */
409
+ sourceToken: TokenRef
410
+ }
411
+
412
+ /** Quote data returned by a funding provider. */
413
+ type ReturnType = z.output<typeof schema.GetQuoteResult>
414
+ }
415
+
416
+ /** Contract of the provider `prepareTransfer` method. */
417
+ export declare namespace prepareTransfer {
418
+ /** Private provider correlation retained for tracking, never exposed publicly. */
419
+ type Correlation = {
420
+ /** Provider status endpoint bound to this preparation, when returned. */
421
+ checkEndpoint?: string | undefined
422
+ /** Provider-issued request identifier. */
423
+ requestId: string
424
+ }
425
+
426
+ /** Input passed to a funding provider preparing one executable transfer. */
427
+ type Parameters = {
428
+ /** Curated candidate selected for preparation. */
429
+ candidate: QuoteCandidate
430
+ /** Funding method the caller selected. */
431
+ method: Transfer.Method
432
+ /** Amount mode the caller selected. */
433
+ mode: Transfer.Mode
434
+ /** Final beneficiary on the destination chain. */
435
+ recipient: string
436
+ /** Source-chain account that signs the funding action. */
437
+ sender: string
438
+ /** Caller slippage bound in basis points. */
439
+ slippageBps?: number | undefined
440
+ }
441
+
442
+ /** Executable preparation returned by a funding provider. */
443
+ type ReturnType = z.output<typeof schema.PrepareResult>
444
+ }
445
+
446
+ /** Contract of the provider `createDepositAddress` method. */
447
+ export declare namespace createDepositAddress {
448
+ /** Input passed to a provider provisioning one reusable deposit address. */
449
+ type Parameters = {
450
+ /** Source token amount in base units used for initial route provisioning. */
451
+ amount: string
452
+ /** Curated reusable-address route selected for provisioning. */
453
+ candidate: DepositAddressCandidate
454
+ /** Final beneficiary on Tempo. */
455
+ recipient: string
456
+ /** Source-chain account that receives refunds. */
457
+ refundAddress: string
458
+ /** Whether Tempo guarantees normalized 1:1 delivery. */
459
+ subsidize: boolean
460
+ }
461
+
462
+ /** Reusable address and private provider correlation. */
463
+ type ReturnType = z.output<typeof schema.DepositAddressResult>
464
+ }
465
+
466
+ /** Contract of the provider `listDepositAddressRequests` method. */
467
+ export declare namespace listDepositAddressRequests {
468
+ /** Input passed to a provider when reconciling one reusable address. */
469
+ type Parameters = {
470
+ /** Reusable provider deposit address. */
471
+ address: string
472
+ /** Opaque provider cursor returned by the previous page. */
473
+ continuation?: string | undefined
474
+ /** Existing provider request to refresh directly. */
475
+ requestId?: string | undefined
476
+ }
477
+
478
+ /** One page of normalized provider requests. */
479
+ type ReturnType = z.output<typeof schema.DepositAddressRequestsResult>
480
+ }
481
+
482
+ /** Contract of the provider `observeDepositAddressRequest` method. */
483
+ export declare namespace observeDepositAddressRequest {
484
+ /** Verified source transfer used to correlate provider delivery. */
485
+ type Source = {
486
+ /** Token quantity in base units. */
487
+ amount: string
488
+ /** Verified source transaction reference. */
489
+ transactionHash: string
490
+ }
491
+
492
+ /** Input passed to a provider observing one pending reusable-address request. */
493
+ type Parameters = {
494
+ /** Provider-owned reusable deposit address. */
495
+ address: string
496
+ /** Chain that receives provider delivery. */
497
+ destinationChain: ChainRef
498
+ /** Token delivered by the provider. */
499
+ destinationToken: TokenRef
500
+ /** Bounded private provider correlation from an earlier observation. */
501
+ providerState?: Record<string, unknown> | undefined
502
+ /** Final beneficiary on the destination chain. */
503
+ recipient: string
504
+ /** Source-chain account credited by the provider deposit. */
505
+ refundAddress: string
506
+ /** Pending provider request being accelerated. */
507
+ request: listDepositAddressRequests.ReturnType['requests'][number]
508
+ /** One verified source transfer attributed to the request. */
509
+ source: Source
510
+ /** Chain containing the source transfer. */
511
+ sourceChain: ChainRef
512
+ /** Token received by the reusable address. */
513
+ sourceToken: TokenRef
514
+ }
515
+
516
+ /** Private provider evidence shared by pending and verified observations. */
517
+ type Evidence = {
518
+ /** Bounded private provider correlation retained for reconciliation. */
519
+ providerState?: Record<string, unknown> | undefined
520
+ /** Verified provider-leg transaction references. */
521
+ providerTransactionHashes?: readonly string[] | undefined
522
+ }
523
+
524
+ /** Bounded provider delivery observation. */
525
+ type ReturnType = Evidence &
526
+ (
527
+ | {
528
+ /** No matching provider delivery has reached the destination yet. */
529
+ type: 'pending'
530
+ }
531
+ | {
532
+ /** This provider or route cannot produce authenticated delivery observations. */
533
+ type: 'unsupported'
534
+ }
535
+ | {
536
+ /** Verified destination transaction references. */
537
+ destinationTransactionHashes: readonly string[]
538
+ /** Authenticated provider delivery was observed onchain. */
539
+ type: 'verified'
540
+ }
541
+ )
542
+ }
543
+
544
+ /** Optional webhook capability implemented by a complete funding integration. */
545
+ export type Webhook = {
546
+ /** Authenticates, resolves, and enqueues one provider status event. */
547
+ receive(input: Webhook.receive.Parameters): Promise<Webhook.receive.ReturnType>
548
+ /** Authenticates a provider status event and returns its bounded hint. */
549
+ verify(input: Webhook.verify.Parameters): Webhook.verify.ReturnType
550
+ }
551
+
552
+ /** Contracts for a funding provider webhook capability. */
553
+ export declare namespace Webhook {
554
+ /** Contracts for receiving one authenticated provider webhook. */
555
+ namespace receive {
556
+ /** Raw provider webhook request passed to a funding integration. */
557
+ type Parameters = {
558
+ /** Exact request body bytes decoded as UTF-8. */
559
+ body: string
560
+ /** Original provider webhook headers. */
561
+ headers: Headers
562
+ }
563
+
564
+ /** Durable queue message emitted for one authenticated funding status hint. */
565
+ type Dispatchable = {
566
+ /** Stored funding deposit address id. */
567
+ addressId: string
568
+ /** Bounded follow-up state for work awaiting provider or settlement confirmation. */
569
+ followUp?: FollowUp | undefined
570
+ /** Reconciliation lease fencing token, when a scheduled poll already claimed the address. */
571
+ pollLeaseVersion?: number | undefined
572
+ /** Optional provider request id that triggered reconciliation. */
573
+ requestId?: string | undefined
574
+ /** Mechanism that requested reconciliation. */
575
+ trigger: 'chain' | 'manual' | 'poll' | 'webhook'
576
+ /** Reconciliation queue message discriminator. */
577
+ type: 'funding:deposit-address:reconcile'
578
+ /** Authenticated provider webhook timing carried into reconciliation. */
579
+ webhookTiming?: WebhookTiming | undefined
580
+ }
581
+
582
+ /** Bounded follow-up state carried between delayed reconciliation messages. */
583
+ type FollowUp = {
584
+ /** Zero-based attempt in the current follow-up schedule. */
585
+ attempt: number
586
+ /** Work that still awaits confirmation. */
587
+ kind: 'delivery' | 'provider' | 'settlement'
588
+ }
589
+
590
+ /** Authenticated provider webhook timing used for latency measurement. */
591
+ type WebhookTiming = {
592
+ /** When Tempo sent the reconciliation message to its queue. */
593
+ enqueuedAt: string
594
+ /** Bounded provider status carried by the webhook. */
595
+ providerStatus: string
596
+ /** When the provider last changed the request status. */
597
+ providerUpdatedAt: string
598
+ /** When Tempo started processing the webhook request. */
599
+ receivedAt: string
600
+ /** When the provider sent the signed webhook. */
601
+ sentAt: string
602
+ }
603
+
604
+ /** Durable reconciliation message, including messages queued before trigger attribution. */
605
+ type Queued = Omit<Dispatchable, 'trigger'> & {
606
+ /** Mechanism that requested reconciliation, when written by a trigger-aware producer. */
607
+ trigger?: Dispatchable['trigger'] | undefined
608
+ }
609
+
610
+ /** Safe disposition of one authenticated funding provider webhook. */
611
+ type ReturnType =
612
+ | { addressId: string; type: 'queued' }
613
+ | { type: 'ignored' }
614
+ | { type: 'unknown_address' }
615
+ }
616
+
617
+ /** Contracts for verifying one provider webhook. */
618
+ namespace verify {
619
+ /** Raw provider webhook request passed to a funding integration. */
620
+ type Parameters = receive.Parameters
621
+
622
+ /** Authenticated provider hint extracted from a funding webhook. */
623
+ type ReturnType = {
624
+ /** Reusable provider address, when the provider attributed one. */
625
+ address?: string | undefined
626
+ /** Bounded provider status carried by the webhook. */
627
+ providerStatus?: string | undefined
628
+ /** When the provider last changed the request status. */
629
+ providerUpdatedAt?: string | undefined
630
+ /** Provider request id, when included in the event. */
631
+ requestId?: string | undefined
632
+ /** When the provider sent the signed webhook. */
633
+ sentAt?: string | undefined
634
+ }
635
+ }
636
+ }
637
+
638
+ /** A funding provider descriptor and live quote implementation. */
639
+ export type Provider<id extends string = string> = core_Provider.Provider<id, 'funding'> & {
640
+ /** Provisions a reusable funding deposit address, when supported. */
641
+ createDepositAddress?(
642
+ input: createDepositAddress.Parameters,
643
+ signal: AbortSignal,
644
+ ): Promise<createDepositAddress.ReturnType>
645
+ /** Requests a live funding quote. */
646
+ getQuote(input: getQuote.Parameters, signal: AbortSignal): Promise<getQuote.ReturnType>
647
+ /** Lists requests discovered for a reusable deposit address, when supported. */
648
+ listDepositAddressRequests?(
649
+ input: listDepositAddressRequests.Parameters,
650
+ signal: AbortSignal,
651
+ ): Promise<listDepositAddressRequests.ReturnType>
652
+ /** Observes authenticated delivery for a pending reusable-address request, when supported. */
653
+ observeDepositAddressRequest?(
654
+ input: observeDepositAddressRequest.Parameters,
655
+ signal: AbortSignal,
656
+ ): Promise<observeDepositAddressRequest.ReturnType>
657
+ /** Prepares an executable funding transfer, when the provider supports it. */
658
+ prepareTransfer?(
659
+ input: prepareTransfer.Parameters,
660
+ signal: AbortSignal,
661
+ ): Promise<prepareTransfer.ReturnType>
662
+ /** Receives authenticated provider status events, when configured. */
663
+ webhook?: Webhook | undefined
664
+ }
665
+
666
+ /** Defines a funding provider from its identity and quote implementation. */
667
+ export function from<const id extends string>(options: from.Options<id>): Provider<id> {
668
+ if (options.id !== normalizeInput(options.id) || options.id.length === 0)
669
+ throw new ProviderConfigurationError('Provider ids must be lowercase and trimmed.')
670
+ return core_Provider.from({ ...options, type: 'funding' })
671
+ }
672
+
673
+ export declare namespace from {
674
+ /** Funding provider definition. */
675
+ type Options<id extends string> = Omit<Provider<id>, 'type'>
676
+ }
677
+
678
+ /** Narrows a registered provider to a funding provider. */
679
+ export function is(provider: core_Provider.Provider): provider is Provider {
680
+ return (
681
+ provider.type === 'funding' && 'getQuote' in provider && typeof provider.getQuote === 'function'
682
+ )
683
+ }
684
+
685
+ /** Narrows a funding provider to one that prepares executable transfers. */
686
+ export function canPrepareTransfer(provider: Provider): provider is Provider & {
687
+ prepareTransfer: NonNullable<Provider['prepareTransfer']>
688
+ } {
689
+ return typeof provider.prepareTransfer === 'function'
690
+ }
691
+
692
+ /** Narrows a funding provider to one that provisions reusable deposit addresses. */
693
+ export function canCreateDepositAddress(provider: Provider): provider is Provider & {
694
+ createDepositAddress: NonNullable<Provider['createDepositAddress']>
695
+ } {
696
+ return typeof provider.createDepositAddress === 'function'
697
+ }
698
+
699
+ /** Narrows a funding provider to one that tracks reusable deposit addresses. */
700
+ export function canListDepositAddressRequests(provider: Provider): provider is Provider & {
701
+ listDepositAddressRequests: NonNullable<Provider['listDepositAddressRequests']>
702
+ } {
703
+ return typeof provider.listDepositAddressRequests === 'function'
704
+ }
705
+
706
+ /** Narrows a funding provider to one that observes reusable-address delivery onchain. */
707
+ export function canObserveDepositAddressRequest(provider: Provider): provider is Provider & {
708
+ observeDepositAddressRequest: NonNullable<Provider['observeDepositAddressRequest']>
709
+ } {
710
+ return typeof provider.observeDepositAddressRequest === 'function'
711
+ }
712
+
713
+ /** Narrows a funding provider to one with authenticated webhook receipt. */
714
+ export function canReceiveWebhook(provider: Provider): provider is Provider & {
715
+ webhook: Webhook
716
+ } {
717
+ return provider.webhook !== undefined
718
+ }
719
+
720
+ /** Funding provider method recorded by request diagnostics. */
721
+ export type ProviderOperation =
722
+ | 'createDepositAddress'
723
+ | 'getQuote'
724
+ | 'listDepositAddressRequests'
725
+ | 'prepareTransfer'
726
+
727
+ /** One provider attempt made while resolving a funding quote request. */
728
+ export type ProviderAttempt =
729
+ | {
730
+ /** Wall-clock duration of the provider attempt in milliseconds. */
731
+ durationMs: number
732
+ /** Provider method invoked by the attempt. */
733
+ operation: ProviderOperation
734
+ /** Successful or expected-unavailable provider outcome. */
735
+ outcome: 'available' | 'thin' | 'unavailable'
736
+ /** Provider that handled the quote candidate. */
737
+ provider: Provider
738
+ }
739
+ | {
740
+ /** Error thrown by the provider boundary. */
741
+ cause: unknown
742
+ /** Wall-clock duration of the provider attempt in milliseconds. */
743
+ durationMs: number
744
+ /** Provider method invoked by the attempt. */
745
+ operation: ProviderOperation
746
+ /** Failed provider outcome. */
747
+ outcome: 'failed'
748
+ /** Provider that handled the quote candidate. */
749
+ provider: Provider
750
+ }
751
+
752
+ /** Bounded result for one provider attempt. */
753
+ export type ProviderAttemptResult = {
754
+ /** Wall-clock duration of the provider attempt in milliseconds. */
755
+ durationMs: number
756
+ /** Failure class, present only when the provider attempt failed. */
757
+ failure?: failure.Result['failure'] | undefined
758
+ /** Provider identifier. */
759
+ id: string
760
+ /** Provider method invoked by the attempt. */
761
+ operation: ProviderOperation
762
+ /** Provider attempt outcome. */
763
+ outcome: ProviderAttempt['outcome']
764
+ }
765
+
766
+ /** A provider failure retained for bounded request diagnostics. */
767
+ export type ProviderFailure = {
768
+ /** Error thrown by the provider boundary. */
769
+ cause: unknown
770
+ /** Provider method that failed. */
771
+ operation: ProviderOperation
772
+ /** Provider that failed. */
773
+ provider: Provider
774
+ }
775
+
776
+ const defaultTimeoutMs = 2_000
777
+
778
+ /** Returns normalized chains and source tokens supported by quote providers. */
779
+ export function getChains(options: getChains.Options) {
780
+ const routes = getRoutes(options.catalog, options.providers)
781
+ const chains = uniqueBy(
782
+ routes.map((entry) => entry.route.source.chain),
783
+ (chain) => chain.id,
784
+ )
785
+ return chains.flatMap((chain) => {
786
+ const tokens = routes
787
+ .filter((entry) => entry.route.source.chain.id === chain.id)
788
+ .map((entry) => entry.route.source)
789
+ if (tokens.length === 0) return []
790
+ return [
791
+ {
792
+ ...chainRef(chain),
793
+ tokens: uniqueBy(tokens, (token) => token.address).map(tokenRef),
794
+ },
795
+ ]
796
+ })
797
+ }
798
+
799
+ export declare namespace getChains {
800
+ /** Options for getting provider-supported source chains. */
801
+ type Options = {
802
+ /** Compiled funding catalog containing provider routes. */
803
+ catalog: core_Catalog.Snapshot
804
+ /** Providers whose routes contribute source chains and tokens. */
805
+ providers: readonly Provider[]
806
+ }
807
+ }
808
+
809
+ /** Returns the supplied funding quote providers. */
810
+ export function getProviders(options: getProviders.Options) {
811
+ return options.providers
812
+ .filter((provider) => (options.catalog.routesByProvider.get(provider.id)?.length ?? 0) > 0)
813
+ .map((provider) => schema.ProviderRef.parse(provider))
814
+ }
815
+
816
+ export declare namespace getProviders {
817
+ /** Options for getting providers. */
818
+ type Options = {
819
+ /** Compiled funding catalog containing provider routes. */
820
+ catalog: core_Catalog.Snapshot
821
+ /** Funding providers included in this deployment. */
822
+ providers: readonly Provider[]
823
+ }
824
+ }
825
+
826
+ /** Returns successful live funding quotes from the supplied providers. */
827
+ export async function getQuotes(options: getQuotes.Options) {
828
+ const providers = options.providers ?? []
829
+ const operation = 'getQuote' satisfies ProviderOperation
830
+ const candidates = getQuoteCandidates(options).flatMap((candidate) => {
831
+ const provider = providers.find((entry) => entry.id === candidate.provider.id)
832
+ return provider ? [{ candidate, provider }] : []
833
+ })
834
+ const attempts = new Map<number, ProviderAttempt>()
835
+ const results = await Promise.allSettled(
836
+ candidates.map(async ({ candidate, provider }, index) => {
837
+ const start = performance.now()
838
+ try {
839
+ const result = await quoteCandidate(candidate, {
840
+ cache: options.cache ?? { bypass: false },
841
+ provider,
842
+ request: {
843
+ destinationToken: options.destinationToken,
844
+ provider: options.provider,
845
+ sourceAmount: options.sourceAmount,
846
+ sourceAmountUnits: options.sourceAmountUnits,
847
+ sourceChain: options.sourceChain,
848
+ sourceToken: options.sourceToken,
849
+ },
850
+ timeoutMs: options.providerTimeoutMs ?? defaultTimeoutMs,
851
+ })
852
+ attempts.set(index, {
853
+ durationMs: performance.now() - start,
854
+ operation,
855
+ outcome: result.outcome,
856
+ provider,
857
+ })
858
+ return 'quote' in result ? result.quote : undefined
859
+ } catch (cause) {
860
+ attempts.set(index, {
861
+ cause,
862
+ durationMs: performance.now() - start,
863
+ operation,
864
+ outcome: 'failed',
865
+ provider,
866
+ })
867
+ throw cause
868
+ }
869
+ }),
870
+ )
871
+ const values = [...candidates.keys()].flatMap((index) => {
872
+ const attempt = attempts.get(index)
873
+ return attempt ? [attempt] : []
874
+ })
875
+ for (const attempt of values) {
876
+ try {
877
+ options.onAttempt?.(attempt)
878
+ } catch {
879
+ // Observability hooks never alter funding quote behavior.
880
+ }
881
+ }
882
+ const quotes = results.flatMap((result) =>
883
+ result.status === 'fulfilled' && result.value ? [result.value] : [],
884
+ )
885
+ const failures = results.flatMap((result, index) =>
886
+ result.status === 'rejected'
887
+ ? [
888
+ {
889
+ cause: result.reason,
890
+ operation,
891
+ provider: candidates[index]!.provider,
892
+ } satisfies ProviderFailure,
893
+ ]
894
+ : [],
895
+ )
896
+ if (quotes.length === 0 && failures.length > 0) throw new ProviderQuoteError(failures, values)
897
+ return quotes
898
+ }
899
+
900
+ /** Returns internal quote candidates for a normalized caller request. */
901
+ export function getQuoteCandidates(options: getQuoteCandidates.Options) {
902
+ const { catalog, providers } = options
903
+ const amount = (
904
+ options.sourceAmountUnits === 'baseUnits' ? schema.PositiveInteger : schema.PositiveDecimal
905
+ ).safeParse(options.sourceAmount)
906
+ if (!amount.success) throw new InvalidAmountError()
907
+ const sourceChain = resolveSourceChain(options.sourceChain, catalog)
908
+ const sourceToken = resolveSourceToken(sourceChain, options.sourceToken, catalog)
909
+ const destination = resolveDestinationToken(options.destinationToken, catalog)
910
+ const provider = options.provider ? resolveProvider(options.provider, providers) : undefined
911
+
912
+ if (providers.length === 0) return []
913
+ if (!sourceToken) return []
914
+
915
+ const sourceAmount = resolveSourceAmount({
916
+ amount: options.sourceAmount,
917
+ token: sourceToken,
918
+ units: options.sourceAmountUnits,
919
+ })
920
+
921
+ return getRoutes(catalog, providers)
922
+ .filter((entry) => entry.route.source.chain.id === sourceChain.id)
923
+ .filter((entry) => entry.route.source.address === sourceToken.address)
924
+ .filter((entry) => entry.route.destination.chain.id === destination.chain.id)
925
+ .filter((entry) => entry.route.destination.address === destination.address)
926
+ .filter((entry) => provider === undefined || entry.provider.id === provider.id)
927
+ .map((entry) =>
928
+ createQuoteCandidate({
929
+ destinationToken: entry.route.destination,
930
+ provider: entry.provider,
931
+ route: entry.route,
932
+ sourceAmount,
933
+ sourceToken: entry.route.source,
934
+ }),
935
+ )
936
+ }
937
+
938
+ export declare namespace getQuoteCandidates {
939
+ /** Options for selecting funding quote candidates. */
940
+ type Options = QuoteRequest & {
941
+ /** Compiled funding catalog containing provider routes. */
942
+ catalog: core_Catalog.Snapshot
943
+ /** Funding providers considered by the request. */
944
+ providers: readonly Provider[]
945
+ }
946
+ }
947
+
948
+ export declare namespace getQuotes {
949
+ /** Options for requesting live funding quotes. */
950
+ type Options = getQuoteCandidates.Options & {
951
+ /** Cache policy for provider-side discovery and quote lookups. */
952
+ cache?: CachePolicy | undefined
953
+ /** Receives one bounded observation for every provider attempt. */
954
+ onAttempt?: ((attempt: ProviderAttempt) => void) | undefined
955
+ /** Per-provider quote timeout in milliseconds. */
956
+ providerTimeoutMs?: number | undefined
957
+ }
958
+ }
959
+
960
+ const defaultPrepareTimeoutMs = 10_000
961
+ // Providers that return no quote validity window get a conservative default:
962
+ // the caller must sign and submit promptly, mirroring wallet quote UX.
963
+ const defaultQuoteTtlMs = 60_000
964
+
965
+ /**
966
+ * Provisions one reusable deposit address through the first deterministic
967
+ * capability-enabled provider. Returns `undefined` when no route is enabled.
968
+ */
969
+ export async function createDepositAddress(
970
+ options: createDepositAddress.Options,
971
+ ): Promise<createDepositAddress.Selection | undefined> {
972
+ const operation = 'createDepositAddress' satisfies ProviderOperation
973
+ if (!schema.PositiveInteger.safeParse(options.amount).success) throw new InvalidAmountError()
974
+ const candidates = getDepositAddressCandidates(options).sort((a, b) =>
975
+ a.provider.id.localeCompare(b.provider.id),
976
+ )
977
+ const selected = candidates[0]
978
+ if (!selected) return undefined
979
+ const recipient = normalizeAccountAddress(options.recipient, selected.candidate.destinationChain)
980
+ const refundAddress = normalizeAccountAddress(
981
+ options.refundAddress,
982
+ selected.candidate.sourceChain,
983
+ )
984
+ if (!recipient) throw new ProviderPayloadError()
985
+ if (!refundAddress) throw new InvalidRefundAddressError()
986
+
987
+ const start = performance.now()
988
+ try {
989
+ const parsed = schema.DepositAddressResult.safeParse(
990
+ await withTimeout(
991
+ (signal) =>
992
+ selected.provider.createDepositAddress(
993
+ {
994
+ amount: options.amount,
995
+ candidate: selected.candidate,
996
+ recipient,
997
+ refundAddress,
998
+ subsidize: options.subsidize,
999
+ },
1000
+ signal,
1001
+ ),
1002
+ options.providerTimeoutMs ?? defaultPrepareTimeoutMs,
1003
+ ),
1004
+ )
1005
+ if (!parsed.success) throw new ProviderPayloadError()
1006
+ const result = parsed.data
1007
+ if (!normalizeAccountAddress(result.address, selected.candidate.sourceChain))
1008
+ throw new ProviderPayloadError()
1009
+ if (BigInt(result.destinationAmountMin) > BigInt(result.destinationAmount))
1010
+ throw new ProviderPayloadError()
1011
+ if (result.expiresAt !== undefined && Date.parse(result.expiresAt) <= Date.now())
1012
+ throw new ProviderPayloadError()
1013
+ const attempt: ProviderAttempt = {
1014
+ durationMs: performance.now() - start,
1015
+ operation,
1016
+ outcome: 'available',
1017
+ provider: selected.provider,
1018
+ }
1019
+ try {
1020
+ options.onAttempt?.(attempt)
1021
+ } catch {
1022
+ // Observability hooks never alter provisioning behavior.
1023
+ }
1024
+ return { ...selected, recipient, refundAddress, result }
1025
+ } catch (cause) {
1026
+ const attempt: ProviderAttempt =
1027
+ cause instanceof ProviderUnavailableError
1028
+ ? {
1029
+ durationMs: performance.now() - start,
1030
+ operation,
1031
+ outcome: 'unavailable',
1032
+ provider: selected.provider,
1033
+ }
1034
+ : {
1035
+ cause,
1036
+ durationMs: performance.now() - start,
1037
+ operation,
1038
+ outcome: 'failed',
1039
+ provider: selected.provider,
1040
+ }
1041
+ try {
1042
+ options.onAttempt?.(attempt)
1043
+ } catch {
1044
+ // Observability hooks never alter provisioning behavior.
1045
+ }
1046
+ if (cause instanceof ProviderUnavailableError) return undefined
1047
+ throw new ProviderQuoteError([{ cause, operation, provider: selected.provider }], [attempt])
1048
+ }
1049
+ }
1050
+
1051
+ export declare namespace createDepositAddress {
1052
+ /** Options for provisioning one reusable deposit address. */
1053
+ type Options = getDepositAddressCandidates.Options & {
1054
+ /** Source token amount in base units used for initial route provisioning. */
1055
+ amount: string
1056
+ /** Receives one bounded observation for the provider attempt. */
1057
+ onAttempt?: ((attempt: ProviderAttempt) => void) | undefined
1058
+ /** Per-provider provisioning timeout in milliseconds. */
1059
+ providerTimeoutMs?: number | undefined
1060
+ /** Final beneficiary on Tempo. */
1061
+ recipient: string
1062
+ /** Source-chain account that receives refunds. */
1063
+ refundAddress: string
1064
+ /** Whether Tempo guarantees normalized 1:1 delivery. */
1065
+ subsidize: boolean
1066
+ }
1067
+
1068
+ /** Selected provider route and its reusable address. */
1069
+ type Selection = {
1070
+ /** Curated route used to provision the address. */
1071
+ candidate: DepositAddressCandidate
1072
+ /** Provider that provisioned the address. */
1073
+ provider: Provider
1074
+ /** Normalized final beneficiary on Tempo. */
1075
+ recipient: string
1076
+ /** Normalized source-chain refund account. */
1077
+ refundAddress: string
1078
+ /** Reusable address and private provider correlation. */
1079
+ result: createDepositAddress.ReturnType
1080
+ }
1081
+ }
1082
+
1083
+ /**
1084
+ * Prepares one executable transfer across capability-enabled candidates,
1085
+ * selecting the best successful preparation. Returns `undefined` when no
1086
+ * enabled corridor matches; throws {@link ProviderQuoteError} when every
1087
+ * matching provider failed unexpectedly.
1088
+ */
1089
+ export async function prepareTransfer(
1090
+ options: prepareTransfer.Options,
1091
+ ): Promise<prepareTransfer.Selection | undefined> {
1092
+ const operation = 'prepareTransfer' satisfies ProviderOperation
1093
+ const candidates = getPrepareCandidates(options)
1094
+ if (candidates.length === 0) return undefined
1095
+
1096
+ const attempts: ProviderAttempt[] = []
1097
+ const results = await Promise.allSettled(
1098
+ candidates.map(async ({ candidate, provider }) => {
1099
+ const start = performance.now()
1100
+ try {
1101
+ const parsed = schema.PrepareResult.safeParse(
1102
+ await withTimeout(
1103
+ (signal) =>
1104
+ provider.prepareTransfer(
1105
+ {
1106
+ candidate,
1107
+ method: options.method,
1108
+ mode: options.mode,
1109
+ recipient: options.recipient,
1110
+ sender: options.sender,
1111
+ slippageBps: options.slippageBps,
1112
+ },
1113
+ signal,
1114
+ ),
1115
+ options.providerTimeoutMs ?? defaultPrepareTimeoutMs,
1116
+ ),
1117
+ )
1118
+ if (!parsed.success) throw new ProviderPayloadError()
1119
+ const result = parsed.data
1120
+ const expiresAt =
1121
+ result.expiresAt ??
1122
+ new Date(Date.parse(result.sampledAt) + defaultQuoteTtlMs).toISOString()
1123
+ if (Date.parse(expiresAt) <= Date.now()) throw new ProviderPayloadError()
1124
+ if (BigInt(result.destinationAmountMin) > BigInt(result.destinationAmount))
1125
+ throw new ProviderPayloadError()
1126
+ // A provider that ignores the caller's slippage bound is unusable for
1127
+ // this request; enforce the bound against the quoted minimum.
1128
+ if (options.slippageBps !== undefined) {
1129
+ const basisPointScale = 10_000n
1130
+ const numerator = BigInt(result.destinationAmount) * BigInt(10_000 - options.slippageBps)
1131
+ const floor = (numerator + basisPointScale - 1n) / basisPointScale
1132
+ if (BigInt(result.destinationAmountMin) < floor) throw new ProviderPayloadError()
1133
+ }
1134
+ if (result.action.type === 'evm:calls')
1135
+ try {
1136
+ Action.validateEvmCalls({
1137
+ action: result.action,
1138
+ sourceAmount: candidate.sourceAmount.amount,
1139
+ sourceTokenAddress: candidate.sourceToken.address,
1140
+ })
1141
+ } catch (cause) {
1142
+ if (cause instanceof Action.InvalidActionError) throw new ProviderPayloadError()
1143
+ throw cause
1144
+ }
1145
+ attempts.push({
1146
+ durationMs: performance.now() - start,
1147
+ operation,
1148
+ outcome: 'available',
1149
+ provider,
1150
+ })
1151
+ return { candidate, provider, result: { ...result, expiresAt } }
1152
+ } catch (cause) {
1153
+ if (cause instanceof ProviderUnavailableError) {
1154
+ attempts.push({
1155
+ durationMs: performance.now() - start,
1156
+ operation,
1157
+ outcome: 'unavailable',
1158
+ provider,
1159
+ })
1160
+ return undefined
1161
+ }
1162
+ attempts.push({
1163
+ cause,
1164
+ durationMs: performance.now() - start,
1165
+ operation,
1166
+ outcome: 'failed',
1167
+ provider,
1168
+ })
1169
+ throw cause
1170
+ }
1171
+ }),
1172
+ )
1173
+ for (const attempt of attempts) {
1174
+ try {
1175
+ options.onAttempt?.(attempt)
1176
+ } catch {
1177
+ // Observability hooks never alter preparation behavior.
1178
+ }
1179
+ }
1180
+ const prepared = results.flatMap((result) =>
1181
+ result.status === 'fulfilled' && result.value ? [result.value] : [],
1182
+ )
1183
+ if (prepared.length === 0) {
1184
+ const failures = results.flatMap((result, index) =>
1185
+ result.status === 'rejected'
1186
+ ? [
1187
+ {
1188
+ cause: result.reason,
1189
+ operation,
1190
+ provider: candidates[index]!.provider,
1191
+ } satisfies ProviderFailure,
1192
+ ]
1193
+ : [],
1194
+ )
1195
+ if (failures.length === 0) return undefined
1196
+ throw new ProviderQuoteError(failures, attempts)
1197
+ }
1198
+
1199
+ // Deterministic selection: highest guaranteed minimum, then provider id.
1200
+ prepared.sort((a, b) => {
1201
+ const delta = BigInt(b.result.destinationAmountMin) - BigInt(a.result.destinationAmountMin)
1202
+ if (delta !== 0n) return delta > 0n ? 1 : -1
1203
+ return a.provider.id < b.provider.id ? -1 : 1
1204
+ })
1205
+ return prepared[0]!
1206
+ }
1207
+
1208
+ export declare namespace prepareTransfer {
1209
+ /** Options for preparing one executable transfer. */
1210
+ type Options = getPrepareCandidates.Options & {
1211
+ /** Receives one bounded observation for every provider attempt. */
1212
+ onAttempt?: ((attempt: ProviderAttempt) => void) | undefined
1213
+ /** Per-provider preparation timeout in milliseconds. */
1214
+ providerTimeoutMs?: number | undefined
1215
+ /** Final beneficiary on the destination chain. */
1216
+ recipient: string
1217
+ /** Source-chain account that signs the funding action. */
1218
+ sender: string
1219
+ /** Caller slippage bound in basis points. */
1220
+ slippageBps?: number | undefined
1221
+ }
1222
+
1223
+ /** The selected preparation with a guaranteed expiry. */
1224
+ type Selection = {
1225
+ /** Curated candidate the preparation was produced for. */
1226
+ candidate: QuoteCandidate
1227
+ /** Provider that produced the selected preparation. */
1228
+ provider: Provider
1229
+ /** The preparation, with a default expiry applied when the provider gave none. */
1230
+ result: prepareTransfer.ReturnType & { expiresAt: string }
1231
+ }
1232
+ }
1233
+
1234
+ /**
1235
+ * Returns capability-enabled reusable-address candidates for a route. Tokens
1236
+ * resolve within their chains and only provider delivery qualifies.
1237
+ */
1238
+ export function getDepositAddressCandidates(options: getDepositAddressCandidates.Options) {
1239
+ const sourceChain = resolveSourceChain(options.sourceChain, options.catalog)
1240
+ const destinationChainId = `eip155:${options.destinationChainId}`
1241
+
1242
+ return options.catalog.routes.flatMap((entry) => {
1243
+ if (entry.route.source.chain.id !== sourceChain.id) return []
1244
+ if (entry.route.destination.chain.id !== destinationChainId) return []
1245
+ if (!matchesToken(entry.route.source, options.sourceToken)) return []
1246
+ if (!matchesToken(entry.route.destination, options.destinationToken)) return []
1247
+ if (!entry.capabilities?.depositAddress) return []
1248
+ const provider = options.providers.find((candidate) => candidate.id === entry.providerId)
1249
+ if (!provider || !canCreateDepositAddress(provider)) return []
1250
+ return [
1251
+ { candidate: createDepositAddressCandidate({ provider, route: entry.route }), provider },
1252
+ ]
1253
+ })
1254
+ }
1255
+
1256
+ export declare namespace getDepositAddressCandidates {
1257
+ /** Options for selecting reusable deposit-address routes. */
1258
+ type Options = {
1259
+ /** Compiled funding catalog containing provider routes and capabilities. */
1260
+ catalog: core_Catalog.Snapshot
1261
+ /** Tempo destination chain selected by app composition. */
1262
+ destinationChainId: number
1263
+ /** Tempo destination token symbol, contract address, or token key. */
1264
+ destinationToken: string
1265
+ /** Funding providers considered by the request. */
1266
+ providers: readonly Provider[]
1267
+ /** Source chain CAIP-2 id, slug, or alias. */
1268
+ sourceChain: string
1269
+ /** Source token symbol, contract address, or token key. */
1270
+ sourceToken: string
1271
+ }
1272
+ }
1273
+
1274
+ /**
1275
+ * Returns capability-enabled preparation candidates for a creation request.
1276
+ * Tokens resolve within their chains. A route must enable the requested mode,
1277
+ * and its provider must implement `prepareTransfer`.
1278
+ */
1279
+ export function getPrepareCandidates(options: getPrepareCandidates.Options) {
1280
+ const amount = schema.PositiveInteger.safeParse(options.sourceAmount)
1281
+ if (!amount.success) throw new InvalidAmountError()
1282
+ const sourceChain = resolveSourceChain(options.sourceChain, options.catalog)
1283
+ const destinationChainId = `eip155:${options.destinationChainId}`
1284
+
1285
+ return options.catalog.routes.flatMap((entry) => {
1286
+ if (entry.route.source.chain.id !== sourceChain.id) return []
1287
+ if (entry.route.destination.chain.id !== destinationChainId) return []
1288
+ if (!matchesToken(entry.route.source, options.sourceToken)) return []
1289
+ if (!matchesToken(entry.route.destination, options.destinationToken)) return []
1290
+ if (!entry.capabilities?.transfer?.modes.includes(options.mode)) return []
1291
+ const provider = options.providers.find((candidate) => candidate.id === entry.providerId)
1292
+ if (!provider || !canPrepareTransfer(provider)) return []
1293
+ return [
1294
+ {
1295
+ candidate: createQuoteCandidate({
1296
+ destinationToken: entry.route.destination,
1297
+ provider,
1298
+ route: entry.route,
1299
+ sourceAmount: resolveSourceAmount({
1300
+ amount: options.sourceAmount,
1301
+ token: entry.route.source,
1302
+ units: 'baseUnits',
1303
+ }),
1304
+ sourceToken: entry.route.source,
1305
+ }),
1306
+ provider,
1307
+ },
1308
+ ]
1309
+ })
1310
+ }
1311
+
1312
+ export declare namespace getPrepareCandidates {
1313
+ /** Options for selecting preparation candidates. */
1314
+ type Options = {
1315
+ /** Compiled funding catalog containing provider routes and capabilities. */
1316
+ catalog: core_Catalog.Snapshot
1317
+ /** Tempo destination chain selected by app composition. */
1318
+ destinationChainId: number
1319
+ /** Tempo destination token symbol, contract address, or token key. */
1320
+ destinationToken: string
1321
+ /** Funding method passed to provider preparation. */
1322
+ method: Transfer.Method
1323
+ /** Amount mode the caller selected. */
1324
+ mode: Transfer.Mode
1325
+ /** Funding providers considered by the request. */
1326
+ providers: readonly Provider[]
1327
+ /** Source amount in base units. */
1328
+ sourceAmount: string
1329
+ /** Source chain CAIP-2 id, slug, or alias. */
1330
+ sourceChain: string
1331
+ /** Source token symbol, contract address, or token key. */
1332
+ sourceToken: string
1333
+ }
1334
+ }
1335
+
1336
+ /** Source amount unit accepted by the funding quote request. */
1337
+ export type SourceAmountUnits = z.output<typeof schema.SourceAmountUnits>
1338
+
1339
+ /** Fetch implementation accepted by funding provider factories. */
1340
+ export type Fetch = typeof globalThis.fetch
1341
+
1342
+ /** Returns bounded provider failure details suitable for structured request logs. */
1343
+ export function failure(options: ProviderFailure): failure.Result {
1344
+ const { cause, operation, provider } = options
1345
+ if (
1346
+ cause instanceof ProviderTimeoutError ||
1347
+ (cause instanceof DOMException && cause.name === 'AbortError')
1348
+ )
1349
+ return { failure: 'timeout', id: provider.id, operation }
1350
+ if (cause instanceof ProviderResponseError) {
1351
+ const code = errorCode(cause.body)
1352
+ return {
1353
+ ...(code === undefined ? {} : { code }),
1354
+ failure: 'http',
1355
+ id: provider.id,
1356
+ operation,
1357
+ status: cause.status,
1358
+ }
1359
+ }
1360
+ if (cause instanceof ProviderPayloadError)
1361
+ return { failure: 'payload', id: provider.id, operation }
1362
+ if (cause instanceof ProviderRateLimitError)
1363
+ return { failure: 'rate_limit', id: provider.id, operation }
1364
+ if (cause instanceof TypeError) return { failure: 'network', id: provider.id, operation }
1365
+ return { failure: 'unknown', id: provider.id, operation }
1366
+ }
1367
+
1368
+ export declare namespace failure {
1369
+ /** Bounded provider failure fields. */
1370
+ type Result = {
1371
+ /** Stable provider error code, when one is safe to retain. */
1372
+ code?: string | undefined
1373
+ /** Failure boundary that rejected the provider request. */
1374
+ failure: 'http' | 'network' | 'payload' | 'rate_limit' | 'timeout' | 'unknown'
1375
+ /** Provider identifier. */
1376
+ id: string
1377
+ /** Provider operation identifier. */
1378
+ operation: ProviderOperation
1379
+ /** Upstream HTTP status, when a response was received. */
1380
+ status?: number | undefined
1381
+ }
1382
+ }
1383
+
1384
+ /** Returns a supported expected-unavailable code from a provider response. */
1385
+ export function unavailable(cause: unknown, codes: readonly string[]) {
1386
+ if (!(cause instanceof ProviderResponseError) || cause.status < 400 || cause.status >= 500)
1387
+ return undefined
1388
+ const code = errorCode(cause.body)
1389
+ if (code && codes.includes(code)) return code
1390
+ return undefined
1391
+ }
1392
+
1393
+ /** Requests and parses a JSON provider response. */
1394
+ export async function requestJson(url: URL, options: requestJson.Options) {
1395
+ const headers = { accept: 'application/json', ...options.headers }
1396
+ const init: RequestInit = {
1397
+ headers:
1398
+ options.body === undefined ? headers : { ...headers, 'content-type': 'application/json' },
1399
+ method: options.method ?? 'GET',
1400
+ signal: options.signal,
1401
+ }
1402
+ if (options.body !== undefined) init.body = JSON.stringify(options.body)
1403
+ const response = await options.fetch(url, init)
1404
+ const text = await response.text()
1405
+ const body = (() => {
1406
+ if (!text) return null
1407
+ try {
1408
+ return JSON.parse(text) as unknown
1409
+ } catch {
1410
+ return text
1411
+ }
1412
+ })()
1413
+ if (!response.ok) throw new ProviderResponseError(response.status, body)
1414
+ return body
1415
+ }
1416
+
1417
+ export declare namespace requestJson {
1418
+ /** Provider request options. */
1419
+ type Options = {
1420
+ /** Optional JSON request body. */
1421
+ body?: unknown
1422
+ /** Fetch implementation. */
1423
+ fetch: Fetch
1424
+ /** Optional request headers. */
1425
+ headers?: Record<string, string> | undefined
1426
+ /** Optional HTTP method. */
1427
+ method?: string | undefined
1428
+ /** Request abort signal. */
1429
+ signal: AbortSignal
1430
+ }
1431
+ }
1432
+
1433
+ /** Creates a normalized expected-unavailable quote result. */
1434
+ export function unavailableResult(options: unavailableResult.Options): getQuote.ReturnType {
1435
+ return {
1436
+ quality: {
1437
+ liquiditySource: options.source,
1438
+ sourceDetail: `${options.detail}:${options.message}`,
1439
+ tier: 'unavailable',
1440
+ },
1441
+ sampledAt: options.now.toISOString(),
1442
+ status: 'unavailable',
1443
+ }
1444
+ }
1445
+
1446
+ export declare namespace unavailableResult {
1447
+ /** Expected-unavailable quote details. */
1448
+ type Options = {
1449
+ /** Provider operation detail. */
1450
+ detail: string
1451
+ /** Stable provider reason. */
1452
+ message: string
1453
+ /** Quote sample time. */
1454
+ now: Date
1455
+ /** Liquidity signal source. */
1456
+ source: string
1457
+ }
1458
+ }
1459
+
1460
+ function tokenKey(token: Token) {
1461
+ const namespace = (() => {
1462
+ if (token.chain.kind === 'solana') return 'token'
1463
+ if (token.chain.kind === 'tron') return 'trc20'
1464
+ return 'erc20'
1465
+ })()
1466
+ return `${token.chain.id}/${namespace}:${token.address}`
1467
+ }
1468
+
1469
+ async function quoteCandidate(
1470
+ candidate: QuoteCandidate,
1471
+ options: {
1472
+ cache: CachePolicy
1473
+ provider: Provider
1474
+ request: QuoteRequest
1475
+ timeoutMs: number
1476
+ },
1477
+ ) {
1478
+ const result = schema.GetQuoteResult.safeParse(
1479
+ await withTimeout(
1480
+ (signal) =>
1481
+ options.provider.getQuote(
1482
+ {
1483
+ candidate,
1484
+ cache: options.cache,
1485
+ destinationChain: candidate.destinationChain,
1486
+ destinationToken: candidate.destinationToken,
1487
+ request: options.request,
1488
+ route: candidate.route,
1489
+ sourceAmount: candidate.sourceAmount,
1490
+ sourceChain: candidate.sourceChain,
1491
+ sourceToken: candidate.sourceToken,
1492
+ },
1493
+ signal,
1494
+ ),
1495
+ options.timeoutMs,
1496
+ ),
1497
+ )
1498
+ if (!result.success) throw new ProviderPayloadError()
1499
+ const quote = result.data
1500
+ if (quote.status === 'unavailable') return { outcome: quote.status }
1501
+ if (
1502
+ (quote.status !== 'available' && quote.status !== 'thin') ||
1503
+ quote.destinationAmount === undefined ||
1504
+ quote.destinationAmount === null
1505
+ )
1506
+ throw new ProviderPayloadError()
1507
+ const destinationAmount = BigInt(quote.destinationAmount)
1508
+ const destinationAmountMin =
1509
+ quote.destinationAmountMin === undefined ? undefined : BigInt(quote.destinationAmountMin)
1510
+ if (
1511
+ destinationAmount === 0n ||
1512
+ destinationAmountMin === 0n ||
1513
+ (destinationAmountMin !== undefined && destinationAmountMin > destinationAmount)
1514
+ )
1515
+ throw new ProviderPayloadError()
1516
+ return {
1517
+ outcome: quote.status,
1518
+ quote: createQuote(candidate, {
1519
+ ...quote,
1520
+ destinationAmount: quote.destinationAmount,
1521
+ status: quote.status,
1522
+ }),
1523
+ }
1524
+ }
1525
+
1526
+ function tokenRef(token: Token): TokenRef {
1527
+ return schema.TokenRef.parse({
1528
+ address: token.address,
1529
+ currency: token.currency,
1530
+ decimals: token.decimals,
1531
+ name: token.name,
1532
+ standard: token.standard,
1533
+ symbol: token.symbol,
1534
+ tokenKey: tokenKey(token),
1535
+ verified: true,
1536
+ })
1537
+ }
1538
+
1539
+ function chainRef(chain: Chain): ChainRef {
1540
+ return schema.ChainRef.parse({
1541
+ addressFormat: chain.addressFormat,
1542
+ id: chain.id,
1543
+ kind: chain.kind,
1544
+ name: chain.name,
1545
+ })
1546
+ }
1547
+
1548
+ function createDepositAddressCandidate(options: { provider: Provider; route: core_Route.Route }) {
1549
+ return {
1550
+ destinationChain: chainRef(options.route.destination.chain),
1551
+ destinationToken: tokenRef(options.route.destination),
1552
+ provider: schema.ProviderRef.parse(options.provider),
1553
+ route: options.route,
1554
+ sourceChain: chainRef(options.route.source.chain),
1555
+ sourceToken: tokenRef(options.route.source),
1556
+ } as const
1557
+ }
1558
+
1559
+ function createQuoteCandidate(options: {
1560
+ destinationToken: Token
1561
+ provider: Provider
1562
+ route: core_Route.Route
1563
+ sourceAmount: ReturnType<typeof resolveSourceAmount>
1564
+ sourceToken: Token
1565
+ }) {
1566
+ return {
1567
+ destinationChain: chainRef(options.destinationToken.chain),
1568
+ destinationToken: tokenRef(options.destinationToken),
1569
+ id: [
1570
+ options.sourceToken.chain.slug,
1571
+ options.sourceToken.slug,
1572
+ options.destinationToken.chain.slug,
1573
+ options.destinationToken.slug,
1574
+ options.provider.id,
1575
+ ].join('-'),
1576
+ provider: schema.ProviderRef.parse(options.provider),
1577
+ route: options.route,
1578
+ sourceAmount: options.sourceAmount,
1579
+ sourceChain: chainRef(options.sourceToken.chain),
1580
+ sourceToken: tokenRef(options.sourceToken),
1581
+ } as const
1582
+ }
1583
+
1584
+ function normalizeInput(value: string) {
1585
+ return value.trim().toLowerCase()
1586
+ }
1587
+
1588
+ function parseBaseUnits(value: string) {
1589
+ return BigInt(value).toString()
1590
+ }
1591
+
1592
+ function parseDecimalUnits(value: string, decimals: number) {
1593
+ const fraction = value.split('.')[1]?.replace(/0+$/, '') ?? ''
1594
+ if (fraction.length > decimals) throw new InvalidAmountError()
1595
+ try {
1596
+ const amount = core_Value.from(value, decimals)
1597
+ if (amount <= 0n) throw new InvalidAmountError()
1598
+ return amount.toString()
1599
+ } catch (cause) {
1600
+ if (cause instanceof InvalidAmountError) throw cause
1601
+ throw new InvalidAmountError()
1602
+ }
1603
+ }
1604
+
1605
+ type SuccessfulQuoteResult = getQuote.ReturnType & {
1606
+ destinationAmount: string
1607
+ status: 'available' | 'thin'
1608
+ }
1609
+
1610
+ function createQuote(candidate: QuoteCandidate, quote: SuccessfulQuoteResult): FundingQuote {
1611
+ return schema.FundingQuote.parse({
1612
+ destinationAmount: Value.tokenAmount({
1613
+ baseUnits: quote.destinationAmount,
1614
+ currency: candidate.destinationToken.currency,
1615
+ decimals: candidate.destinationToken.decimals,
1616
+ }),
1617
+ ...(quote.destinationAmountMin !== undefined
1618
+ ? {
1619
+ destinationAmountMin: Value.tokenAmount({
1620
+ baseUnits: quote.destinationAmountMin,
1621
+ currency: candidate.destinationToken.currency,
1622
+ decimals: candidate.destinationToken.decimals,
1623
+ }),
1624
+ }
1625
+ : {}),
1626
+ destinationChain: candidate.destinationChain,
1627
+ destinationToken: candidate.destinationToken,
1628
+ id: candidate.id,
1629
+ provider: candidate.provider,
1630
+ quality: {
1631
+ ...(quote.quality?.estimatedSeconds !== undefined
1632
+ ? { estimatedSeconds: quote.quality.estimatedSeconds }
1633
+ : {}),
1634
+ liquiditySource: quote.quality?.liquiditySource ?? 'providerQuote',
1635
+ ...(quote.quality?.sourceDetail !== undefined
1636
+ ? { sourceDetail: quote.quality.sourceDetail }
1637
+ : {}),
1638
+ tier: quote.status === 'thin' ? ('thin' as const) : ('liquid' as const),
1639
+ },
1640
+ quote: {
1641
+ ...(quote.expiresAt !== undefined ? { expiresAt: quote.expiresAt } : {}),
1642
+ sampledAt: quote.sampledAt,
1643
+ },
1644
+ sourceAmount: Value.tokenAmount({
1645
+ baseUnits: candidate.sourceAmount.amount,
1646
+ currency: candidate.sourceToken.currency,
1647
+ decimals: candidate.sourceToken.decimals,
1648
+ }),
1649
+ sourceChain: candidate.sourceChain,
1650
+ sourceToken: candidate.sourceToken,
1651
+ })
1652
+ }
1653
+
1654
+ function withTimeout<result>(fn: (signal: AbortSignal) => Promise<result>, timeoutMs: number) {
1655
+ const controller = new AbortController()
1656
+ const timeout = setTimeout(() => controller.abort(), timeoutMs)
1657
+ // Some provider implementations may not honor the signal, so the boundary also races them.
1658
+ return Promise.race([
1659
+ fn(controller.signal),
1660
+ new Promise<never>((_, reject) => {
1661
+ if (controller.signal.aborted) {
1662
+ reject(new ProviderTimeoutError())
1663
+ return
1664
+ }
1665
+ controller.signal.addEventListener('abort', () => reject(new ProviderTimeoutError()), {
1666
+ once: true,
1667
+ })
1668
+ }),
1669
+ ]).finally(() => clearTimeout(timeout))
1670
+ }
1671
+
1672
+ function errorCode(input: unknown) {
1673
+ const result = schema.ErrorBody.safeParse(input)
1674
+ if (!result.success) return undefined
1675
+ const body = result.data
1676
+ const code =
1677
+ body._tag ??
1678
+ body.code ??
1679
+ body.errorCode ??
1680
+ body.errorType ??
1681
+ body.type ??
1682
+ body.error?.code ??
1683
+ body.error?.type
1684
+ const parsed = schema.ErrorCode.safeParse(code)
1685
+ return parsed.success ? parsed.data : undefined
1686
+ }
1687
+
1688
+ function attemptResult(attempt: ProviderAttempt): ProviderAttemptResult {
1689
+ return {
1690
+ durationMs: attempt.durationMs,
1691
+ ...(attempt.outcome === 'failed'
1692
+ ? {
1693
+ failure: failure({
1694
+ cause: attempt.cause,
1695
+ operation: attempt.operation,
1696
+ provider: attempt.provider,
1697
+ }).failure,
1698
+ }
1699
+ : {}),
1700
+ id: attempt.provider.id,
1701
+ operation: attempt.operation,
1702
+ outcome: attempt.outcome,
1703
+ }
1704
+ }
1705
+
1706
+ function resolveDestinationToken(input: string | undefined, catalog: core_Catalog.Snapshot) {
1707
+ const destinations = uniqueBy(
1708
+ catalog.routes.map((entry) => entry.route.destination),
1709
+ (token) => `${token.chain.id}:${token.address}`,
1710
+ )
1711
+ if (input === undefined) {
1712
+ const destination = destinations.find((candidate) => candidate.slug === defaultDestinationToken)
1713
+ if (!destination) throw new UnsupportedDestinationTokenError()
1714
+ return destination
1715
+ }
1716
+ const destination = destinations.find((candidate) => matchesToken(candidate, input))
1717
+ if (!destination) throw new UnsupportedDestinationTokenError()
1718
+ return destination
1719
+ }
1720
+
1721
+ function resolveProvider(input: string, providers: readonly Provider[]) {
1722
+ const provider = providers.find((candidate) => candidate.id === normalizeInput(input))
1723
+ if (!provider) throw new UnsupportedProviderError()
1724
+ return provider
1725
+ }
1726
+
1727
+ function resolveSourceAmount(options: resolveSourceAmount.Options) {
1728
+ const amount =
1729
+ options.units === 'baseUnits'
1730
+ ? parseBaseUnits(options.amount)
1731
+ : parseDecimalUnits(options.amount, options.token.decimals)
1732
+ return {
1733
+ amount,
1734
+ formatted: core_Value.format(BigInt(amount), options.token.decimals),
1735
+ }
1736
+ }
1737
+
1738
+ declare namespace resolveSourceAmount {
1739
+ type Options = {
1740
+ amount: string
1741
+ token: Token
1742
+ units: SourceAmountUnits
1743
+ }
1744
+ }
1745
+
1746
+ function resolveSourceToken(chain: Chain, input: string, catalog: core_Catalog.Snapshot) {
1747
+ const tokens = catalog.routes
1748
+ .filter((entry) => entry.route.source.chain.id === chain.id)
1749
+ .map((entry) => entry.route.source)
1750
+ return tokens.find((token) => matchesToken(token, input))
1751
+ }
1752
+
1753
+ function matchesToken(token: Token, input: string) {
1754
+ const trimmed = input.trim()
1755
+ const normalized = normalizeInput(input)
1756
+ return (
1757
+ token.slug === normalized ||
1758
+ token.symbol.toLowerCase() === normalized ||
1759
+ matchesTokenIdentifier(token.chain, token.address, trimmed, normalized) ||
1760
+ matchesTokenIdentifier(token.chain, tokenKey(token), trimmed, normalized)
1761
+ )
1762
+ }
1763
+
1764
+ function matchesTokenIdentifier(
1765
+ chain: Chain,
1766
+ candidate: string,
1767
+ trimmed: string,
1768
+ normalized: string,
1769
+ ) {
1770
+ return chain.kind === 'evm' ? candidate.toLowerCase() === normalized : candidate === trimmed
1771
+ }
1772
+
1773
+ function resolveSourceChain(input: string, catalog: core_Catalog.Snapshot) {
1774
+ const normalized = normalizeInput(input)
1775
+ const chain = catalog.chainsByKey.get(normalized)
1776
+ if (!chain || !catalog.routes.some((entry) => entry.route.source.chain.id === chain.id))
1777
+ throw new UnsupportedSourceChainError()
1778
+ return chain
1779
+ }
1780
+
1781
+ function getRoutes(catalog: core_Catalog.Snapshot, providers: readonly Provider[]) {
1782
+ return providers.flatMap((provider) =>
1783
+ (catalog.routesByProvider.get(provider.id) ?? []).map((route) => ({ provider, route })),
1784
+ )
1785
+ }
1786
+
1787
+ function uniqueBy<const value>(values: readonly value[], key: (value: value) => string): value[] {
1788
+ const seen = new Set<string>()
1789
+ return values.filter((value) => {
1790
+ const id = key(value)
1791
+ if (seen.has(id)) return false
1792
+ seen.add(id)
1793
+ return true
1794
+ })
1795
+ }
1796
+
1797
+ function normalizeAccountAddress(value: string, chain: ChainRef): string | undefined {
1798
+ if (chain.kind === 'evm')
1799
+ return Address.validate(value, { strict: false }) ? Address.checksum(value) : undefined
1800
+ try {
1801
+ const bytes = Base58.toBytes(value)
1802
+ if (chain.kind === 'solana') return bytes.length === 32 ? value : undefined
1803
+ if (bytes.length !== 25 || bytes[0] !== 0x41) return undefined
1804
+ const payload = bytes.slice(0, 21)
1805
+ const checksum = Hash.sha256(Hash.sha256(payload), { as: 'Bytes' }).slice(0, 4)
1806
+ return Bytes.isEqual(bytes.slice(21), checksum) ? value : undefined
1807
+ } catch {
1808
+ return undefined
1809
+ }
1810
+ }
1811
+
1812
+ /** Error thrown when the caller supplies an unsupported destination token. */
1813
+ export class UnsupportedDestinationTokenError extends Error {
1814
+ override name = 'FundingProvider.UnsupportedDestinationTokenError'
1815
+ }
1816
+
1817
+ /** Error thrown when a provider webhook cannot be authenticated. */
1818
+ export class WebhookAuthenticationError extends Error {
1819
+ override name = 'FundingProvider.WebhookAuthenticationError'
1820
+ }
1821
+
1822
+ /** Error thrown when an authenticated provider webhook has an invalid body. */
1823
+ export class WebhookPayloadError extends Error {
1824
+ override name = 'FundingProvider.WebhookPayloadError'
1825
+ }
1826
+
1827
+ /** Error thrown when the caller supplies an invalid source amount. */
1828
+ export class InvalidAmountError extends Error {
1829
+ override name = 'FundingProvider.InvalidAmountError'
1830
+ }
1831
+
1832
+ /** Error thrown when the caller supplies an invalid source-chain refund address. */
1833
+ export class InvalidRefundAddressError extends Error {
1834
+ override name = 'FundingProvider.InvalidRefundAddressError'
1835
+ }
1836
+
1837
+ /** Error thrown when provider deployment configuration is invalid. */
1838
+ export class ProviderConfigurationError extends Error {
1839
+ override name = 'FundingProvider.ProviderConfigurationError'
1840
+ }
1841
+
1842
+ /** Error thrown when a provider response does not match the requested quote. */
1843
+ export class ProviderPayloadError extends Error {
1844
+ override name = 'FundingProvider.ProviderPayloadError'
1845
+ }
1846
+
1847
+ /** Error thrown when a provider confirms that no executable route is available. */
1848
+ export class ProviderUnavailableError extends Error {
1849
+ override name = 'FundingProvider.ProviderUnavailableError'
1850
+ }
1851
+
1852
+ /** Error thrown internally when a provider exceeds its quote timeout. */
1853
+ export class ProviderTimeoutError extends Error {
1854
+ override name = 'FundingProvider.ProviderTimeoutError'
1855
+ }
1856
+
1857
+ /** Error thrown when an internal provider quota rejects a quote request. */
1858
+ export class ProviderRateLimitError extends Error {
1859
+ override name = 'FundingProvider.ProviderRateLimitError'
1860
+ }
1861
+
1862
+ /** Error thrown when a provider returns an unsuccessful HTTP response. */
1863
+ export class ProviderResponseError extends Error {
1864
+ override name = 'FundingProvider.ProviderResponseError'
1865
+
1866
+ constructor(
1867
+ /** Provider response status. */
1868
+ readonly status: number,
1869
+ /** Parsed provider response body. */
1870
+ readonly body: unknown,
1871
+ ) {
1872
+ super(`Provider request failed with status ${status}`)
1873
+ }
1874
+ }
1875
+
1876
+ /** Error thrown when every matching provider fails to produce a quote. */
1877
+ export class ProviderQuoteError extends Error {
1878
+ override name = 'FundingProvider.ProviderQuoteError'
1879
+
1880
+ /** Provider failures that prevented a successful quote. */
1881
+ failures: readonly ProviderFailure[]
1882
+
1883
+ /** Bounded provider attempts retained for request logs. */
1884
+ fundingProviderAttempts: readonly ProviderAttemptResult[]
1885
+
1886
+ /** First bounded provider failure retained for request logs. */
1887
+ providerFailure?: failure.Result | undefined
1888
+
1889
+ /** Bounded provider failures retained when multiple providers failed. */
1890
+ providerFailures?: readonly failure.Result[] | undefined
1891
+
1892
+ constructor(failures: readonly ProviderFailure[], attempts: readonly ProviderAttempt[] = []) {
1893
+ super()
1894
+ this.failures = failures
1895
+ this.fundingProviderAttempts = attempts.map(attemptResult)
1896
+ const values = failures.map(failure)
1897
+ const first = values[0]
1898
+ if (first) this.providerFailure = first
1899
+ if (values.length > 1) this.providerFailures = values
1900
+ }
1901
+ }
1902
+
1903
+ /** Error thrown when the caller filters to an unknown provider. */
1904
+ export class UnsupportedProviderError extends Error {
1905
+ override name = 'FundingProvider.UnsupportedProviderError'
1906
+ }
1907
+
1908
+ /** Error thrown when the caller supplies an unsupported source chain. */
1909
+ export class UnsupportedSourceChainError extends Error {
1910
+ override name = 'FundingProvider.UnsupportedSourceChainError'
1911
+ }