@ember-finance/sdk 2.23.0 → 2.24.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.
@@ -1,5 +1,7 @@
1
1
  import { BaseClient as SuiClient } from "@mysten/sui/client";
2
2
  import { FeeMultiplierTier, InstantWithdrawQuote } from "../../atomic/instant-withdraw.js";
3
+ /** Strategy an atomic vault's idle collateral can be supplied to. */
4
+ export type SuiAtomicStrategy = "none" | "suilend";
3
5
  /**
4
6
  * Read-only views + instant-withdraw quotes for the Sui Atomic Liquidity Vault (BET-4111).
5
7
  *
@@ -40,6 +42,19 @@ export declare class SuiAtomicLiquidityReader {
40
42
  } | null>;
41
43
  /** Caller's ALV (non-transferable) share balance from the `shares` table. */
42
44
  shareOf(vaultId: string, account: string): Promise<bigint>;
45
+ /**
46
+ * Where an atomic vault's collateral sits: idle in the vault, or supplied to its
47
+ * strategy.
48
+ * @param vaultId Object id of the atomic vault
49
+ * @returns The active strategy, idle collateral and strategy assets, in collateral
50
+ * base units. `suilendMarketId` is set when the strategy is Suilend.
51
+ */
52
+ getStrategyState(vaultId: string): Promise<{
53
+ strategy: SuiAtomicStrategy;
54
+ idleCollateral: bigint;
55
+ strategyAssets: bigint;
56
+ suilendMarketId?: string;
57
+ }>;
43
58
  /**
44
59
  * Live quote for the EmberShare swap-with-holdback "instant withdraw" on Sui.
45
60
  * Reads ALV + source vault fields and replicates `swap_ember_shares` math.
@@ -1,6 +1,10 @@
1
1
  import { bcs } from "@mysten/sui/bcs";
2
+ import { Transaction } from "@mysten/sui/transactions";
3
+ import { SUI_ZERO_ADDRESS } from "./protocol-config-reader.js";
2
4
  import { tableIdOf, unwrapMoveFields } from "../utils/common.js";
3
5
  import { computeSwapQuote, computePlainInstantQuote } from "../../atomic/instant-withdraw.js";
6
+ // Indexed by the Move `strategy_kind` u8.
7
+ const SUI_ATOMIC_STRATEGIES = ["none", "suilend"];
4
8
  /** Sui fixed-point scale (1e9) used by the Atomic Liquidity Vault Move math. */
5
9
  const SUI_SCALE = 1000000000n;
6
10
  const toBig = (v) => v === undefined || v === null ? 0n : BigInt(v);
@@ -107,6 +111,72 @@ export class SuiAtomicLiquidityReader {
107
111
  return 0n;
108
112
  return toBig(await this.readTableValue(tableId, "address", account));
109
113
  }
114
+ /**
115
+ * Where an atomic vault's collateral sits: idle in the vault, or supplied to its
116
+ * strategy.
117
+ * @param vaultId Object id of the atomic vault
118
+ * @returns The active strategy, idle collateral and strategy assets, in collateral
119
+ * base units. `suilendMarketId` is set when the strategy is Suilend.
120
+ */
121
+ async getStrategyState(vaultId) {
122
+ const res = await this.suiClient.core.getObject({
123
+ objectId: vaultId,
124
+ include: { json: true }
125
+ });
126
+ const fields = unwrapMoveFields(res.object?.json);
127
+ if (!fields)
128
+ throw new Error(`Atomic vault ${vaultId} not found`);
129
+ const strategy = SUI_ATOMIC_STRATEGIES[Number(fields.strategy_kind)];
130
+ if (!strategy) {
131
+ throw new Error(`Unknown strategy kind ${fields.strategy_kind} on ${vaultId}`);
132
+ }
133
+ const idleCollateral = toBig(fields.balance);
134
+ if (strategy === "none") {
135
+ return { strategy, idleCollateral, strategyAssets: 0n };
136
+ }
137
+ // The vault's type names the package that defines it, which is the one with
138
+ // the views. The position is valued by Suilend against the reserve's current
139
+ // interest, so it is simulated rather than read from fields.
140
+ const vaultType = res.object.type;
141
+ const collateralType = vaultType.slice(vaultType.indexOf("<") + 1, -1);
142
+ const packageId = vaultType.split("::")[0];
143
+ const marketField = await this.suiClient.core.getDynamicField({
144
+ parentId: vaultId,
145
+ name: {
146
+ type: "vector<u8>",
147
+ bcs: bcs
148
+ .vector(bcs.u8())
149
+ .serialize(new TextEncoder().encode("al_strategy_suilend_market_id"))
150
+ .toBytes()
151
+ }
152
+ });
153
+ const suilendMarketId = bcs.Address.parse(marketField.dynamicField.value.bcs);
154
+ const market = await this.suiClient.core.getObject({ objectId: suilendMarketId });
155
+ const marketType = market.object.type;
156
+ const poolType = marketType.slice(marketType.indexOf("<") + 1, -1);
157
+ const tx = new Transaction();
158
+ tx.setSender(SUI_ZERO_ADDRESS);
159
+ tx.moveCall({
160
+ target: `${packageId}::atomic_liquidity_vault::get_suilend_strategy_assets`,
161
+ typeArguments: [collateralType, poolType],
162
+ arguments: [tx.object(vaultId), tx.object(suilendMarketId), tx.object.clock()]
163
+ });
164
+ const sim = await this.suiClient.core.simulateTransaction({
165
+ transaction: tx,
166
+ checksEnabled: false,
167
+ include: { commandResults: true }
168
+ });
169
+ const returned = sim.commandResults?.[0]?.returnValues?.[0]?.bcs;
170
+ if (sim.$kind !== "Transaction" || !returned) {
171
+ throw new Error(`get_suilend_strategy_assets failed for ${vaultId}: ${sim.FailedTransaction?.status?.error?.message ?? "no return value"}`);
172
+ }
173
+ return {
174
+ strategy,
175
+ idleCollateral,
176
+ strategyAssets: BigInt(bcs.u64().parse(returned)),
177
+ suilendMarketId
178
+ };
179
+ }
110
180
  /**
111
181
  * Live quote for the EmberShare swap-with-holdback "instant withdraw" on Sui.
112
182
  * Reads ALV + source vault fields and replicates `swap_ember_shares` math.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ember-finance/sdk",
3
3
  "description": "Ember Protocol SDK",
4
- "version": "2.23.0",
4
+ "version": "2.24.0",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
7
7
  "main": "./dist/index.js",