tapimo 0.15.1 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (709) hide show
  1. package/README.md +137 -0
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +4 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +37 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +163 -10
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +13085 -11974
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +46 -15
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +1 -1
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +1 -1
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +893 -191
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +5 -1
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +70 -70
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +8 -3
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +66 -27
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  28. package/dist/admin/apps/earn-vaults.js +36 -7
  29. package/dist/admin/apps/earn-vaults.js.map +1 -1
  30. package/dist/admin/apps/organizations.d.ts +25 -25
  31. package/dist/admin/apps/organizations.d.ts.map +1 -1
  32. package/dist/admin/apps/organizations.js +5 -4
  33. package/dist/admin/apps/organizations.js.map +1 -1
  34. package/dist/admin/apps/route-policies.d.ts +632 -0
  35. package/dist/admin/apps/route-policies.d.ts.map +1 -0
  36. package/dist/admin/apps/route-policies.js +257 -0
  37. package/dist/admin/apps/route-policies.js.map +1 -0
  38. package/dist/admin/apps/routes-support.js +39 -3
  39. package/dist/admin/apps/routes-support.js.map +1 -1
  40. package/dist/admin/apps/routes.d.ts +529 -76
  41. package/dist/admin/apps/routes.d.ts.map +1 -1
  42. package/dist/admin/apps/routes.js +82 -1
  43. package/dist/admin/apps/routes.js.map +1 -1
  44. package/dist/admin/apps/verified-tokens.d.ts +157 -157
  45. package/dist/admin/index.d.ts +0 -1
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +0 -1
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/admin/ui.generated.d.ts +1 -1
  50. package/dist/admin/ui.generated.d.ts.map +1 -1
  51. package/dist/admin/ui.generated.js +205 -201
  52. package/dist/admin/ui.generated.js.map +1 -1
  53. package/dist/analytics/Analytics.d.ts.map +1 -1
  54. package/dist/analytics/Analytics.js +65 -1
  55. package/dist/analytics/Analytics.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  57. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  58. package/dist/analytics/tables/requestEvents.js +58 -59
  59. package/dist/analytics/tables/requestEvents.js.map +1 -1
  60. package/dist/apps/data/App.d.ts +2709 -2670
  61. package/dist/apps/data/App.d.ts.map +1 -1
  62. package/dist/apps/data/routes/activities.d.ts +357 -357
  63. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  64. package/dist/apps/data/routes/activities.js +50 -0
  65. package/dist/apps/data/routes/activities.js.map +1 -1
  66. package/dist/apps/data/routes/addresses.d.ts +248 -248
  67. package/dist/apps/data/routes/balances.d.ts +22 -22
  68. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  69. package/dist/apps/data/routes/balances.js +5 -7
  70. package/dist/apps/data/routes/balances.js.map +1 -1
  71. package/dist/apps/data/routes/blocks.d.ts +125 -125
  72. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  73. package/dist/apps/data/routes/earn.d.ts +103 -12
  74. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  75. package/dist/apps/data/routes/earn.js +456 -220
  76. package/dist/apps/data/routes/earn.js.map +1 -1
  77. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  78. package/dist/apps/data/routes/exchanges.js +267 -97
  79. package/dist/apps/data/routes/exchanges.js.map +1 -1
  80. package/dist/apps/data/routes/fee-amm.d.ts +109 -127
  81. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.js +83 -54
  83. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +43 -43
  85. package/dist/apps/data/routes/receipts.d.ts +235 -235
  86. package/dist/apps/data/routes/rpc.d.ts +30 -30
  87. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  88. package/dist/apps/data/routes/tokens.js +11 -6
  89. package/dist/apps/data/routes/tokens.js.map +1 -1
  90. package/dist/apps/data/routes/transactions.d.ts +2 -0
  91. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  92. package/dist/apps/data/routes/transactions.js +30 -22
  93. package/dist/apps/data/routes/transactions.js.map +1 -1
  94. package/dist/apps/data/routes/transfers.d.ts +77 -77
  95. package/dist/apps/data/routes/valuation.d.ts +32 -32
  96. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  97. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  98. package/dist/apps/data/routes/webhooks.js +1 -1
  99. package/dist/apps/data/routes/webhooks.js.map +1 -1
  100. package/dist/apps/data/routes/zones.d.ts +31 -31
  101. package/dist/apps/management/App.d.ts +2909 -2064
  102. package/dist/apps/management/App.d.ts.map +1 -1
  103. package/dist/apps/management/App.js +2 -0
  104. package/dist/apps/management/App.js.map +1 -1
  105. package/dist/apps/management/Billing.d.ts +2 -4
  106. package/dist/apps/management/Billing.d.ts.map +1 -1
  107. package/dist/apps/management/Billing.js +65 -26
  108. package/dist/apps/management/Billing.js.map +1 -1
  109. package/dist/apps/management/routes/api-keys.d.ts +257 -245
  110. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  111. package/dist/apps/management/routes/api-keys.js +70 -11
  112. package/dist/apps/management/routes/api-keys.js.map +1 -1
  113. package/dist/apps/management/routes/billing.d.ts +84 -84
  114. package/dist/apps/management/routes/cli.d.ts +912 -0
  115. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  116. package/dist/apps/management/routes/cli.js +416 -0
  117. package/dist/apps/management/routes/cli.js.map +1 -0
  118. package/dist/apps/management/routes/faucet.d.ts +8 -8
  119. package/dist/apps/management/routes/invitations.d.ts +138 -138
  120. package/dist/apps/management/routes/invite-links.d.ts +172 -172
  121. package/dist/apps/management/routes/members.d.ts +16 -16
  122. package/dist/apps/management/routes/orgs.d.ts +104 -104
  123. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  124. package/dist/apps/management/routes/orgs.js +8 -2
  125. package/dist/apps/management/routes/orgs.js.map +1 -1
  126. package/dist/apps/management/routes/projects.d.ts +125 -125
  127. package/dist/apps/management/routes/usage.d.ts +8 -8
  128. package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
  129. package/dist/apps/management/routes/webhooks.d.ts +485 -485
  130. package/dist/apps/mpp/App.d.ts +44 -44
  131. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  132. package/dist/apps/mpp/internal/Policy.js +4 -2
  133. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  134. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  135. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  136. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  137. package/dist/apps/relay/App.d.ts +8 -0
  138. package/dist/apps/relay/App.d.ts.map +1 -1
  139. package/dist/apps/relay/App.js +16 -4
  140. package/dist/apps/relay/App.js.map +1 -1
  141. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  142. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  143. package/dist/apps/relay/Sponsorships.js +71 -60
  144. package/dist/apps/relay/Sponsorships.js.map +1 -1
  145. package/dist/apps/routes/Access.d.ts +53 -0
  146. package/dist/apps/routes/Access.d.ts.map +1 -1
  147. package/dist/apps/routes/Access.js +121 -0
  148. package/dist/apps/routes/Access.js.map +1 -1
  149. package/dist/apps/routes/App.d.ts +397 -158
  150. package/dist/apps/routes/App.d.ts.map +1 -1
  151. package/dist/apps/routes/App.js.map +1 -1
  152. package/dist/apps/routes/routes/chains.d.ts +25 -25
  153. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  154. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  155. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  156. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  157. package/dist/apps/routes/routes/quotes.d.ts +171 -81
  158. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  159. package/dist/apps/routes/routes/quotes.js +101 -27
  160. package/dist/apps/routes/routes/quotes.js.map +1 -1
  161. package/dist/apps/routes/routes/transfers.d.ts +532 -480
  162. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/transfers.js +182 -37
  164. package/dist/apps/routes/routes/transfers.js.map +1 -1
  165. package/dist/cli/ApiKeys.d.ts +120 -0
  166. package/dist/cli/ApiKeys.d.ts.map +1 -0
  167. package/dist/cli/ApiKeys.js +138 -0
  168. package/dist/cli/ApiKeys.js.map +1 -0
  169. package/dist/cli/Cli.d.ts +92 -34
  170. package/dist/cli/Cli.d.ts.map +1 -1
  171. package/dist/cli/Cli.js +188 -11
  172. package/dist/cli/Cli.js.map +1 -1
  173. package/dist/cli/Credentials.d.ts +95 -0
  174. package/dist/cli/Credentials.d.ts.map +1 -0
  175. package/dist/cli/Credentials.js +110 -0
  176. package/dist/cli/Credentials.js.map +1 -0
  177. package/dist/cli/Spec.d.ts +59 -0
  178. package/dist/cli/Spec.d.ts.map +1 -0
  179. package/dist/cli/Spec.js +77 -0
  180. package/dist/cli/Spec.js.map +1 -0
  181. package/dist/cli/bin.js +5 -1
  182. package/dist/cli/bin.js.map +1 -1
  183. package/dist/cli/commands/admin.d.ts +5 -5
  184. package/dist/cli/commands/admin.d.ts.map +1 -1
  185. package/dist/cli/commands/auth.d.ts +73 -0
  186. package/dist/cli/commands/auth.d.ts.map +1 -0
  187. package/dist/cli/commands/auth.js +204 -0
  188. package/dist/cli/commands/auth.js.map +1 -0
  189. package/dist/cli/commands/keys.d.ts +17 -0
  190. package/dist/cli/commands/keys.d.ts.map +1 -0
  191. package/dist/cli/commands/keys.js +109 -0
  192. package/dist/cli/commands/keys.js.map +1 -0
  193. package/dist/cloudflare.d.ts +27 -2
  194. package/dist/cloudflare.d.ts.map +1 -1
  195. package/dist/cloudflare.js +144 -17
  196. package/dist/cloudflare.js.map +1 -1
  197. package/dist/db/Db.d.ts +23 -0
  198. package/dist/db/Db.d.ts.map +1 -1
  199. package/dist/db/Db.js +413 -1
  200. package/dist/db/Db.js.map +1 -1
  201. package/dist/db/Schema.d.ts +44 -1
  202. package/dist/db/Schema.d.ts.map +1 -1
  203. package/dist/db/Schema.js +56 -3
  204. package/dist/db/Schema.js.map +1 -1
  205. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  206. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  207. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  208. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  209. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  210. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  211. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  212. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  213. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  214. package/dist/db/tables/authAccounts.js +1 -0
  215. package/dist/db/tables/authAccounts.js.map +1 -1
  216. package/dist/db/tables/earnVaults.d.ts +5 -1
  217. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  218. package/dist/db/tables/earnVaults.js +12 -1
  219. package/dist/db/tables/earnVaults.js.map +1 -1
  220. package/dist/db/tables/organizations.d.ts +4 -2
  221. package/dist/db/tables/organizations.d.ts.map +1 -1
  222. package/dist/db/tables/organizations.js +8 -34
  223. package/dist/db/tables/organizations.js.map +1 -1
  224. package/dist/db/tables/requestUsage.d.ts +5 -1
  225. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  226. package/dist/db/tables/requestUsage.js +10 -2
  227. package/dist/db/tables/requestUsage.js.map +1 -1
  228. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  229. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  230. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  231. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  232. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  233. package/dist/db/tables/rewardRuns.js +4 -0
  234. package/dist/db/tables/rewardRuns.js.map +1 -1
  235. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  236. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  237. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  238. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  239. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  240. package/dist/db/tables/routesDepositAddresses.js +84 -31
  241. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  242. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  243. package/dist/db/tables/routesDeposits.js +31 -21
  244. package/dist/db/tables/routesDeposits.js.map +1 -1
  245. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  246. package/dist/db/tables/routesIdempotency.js +2 -0
  247. package/dist/db/tables/routesIdempotency.js.map +1 -1
  248. package/dist/db/tables/routesPolicies.d.ts +58 -0
  249. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  250. package/dist/db/tables/routesPolicies.js +198 -0
  251. package/dist/db/tables/routesPolicies.js.map +1 -0
  252. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  253. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  254. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  255. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  256. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  257. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  258. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  259. package/dist/db/tables/routesTransfers.d.ts +26 -1
  260. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  261. package/dist/db/tables/routesTransfers.js +36 -6
  262. package/dist/db/tables/routesTransfers.js.map +1 -1
  263. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  264. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.js +144 -33
  266. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  267. package/dist/db/tables/users.d.ts +2 -0
  268. package/dist/db/tables/users.d.ts.map +1 -1
  269. package/dist/db/tables/users.js +11 -0
  270. package/dist/db/tables/users.js.map +1 -1
  271. package/dist/handlers/internal/multisig.d.ts +1 -1
  272. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  273. package/dist/handlers/internal/multisig.js +3 -2
  274. package/dist/handlers/internal/multisig.js.map +1 -1
  275. package/dist/handlers/relay.d.ts +2 -0
  276. package/dist/handlers/relay.d.ts.map +1 -1
  277. package/dist/handlers/relay.js +34 -15
  278. package/dist/handlers/relay.js.map +1 -1
  279. package/dist/internal/Auth.d.ts +57 -6
  280. package/dist/internal/Auth.d.ts.map +1 -1
  281. package/dist/internal/Auth.js +182 -78
  282. package/dist/internal/Auth.js.map +1 -1
  283. package/dist/internal/BetterAuth.d.ts +22 -0
  284. package/dist/internal/BetterAuth.d.ts.map +1 -1
  285. package/dist/internal/BetterAuth.js +17 -14
  286. package/dist/internal/BetterAuth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts +5 -0
  288. package/dist/internal/Cache.d.ts.map +1 -1
  289. package/dist/internal/Cache.js +3 -1
  290. package/dist/internal/Cache.js.map +1 -1
  291. package/dist/internal/CliAuth.d.ts +243 -0
  292. package/dist/internal/CliAuth.d.ts.map +1 -0
  293. package/dist/internal/CliAuth.js +249 -0
  294. package/dist/internal/CliAuth.js.map +1 -0
  295. package/dist/internal/EarnSharePrices.d.ts +1 -1
  296. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  297. package/dist/internal/EarnSharePrices.js +7 -3
  298. package/dist/internal/EarnSharePrices.js.map +1 -1
  299. package/dist/internal/EarnVaults.d.ts +47 -0
  300. package/dist/internal/EarnVaults.d.ts.map +1 -1
  301. package/dist/internal/EarnVaults.js +188 -4
  302. package/dist/internal/EarnVaults.js.map +1 -1
  303. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  304. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  305. package/dist/internal/EarnWithdrawals.js +189 -0
  306. package/dist/internal/EarnWithdrawals.js.map +1 -0
  307. package/dist/internal/ExecutionContext.d.ts +21 -0
  308. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  309. package/dist/internal/ExecutionContext.js +16 -0
  310. package/dist/internal/ExecutionContext.js.map +1 -0
  311. package/dist/internal/Log.d.ts +7 -3
  312. package/dist/internal/Log.d.ts.map +1 -1
  313. package/dist/internal/Log.js +163 -130
  314. package/dist/internal/Log.js.map +1 -1
  315. package/dist/internal/MetricSink.d.ts.map +1 -1
  316. package/dist/internal/MetricSink.js +26 -1
  317. package/dist/internal/MetricSink.js.map +1 -1
  318. package/dist/internal/RateLimit.d.ts +67 -0
  319. package/dist/internal/RateLimit.d.ts.map +1 -1
  320. package/dist/internal/RateLimit.js +174 -27
  321. package/dist/internal/RateLimit.js.map +1 -1
  322. package/dist/internal/Store.d.ts +6 -0
  323. package/dist/internal/Store.d.ts.map +1 -1
  324. package/dist/internal/Store.js +4 -5
  325. package/dist/internal/Store.js.map +1 -1
  326. package/dist/internal/Timing.d.ts +6 -0
  327. package/dist/internal/Timing.d.ts.map +1 -1
  328. package/dist/internal/Timing.js +21 -1
  329. package/dist/internal/Timing.js.map +1 -1
  330. package/dist/internal/Tron.d.ts +124 -0
  331. package/dist/internal/Tron.d.ts.map +1 -0
  332. package/dist/internal/Tron.js +202 -0
  333. package/dist/internal/Tron.js.map +1 -0
  334. package/dist/internal/Viem.d.ts +4 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Viem.js +25 -6
  337. package/dist/internal/Viem.js.map +1 -1
  338. package/dist/internal/rewards/Read.d.ts +2 -2
  339. package/dist/internal/rewards/Read.d.ts.map +1 -1
  340. package/dist/internal/rewards/Read.js +11 -2
  341. package/dist/internal/rewards/Read.js.map +1 -1
  342. package/dist/internal/routes/Action.d.ts +27 -0
  343. package/dist/internal/routes/Action.d.ts.map +1 -1
  344. package/dist/internal/routes/Action.js +49 -1
  345. package/dist/internal/routes/Action.js.map +1 -1
  346. package/dist/internal/routes/Chain.d.ts +2 -0
  347. package/dist/internal/routes/Chain.d.ts.map +1 -1
  348. package/dist/internal/routes/Chain.js +4 -0
  349. package/dist/internal/routes/Chain.js.map +1 -1
  350. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  351. package/dist/internal/routes/DepositAddress.js +5 -0
  352. package/dist/internal/routes/DepositAddress.js.map +1 -1
  353. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  354. package/dist/internal/routes/Evidence.js +6 -2
  355. package/dist/internal/routes/Evidence.js.map +1 -1
  356. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  357. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  358. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  359. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  360. package/dist/internal/routes/Policy.d.ts +161 -0
  361. package/dist/internal/routes/Policy.d.ts.map +1 -0
  362. package/dist/internal/routes/Policy.js +249 -0
  363. package/dist/internal/routes/Policy.js.map +1 -0
  364. package/dist/internal/routes/Provider.d.ts +66 -3
  365. package/dist/internal/routes/Provider.d.ts.map +1 -1
  366. package/dist/internal/routes/Provider.js +106 -27
  367. package/dist/internal/routes/Provider.js.map +1 -1
  368. package/dist/internal/routes/Quota.d.ts +57 -0
  369. package/dist/internal/routes/Quota.d.ts.map +1 -0
  370. package/dist/internal/routes/Quota.js +144 -0
  371. package/dist/internal/routes/Quota.js.map +1 -0
  372. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  373. package/dist/internal/routes/Reconciliation.js +163 -47
  374. package/dist/internal/routes/Reconciliation.js.map +1 -1
  375. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  376. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  377. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  378. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  379. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  380. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  381. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  382. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  383. package/dist/internal/routes/Subsidy.d.ts +2 -2
  384. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  385. package/dist/internal/routes/Subsidy.js +2 -2
  386. package/dist/internal/routes/Subsidy.js.map +1 -1
  387. package/dist/internal/routes/Transfer.d.ts +229 -1
  388. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  389. package/dist/internal/routes/Transfer.js +644 -7
  390. package/dist/internal/routes/Transfer.js.map +1 -1
  391. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  392. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  393. package/dist/internal/routes/TransferReconciliation.js +83 -159
  394. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  395. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  396. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  397. package/dist/internal/routes/TransferSettlement.js +2 -0
  398. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  399. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  400. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  401. package/dist/internal/routes/TransferSubsidy.js +64 -5
  402. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  403. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  404. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  405. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  406. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  407. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  408. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  409. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  410. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  411. package/dist/internal/routes/index.d.ts +3 -0
  412. package/dist/internal/routes/index.d.ts.map +1 -1
  413. package/dist/internal/routes/index.js +3 -0
  414. package/dist/internal/routes/index.js.map +1 -1
  415. package/dist/internal/routes/providers/across.d.ts +3 -0
  416. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  417. package/dist/internal/routes/providers/across.js +11 -0
  418. package/dist/internal/routes/providers/across.js.map +1 -1
  419. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  420. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  421. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  422. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  423. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  424. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  425. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  426. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  427. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  428. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  429. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  430. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  431. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  432. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  434. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  435. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  436. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/propAmm.js +524 -0
  438. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  439. package/dist/internal/routes/providers/relay.d.ts +3 -0
  440. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  441. package/dist/internal/routes/providers/relay.js +352 -41
  442. package/dist/internal/routes/providers/relay.js.map +1 -1
  443. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  444. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  445. package/dist/internal/routes/providers/rhino.js +11 -0
  446. package/dist/internal/routes/providers/rhino.js.map +1 -1
  447. package/dist/internal/routes/providers/squid.d.ts +3 -0
  448. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  449. package/dist/internal/routes/providers/squid.js +19 -0
  450. package/dist/internal/routes/providers/squid.js.map +1 -1
  451. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  452. package/dist/internal/routes/providers/stargate.js +22 -9
  453. package/dist/internal/routes/providers/stargate.js.map +1 -1
  454. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  455. package/dist/internal/routes/providers/symbiosis.js +13 -17
  456. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  457. package/dist/providers/index.d.ts +14 -0
  458. package/dist/providers/index.d.ts.map +1 -1
  459. package/dist/providers/index.js +6 -0
  460. package/dist/providers/index.js.map +1 -1
  461. package/package.json +16 -6
  462. package/src/ApiKey.ts +7 -3
  463. package/src/ApiKeys.test.ts +652 -8
  464. package/src/ApiKeys.ts +191 -11
  465. package/src/App.test.ts +405 -18
  466. package/src/App.ts +51 -15
  467. package/src/Client.test-d.ts +157 -10
  468. package/src/Client.test.ts +4 -4
  469. package/src/Scope.ts +1 -2
  470. package/src/admin/App.ts +11 -5
  471. package/src/admin/apps/api-keys.test.ts +98 -2
  472. package/src/admin/apps/api-keys.ts +21 -12
  473. package/src/admin/apps/earn-vaults.test.ts +76 -7
  474. package/src/admin/apps/earn-vaults.ts +47 -8
  475. package/src/admin/apps/organizations.test.ts +147 -31
  476. package/src/admin/apps/organizations.ts +5 -4
  477. package/src/admin/apps/route-policies.test.ts +220 -0
  478. package/src/admin/apps/route-policies.ts +322 -0
  479. package/src/admin/apps/routes-support.test.ts +107 -2
  480. package/src/admin/apps/routes-support.ts +43 -3
  481. package/src/admin/apps/routes.test.ts +150 -0
  482. package/src/admin/apps/routes.ts +97 -1
  483. package/src/admin/apps/scopes.test.ts +1 -1
  484. package/src/admin/index.ts +0 -1
  485. package/src/admin/ui/plugin.ts +2 -1
  486. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  487. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  488. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  489. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  490. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  491. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  492. package/src/admin/ui/src/lib/routes.ts +34 -0
  493. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  494. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  495. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  496. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  497. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  498. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  499. package/src/admin/ui/src/routes/organizations.tsx +1 -0
  500. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  501. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  502. package/src/admin/ui/src/routes/routes.tsx +85 -2
  503. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  504. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  505. package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
  506. package/src/admin/ui.generated.ts +258 -202
  507. package/src/analytics/Analytics.test.ts +4 -50
  508. package/src/analytics/Analytics.ts +65 -1
  509. package/src/analytics/tables/requestEvents.test.ts +402 -1
  510. package/src/analytics/tables/requestEvents.ts +62 -93
  511. package/src/apps/data/routes/activities.test.ts +315 -14
  512. package/src/apps/data/routes/activities.ts +60 -0
  513. package/src/apps/data/routes/balances.ts +5 -7
  514. package/src/apps/data/routes/earn.bench.ts +18 -0
  515. package/src/apps/data/routes/earn.local.test.ts +507 -0
  516. package/src/apps/data/routes/earn.test.ts +405 -127
  517. package/src/apps/data/routes/earn.ts +660 -270
  518. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  519. package/src/apps/data/routes/exchanges.test.ts +166 -2
  520. package/src/apps/data/routes/exchanges.ts +308 -101
  521. package/src/apps/data/routes/fee-amm.test.ts +134 -2
  522. package/src/apps/data/routes/fee-amm.ts +122 -60
  523. package/src/apps/data/routes/receipts.test.ts +21 -18
  524. package/src/apps/data/routes/rpc.test.ts +2 -2
  525. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  526. package/src/apps/data/routes/tokens.test.ts +4 -4
  527. package/src/apps/data/routes/tokens.ts +11 -6
  528. package/src/apps/data/routes/transactions.test.ts +29 -0
  529. package/src/apps/data/routes/transactions.ts +33 -22
  530. package/src/apps/data/routes/webhooks.test.ts +12 -3
  531. package/src/apps/data/routes/webhooks.ts +2 -1
  532. package/src/apps/management/App.ts +4 -0
  533. package/src/apps/management/Billing.test.ts +253 -27
  534. package/src/apps/management/Billing.ts +83 -29
  535. package/src/apps/management/routes/api-keys.test.ts +1 -1
  536. package/src/apps/management/routes/api-keys.ts +85 -11
  537. package/src/apps/management/routes/billing.test.ts +68 -4
  538. package/src/apps/management/routes/cli.test.ts +370 -0
  539. package/src/apps/management/routes/cli.ts +533 -0
  540. package/src/apps/management/routes/me.test.ts +14 -4
  541. package/src/apps/management/routes/orgs.test.ts +108 -4
  542. package/src/apps/management/routes/orgs.ts +7 -2
  543. package/src/apps/management/routes/usage.test.ts +2 -2
  544. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  545. package/src/apps/mpp/internal/Policy.ts +6 -2
  546. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  547. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  548. package/src/apps/relay/App.test.ts +85 -1
  549. package/src/apps/relay/App.ts +28 -4
  550. package/src/apps/relay/Sponsorships.test.ts +97 -1
  551. package/src/apps/relay/Sponsorships.ts +77 -66
  552. package/src/apps/routes/Access.test.ts +319 -0
  553. package/src/apps/routes/Access.ts +147 -0
  554. package/src/apps/routes/App.ts +10 -0
  555. package/src/apps/routes/routes/chains.test.ts +3 -2
  556. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  557. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  558. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  559. package/src/apps/routes/routes/quotes.test.ts +81 -8
  560. package/src/apps/routes/routes/quotes.ts +109 -27
  561. package/src/apps/routes/routes/transfers.test.ts +252 -15
  562. package/src/apps/routes/routes/transfers.ts +212 -33
  563. package/src/cli/ApiKeys.test.ts +265 -0
  564. package/src/cli/ApiKeys.ts +189 -0
  565. package/src/cli/Cli.test.ts +188 -0
  566. package/src/cli/Cli.ts +280 -12
  567. package/src/cli/Credentials.test.ts +122 -0
  568. package/src/cli/Credentials.ts +144 -0
  569. package/src/cli/Spec.test.ts +133 -0
  570. package/src/cli/Spec.ts +132 -0
  571. package/src/cli/bin.test.ts +49 -0
  572. package/src/cli/bin.ts +5 -1
  573. package/src/cli/commands/auth.test.ts +138 -0
  574. package/src/cli/commands/auth.ts +254 -0
  575. package/src/cli/commands/keys.test.ts +68 -0
  576. package/src/cli/commands/keys.ts +125 -0
  577. package/src/cloudflare.ts +184 -36
  578. package/src/db/Db.test.ts +877 -0
  579. package/src/db/Db.ts +498 -1
  580. package/src/db/Schema.ts +75 -4
  581. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  582. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  583. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  584. package/src/db/tables/authAccounts.test.ts +30 -0
  585. package/src/db/tables/authAccounts.ts +1 -0
  586. package/src/db/tables/earnVaults.test.ts +34 -0
  587. package/src/db/tables/earnVaults.ts +17 -2
  588. package/src/db/tables/organizations.test.ts +148 -84
  589. package/src/db/tables/organizations.ts +11 -43
  590. package/src/db/tables/requestUsage.ts +13 -2
  591. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  592. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  593. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  594. package/src/db/tables/rewardRuns.ts +4 -0
  595. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  596. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  597. package/src/db/tables/routesDepositAddresses.ts +118 -34
  598. package/src/db/tables/routesDeposits.test.ts +66 -5
  599. package/src/db/tables/routesDeposits.ts +47 -26
  600. package/src/db/tables/routesIdempotency.test.ts +80 -0
  601. package/src/db/tables/routesIdempotency.ts +2 -0
  602. package/src/db/tables/routesPolicies.test.ts +143 -0
  603. package/src/db/tables/routesPolicies.ts +251 -0
  604. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  605. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  606. package/src/db/tables/routesTransfers.test.ts +183 -2
  607. package/src/db/tables/routesTransfers.ts +65 -6
  608. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  609. package/src/db/tables/sponsoredTransactions.ts +182 -38
  610. package/src/db/tables/users.test.ts +51 -0
  611. package/src/db/tables/users.ts +12 -0
  612. package/src/handlers/internal/multisig.store.test.ts +120 -0
  613. package/src/handlers/internal/multisig.test.ts +389 -0
  614. package/src/handlers/internal/multisig.ts +13 -10
  615. package/src/handlers/relay.test.ts +259 -83
  616. package/src/handlers/relay.ts +36 -17
  617. package/src/internal/Auth.test.ts +291 -8
  618. package/src/internal/Auth.ts +227 -96
  619. package/src/internal/BetterAuth.test.ts +58 -22
  620. package/src/internal/BetterAuth.ts +23 -17
  621. package/src/internal/Cache.ts +3 -1
  622. package/src/internal/CliAuth.test.ts +279 -0
  623. package/src/internal/CliAuth.ts +319 -0
  624. package/src/internal/EarnSharePrices.test.ts +25 -0
  625. package/src/internal/EarnSharePrices.ts +9 -2
  626. package/src/internal/EarnVaults.test.ts +67 -0
  627. package/src/internal/EarnVaults.ts +299 -4
  628. package/src/internal/EarnWithdrawals.test.ts +315 -0
  629. package/src/internal/EarnWithdrawals.ts +266 -0
  630. package/src/internal/ExecutionContext.ts +31 -0
  631. package/src/internal/Log.test.ts +210 -0
  632. package/src/internal/Log.ts +180 -142
  633. package/src/internal/MetricSink.test.ts +190 -15
  634. package/src/internal/MetricSink.ts +27 -1
  635. package/src/internal/RateLimit.test.ts +144 -8
  636. package/src/internal/RateLimit.ts +254 -26
  637. package/src/internal/Store.ts +4 -5
  638. package/src/internal/Timing.test.ts +32 -0
  639. package/src/internal/Timing.ts +20 -1
  640. package/src/internal/Tron.test-d.ts +22 -0
  641. package/src/internal/Tron.test.ts +94 -0
  642. package/src/internal/Tron.ts +289 -0
  643. package/src/internal/Viem.rpc.test.ts +76 -0
  644. package/src/internal/Viem.ts +29 -6
  645. package/src/internal/rewards/Read.test.ts +109 -0
  646. package/src/internal/rewards/Read.ts +13 -4
  647. package/src/internal/routes/Action.test.ts +70 -0
  648. package/src/internal/routes/Action.ts +76 -1
  649. package/src/internal/routes/Chain.test.ts +18 -0
  650. package/src/internal/routes/Chain.ts +5 -0
  651. package/src/internal/routes/DepositAddress.ts +5 -0
  652. package/src/internal/routes/Evidence.test.ts +64 -0
  653. package/src/internal/routes/Evidence.ts +11 -3
  654. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  655. package/src/internal/routes/Policy.test.ts +316 -0
  656. package/src/internal/routes/Policy.ts +399 -0
  657. package/src/internal/routes/Provider.test.ts +103 -2
  658. package/src/internal/routes/Provider.ts +149 -27
  659. package/src/internal/routes/Quota.test.ts +149 -0
  660. package/src/internal/routes/Quota.ts +226 -0
  661. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  662. package/src/internal/routes/Reconciliation.test.ts +371 -13
  663. package/src/internal/routes/Reconciliation.ts +193 -42
  664. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  665. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  666. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  667. package/src/internal/routes/SourceObservation.test.ts +221 -0
  668. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  669. package/src/internal/routes/Subsidy.ts +4 -2
  670. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  671. package/src/internal/routes/Transfer.test.ts +130 -1
  672. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  673. package/src/internal/routes/Transfer.ts +866 -8
  674. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  675. package/src/internal/routes/TransferReconciliation.ts +91 -166
  676. package/src/internal/routes/TransferSettlement.ts +48 -0
  677. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  678. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  679. package/src/internal/routes/TransferSubsidy.ts +87 -12
  680. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  681. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  682. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  683. package/src/internal/routes/index.test.ts +3 -0
  684. package/src/internal/routes/index.ts +3 -0
  685. package/src/internal/routes/providers/across.ts +13 -0
  686. package/src/internal/routes/providers/index.test.ts +141 -0
  687. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  688. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  689. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  690. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  691. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  692. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  693. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  694. package/src/internal/routes/providers/propAmm.ts +640 -0
  695. package/src/internal/routes/providers/relay.test.ts +1263 -41
  696. package/src/internal/routes/providers/relay.ts +423 -38
  697. package/src/internal/routes/providers/rhino.ts +14 -1
  698. package/src/internal/routes/providers/squid.ts +21 -0
  699. package/src/internal/routes/providers/stargate.test.ts +105 -1
  700. package/src/internal/routes/providers/stargate.ts +22 -9
  701. package/src/internal/routes/providers/symbiosis.ts +13 -47
  702. package/src/providers/index.test.ts +2 -0
  703. package/src/providers/index.ts +18 -0
  704. package/dist/admin/Access.d.ts +0 -39
  705. package/dist/admin/Access.d.ts.map +0 -1
  706. package/dist/admin/Access.js +0 -73
  707. package/dist/admin/Access.js.map +0 -1
  708. package/src/admin/Access.test.ts +0 -130
  709. package/src/admin/Access.ts +0 -85
@@ -0,0 +1,760 @@
1
+ import { ed25519 } from '@noble/curves/ed25519'
2
+ import {
3
+ findAssociatedTokenPda,
4
+ getTokenDecoder,
5
+ getTransferCheckedInstruction,
6
+ TOKEN_PROGRAM_ADDRESS,
7
+ } from '@solana-program/token'
8
+ import {
9
+ address,
10
+ appendTransactionMessageInstruction,
11
+ blockhash,
12
+ compileTransaction,
13
+ createTransactionMessage,
14
+ decompileTransactionMessage,
15
+ getCompiledTransactionMessageDecoder,
16
+ getTransactionDecoder,
17
+ getTransactionEncoder,
18
+ setTransactionMessageFeePayer,
19
+ setTransactionMessageLifetimeUsingBlockhash,
20
+ } from '@solana/kit'
21
+ import { Base58 } from 'ox'
22
+
23
+ import type * as Chain from './Chain.js'
24
+
25
+ const mainnet = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
26
+ const usdcMint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
27
+ const recoverySlotWindow = 256
28
+ const signingBlockMargin = 64
29
+
30
+ /** An immutable Solana transaction prepared before requesting a Horcrux signature. */
31
+ export type Prepared = {
32
+ /** Horcrux wallet public key. */
33
+ account: string
34
+ /** Destination token quantity in base units. */
35
+ amount: string
36
+ /** Destination chain identifier. */
37
+ chainId: string
38
+ /** Derived recipient USDC token account. */
39
+ destination: string
40
+ /** Last block height at which Solana accepts the transaction. */
41
+ lastValidBlockHeight: number
42
+ /** Native SOL fee reserved in lamports. */
43
+ nativeAmount: string
44
+ /** Finalized slot that supplied the transaction blockhash. */
45
+ originSlot: number
46
+ /** Recipient wallet public key. */
47
+ recipient: string
48
+ /** Exact body sent to Horcrux on signing retries. */
49
+ request: { network: 'solana:mainnet-beta'; transaction: string }
50
+ /** Derived subsidy wallet USDC token account. */
51
+ source: string
52
+ /** Destination token mint. */
53
+ token: string
54
+ }
55
+
56
+ /** A Horcrux-signed transaction persisted before broadcast. */
57
+ export type Signed = Prepared & {
58
+ /** First Solana signature, used as the transaction identifier. */
59
+ hash: string
60
+ /** Canonical signed transaction in standard base64. */
61
+ transaction: string
62
+ }
63
+
64
+ /** Read-only Solana destination subsidy inventory checker. */
65
+ export type Inventory = {
66
+ /** Horcrux wallet public key. */
67
+ account: string
68
+ /** Checks USDC and SOL capacity including unsettled commitments. */
69
+ check(options: create.CheckOptions): Promise<{ nativeAmount: string }>
70
+ /** Operational maximum destination subsidy. */
71
+ policy: { maxAmount: string }
72
+ }
73
+
74
+ /** Prepares, signs, broadcasts, and verifies Solana destination subsidies. */
75
+ export type Settler = Inventory & {
76
+ /** Broadcasts the persisted signed transaction. */
77
+ broadcast(options: { chain: Chain.Chain; signed: Signed }): Promise<void>
78
+ /** Checks whether a prepared blockhash is too close to expiry to sign safely. */
79
+ expiring(options: { chain: Chain.Chain; prepared: Prepared }): Promise<boolean>
80
+ /** Constructs an unsigned transfer without contacting Horcrux. */
81
+ prepare(options: create.CheckOptions): Promise<Prepared>
82
+ /** Signs an immutable request through Horcrux. */
83
+ sign(options: { idempotencyKey: string; prepared: Prepared }): Promise<Signed>
84
+ /** Reads finalized execution for the exact signed transaction. */
85
+ status(
86
+ options: create.StatusOptions,
87
+ ): Promise<'ambiguous' | 'expired' | 'pending' | 'reverted' | 'success'>
88
+ }
89
+
90
+ /** Validates prepared subsidy state restored from durable storage. */
91
+ export function readPrepared(value: unknown): Prepared | undefined {
92
+ if (typeof value === 'string') {
93
+ try {
94
+ value = JSON.parse(value)
95
+ } catch {
96
+ return undefined
97
+ }
98
+ }
99
+ if (!isObject(value) || !isObject(value['request'])) return undefined
100
+ const request = value['request']
101
+ if (
102
+ typeof value['account'] !== 'string' ||
103
+ typeof value['amount'] !== 'string' ||
104
+ !/^[1-9]\d*$/.test(value['amount']) ||
105
+ value['chainId'] !== mainnet ||
106
+ typeof value['destination'] !== 'string' ||
107
+ typeof value['lastValidBlockHeight'] !== 'number' ||
108
+ !Number.isSafeInteger(value['lastValidBlockHeight']) ||
109
+ value['lastValidBlockHeight'] <= 0 ||
110
+ typeof value['nativeAmount'] !== 'string' ||
111
+ !/^[1-9]\d*$/.test(value['nativeAmount']) ||
112
+ typeof value['originSlot'] !== 'number' ||
113
+ !Number.isSafeInteger(value['originSlot']) ||
114
+ value['originSlot'] <= 0 ||
115
+ typeof value['recipient'] !== 'string' ||
116
+ typeof value['source'] !== 'string' ||
117
+ value['token'] !== usdcMint ||
118
+ request['network'] !== 'solana:mainnet-beta' ||
119
+ typeof request['transaction'] !== 'string'
120
+ )
121
+ return undefined
122
+ try {
123
+ const account = address(value['account'])
124
+ address(value['recipient'])
125
+ const source = address(value['source'])
126
+ const destination = address(value['destination'])
127
+ const raw = Buffer.from(request['transaction'], 'base64')
128
+ if (raw.toString('base64') !== request['transaction']) return undefined
129
+ const tx = getTransactionDecoder().decode(raw)
130
+ const compiled = getCompiledTransactionMessageDecoder().decode(tx.messageBytes)
131
+ if (compiled.version !== 'legacy') return undefined
132
+ const message = decompileTransactionMessage(compiled)
133
+ if (!('blockhash' in message.lifetimeConstraint)) return undefined
134
+ if (Object.keys(tx.signatures).length !== 1 || tx.signatures[account] !== null) return undefined
135
+ const expected = unsignedTransaction({
136
+ account,
137
+ amount: BigInt(value['amount']),
138
+ blockhash: message.lifetimeConstraint.blockhash,
139
+ destination,
140
+ source,
141
+ })
142
+ if (!Buffer.from(getTransactionEncoder().encode(expected)).equals(raw)) return undefined
143
+ } catch {
144
+ return undefined
145
+ }
146
+ return value as Prepared
147
+ }
148
+
149
+ /** Validates signed subsidy state restored from durable storage. */
150
+ export function readSigned(value: unknown): Signed | undefined {
151
+ const prepared = readPrepared(value)
152
+ if (!prepared || typeof (prepared as Signed).transaction !== 'string') return undefined
153
+ const signed = prepared as Signed
154
+ try {
155
+ const raw = Buffer.from(signed.transaction, 'base64')
156
+ if (raw.toString('base64') !== signed.transaction) return undefined
157
+ const tx = getTransactionDecoder().decode(raw)
158
+ const signature = tx.signatures[address(signed.account)]
159
+ const preparedTransaction = getTransactionDecoder().decode(
160
+ Buffer.from(prepared.request.transaction, 'base64'),
161
+ )
162
+ if (
163
+ typeof signed.hash !== 'string' ||
164
+ !signature ||
165
+ Object.keys(tx.signatures).length !== 1 ||
166
+ !Buffer.from(tx.messageBytes).equals(Buffer.from(preparedTransaction.messageBytes)) ||
167
+ !ed25519.verify(
168
+ Buffer.from(signature),
169
+ Buffer.from(tx.messageBytes),
170
+ Base58.toBytes(signed.account),
171
+ ) ||
172
+ Base58.fromBytes(signature) !== signed.hash ||
173
+ !Buffer.from(getTransactionEncoder().encode(tx)).equals(raw)
174
+ )
175
+ return undefined
176
+ } catch {
177
+ return undefined
178
+ }
179
+ return signed
180
+ }
181
+
182
+ /** Checks persisted transaction terms against freshly verified delivery. */
183
+ export function matchesTerms(prepared: Prepared, options: matchesTerms.Options): boolean {
184
+ return (
185
+ readPrepared(prepared) !== undefined &&
186
+ prepared.account === options.account &&
187
+ prepared.amount === options.amount.toString() &&
188
+ prepared.chainId === options.chainId &&
189
+ prepared.recipient === options.recipient &&
190
+ prepared.token === options.token
191
+ )
192
+ }
193
+
194
+ export declare namespace matchesTerms {
195
+ /** Exact terms required before a subsidy is signed or broadcast. */
196
+ type Options = {
197
+ account: string
198
+ amount: bigint
199
+ chainId: string
200
+ recipient: string
201
+ token: string
202
+ }
203
+ }
204
+
205
+ /** Creates a Solana inventory checker and Horcrux signer for one wallet. */
206
+ export function create(options: create.Options): Settler {
207
+ const account = address(options.account)
208
+ if (!/^[0-9a-fA-F-]{36}$/.test(options.walletId))
209
+ throw new ConfigurationError('Invalid Horcrux wallet ID.')
210
+ const horcruxUrl = new URL(options.horcrux.url)
211
+ if (
212
+ !['https:', 'http:'].includes(horcruxUrl.protocol) ||
213
+ (horcruxUrl.protocol === 'http:' &&
214
+ !['localhost', '127.0.0.1', '[::1]'].includes(horcruxUrl.hostname)) ||
215
+ horcruxUrl.username ||
216
+ horcruxUrl.password ||
217
+ horcruxUrl.search ||
218
+ horcruxUrl.hash
219
+ )
220
+ throw new ConfigurationError('Horcrux requires HTTPS or loopback HTTP.')
221
+ if (
222
+ options.horcrux.auth.type === 'none' &&
223
+ !['localhost', '127.0.0.1', '[::1]'].includes(horcruxUrl.hostname)
224
+ )
225
+ throw new ConfigurationError('Unauthenticated Horcrux requires loopback.')
226
+
227
+ async function rpc(chain: Chain.Chain, method: string, params: readonly unknown[]) {
228
+ assertChain(chain)
229
+ let failure: UpstreamError | undefined
230
+ for (const url of chain.rpcUrls) {
231
+ let response: Response
232
+ try {
233
+ response = await options.fetch(url, {
234
+ body: JSON.stringify({ id: 1, jsonrpc: '2.0', method, params }),
235
+ headers: { 'content-type': 'application/json' },
236
+ method: 'POST',
237
+ signal: AbortSignal.timeout(10_000),
238
+ })
239
+ } catch {
240
+ failure = new UpstreamError(`Solana RPC ${method} is unavailable.`)
241
+ continue
242
+ }
243
+ if (!response.ok) {
244
+ failure = new UpstreamError(`Solana RPC returned HTTP ${response.status}.`)
245
+ continue
246
+ }
247
+ let body: unknown
248
+ try {
249
+ body = await response.json()
250
+ } catch {
251
+ failure = new UpstreamError(`Solana RPC ${method} returned an invalid response.`)
252
+ continue
253
+ }
254
+ if (!isObject(body)) {
255
+ failure = new UpstreamError(`Solana RPC ${method} returned an invalid response.`)
256
+ continue
257
+ }
258
+ if (body['error'] !== undefined) {
259
+ const cause = body['error']
260
+ const message =
261
+ isObject(cause) && typeof cause['message'] === 'string'
262
+ ? cause['message']
263
+ : 'unknown error'
264
+ const blockhashNotFound =
265
+ isObject(cause) &&
266
+ ((isObject(cause['data']) && cause['data']['err'] === 'BlockhashNotFound') ||
267
+ /blockhash not found/i.test(message))
268
+ const error = new UpstreamError(`Solana RPC ${method} failed: ${message}`)
269
+ // Other nodes may still serve a request when one node is unhealthy or lacks recent history.
270
+ if (
271
+ isObject(cause) &&
272
+ typeof cause['code'] === 'number' &&
273
+ ([-32603, -32016, -32009, -32005, -32004].includes(cause['code']) ||
274
+ (method === 'sendTransaction' && cause['code'] === -32002 && blockhashNotFound))
275
+ ) {
276
+ failure = error
277
+ continue
278
+ }
279
+ throw error
280
+ }
281
+ if (!('result' in body)) {
282
+ failure = new UpstreamError(`Solana RPC ${method} omitted a result.`)
283
+ continue
284
+ }
285
+ return body['result']
286
+ }
287
+ throw failure ?? new UpstreamError(`Solana RPC ${method} is unavailable.`)
288
+ }
289
+
290
+ async function expiredStatus(chain: Chain.Chain, signed: Signed) {
291
+ const info = await rpc(chain, 'getEpochInfo', [{ commitment: 'finalized' }])
292
+ if (
293
+ !isObject(info) ||
294
+ typeof info['absoluteSlot'] !== 'number' ||
295
+ typeof info['blockHeight'] !== 'number' ||
296
+ !Number.isSafeInteger(info['absoluteSlot']) ||
297
+ !Number.isSafeInteger(info['blockHeight'])
298
+ )
299
+ throw new UpstreamError('Solana finalized position is unavailable.')
300
+ if (info['blockHeight'] <= signed.lastValidBlockHeight) return 'pending' as const
301
+ const endSlot = info['absoluteSlot']
302
+ if (endSlot < signed.originSlot) return 'ambiguous' as const
303
+ const first = await rpc(chain, 'getFirstAvailableBlock', [])
304
+ if (typeof first !== 'number' || !Number.isSafeInteger(first))
305
+ throw new UpstreamError('Solana block history boundary is unavailable.')
306
+ if (first > signed.originSlot) return 'ambiguous' as const
307
+ let previousSlot: number | undefined
308
+ let previousBlockhash: string | undefined
309
+ let previousHeight: number | undefined
310
+ for (let start = signed.originSlot; start <= endSlot; start += recoverySlotWindow) {
311
+ const end = Math.min(start + recoverySlotWindow - 1, endSlot)
312
+ const slots = await rpc(chain, 'getBlocks', [start, end, { commitment: 'finalized' }])
313
+ if (
314
+ !Array.isArray(slots) ||
315
+ slots.some(
316
+ (slot, index) =>
317
+ typeof slot !== 'number' ||
318
+ !Number.isSafeInteger(slot) ||
319
+ slot < start ||
320
+ slot > end ||
321
+ (index > 0 && slot <= slots[index - 1]),
322
+ )
323
+ )
324
+ return 'ambiguous' as const
325
+ for (let offset = 0; offset < slots.length; offset += 8) {
326
+ const batch = slots.slice(offset, offset + 8)
327
+ const blocks = await Promise.all(
328
+ batch.map((slot) =>
329
+ rpc(chain, 'getBlock', [
330
+ slot,
331
+ {
332
+ commitment: 'finalized',
333
+ maxSupportedTransactionVersion: 1,
334
+ rewards: false,
335
+ transactionDetails: 'signatures',
336
+ },
337
+ ]),
338
+ ),
339
+ )
340
+ for (const [index, block] of blocks.entries()) {
341
+ const slot = batch[index]!
342
+ const result = inspectFinalizedBlock({
343
+ block,
344
+ lastValidBlockHeight: signed.lastValidBlockHeight,
345
+ originSlot: signed.originSlot,
346
+ previousBlockhash,
347
+ previousHeight,
348
+ previousSlot,
349
+ signature: signed.hash,
350
+ slot,
351
+ })
352
+ if (result.type === 'ambiguous') return 'ambiguous' as const
353
+ previousSlot = slot
354
+ previousBlockhash = result.blockhash
355
+ previousHeight = result.blockHeight
356
+ if (result.type === 'found') {
357
+ const full = await rpc(chain, 'getBlock', [
358
+ slot,
359
+ {
360
+ commitment: 'finalized',
361
+ encoding: 'json',
362
+ maxSupportedTransactionVersion: 1,
363
+ rewards: false,
364
+ transactionDetails: 'full',
365
+ },
366
+ ])
367
+ if (
368
+ !isObject(full) ||
369
+ full['blockhash'] !== result.blockhash ||
370
+ !Array.isArray(full['transactions'])
371
+ )
372
+ return 'ambiguous' as const
373
+ const entry = full['transactions'].find(
374
+ (value) =>
375
+ isObject(value) &&
376
+ isObject(value['transaction']) &&
377
+ Array.isArray(value['transaction']['signatures']) &&
378
+ value['transaction']['signatures'].includes(signed.hash),
379
+ )
380
+ if (!isObject(entry) || !isObject(entry['meta']) || !('err' in entry['meta']))
381
+ return 'ambiguous' as const
382
+ return entry['meta']['err'] === null ? ('success' as const) : ('reverted' as const)
383
+ }
384
+ // The first finalized block above the validity height closes the entire inclusion window.
385
+ if (result.type === 'expired') return 'expired' as const
386
+ }
387
+ }
388
+ }
389
+ return 'ambiguous' as const
390
+ }
391
+
392
+ async function accountsMatch(prepared: Prepared) {
393
+ const mint = address(prepared.token)
394
+ const [[source], [destination]] = await Promise.all([
395
+ findAssociatedTokenPda({
396
+ mint,
397
+ owner: address(prepared.account),
398
+ tokenProgram: TOKEN_PROGRAM_ADDRESS,
399
+ }),
400
+ findAssociatedTokenPda({
401
+ mint,
402
+ owner: address(prepared.recipient),
403
+ tokenProgram: TOKEN_PROGRAM_ADDRESS,
404
+ }),
405
+ ])
406
+ return prepared.source === source && prepared.destination === destination
407
+ }
408
+
409
+ async function tokenAccount(chain: Chain.Chain, tokenAddress: string) {
410
+ const result = await rpc(chain, 'getAccountInfo', [
411
+ tokenAddress,
412
+ { commitment: 'finalized', encoding: 'base64' },
413
+ ])
414
+ if (!isObject(result) || !isObject(result['value'])) throw new BalanceUnavailableError()
415
+ const value = result['value']
416
+ if (
417
+ value['owner'] !== TOKEN_PROGRAM_ADDRESS ||
418
+ !Array.isArray(value['data']) ||
419
+ typeof value['data'][0] !== 'string' ||
420
+ value['data'][1] !== 'base64'
421
+ )
422
+ throw new ConfigurationError('Solana subsidy token account is invalid.')
423
+ return getTokenDecoder().decode(Buffer.from(value['data'][0], 'base64'))
424
+ }
425
+
426
+ async function construct(parameters: create.CheckOptions, requireDestination: boolean) {
427
+ assertChain(parameters.chain)
428
+ if (parameters.token !== usdcMint)
429
+ throw new ConfigurationError('Unsupported Solana subsidy token.')
430
+ const mint = address(parameters.token)
431
+ const recipient = address(parameters.recipient)
432
+ const [[source], [destination]] = await Promise.all([
433
+ findAssociatedTokenPda({ mint, owner: account, tokenProgram: TOKEN_PROGRAM_ADDRESS }),
434
+ findAssociatedTokenPda({ mint, owner: recipient, tokenProgram: TOKEN_PROGRAM_ADDRESS }),
435
+ ])
436
+ const [sourceAccount, destinationAccount, balanceResult, latestResult] = await Promise.all([
437
+ tokenAccount(parameters.chain, source),
438
+ requireDestination ? tokenAccount(parameters.chain, destination) : Promise.resolve(undefined),
439
+ rpc(parameters.chain, 'getBalance', [account, { commitment: 'finalized' }]),
440
+ rpc(parameters.chain, 'getLatestBlockhash', [{ commitment: 'finalized' }]),
441
+ ])
442
+ if (
443
+ !isObject(balanceResult) ||
444
+ typeof balanceResult['value'] !== 'number' ||
445
+ !isObject(latestResult) ||
446
+ !isObject(latestResult['value']) ||
447
+ typeof latestResult['value']['blockhash'] !== 'string' ||
448
+ typeof latestResult['value']['lastValidBlockHeight'] !== 'number' ||
449
+ !isObject(latestResult['context']) ||
450
+ typeof latestResult['context']['slot'] !== 'number' ||
451
+ !Number.isSafeInteger(latestResult['context']['slot']) ||
452
+ latestResult['context']['slot'] <= 0
453
+ )
454
+ throw new UpstreamError('Solana balance or blockhash is unavailable.')
455
+ const latest = latestResult['value']
456
+ if (
457
+ sourceAccount.owner !== account ||
458
+ sourceAccount.mint !== mint ||
459
+ (destinationAccount !== undefined &&
460
+ (destinationAccount.owner !== recipient || destinationAccount.mint !== mint))
461
+ )
462
+ throw new ConfigurationError('Solana subsidy token account terms changed.')
463
+ if (sourceAccount.amount < parameters.amount + parameters.reservations.tokenAmount)
464
+ throw new BalanceUnavailableError()
465
+ const tx = unsignedTransaction({
466
+ account,
467
+ amount: parameters.amount,
468
+ blockhash: blockhash(latest['blockhash'] as string),
469
+ destination,
470
+ source,
471
+ })
472
+ const feeResult = await rpc(parameters.chain, 'getFeeForMessage', [
473
+ Buffer.from(tx.messageBytes).toString('base64'),
474
+ { commitment: 'finalized' },
475
+ ])
476
+ if (!isObject(feeResult) || typeof feeResult['value'] !== 'number' || feeResult['value'] <= 0)
477
+ throw new UpstreamError('Solana fee is unavailable.')
478
+ const fee = feeResult['value']
479
+ if (BigInt(balanceResult['value']) < BigInt(fee) + parameters.reservations.nativeAmount)
480
+ throw new BalanceUnavailableError()
481
+ return {
482
+ destination,
483
+ fee,
484
+ latest,
485
+ originSlot: latestResult['context']['slot'] as number,
486
+ source,
487
+ tx,
488
+ }
489
+ }
490
+
491
+ return {
492
+ account,
493
+ async broadcast({ chain, signed }) {
494
+ if (!readSigned(signed) || signed.account !== account || !(await accountsMatch(signed)))
495
+ throw new ConfigurationError('Invalid signed Solana subsidy transaction.')
496
+ const hash = await rpc(chain, 'sendTransaction', [
497
+ signed.transaction,
498
+ { encoding: 'base64' },
499
+ ]).catch((cause) => {
500
+ if (cause instanceof Error && /already processed|duplicate signature/i.test(cause.message))
501
+ return signed.hash
502
+ throw cause
503
+ })
504
+ if (hash !== signed.hash) throw new BroadcastError('Solana returned a different signature.')
505
+ },
506
+ async check(parameters) {
507
+ const { fee } = await construct(parameters, false)
508
+ return { nativeAmount: String(fee) }
509
+ },
510
+ async expiring({ chain, prepared }) {
511
+ assertChain(chain)
512
+ if (!readPrepared(prepared) || prepared.chainId !== chain.id)
513
+ throw new ConfigurationError('Invalid prepared Solana subsidy transaction.')
514
+ const height = await rpc(chain, 'getBlockHeight', [{ commitment: 'confirmed' }])
515
+ if (typeof height !== 'number' || !Number.isSafeInteger(height) || height < 0)
516
+ throw new UpstreamError('Solana block height is unavailable.')
517
+ // Leave time for Horcrux signing, persistence, and the first broadcast.
518
+ return height + signingBlockMargin >= prepared.lastValidBlockHeight
519
+ },
520
+ policy: options.policy,
521
+ async prepare(parameters) {
522
+ const { destination, fee, latest, originSlot, source, tx } = await construct(parameters, true)
523
+ return {
524
+ account,
525
+ amount: parameters.amount.toString(),
526
+ chainId: parameters.chain.id,
527
+ destination,
528
+ lastValidBlockHeight: latest['lastValidBlockHeight'] as number,
529
+ nativeAmount: String(fee),
530
+ originSlot,
531
+ recipient: parameters.recipient,
532
+ request: {
533
+ network: 'solana:mainnet-beta',
534
+ transaction: Buffer.from(getTransactionEncoder().encode(tx)).toString('base64'),
535
+ },
536
+ source,
537
+ token: parameters.token,
538
+ }
539
+ },
540
+ async sign({ idempotencyKey, prepared }) {
541
+ if (!/^[\x21-\x7e]{1,256}$/.test(idempotencyKey))
542
+ throw new ConfigurationError('Invalid Horcrux idempotency key.')
543
+ if (
544
+ !readPrepared(prepared) ||
545
+ prepared.account !== account ||
546
+ !(await accountsMatch(prepared))
547
+ )
548
+ throw new ConfigurationError('Invalid prepared Solana subsidy transaction.')
549
+ const headers: Record<string, string> = {
550
+ 'content-type': 'application/json',
551
+ 'Idempotency-Key': idempotencyKey,
552
+ }
553
+ if (options.horcrux.auth.type === 'cloudflare-access') {
554
+ headers['CF-Access-Client-Id'] = options.horcrux.auth.clientId
555
+ headers['CF-Access-Client-Secret'] = options.horcrux.auth.clientSecret
556
+ }
557
+ const response = await options.fetch(
558
+ new URL(`/v1/wallets/${options.walletId}/sign`, horcruxUrl),
559
+ {
560
+ body: JSON.stringify(prepared.request),
561
+ headers,
562
+ method: 'POST',
563
+ redirect: 'manual',
564
+ signal: AbortSignal.timeout(10_000),
565
+ },
566
+ )
567
+ if (!response.ok) throw new SigningError(`Horcrux signing returned HTTP ${response.status}.`)
568
+ const result: unknown = await response.json()
569
+ if (!isObject(result) || typeof result['signed_transaction'] !== 'string')
570
+ throw new SigningError('Horcrux returned an invalid signing response.')
571
+ const tx = getTransactionDecoder().decode(Buffer.from(result['signed_transaction'], 'base64'))
572
+ const signature = tx.signatures[address(account)]
573
+ if (!signature) throw new SigningError('Horcrux omitted the Solana signature.')
574
+ const signed = {
575
+ ...prepared,
576
+ hash: Base58.fromBytes(signature),
577
+ transaction: result['signed_transaction'],
578
+ }
579
+ if (!readSigned(signed)) throw new SigningError('Horcrux changed the Solana transaction.')
580
+ return signed
581
+ },
582
+ async status({ chain, recipient, signed, token }) {
583
+ if (
584
+ !readSigned(signed) ||
585
+ !(await accountsMatch(signed)) ||
586
+ !matchesTerms(signed, {
587
+ account,
588
+ amount: BigInt(signed.amount),
589
+ chainId: chain.id,
590
+ recipient,
591
+ token,
592
+ })
593
+ )
594
+ return 'reverted'
595
+ const result = await rpc(chain, 'getSignatureStatuses', [
596
+ [signed.hash],
597
+ { searchTransactionHistory: true },
598
+ ])
599
+ if (!isObject(result) || !Array.isArray(result['value']))
600
+ throw new UpstreamError('Solana signature status is unavailable.')
601
+ const receipt = result['value'][0]
602
+ if (!receipt) return expiredStatus(chain, signed)
603
+ if (!isObject(receipt)) throw new UpstreamError('Solana signature status is invalid.')
604
+ if (receipt['confirmationStatus'] !== 'finalized') return 'pending'
605
+ return receipt['err'] ? 'reverted' : 'success'
606
+ },
607
+ }
608
+ }
609
+
610
+ export declare namespace create {
611
+ /** Horcrux connection and Solana RPC dependencies. */
612
+ type Options = {
613
+ account: string
614
+ fetch: typeof globalThis.fetch
615
+ horcrux: {
616
+ auth: { type: 'none' } | { clientId: string; clientSecret: string; type: 'cloudflare-access' }
617
+ url: string
618
+ }
619
+ policy: { maxAmount: string }
620
+ walletId: string
621
+ }
622
+
623
+ /** Creation-time inventory request. */
624
+ type CheckOptions = {
625
+ amount: bigint
626
+ chain: Chain.Chain
627
+ recipient: string
628
+ reservations: { nativeAmount: bigint; tokenAmount: bigint }
629
+ token: string
630
+ }
631
+
632
+ /** Finalized receipt query and expected delivery. */
633
+ type StatusOptions = { chain: Chain.Chain; recipient: string; signed: Signed; token: string }
634
+ }
635
+
636
+ /** Checks one finalized block against the signed transaction and the preceding block. */
637
+ export function inspectFinalizedBlock(
638
+ options: inspectFinalizedBlock.Options,
639
+ ):
640
+ | { type: 'ambiguous' }
641
+ | { blockhash: string; blockHeight: number; type: 'absent' | 'expired' | 'found' } {
642
+ const block = options.block
643
+ if (
644
+ !isObject(block) ||
645
+ typeof block['blockhash'] !== 'string' ||
646
+ typeof block['previousBlockhash'] !== 'string' ||
647
+ typeof block['parentSlot'] !== 'number' ||
648
+ !Number.isSafeInteger(block['parentSlot']) ||
649
+ typeof block['blockHeight'] !== 'number' ||
650
+ !Number.isSafeInteger(block['blockHeight']) ||
651
+ !Array.isArray(block['signatures']) ||
652
+ !block['signatures'].every((signature) => typeof signature === 'string') ||
653
+ (options.previousSlot === undefined && options.slot !== options.originSlot) ||
654
+ (options.previousSlot !== undefined &&
655
+ (block['parentSlot'] !== options.previousSlot ||
656
+ block['previousBlockhash'] !== options.previousBlockhash ||
657
+ options.previousHeight === undefined ||
658
+ block['blockHeight'] !== options.previousHeight + 1))
659
+ )
660
+ return { type: 'ambiguous' }
661
+ const blockHeight = block['blockHeight']
662
+ const type = (() => {
663
+ if (block['signatures'].includes(options.signature)) return 'found' as const
664
+ if (blockHeight > options.lastValidBlockHeight) return 'expired' as const
665
+ return 'absent' as const
666
+ })()
667
+ return {
668
+ blockhash: block['blockhash'],
669
+ blockHeight,
670
+ type,
671
+ }
672
+ }
673
+
674
+ export declare namespace inspectFinalizedBlock {
675
+ /** Finalized block and its expected place in a continuous chain. */
676
+ type Options = {
677
+ block: unknown
678
+ lastValidBlockHeight: number
679
+ originSlot: number
680
+ previousBlockhash: string | undefined
681
+ previousHeight: number | undefined
682
+ previousSlot: number | undefined
683
+ signature: string
684
+ slot: number
685
+ }
686
+ }
687
+
688
+ function assertChain(chain: Chain.Chain) {
689
+ if (chain.id !== mainnet || chain.kind !== 'solana' || chain.rpcUrls.length === 0)
690
+ throw new ConfigurationError('Unsupported Solana subsidy chain.')
691
+ }
692
+
693
+ function isObject(value: unknown): value is Record<string, unknown> {
694
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
695
+ }
696
+
697
+ function unsignedTransaction(options: unsignedTransaction.Options) {
698
+ const message = appendTransactionMessageInstruction(
699
+ getTransferCheckedInstruction({
700
+ amount: options.amount,
701
+ authority: options.account,
702
+ decimals: 6,
703
+ destination: options.destination,
704
+ mint: address(usdcMint),
705
+ source: options.source,
706
+ }),
707
+ setTransactionMessageLifetimeUsingBlockhash(
708
+ { blockhash: options.blockhash, lastValidBlockHeight: 0n },
709
+ setTransactionMessageFeePayer(
710
+ options.account,
711
+ createTransactionMessage({ version: 'legacy' }),
712
+ ),
713
+ ),
714
+ )
715
+ return compileTransaction(message)
716
+ }
717
+
718
+ declare namespace unsignedTransaction {
719
+ type Options = {
720
+ account: ReturnType<typeof address>
721
+ amount: bigint
722
+ blockhash: ReturnType<typeof blockhash>
723
+ destination: ReturnType<typeof address>
724
+ source: ReturnType<typeof address>
725
+ }
726
+ }
727
+
728
+ /** Returns whether replaying the same signed transaction cannot succeed. */
729
+ export function isPermanentBroadcastError(cause: unknown): boolean {
730
+ if (cause instanceof BroadcastError || cause instanceof ConfigurationError) return true
731
+ if (!(cause instanceof Error)) return false
732
+ return /block height exceeded|transaction expired|custom program error|invalid account data|signature verification failed/i.test(
733
+ cause.message,
734
+ )
735
+ }
736
+
737
+ /** The subsidy wallet lacks USDC or SOL inventory. */
738
+ export class BalanceUnavailableError extends Error {
739
+ override name = 'Routes.SolanaTransferSubsidy.BalanceUnavailableError'
740
+ }
741
+
742
+ /** Solana subsidy configuration or persisted terms are invalid. */
743
+ export class ConfigurationError extends Error {
744
+ override name = 'Routes.SolanaTransferSubsidy.ConfigurationError'
745
+ }
746
+
747
+ /** Horcrux failed to return the expected Solana signature. */
748
+ export class SigningError extends Error {
749
+ override name = 'Routes.SolanaTransferSubsidy.SigningError'
750
+ }
751
+
752
+ /** Solana rejected a signed subsidy transaction. */
753
+ export class BroadcastError extends Error {
754
+ override name = 'Routes.SolanaTransferSubsidy.BroadcastError'
755
+ }
756
+
757
+ /** Solana RPC could not provide reliable inventory or fee data. */
758
+ export class UpstreamError extends Error {
759
+ override name = 'Routes.SolanaTransferSubsidy.UpstreamError'
760
+ }