@upshiftfinance/sdk 0.0.0-stage → 0.2.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 (344) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -2
  3. package/lib/abis/AddressResolver.d.ts +28 -0
  4. package/lib/abis/AddressResolver.js +23 -0
  5. package/lib/abis/ChainlinkV3.d.ts +87 -0
  6. package/lib/abis/ChainlinkV3.js +117 -0
  7. package/lib/abis/ERC20.d.ts +168 -0
  8. package/lib/abis/ERC20.js +226 -0
  9. package/lib/abis/ERC20_Bytes32.d.ts +139 -0
  10. package/lib/abis/ERC20_Bytes32.js +196 -0
  11. package/lib/abis/ERC4626.d.ts +364 -0
  12. package/lib/abis/ERC4626.js +507 -0
  13. package/lib/abis/ERC721.d.ts +231 -0
  14. package/lib/abis/ERC721.js +321 -0
  15. package/lib/abis/FeeOracle.d.ts +120 -0
  16. package/lib/abis/FeeOracle.js +162 -0
  17. package/lib/abis/LendingPool.d.ts +1393 -0
  18. package/lib/abis/LendingPool.js +1807 -0
  19. package/lib/abis/LendingPoolV2.d.ts +1413 -0
  20. package/lib/abis/LendingPoolV2.js +1833 -0
  21. package/lib/abis/LendingPoolV3.d.ts +1677 -0
  22. package/lib/abis/LendingPoolV3.js +1160 -0
  23. package/lib/abis/Loan.d.ts +837 -0
  24. package/lib/abis/Loan.js +1080 -0
  25. package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
  26. package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
  27. package/lib/abis/Multicall3.d.ts +30 -0
  28. package/lib/abis/Multicall3.js +97 -0
  29. package/lib/abis/OFT.d.ts +116 -0
  30. package/lib/abis/OFT.js +85 -0
  31. package/lib/abis/PoolAdapter.d.ts +36 -0
  32. package/lib/abis/PoolAdapter.js +51 -0
  33. package/lib/abis/RewardDistributor.d.ts +267 -0
  34. package/lib/abis/RewardDistributor.js +352 -0
  35. package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
  36. package/lib/abis/RwaRedeemSubaccount.js +548 -0
  37. package/lib/abis/SmartAccount.d.ts +17 -0
  38. package/lib/abis/SmartAccount.js +19 -0
  39. package/lib/abis/SwapRouter.d.ts +953 -0
  40. package/lib/abis/SwapRouter.js +1228 -0
  41. package/lib/abis/TextResolver.d.ts +16 -0
  42. package/lib/abis/TextResolver.js +16 -0
  43. package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
  44. package/lib/abis/TokenizedVaultV2.js +1041 -0
  45. package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
  46. package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
  47. package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
  48. package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
  49. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
  50. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
  51. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
  52. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
  53. package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
  54. package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
  55. package/lib/abis/UniversalResolverResolve.d.ts +69 -0
  56. package/lib/abis/UniversalResolverResolve.js +35 -0
  57. package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
  58. package/lib/abis/UniversalSignatureValidator.js +30 -0
  59. package/lib/abis/WrapperAdapter.d.ts +71 -0
  60. package/lib/abis/WrapperAdapter.js +77 -0
  61. package/lib/abis/index.d.ts +34 -0
  62. package/lib/abis/index.js +51 -0
  63. package/lib/adapters/evm/getters.d.ts +19 -0
  64. package/lib/adapters/evm/getters.js +249 -0
  65. package/lib/adapters/evm/index.d.ts +539 -0
  66. package/lib/adapters/evm/index.js +656 -0
  67. package/lib/adapters/evm/utils.d.ts +8 -0
  68. package/lib/adapters/evm/utils.js +51 -0
  69. package/lib/adapters/solana/confirm.d.ts +88 -0
  70. package/lib/adapters/solana/confirm.js +291 -0
  71. package/lib/adapters/solana/constants.d.ts +42 -0
  72. package/lib/adapters/solana/constants.js +59 -0
  73. package/lib/adapters/solana/getters.d.ts +42 -0
  74. package/lib/adapters/solana/getters.js +275 -0
  75. package/lib/adapters/solana/idl/vault-idl.d.ts +700 -0
  76. package/lib/adapters/solana/idl/vault-idl.js +2101 -0
  77. package/lib/adapters/solana/idl/withdrawal-queue-idl.d.ts +795 -0
  78. package/lib/adapters/solana/idl/withdrawal-queue-idl.js +1864 -0
  79. package/lib/adapters/solana/index.d.ts +372 -0
  80. package/lib/adapters/solana/index.js +459 -0
  81. package/lib/adapters/solana/pricing.d.ts +184 -0
  82. package/lib/adapters/solana/pricing.js +239 -0
  83. package/lib/adapters/solana/queue-hints.d.ts +29 -0
  84. package/lib/adapters/solana/queue-hints.js +59 -0
  85. package/lib/adapters/solana/queue.actions.d.ts +97 -0
  86. package/lib/adapters/solana/queue.actions.js +468 -0
  87. package/lib/adapters/solana/token-reads.d.ts +108 -0
  88. package/lib/adapters/solana/token-reads.js +145 -0
  89. package/lib/adapters/solana/types.d.ts +325 -0
  90. package/lib/adapters/solana/types.js +3 -0
  91. package/lib/adapters/solana/utils.d.ts +229 -0
  92. package/lib/adapters/solana/utils.js +773 -0
  93. package/lib/adapters/solana/vault.actions.d.ts +140 -0
  94. package/lib/adapters/solana/vault.actions.js +657 -0
  95. package/lib/adapters/solana/withdrawal-queue.d.ts +125 -0
  96. package/lib/adapters/solana/withdrawal-queue.js +301 -0
  97. package/lib/adapters/stellar/actions.d.ts +41 -0
  98. package/lib/adapters/stellar/actions.js +126 -0
  99. package/lib/adapters/stellar/constants.d.ts +43 -0
  100. package/lib/adapters/stellar/constants.js +53 -0
  101. package/lib/adapters/stellar/getters.d.ts +68 -0
  102. package/lib/adapters/stellar/getters.js +290 -0
  103. package/lib/adapters/stellar/index.d.ts +126 -0
  104. package/lib/adapters/stellar/index.js +187 -0
  105. package/lib/adapters/stellar/invocation.d.ts +55 -0
  106. package/lib/adapters/stellar/invocation.js +92 -0
  107. package/lib/adapters/stellar/soroban.d.ts +131 -0
  108. package/lib/adapters/stellar/soroban.js +617 -0
  109. package/lib/adapters/stellar/submit.d.ts +42 -0
  110. package/lib/adapters/stellar/submit.js +195 -0
  111. package/lib/adapters/stellar/types.d.ts +57 -0
  112. package/lib/adapters/stellar/types.js +6 -0
  113. package/lib/adapters/stellar/utils.d.ts +24 -0
  114. package/lib/adapters/stellar/utils.js +34 -0
  115. package/lib/adapters/sui/client.d.ts +83 -0
  116. package/lib/adapters/sui/client.js +216 -0
  117. package/lib/adapters/sui/constants.d.ts +33 -0
  118. package/lib/adapters/sui/constants.js +31 -0
  119. package/lib/adapters/sui/index.d.ts +57 -0
  120. package/lib/adapters/sui/index.js +100 -0
  121. package/lib/adapters/sui/targets.d.ts +171 -0
  122. package/lib/adapters/sui/targets.js +225 -0
  123. package/lib/adapters/sui/utils.d.ts +8 -0
  124. package/lib/adapters/sui/utils.js +17 -0
  125. package/lib/core/analytics/app-name.d.ts +27 -0
  126. package/lib/core/analytics/app-name.js +48 -0
  127. package/lib/core/analytics/chain-name.d.ts +9 -0
  128. package/lib/core/analytics/chain-name.js +34 -0
  129. package/lib/core/analytics/constants.d.ts +15 -0
  130. package/lib/core/analytics/constants.js +28 -0
  131. package/lib/core/analytics/env.d.ts +46 -0
  132. package/lib/core/analytics/env.js +147 -0
  133. package/lib/core/analytics/index.d.ts +39 -0
  134. package/lib/core/analytics/index.js +83 -0
  135. package/lib/core/analytics/instrumentation.d.ts +29 -0
  136. package/lib/core/analytics/instrumentation.js +292 -0
  137. package/lib/core/analytics/method-taxonomy.d.ts +19 -0
  138. package/lib/core/analytics/method-taxonomy.js +156 -0
  139. package/lib/core/analytics/metrics.d.ts +48 -0
  140. package/lib/core/analytics/metrics.js +142 -0
  141. package/lib/core/analytics/sanitize.d.ts +57 -0
  142. package/lib/core/analytics/sanitize.js +272 -0
  143. package/lib/core/analytics/sentry-runtime.d.ts +15 -0
  144. package/lib/core/analytics/sentry-runtime.js +131 -0
  145. package/lib/core/analytics/sentry.d.ts +100 -0
  146. package/lib/core/analytics/sentry.js +696 -0
  147. package/lib/core/analytics/types.d.ts +55 -0
  148. package/lib/core/analytics/types.js +3 -0
  149. package/lib/core/analytics/user-identity.d.ts +55 -0
  150. package/lib/core/analytics/user-identity.js +218 -0
  151. package/lib/core/analytics/version.d.ts +6 -0
  152. package/lib/core/analytics/version.js +10 -0
  153. package/lib/core/attribution.d.ts +159 -0
  154. package/lib/core/attribution.js +194 -0
  155. package/lib/core/auth/index.d.ts +1 -0
  156. package/lib/core/auth/index.js +18 -0
  157. package/lib/core/auth/verify.d.ts +2 -0
  158. package/lib/core/auth/verify.js +35 -0
  159. package/lib/core/base.class.d.ts +193 -0
  160. package/lib/core/base.class.js +163 -0
  161. package/lib/core/cache.d.ts +9 -0
  162. package/lib/core/cache.js +31 -0
  163. package/lib/core/constants/adapters.d.ts +103 -0
  164. package/lib/core/constants/adapters.js +180 -0
  165. package/lib/core/constants/core.d.ts +162 -0
  166. package/lib/core/constants/core.js +281 -0
  167. package/lib/core/constants/swap-router.d.ts +180 -0
  168. package/lib/core/constants/swap-router.js +203 -0
  169. package/lib/core/constants/vaults.d.ts +93 -0
  170. package/lib/core/constants/vaults.js +277 -0
  171. package/lib/core/constants/web3.d.ts +106 -0
  172. package/lib/core/constants/web3.js +251 -0
  173. package/lib/core/errors/index.d.ts +177 -0
  174. package/lib/core/errors/index.js +257 -0
  175. package/lib/core/fetcher.d.ts +237 -0
  176. package/lib/core/fetcher.js +1103 -0
  177. package/lib/core/helpers/adapters.d.ts +13 -0
  178. package/lib/core/helpers/adapters.js +39 -0
  179. package/lib/core/helpers/chain-address.d.ts +13 -0
  180. package/lib/core/helpers/chain-address.js +47 -0
  181. package/lib/core/helpers/chain-error.d.ts +207 -0
  182. package/lib/core/helpers/chain-error.js +697 -0
  183. package/lib/core/helpers/chain-support.d.ts +98 -0
  184. package/lib/core/helpers/chain-support.js +139 -0
  185. package/lib/core/helpers/concurrency.d.ts +51 -0
  186. package/lib/core/helpers/concurrency.js +79 -0
  187. package/lib/core/helpers/core.d.ts +92 -0
  188. package/lib/core/helpers/core.js +368 -0
  189. package/lib/core/helpers/explorer-link.d.ts +16 -0
  190. package/lib/core/helpers/explorer-link.js +26 -0
  191. package/lib/core/helpers/multicall.d.ts +68 -0
  192. package/lib/core/helpers/multicall.js +103 -0
  193. package/lib/core/helpers/revert-decode.d.ts +248 -0
  194. package/lib/core/helpers/revert-decode.js +515 -0
  195. package/lib/core/helpers/signer.d.ts +61 -0
  196. package/lib/core/helpers/signer.js +184 -0
  197. package/lib/core/helpers/swap-router.d.ts +269 -0
  198. package/lib/core/helpers/swap-router.js +542 -0
  199. package/lib/core/helpers/vault-version.d.ts +24 -0
  200. package/lib/core/helpers/vault-version.js +83 -0
  201. package/lib/core/helpers/vaults.d.ts +89 -0
  202. package/lib/core/helpers/vaults.js +241 -0
  203. package/lib/core/helpers/web3.d.ts +366 -0
  204. package/lib/core/helpers/web3.js +1034 -0
  205. package/lib/core/index.d.ts +23 -0
  206. package/lib/core/index.js +40 -0
  207. package/lib/core/logger/curator-alert.d.ts +217 -0
  208. package/lib/core/logger/curator-alert.js +276 -0
  209. package/lib/core/logger/index.d.ts +99 -0
  210. package/lib/core/logger/index.js +163 -0
  211. package/lib/core/logger/slack.d.ts +49 -0
  212. package/lib/core/logger/slack.js +111 -0
  213. package/lib/core/vault-metadata.d.ts +12 -0
  214. package/lib/core/vault-metadata.js +42 -0
  215. package/lib/core/version-check.d.ts +58 -0
  216. package/lib/core/version-check.js +182 -0
  217. package/lib/evm/index.d.ts +2 -0
  218. package/lib/evm/index.js +19 -0
  219. package/lib/evm/methods/crossChainVault.d.ts +132 -0
  220. package/lib/evm/methods/crossChainVault.js +857 -0
  221. package/lib/evm/methods/crossChainVaultRegistry.d.ts +92 -0
  222. package/lib/evm/methods/crossChainVaultRegistry.js +239 -0
  223. package/lib/evm/methods/index.d.ts +2 -0
  224. package/lib/evm/methods/index.js +19 -0
  225. package/lib/evm/types/crossChain.d.ts +363 -0
  226. package/lib/evm/types/crossChain.js +20 -0
  227. package/lib/evm/types/index.d.ts +1 -0
  228. package/lib/evm/types/index.js +18 -0
  229. package/lib/index.d.ts +30 -0
  230. package/lib/index.js +52 -0
  231. package/lib/main.d.ts +596 -0
  232. package/lib/main.js +681 -0
  233. package/lib/modules/api/fetcher.d.ts +108 -0
  234. package/lib/modules/api/fetcher.js +187 -0
  235. package/lib/modules/api/index.d.ts +1 -0
  236. package/lib/modules/api/index.js +6 -0
  237. package/lib/modules/api/main.d.ts +587 -0
  238. package/lib/modules/api/main.js +911 -0
  239. package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
  240. package/lib/modules/sub-accounts/fetcher.js +96 -0
  241. package/lib/modules/sub-accounts/index.d.ts +2 -0
  242. package/lib/modules/sub-accounts/index.js +19 -0
  243. package/lib/modules/sub-accounts/main.d.ts +249 -0
  244. package/lib/modules/sub-accounts/main.js +211 -0
  245. package/lib/modules/sub-accounts/utils.d.ts +106 -0
  246. package/lib/modules/sub-accounts/utils.js +112 -0
  247. package/lib/modules/vaults/adapter.helpers.d.ts +84 -0
  248. package/lib/modules/vaults/adapter.helpers.js +202 -0
  249. package/lib/modules/vaults/fetcher.d.ts +147 -0
  250. package/lib/modules/vaults/fetcher.js +357 -0
  251. package/lib/modules/vaults/getters.d.ts +1060 -0
  252. package/lib/modules/vaults/getters.js +4079 -0
  253. package/lib/modules/vaults/index.d.ts +20 -0
  254. package/lib/modules/vaults/index.js +44 -0
  255. package/lib/modules/vaults/main.d.ts +607 -0
  256. package/lib/modules/vaults/main.js +1687 -0
  257. package/lib/modules/vaults/prefetch.d.ts +65 -0
  258. package/lib/modules/vaults/prefetch.js +120 -0
  259. package/lib/modules/vaults/read.actions.d.ts +406 -0
  260. package/lib/modules/vaults/read.actions.js +891 -0
  261. package/lib/modules/vaults/types.d.ts +149 -0
  262. package/lib/modules/vaults/types.js +3 -0
  263. package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
  264. package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
  265. package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
  266. package/lib/modules/vaults/utils/date-utils.js +84 -0
  267. package/lib/modules/vaults/utils.d.ts +153 -0
  268. package/lib/modules/vaults/utils.js +818 -0
  269. package/lib/modules/vaults/write.actions.d.ts +812 -0
  270. package/lib/modules/vaults/write.actions.js +2377 -0
  271. package/lib/polyfills.d.ts +1 -0
  272. package/lib/polyfills.js +12 -0
  273. package/lib/sdk.d.ts +30173 -0
  274. package/lib/services/coingecko/fetcher.d.ts +15 -0
  275. package/lib/services/coingecko/fetcher.js +67 -0
  276. package/lib/services/coingecko/index.d.ts +2 -0
  277. package/lib/services/coingecko/index.js +19 -0
  278. package/lib/services/coingecko/utils.d.ts +1 -0
  279. package/lib/services/coingecko/utils.js +24 -0
  280. package/lib/services/debank/fetcher.d.ts +126 -0
  281. package/lib/services/debank/fetcher.js +47 -0
  282. package/lib/services/debank/index.d.ts +2 -0
  283. package/lib/services/debank/index.js +19 -0
  284. package/lib/services/debank/utils.d.ts +50 -0
  285. package/lib/services/debank/utils.js +325 -0
  286. package/lib/services/layerzero/deposits.d.ts +55 -0
  287. package/lib/services/layerzero/deposits.js +174 -0
  288. package/lib/services/layerzero/redeems.d.ts +20 -0
  289. package/lib/services/layerzero/redeems.js +92 -0
  290. package/lib/services/layerzero/utils.d.ts +9 -0
  291. package/lib/services/layerzero/utils.js +22 -0
  292. package/lib/services/octavfi/fetcher.d.ts +33 -0
  293. package/lib/services/octavfi/fetcher.js +39 -0
  294. package/lib/services/octavfi/index.d.ts +3 -0
  295. package/lib/services/octavfi/index.js +20 -0
  296. package/lib/services/octavfi/types.d.ts +34 -0
  297. package/lib/services/octavfi/types.js +3 -0
  298. package/lib/services/octavfi/utils.d.ts +16 -0
  299. package/lib/services/octavfi/utils.js +244 -0
  300. package/lib/services/subgraph/fetcher.d.ts +2 -0
  301. package/lib/services/subgraph/fetcher.js +66 -0
  302. package/lib/services/subgraph/index.d.ts +2 -0
  303. package/lib/services/subgraph/index.js +19 -0
  304. package/lib/services/subgraph/schema.d.ts +48 -0
  305. package/lib/services/subgraph/schema.js +87 -0
  306. package/lib/services/subgraph/vaults.d.ts +83 -0
  307. package/lib/services/subgraph/vaults.js +1282 -0
  308. package/lib/services/swap-quotes/index.d.ts +105 -0
  309. package/lib/services/swap-quotes/index.js +77 -0
  310. package/lib/services/swap-quotes/paraswap.d.ts +51 -0
  311. package/lib/services/swap-quotes/paraswap.js +138 -0
  312. package/lib/services/untangled/fetcher.d.ts +40 -0
  313. package/lib/services/untangled/fetcher.js +110 -0
  314. package/lib/services/untangled/index.d.ts +3 -0
  315. package/lib/services/untangled/index.js +20 -0
  316. package/lib/services/untangled/types.d.ts +83 -0
  317. package/lib/services/untangled/types.js +10 -0
  318. package/lib/services/untangled/utils.d.ts +91 -0
  319. package/lib/services/untangled/utils.js +339 -0
  320. package/lib/types/api.d.ts +498 -0
  321. package/lib/types/api.js +3 -0
  322. package/lib/types/index.d.ts +12 -0
  323. package/lib/types/index.js +28 -0
  324. package/lib/types/points.d.ts +28 -0
  325. package/lib/types/points.js +3 -0
  326. package/lib/types/pools.d.ts +144 -0
  327. package/lib/types/pools.js +3 -0
  328. package/lib/types/staking.d.ts +28 -0
  329. package/lib/types/staking.js +3 -0
  330. package/lib/types/sub-accounts.d.ts +150 -0
  331. package/lib/types/sub-accounts.js +3 -0
  332. package/lib/types/subgraph.d.ts +84 -0
  333. package/lib/types/subgraph.js +3 -0
  334. package/lib/types/typed-contract.d.ts +102 -0
  335. package/lib/types/typed-contract.js +3 -0
  336. package/lib/types/user.d.ts +1 -0
  337. package/lib/types/user.js +3 -0
  338. package/lib/types/vaults.d.ts +886 -0
  339. package/lib/types/vaults.js +30 -0
  340. package/lib/types/web3.d.ts +100 -0
  341. package/lib/types/web3.js +14 -0
  342. package/lib/types/webserver.d.ts +730 -0
  343. package/lib/types/webserver.js +3 -0
  344. package/package.json +79 -3
@@ -0,0 +1,468 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queueHint = void 0;
4
+ exports.deriveWithdrawalRequestPda = deriveWithdrawalRequestPda;
5
+ exports.handleSolanaRequestRedeem = handleSolanaRequestRedeem;
6
+ exports.handleSolanaClaimRedeem = handleSolanaClaimRedeem;
7
+ exports.handleSolanaCancelRedeemRequest = handleSolanaCancelRedeemRequest;
8
+ /**
9
+ * Write paths for the august_withdrawal_queue program: request a withdrawal,
10
+ * claim (finalize) a ready one, cancel a pending one.
11
+ *
12
+ * Built like the vault's deposit and redeem handlers (`vault.actions.ts`):
13
+ * every check the SDK can make runs before the wallet is asked to sign, every
14
+ * account the transaction needs is created inside it with an idempotent
15
+ * instruction, and failures surface as `UpshiftValidationError` (bad input or
16
+ * state the caller can fix) or `UpshiftSDKError` (the transaction failed, with
17
+ * the program's reason and the numeric code).
18
+ */
19
+ const anchor_1 = require("@coral-xyz/anchor");
20
+ const spl_token_1 = require("@solana/spl-token");
21
+ const web3_js_1 = require("@solana/web3.js");
22
+ const core_1 = require("../../core");
23
+ const vault_idl_1 = require("./idl/vault-idl");
24
+ const withdrawal_queue_idl_1 = require("./idl/withdrawal-queue-idl");
25
+ const pricing_1 = require("./pricing");
26
+ const utils_1 = require("./utils");
27
+ const token_reads_1 = require("./token-reads");
28
+ const vault_actions_1 = require("./vault.actions");
29
+ const withdrawal_queue_1 = require("./withdrawal-queue");
30
+ const queue_hints_1 = require("./queue-hints");
31
+ var queue_hints_2 = require("./queue-hints");
32
+ Object.defineProperty(exports, "queueHint", { enumerable: true, get: function () { return queue_hints_2.queueHint; } });
33
+ const WITHDRAWAL_REQUEST_SEED = 'withdrawal_request';
34
+ /** Largest request id the program's `u64` can hold. */
35
+ const U64_MAX = 18446744073709551615n;
36
+ /** A queue program client that signs through `provider`'s wallet. */
37
+ function queueProgram(provider, queueProgramId) {
38
+ return new anchor_1.Program({ ...withdrawal_queue_idl_1.withdrawalQueueIdl, address: queueProgramId.toBase58() }, provider);
39
+ }
40
+ /**
41
+ * The queue's instruction builders, typed by what these handlers call. The IDL
42
+ * is a plain object here, not Anchor's generated type, so `program.methods` is
43
+ * untyped without this.
44
+ */
45
+ function queueMethods(program) {
46
+ return program.methods;
47
+ }
48
+ /** A vault program client, used only for its account coder. */
49
+ function vaultCoder(provider) {
50
+ return new anchor_1.Program(vault_idl_1.vaultIdl, provider).coder.accounts;
51
+ }
52
+ /** The request PDA: `["withdrawal_request", queue, owner, request_id as u64 LE]`. */
53
+ function deriveWithdrawalRequestPda(queue, owner, requestId, queueProgramId) {
54
+ return web3_js_1.PublicKey.findProgramAddressSync([
55
+ Buffer.from(WITHDRAWAL_REQUEST_SEED),
56
+ queue.toBuffer(),
57
+ owner.toBuffer(),
58
+ new anchor_1.BN(requestId.toString()).toArrayLike(Buffer, 'le', 8),
59
+ ], queueProgramId)[0];
60
+ }
61
+ /**
62
+ * A random `u64` request id. `crypto.getRandomValues` is available in every
63
+ * browser and in Node 19+, the SDK's floor being 22. A collision needs another
64
+ * pending request of the same holder with the same id: about 2^-64 per pair,
65
+ * and it would fail cleanly, the request account already existing.
66
+ */
67
+ function randomRequestId() {
68
+ const bytes = new Uint8Array(8);
69
+ globalThis.crypto.getRandomValues(bytes);
70
+ return bytes.reduce((id, byte) => (id << 8n) | BigInt(byte), 0n);
71
+ }
72
+ /** The commitment reads use, so writes confirm where reads will see them. */
73
+ function commitmentOf(connection) {
74
+ return connection.commitment ?? 'finalized';
75
+ }
76
+ /** Decode `info` as `name` with `coder`, or throw naming the account. */
77
+ function decodeOrThrow(coder, name, address, info, missing) {
78
+ if (!info)
79
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', missing);
80
+ try {
81
+ return coder.decode(name, info.data);
82
+ }
83
+ catch (e) {
84
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `Account ${address.toBase58()} is not a ${name} account.`, { cause: e });
85
+ }
86
+ }
87
+ /** Wrap a non-SDK failure the way the vault handlers do, keeping `cause`. */
88
+ function wrapFailure(operation, e, context) {
89
+ if (e instanceof core_1.UpshiftSDKError)
90
+ throw e;
91
+ core_1.Logger.log.error(operation, e, context);
92
+ throw new core_1.UpshiftSDKError('UNKNOWN', `Solana ${operation} failed: ${(0, vault_actions_1.describeSolanaError)(e)}${(0, queue_hints_1.queueHint)(e)}`, { cause: e, context });
93
+ }
94
+ /**
95
+ * Escrow shares in a withdrawal request on a vault with a queue attached.
96
+ *
97
+ * Reads the vault state and queue in one call, checks the gate points at the
98
+ * queue, and submits `request_withdrawal` from the holder's share account. The
99
+ * recipient's deposit-token account is created in the same transaction when it
100
+ * has none. Unless `minAssetsOut` is given, the request's floor is the current
101
+ * net quote lowered by `slippageBps`, the floor `vaultRedeem` would use.
102
+ *
103
+ * RPC: one `getMultipleAccountsInfo` (vault state and queue), one
104
+ * `getAccountInfo` for the share mint (decimals for a UI `amount`, supply for
105
+ * the default floor) unless `amount` is raw and `minAssetsOut` is given, one
106
+ * `getParsedTokenAccountsByOwner` for the share account, and one more read for
107
+ * the payout account (the holder's, or another recipient's ATA, which may be
108
+ * off-curve), then the send.
109
+ *
110
+ * @returns The signature, the new request's address and its id.
111
+ * @throws UpshiftValidationError for bad input, a vault without an attached
112
+ * queue, a frozen account or too few shares, all before signing.
113
+ * @throws UpshiftSDKError when the transaction fails.
114
+ */
115
+ async function handleSolanaRequestRedeem({ provider, connection, queueProgramId, params, }) {
116
+ const context = {
117
+ vault: String(params.vault),
118
+ amount: String(params.amount),
119
+ };
120
+ try {
121
+ const { amount, requestId } = params;
122
+ if (!params.wallet)
123
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultRequestRedeem: wallet not connected');
124
+ if (!params.vault)
125
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultRequestRedeem: vault is required');
126
+ if ((typeof amount === 'bigint' && amount <= 0n) ||
127
+ (typeof amount === 'number' && !(amount > 0)) ||
128
+ (typeof amount !== 'bigint' && typeof amount !== 'number'))
129
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultRequestRedeem: amount is required and must be > 0');
130
+ if (requestId !== undefined &&
131
+ (typeof requestId !== 'bigint' || requestId < 0n || requestId > U64_MAX))
132
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRequestRedeem: requestId must be a bigint between 0 and ${U64_MAX}, got ${String(requestId)}.`);
133
+ // Before any RPC: an unusable floor should cost the caller nothing.
134
+ if (params.minAssetsOut !== undefined)
135
+ (0, vault_actions_1.validateExplicitFloor)(params.minAssetsOut, 'minAssetsOut');
136
+ else if (params.slippageBps !== undefined)
137
+ (0, pricing_1.validateSlippageBps)(params.slippageBps);
138
+ const owner = new web3_js_1.PublicKey(params.wallet);
139
+ const vaultState = new web3_js_1.PublicKey(params.vault);
140
+ const queue = (0, withdrawal_queue_1.deriveWithdrawalQueuePda)(vaultState, queueProgramId);
141
+ const program = queueProgram(provider, queueProgramId);
142
+ const [stateInfo, queueInfo] = await connection.getMultipleAccountsInfo([
143
+ vaultState,
144
+ queue,
145
+ ]);
146
+ const vaultStateData = decodeOrThrow(vaultCoder(provider), 'vaultState', vaultState, stateInfo, `vaultRequestRedeem: no vault state at ${vaultState.toBase58()}.`);
147
+ const gate = vaultStateData.withdrawalQueueAuthority;
148
+ if (!gate || !new web3_js_1.PublicKey(gate).equals(queue)) {
149
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRequestRedeem: vault ${vaultState.toBase58()} has no withdrawal queue attached; redeem directly with \`vaultRedeem\`.`);
150
+ }
151
+ const queueState = decodeOrThrow(program.coder.accounts, 'withdrawalQueue', queue, queueInfo, `vaultRequestRedeem: the vault's queue ${queue.toBase58()} does not exist.`);
152
+ const shareMint = new web3_js_1.PublicKey(queueState.shareMint);
153
+ const depositMint = new web3_js_1.PublicKey(queueState.depositMint);
154
+ // Decimals for a UI amount, supply for the default floor: read at most once.
155
+ let shareMintState;
156
+ const readShareMint = async () => {
157
+ if (shareMintState)
158
+ return shareMintState;
159
+ const mintInfo = await connection.getAccountInfo(shareMint);
160
+ if (!mintInfo)
161
+ throw new core_1.UpshiftSDKError('UNKNOWN', `Share mint ${shareMint.toBase58()} does not exist.`);
162
+ shareMintState = (0, spl_token_1.unpackMint)(shareMint, mintInfo, spl_token_1.TOKEN_PROGRAM_ID);
163
+ return shareMintState;
164
+ };
165
+ let shares;
166
+ if (typeof amount === 'bigint') {
167
+ shares = new anchor_1.BN(amount.toString());
168
+ }
169
+ else {
170
+ const { decimals } = await readShareMint();
171
+ shares = (0, utils_1.uiAmountToRawBn)(amount, decimals);
172
+ if (shares.lten(0)) {
173
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRequestRedeem: ${amount} is below one raw unit of a ${decimals}-decimal share mint.`);
174
+ }
175
+ }
176
+ const shareAccount = await (0, token_reads_1.resolveUserTokenAccount)({
177
+ connection,
178
+ owner,
179
+ mint: shareMint,
180
+ });
181
+ if (shareAccount.frozen) {
182
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'Your share account is frozen by the token issuer, so these shares cannot be escrowed.');
183
+ }
184
+ if (shareAccount.balance < BigInt(shares.toString())) {
185
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `Insufficient shares to request: this wallet holds ${shareAccount.balance} raw share units, and the request needs ${shares.toString()}.`);
186
+ }
187
+ // The holder pays out to their own richest deposit-token account, as a
188
+ // direct redeem does; anyone else, to their associated account.
189
+ const preInstructions = [];
190
+ let recipientTokenAccount;
191
+ const recipient = params.recipient
192
+ ? new web3_js_1.PublicKey(params.recipient)
193
+ : owner;
194
+ if (recipient.equals(owner)) {
195
+ const payout = await (0, token_reads_1.resolveUserTokenAccount)({
196
+ connection,
197
+ owner,
198
+ mint: depositMint,
199
+ });
200
+ if (payout.frozen) {
201
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'Your token account for the deposit mint is frozen by the token issuer, so it cannot receive the payout.');
202
+ }
203
+ recipientTokenAccount = payout.address;
204
+ if (payout.createIx)
205
+ preInstructions.push(payout.createIx);
206
+ }
207
+ else {
208
+ // Off-curve owners are allowed: a multisig vault or another program's
209
+ // PDA is a valid recipient, and the program accepts it.
210
+ recipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(depositMint, recipient, true);
211
+ const existing = await connection.getAccountInfo(recipientTokenAccount);
212
+ if (!existing) {
213
+ preInstructions.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(owner, recipientTokenAccount, recipient, depositMint));
214
+ }
215
+ else if ((0, spl_token_1.unpackAccount)(recipientTokenAccount, existing, existing.owner).isFrozen) {
216
+ // The request would land, but every claim would then fail paying it.
217
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `The recipient's token account ${recipientTokenAccount.toBase58()} is frozen by the token issuer, so it could not receive the payout.`);
218
+ }
219
+ }
220
+ // Quoted from the vault state read above and the mint's supply. The program
221
+ // checks it at claim time against the shares' value then, net of the fee.
222
+ // The two reads can straddle a state change; the slippage allowance absorbs
223
+ // that, and an exact floor goes in `minAssetsOut`.
224
+ let minAssetsOut;
225
+ if (params.minAssetsOut !== undefined) {
226
+ minAssetsOut = params.minAssetsOut;
227
+ }
228
+ else {
229
+ const { supply } = await readShareMint();
230
+ const totalAssets = (0, pricing_1.totalAssetsOf)(vaultStateData);
231
+ // A marked-down vault can still queue a request, just not at a quote.
232
+ if (!(0, pricing_1.hasSharePrice)(supply, totalAssets)) {
233
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultRequestRedeem: this vault holds no assets while shares are outstanding, so there is no share price to quote a floor from; pass `minAssetsOut: 0n` to request without a floor.');
234
+ }
235
+ minAssetsOut = (0, pricing_1.quoteRedeemFloor)({
236
+ supply,
237
+ totalAssets,
238
+ shares: BigInt(shares.toString()),
239
+ offset: (0, pricing_1.resolveShareOffset)(vaultStateData.shareOffset),
240
+ feePpm: (0, pricing_1.toBigInt)(vaultStateData.withdrawalFee, 'withdrawalFee'),
241
+ slippageBps: params.slippageBps ?? pricing_1.DEFAULT_SLIPPAGE_BPS,
242
+ });
243
+ }
244
+ const id = requestId ?? randomRequestId();
245
+ const request = deriveWithdrawalRequestPda(queue, owner, id, queueProgramId);
246
+ const finalizer = params.finalizer
247
+ ? new web3_js_1.PublicKey(params.finalizer)
248
+ : web3_js_1.PublicKey.default;
249
+ const commitment = commitmentOf(connection);
250
+ const signature = await queueMethods(program)
251
+ .requestWithdrawal(new anchor_1.BN(id.toString()), shares, new anchor_1.BN(minAssetsOut.toString()), finalizer)
252
+ .accountsPartial({
253
+ queue,
254
+ vaultState,
255
+ owner,
256
+ ownerShareAccount: shareAccount.address,
257
+ escrowShares: queueState.escrowShares,
258
+ shareMint,
259
+ recipientTokenAccount,
260
+ request,
261
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
262
+ })
263
+ .preInstructions(preInstructions)
264
+ .rpc({
265
+ skipPreflight: false,
266
+ preflightCommitment: commitment,
267
+ commitment,
268
+ });
269
+ core_1.Logger.log.info('vaultRequestRedeem', 'Request submitted:', signature);
270
+ return { signature, request: request.toBase58(), requestId: id.toString() };
271
+ }
272
+ catch (e) {
273
+ wrapFailure('withdrawal request', e, context);
274
+ }
275
+ }
276
+ /**
277
+ * Read a request and the queue it names: two reads in turn, since the queue's
278
+ * address comes from the request.
279
+ */
280
+ async function loadRequest({ provider, connection, queueProgramId, request, operation, }) {
281
+ const program = queueProgram(provider, queueProgramId);
282
+ const requestInfo = await connection.getAccountInfo(request);
283
+ const requestState = decodeOrThrow(program.coder.accounts, 'withdrawalRequest', request, requestInfo, `${operation}: no pending request at ${request.toBase58()}; it may already have been claimed or cancelled.`);
284
+ const queue = new web3_js_1.PublicKey(requestState.queue);
285
+ const [queueInfo] = await connection.getMultipleAccountsInfo([queue]);
286
+ const queueState = decodeOrThrow(program.coder.accounts, 'withdrawalQueue', queue, queueInfo, `${operation}: the request's queue ${queue.toBase58()} does not exist.`);
287
+ return { program, requestState, queue, queueState };
288
+ }
289
+ /**
290
+ * Claim a request whose cooldown has run: `finalize_withdrawal`, which redeems
291
+ * the escrowed shares through the vault and pays the request's recipient.
292
+ *
293
+ * Anyone the request permits may claim it: the holder always, and anyone else
294
+ * unless it names a finalizer, in which case only that key. It is refused here,
295
+ * before signing, when the caller is not permitted, the cooldown has not run,
296
+ * or the window has closed; the wall clock stands in for the chain's, so at the
297
+ * boundary the program may still disagree by a slot. The vault's fee-recipient
298
+ * account is created in the same transaction when it has none, and so is the
299
+ * request's payout account when it is the holder's own ATA and has been closed
300
+ * since; any other closed or a frozen payout account is refused before
301
+ * signing, since the claim could only fail.
302
+ *
303
+ * RPC: three reads in turn, each address coming from the account before it
304
+ * (the request, its queue, then the queue's vault together with the payout
305
+ * account), then the send.
306
+ *
307
+ * @throws UpshiftValidationError for a missing request or one the caller cannot
308
+ * claim yet, before signing.
309
+ * @throws UpshiftSDKError when the transaction fails, e.g. `NotEnoughLiquidity`
310
+ * while the vault's reserve is deployed; the request stays pending.
311
+ */
312
+ async function handleSolanaClaimRedeem({ provider, connection, vaultProgramId, queueProgramId, wallet, request: requestAddress, nowSeconds, }) {
313
+ const context = { request: String(requestAddress) };
314
+ try {
315
+ if (!wallet)
316
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultRedeem: wallet not connected');
317
+ const finalizer = new web3_js_1.PublicKey(wallet);
318
+ const request = new web3_js_1.PublicKey(requestAddress);
319
+ const { program, requestState, queue, queueState } = await loadRequest({
320
+ provider,
321
+ connection,
322
+ queueProgramId,
323
+ request,
324
+ operation: 'vaultRedeem',
325
+ });
326
+ const named = new web3_js_1.PublicKey(requestState.finalizer);
327
+ const permitted = finalizer.equals(new web3_js_1.PublicKey(requestState.owner)) ||
328
+ named.equals(web3_js_1.PublicKey.default) ||
329
+ named.equals(finalizer);
330
+ if (!permitted) {
331
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRedeem: only the holder or ${named.toBase58()} may claim this request.`);
332
+ }
333
+ const now = BigInt(nowSeconds ?? Math.floor(Date.now() / 1000));
334
+ const expiresAt = BigInt(requestState.expiresAt.toString());
335
+ if (expiresAt !== 0n && now >= expiresAt) {
336
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultRedeem: this request is past its fulfillment window and can no longer be claimed; cancel it with `vaultCancelRedeemRequest` to get the shares back.');
337
+ }
338
+ const eligibleAt = BigInt(requestState.eligibleAt.toString());
339
+ if (now < eligibleAt) {
340
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRedeem: this request is still in its cooldown; it can be claimed from ${new Date(Number(eligibleAt) * 1000).toISOString()}.`);
341
+ }
342
+ const vaultState = new web3_js_1.PublicKey(queueState.vaultState);
343
+ const recipientTokenAccount = new web3_js_1.PublicKey(requestState.recipientTokenAccount);
344
+ const [vaultInfo, recipientInfo] = await connection.getMultipleAccountsInfo([vaultState, recipientTokenAccount]);
345
+ const vault = decodeOrThrow(vaultCoder(provider), 'vaultState', vaultState, vaultInfo, `vaultRedeem: the request's vault ${vaultState.toBase58()} does not exist.`);
346
+ const depositMint = new web3_js_1.PublicKey(queueState.depositMint);
347
+ const feeRecipient = new web3_js_1.PublicKey(vault.feeRecipient);
348
+ // Off-curve allowed: a multisig vault or program PDA can be the fee recipient.
349
+ const feeRecipientAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(depositMint, feeRecipient, true);
350
+ const preInstructions = [
351
+ (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(finalizer, feeRecipientAccount, feeRecipient, depositMint),
352
+ ];
353
+ // The payout account is fixed by the request, and may have been closed
354
+ // since: a wallet's cleanup closes an empty token account. The holder's own
355
+ // ATA can be recreated here, as the fee recipient's is; any other account
356
+ // cannot be rebuilt from its address, so say so before signing.
357
+ const requestOwner = new web3_js_1.PublicKey(requestState.owner);
358
+ if (!recipientInfo) {
359
+ const ownerAta = (0, spl_token_1.getAssociatedTokenAddressSync)(depositMint, requestOwner, true);
360
+ if (!recipientTokenAccount.equals(ownerAta)) {
361
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRedeem: this request pays ${recipientTokenAccount.toBase58()}, which no longer exists; it must be recreated before the request can be claimed, or the holder can cancel it.`);
362
+ }
363
+ preInstructions.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(finalizer, ownerAta, requestOwner, depositMint));
364
+ }
365
+ else if ((0, spl_token_1.unpackAccount)(recipientTokenAccount, recipientInfo, recipientInfo.owner)
366
+ .isFrozen) {
367
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', `vaultRedeem: this request pays ${recipientTokenAccount.toBase58()}, which is frozen by the token issuer, so the claim would fail; the holder can cancel the request.`);
368
+ }
369
+ const commitment = commitmentOf(connection);
370
+ const signature = await queueMethods(program)
371
+ .finalizeWithdrawal(requestState.sequence)
372
+ .accountsPartial({
373
+ queue,
374
+ vaultState,
375
+ vaultDepositAta: utils_1.SolanaUtils.deriveVaultTokenAtaPda(vaultProgramId, depositMint, vault.vaultVersion[0]),
376
+ feeRecipientAccount,
377
+ escrowShares: queueState.escrowShares,
378
+ escrowAssets: queueState.escrowAssets,
379
+ shareMint: queueState.shareMint,
380
+ depositMint,
381
+ finalizer,
382
+ request,
383
+ owner: requestOwner,
384
+ recipientTokenAccount,
385
+ vaultProgram: vaultProgramId,
386
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
387
+ })
388
+ .preInstructions(preInstructions)
389
+ .rpc({
390
+ skipPreflight: false,
391
+ preflightCommitment: commitment,
392
+ commitment,
393
+ });
394
+ core_1.Logger.log.info('vaultRedeem', 'Request claimed:', signature);
395
+ return signature;
396
+ }
397
+ catch (e) {
398
+ wrapFailure('withdrawal claim', e, context);
399
+ }
400
+ }
401
+ /**
402
+ * Cancel a pending request: `cancel_withdrawal` returns its shares to the
403
+ * holder's share account (created in the same transaction when they closed
404
+ * theirs) and closes the request, refunding its rent. Allowed at any time
405
+ * while the request exists, cooldown or not, expired or not, paused or not.
406
+ *
407
+ * RPC: two reads in turn (the request, then its queue), one
408
+ * `getParsedTokenAccountsByOwner`, then the send.
409
+ *
410
+ * @returns The confirmed transaction's signature.
411
+ * @throws UpshiftValidationError for a missing request or one `wallet` did not
412
+ * make, before signing.
413
+ * @throws UpshiftSDKError when the transaction fails.
414
+ */
415
+ async function handleSolanaCancelRedeemRequest({ provider, connection, queueProgramId, params, }) {
416
+ const context = { request: String(params.request) };
417
+ try {
418
+ if (!params.wallet)
419
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultCancelRedeemRequest: wallet not connected');
420
+ if (!params.request)
421
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultCancelRedeemRequest: request is required');
422
+ const owner = new web3_js_1.PublicKey(params.wallet);
423
+ const request = new web3_js_1.PublicKey(params.request);
424
+ const { program, requestState, queue, queueState } = await loadRequest({
425
+ provider,
426
+ connection,
427
+ queueProgramId,
428
+ request,
429
+ operation: 'vaultCancelRedeemRequest',
430
+ });
431
+ if (!owner.equals(new web3_js_1.PublicKey(requestState.owner))) {
432
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'vaultCancelRedeemRequest: only the holder who made this request may cancel it.');
433
+ }
434
+ const shareMint = new web3_js_1.PublicKey(queueState.shareMint);
435
+ const destination = await (0, token_reads_1.resolveUserTokenAccount)({
436
+ connection,
437
+ owner,
438
+ mint: shareMint,
439
+ });
440
+ if (destination.frozen) {
441
+ throw new core_1.UpshiftValidationError('INVALID_INPUT', 'Your share account is frozen by the token issuer, so it cannot take the shares back.');
442
+ }
443
+ const commitment = commitmentOf(connection);
444
+ const signature = await queueMethods(program)
445
+ .cancelWithdrawal(requestState.sequence)
446
+ .accountsPartial({
447
+ queue,
448
+ owner,
449
+ request,
450
+ escrowShares: queueState.escrowShares,
451
+ shareMint,
452
+ destinationShareAccount: destination.address,
453
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
454
+ })
455
+ .preInstructions(destination.createIx ? [destination.createIx] : [])
456
+ .rpc({
457
+ skipPreflight: false,
458
+ preflightCommitment: commitment,
459
+ commitment,
460
+ });
461
+ core_1.Logger.log.info('vaultCancelRedeemRequest', 'Request cancelled:', signature);
462
+ return signature;
463
+ }
464
+ catch (e) {
465
+ wrapFailure('withdrawal cancel', e, context);
466
+ }
467
+ }
468
+ //# sourceMappingURL=queue.actions.js.map
@@ -0,0 +1,108 @@
1
+ import type { AccountInfo, Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';
2
+ /**
3
+ * The vault state and share-mint supply as of a **single slot**.
4
+ *
5
+ * Both figures price the quote, so they have to come from one snapshot. Read
6
+ * independently — even concurrently, as two RPC requests — a deposit or
7
+ * redemption landing in between combines a supply and an asset total that
8
+ * never coexisted, and the quote is wrong in whichever direction the
9
+ * interleaving fell. Seeing a 10% deposit's new assets against the old supply
10
+ * quotes ~10% high, and the floor then rejects a redemption whose share price
11
+ * never moved; the opposite ordering quotes low and silently weakens the
12
+ * protection. `getMultipleAccountsInfo` is served from one slot, so the pair
13
+ * is always coherent — and it costs one round trip instead of two.
14
+ *
15
+ * @param program - Anchor program, used only for its account coder; the
16
+ * provider it was built with is irrelevant, so no read-only program is needed.
17
+ * @param vaultStatePda - Vault state account to decode.
18
+ * @param shareMintAddr - Share mint whose supply and decimals are read.
19
+ * @param extraAccounts - Further accounts to read in the same call and slot,
20
+ * returned raw and in order (`null` for an absent one). Lets a caller that
21
+ * also needs, say, token accounts avoid a second round trip.
22
+ * @returns The decoded `VaultState`, the share mint's raw `supply`, its
23
+ * `decimals`, and `extraAccountInfos` — all from the same slot.
24
+ * @throws {@link UpshiftSDKError} when either account is absent, or is not the
25
+ * account type it should be.
26
+ */
27
+ export declare function readPricingSnapshot({ connection, program, vaultStatePda, shareMintAddr, extraAccounts, }: {
28
+ connection: Connection;
29
+ program: any;
30
+ vaultStatePda: PublicKey;
31
+ shareMintAddr: PublicKey;
32
+ extraAccounts?: PublicKey[];
33
+ }): Promise<{
34
+ vaultStateData: any;
35
+ supply: bigint;
36
+ shareDecimals: number;
37
+ extraAccountInfos: (AccountInfo<Buffer> | null)[];
38
+ }>;
39
+ /**
40
+ * The token account a vault instruction should use for `mint`, its balance,
41
+ * and the instruction (if any) needed to bring it into existence.
42
+ *
43
+ * `createIx` is present iff the owner holds no *account* for `mint`. It says
44
+ * nothing about balance — an existing account may hold zero, which is a
45
+ * distinct state. Callers that need funds must check {@link balance}.
46
+ */
47
+ export interface IResolvedTokenAccount {
48
+ /** Account to pass to the program as `sender_token_account` / `sender_share_account`. */
49
+ address: PublicKey;
50
+ /** Raw on-chain balance of {@link address}; `0n` when the account is absent. */
51
+ balance: bigint;
52
+ /**
53
+ * True when every account the wallet holds for this mint is frozen. Tokens
54
+ * can move neither out of nor into a frozen account, so this is fatal for
55
+ * funding, burning *and* payout — reject before requesting a signature.
56
+ */
57
+ frozen: boolean;
58
+ /**
59
+ * Idempotent ATA-creation instruction, or `undefined` when an account
60
+ * already exists. Prepend to the vault instruction — never send on its own.
61
+ */
62
+ createIx?: TransactionInstruction;
63
+ }
64
+ /**
65
+ * Pick which token account to hand the vault program for a given mint, and
66
+ * describe how to create it when the user has none.
67
+ *
68
+ * The vault program constrains these accounts by `token::mint` +
69
+ * `token::authority` (not `associated_token::…`), so any account the signer
70
+ * owns qualifies. We therefore keep an existing account when there is one —
71
+ * that is where the user's balance already lives — and fall back to the
72
+ * associated token account otherwise.
73
+ *
74
+ * Two deliberate choices:
75
+ *
76
+ * - **The create is returned, not sent.** Prepended to the deposit/redeem via
77
+ * `.preInstructions()` it is atomic with the transfer, so there is no window
78
+ * in which the vault instruction can reference an account that has not
79
+ * landed. Sent as its own transaction — as this module used to — it raced
80
+ * its own confirmation. Observed in production (2026-08-11):
81
+ * a deposit failed with `Simulation failed … Logs: []` while the share-ATA
82
+ * create was still in flight, then succeeded 17s later on retry. The empty
83
+ * log array means the transaction never reached program execution, so there
84
+ * was nothing on-chain to debug from.
85
+ * - **Idempotent.** `createAssociatedTokenAccountIdempotentInstruction` is a
86
+ * no-op when the account already exists, so a concurrent create — another
87
+ * tab, a wallet's auto-provisioning — cannot turn into an
88
+ * `SystemError::AccountAlreadyInUse` ("already in use") failure between our
89
+ * read and our submit.
90
+ *
91
+ * Which account wins when several exist is decided by
92
+ * {@link selectRichestTokenAccount} — the same rule every balance *read* in
93
+ * this adapter uses, so the account a UI reports and the account a transfer
94
+ * names are never different accounts.
95
+ *
96
+ * Classic SPL Token only: the ATA is derived under `TOKEN_PROGRAM_ID`, matching
97
+ * the `tokenProgram` both handlers pass, even though the program's
98
+ * `TokenInterface` would also accept Token-2022.
99
+ *
100
+ * @param owner - Wallet that owns the account and pays rent for any creation.
101
+ * @throws UpshiftSDKError when a candidate account's balance cannot be read
102
+ * (propagated from the shared selector).
103
+ */
104
+ export declare function resolveUserTokenAccount({ connection, owner, mint, }: {
105
+ connection: Connection;
106
+ owner: PublicKey;
107
+ mint: PublicKey;
108
+ }): Promise<IResolvedTokenAccount>;