@t2000/sdk 0.16.16 → 0.16.18

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.
@@ -669,6 +669,13 @@ declare class SuilendAdapter implements LendingAdapter {
669
669
  coin: TransactionObjectArgument;
670
670
  effectiveAmount: number;
671
671
  }>;
672
+ /**
673
+ * 3-step cToken redemption matching the official Suilend SDK flow:
674
+ * 1. redeem_ctokens_and_withdraw_liquidity_request — creates a LiquidityRequest
675
+ * 2. unstake_sui_from_staker — (SUI only) unstakes from validators to replenish available_liquidity
676
+ * 3. fulfill_liquidity_request — splits underlying tokens from the reserve
677
+ */
678
+ private redeemCtokens;
672
679
  addSaveToTx(tx: Transaction, address: string, coin: TransactionObjectArgument, asset: string, options?: {
673
680
  collectFee?: boolean;
674
681
  }): Promise<void>;
@@ -669,6 +669,13 @@ declare class SuilendAdapter implements LendingAdapter {
669
669
  coin: TransactionObjectArgument;
670
670
  effectiveAmount: number;
671
671
  }>;
672
+ /**
673
+ * 3-step cToken redemption matching the official Suilend SDK flow:
674
+ * 1. redeem_ctokens_and_withdraw_liquidity_request — creates a LiquidityRequest
675
+ * 2. unstake_sui_from_staker — (SUI only) unstakes from validators to replenish available_liquidity
676
+ * 3. fulfill_liquidity_request — splits underlying tokens from the reserve
677
+ */
678
+ private redeemCtokens;
672
679
  addSaveToTx(tx: Transaction, address: string, coin: TransactionObjectArgument, asset: string, options?: {
673
680
  collectFee?: boolean;
674
681
  }): Promise<void>;
package/dist/index.cjs CHANGED
@@ -185,11 +185,10 @@ function parseMoveAbortMessage(msg) {
185
185
  if (abortMatch) {
186
186
  const code = parseInt(abortMatch[1], 10);
187
187
  const mapped = mapMoveAbortCode(code);
188
- if (mapped.startsWith("Move abort code:")) {
189
- const moduleMatch = msg.match(/in '([^']+)'/);
190
- if (moduleMatch) return `${mapped} (in ${moduleMatch[1]})`;
191
- }
192
- return mapped;
188
+ const moduleMatch = msg.match(/Identifier\("([^"]+)"\)/) ?? msg.match(/in '([^']+)'/);
189
+ const fnMatch = msg.match(/function_name:\s*Some\("([^"]+)"\)/);
190
+ const suffix = moduleMatch ? ` [${moduleMatch[1]}${fnMatch ? `::${fnMatch[1]}` : ""}]` : "";
191
+ return `${mapped}${suffix}`;
193
192
  }
194
193
  return msg;
195
194
  }
@@ -1776,6 +1775,7 @@ SUPPORTED_ASSETS.USDC.type;
1776
1775
  var WAD = 1e18;
1777
1776
  var MIN_HEALTH_FACTOR2 = 1.5;
1778
1777
  var CLOCK2 = "0x6";
1778
+ var SUI_SYSTEM_STATE2 = "0x5";
1779
1779
  var LENDING_MARKET_ID = "0x84030d26d85eaa7035084a057f2f11f701b7e2e4eda87551becbc7c97505ece1";
1780
1780
  var LENDING_MARKET_TYPE = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf::suilend::MAIN_POOL";
1781
1781
  var SUILEND_PACKAGE = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
@@ -1791,6 +1791,9 @@ var descriptor4 = {
1791
1791
  "lending_market::create_obligation": "save",
1792
1792
  "lending_market::withdraw_ctokens": "withdraw",
1793
1793
  "lending_market::redeem_ctokens_and_withdraw_liquidity": "withdraw",
1794
+ "lending_market::redeem_ctokens_and_withdraw_liquidity_request": "withdraw",
1795
+ "lending_market::fulfill_liquidity_request": "withdraw",
1796
+ "lending_market::unstake_sui_from_staker": "withdraw",
1794
1797
  "lending_market::borrow": "borrow",
1795
1798
  "lending_market::repay": "repay"
1796
1799
  }
@@ -2135,7 +2138,9 @@ var SuilendAdapter = class {
2135
2138
  const deposited = dep ? dep.ctokenAmount * ratio / 10 ** reserve.mintDecimals : 0;
2136
2139
  const effectiveAmount = Math.min(amount, deposited);
2137
2140
  if (effectiveAmount <= 0) throw new T2000Error("NO_COLLATERAL", `Nothing to withdraw for ${assetInfo.displayName} on Suilend`);
2138
- const rawAmount = Math.floor(effectiveAmount * 10 ** reserve.mintDecimals);
2141
+ const U64_MAX = "18446744073709551615";
2142
+ const isFullWithdraw = dep && effectiveAmount >= deposited * 0.999;
2143
+ const withdrawArg = isFullWithdraw ? U64_MAX : String(Math.floor(effectiveAmount * 10 ** reserve.mintDecimals / ratio));
2139
2144
  const tx = new transactions.Transaction();
2140
2145
  tx.setSender(address);
2141
2146
  const [ctokens] = tx.moveCall({
@@ -2146,25 +2151,10 @@ var SuilendAdapter = class {
2146
2151
  tx.pure.u64(reserve.arrayIndex),
2147
2152
  tx.object(caps[0].id),
2148
2153
  tx.object(CLOCK2),
2149
- tx.pure.u64(rawAmount)
2150
- ]
2151
- });
2152
- const exemptionType = `${SUILEND_PACKAGE}::lending_market::RateLimiterExemption<${LENDING_MARKET_TYPE}, ${assetInfo.type}>`;
2153
- const [none] = tx.moveCall({
2154
- target: "0x1::option::none",
2155
- typeArguments: [exemptionType]
2156
- });
2157
- const [coin] = tx.moveCall({
2158
- target: `${pkg}::lending_market::redeem_ctokens_and_withdraw_liquidity`,
2159
- typeArguments: [LENDING_MARKET_TYPE, assetInfo.type],
2160
- arguments: [
2161
- tx.object(LENDING_MARKET_ID),
2162
- tx.pure.u64(reserve.arrayIndex),
2163
- tx.object(CLOCK2),
2164
- ctokens,
2165
- none
2154
+ tx.pure("u64", BigInt(withdrawArg))
2166
2155
  ]
2167
2156
  });
2157
+ const coin = this.redeemCtokens(tx, pkg, reserve, assetInfo.type, assetKey, ctokens);
2168
2158
  tx.transferObjects([coin], address);
2169
2159
  return { tx, effectiveAmount };
2170
2160
  }
@@ -2182,7 +2172,7 @@ var SuilendAdapter = class {
2182
2172
  const deposited = dep ? dep.ctokenAmount * ratio / 10 ** reserve.mintDecimals : 0;
2183
2173
  const effectiveAmount = Math.min(amount, deposited);
2184
2174
  if (effectiveAmount <= 0) throw new T2000Error("NO_COLLATERAL", `Nothing to withdraw for ${assetInfo.displayName} on Suilend`);
2185
- const rawAmount = Math.floor(effectiveAmount * 10 ** reserve.mintDecimals);
2175
+ const ctokenAmount = dep && effectiveAmount >= deposited * 0.999 ? dep.ctokenAmount : Math.floor(effectiveAmount * 10 ** reserve.mintDecimals / ratio);
2186
2176
  const [ctokens] = tx.moveCall({
2187
2177
  target: `${pkg}::lending_market::withdraw_ctokens`,
2188
2178
  typeArguments: [LENDING_MARKET_TYPE, assetInfo.type],
@@ -2191,17 +2181,27 @@ var SuilendAdapter = class {
2191
2181
  tx.pure.u64(reserve.arrayIndex),
2192
2182
  tx.object(caps[0].id),
2193
2183
  tx.object(CLOCK2),
2194
- tx.pure.u64(rawAmount)
2184
+ tx.pure.u64(ctokenAmount)
2195
2185
  ]
2196
2186
  });
2197
- const exemptionType = `${SUILEND_PACKAGE}::lending_market::RateLimiterExemption<${LENDING_MARKET_TYPE}, ${assetInfo.type}>`;
2187
+ const coin = this.redeemCtokens(tx, pkg, reserve, assetInfo.type, assetKey, ctokens);
2188
+ return { coin, effectiveAmount };
2189
+ }
2190
+ /**
2191
+ * 3-step cToken redemption matching the official Suilend SDK flow:
2192
+ * 1. redeem_ctokens_and_withdraw_liquidity_request — creates a LiquidityRequest
2193
+ * 2. unstake_sui_from_staker — (SUI only) unstakes from validators to replenish available_liquidity
2194
+ * 3. fulfill_liquidity_request — splits underlying tokens from the reserve
2195
+ */
2196
+ redeemCtokens(tx, pkg, reserve, coinType, assetKey, ctokens) {
2197
+ const exemptionType = `${SUILEND_PACKAGE}::lending_market::RateLimiterExemption<${LENDING_MARKET_TYPE}, ${coinType}>`;
2198
2198
  const [none] = tx.moveCall({
2199
2199
  target: "0x1::option::none",
2200
2200
  typeArguments: [exemptionType]
2201
2201
  });
2202
- const [coin] = tx.moveCall({
2203
- target: `${pkg}::lending_market::redeem_ctokens_and_withdraw_liquidity`,
2204
- typeArguments: [LENDING_MARKET_TYPE, assetInfo.type],
2202
+ const [liquidityRequest] = tx.moveCall({
2203
+ target: `${pkg}::lending_market::redeem_ctokens_and_withdraw_liquidity_request`,
2204
+ typeArguments: [LENDING_MARKET_TYPE, coinType],
2205
2205
  arguments: [
2206
2206
  tx.object(LENDING_MARKET_ID),
2207
2207
  tx.pure.u64(reserve.arrayIndex),
@@ -2210,7 +2210,28 @@ var SuilendAdapter = class {
2210
2210
  none
2211
2211
  ]
2212
2212
  });
2213
- return { coin, effectiveAmount };
2213
+ if (assetKey === "SUI") {
2214
+ tx.moveCall({
2215
+ target: `${pkg}::lending_market::unstake_sui_from_staker`,
2216
+ typeArguments: [LENDING_MARKET_TYPE],
2217
+ arguments: [
2218
+ tx.object(LENDING_MARKET_ID),
2219
+ tx.pure.u64(reserve.arrayIndex),
2220
+ liquidityRequest,
2221
+ tx.object(SUI_SYSTEM_STATE2)
2222
+ ]
2223
+ });
2224
+ }
2225
+ const [coin] = tx.moveCall({
2226
+ target: `${pkg}::lending_market::fulfill_liquidity_request`,
2227
+ typeArguments: [LENDING_MARKET_TYPE, coinType],
2228
+ arguments: [
2229
+ tx.object(LENDING_MARKET_ID),
2230
+ tx.pure.u64(reserve.arrayIndex),
2231
+ liquidityRequest
2232
+ ]
2233
+ });
2234
+ return coin;
2214
2235
  }
2215
2236
  async addSaveToTx(tx, address, coin, asset, options) {
2216
2237
  const assetKey = asset in SUPPORTED_ASSETS ? asset : "USDC";