@ember-finance/sdk 2.31.0 → 2.34.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.
- package/dist/src/sui-vaults/on-chain-calls/atomic-liquidity.d.ts +6 -0
- package/dist/src/sui-vaults/on-chain-calls/atomic-liquidity.js +21 -0
- package/dist/src/sui-vaults/on-chain-calls/operator.d.ts +12 -1
- package/dist/src/sui-vaults/on-chain-calls/operator.js +37 -1
- package/dist/src/sui-vaults/on-chain-calls/tx-builder.d.ts +10 -0
- package/dist/src/sui-vaults/on-chain-calls/tx-builder.js +27 -0
- package/dist/src/sui-vaults/on-chain-calls/user.d.ts +1 -0
- package/dist/src/sui-vaults/on-chain-calls/user.js +18 -7
- package/package.json +1 -1
|
@@ -62,6 +62,12 @@ export declare class SuiAtomicLiquidityReader {
|
|
|
62
62
|
private readTableValue;
|
|
63
63
|
/** Rate value (1e9) of any vault object (ALV or source EmberVault). */
|
|
64
64
|
private rateValue;
|
|
65
|
+
/**
|
|
66
|
+
* Platform fee a collection would settle at `atMs` (epoch ms), in collateral base units.
|
|
67
|
+
* @param vaultId The id of the atomic vault
|
|
68
|
+
* @param atMs Time to project the fee to
|
|
69
|
+
*/
|
|
70
|
+
getPlatformFeeDue(vaultId: string, atMs: bigint): Promise<bigint>;
|
|
65
71
|
/** Per-source-share EmberShare config from the `ember_share_configs` table. */
|
|
66
72
|
getEmberShareConfig(vaultId: string, sourceVaultId: string): Promise<{
|
|
67
73
|
whitelisted: boolean;
|
|
@@ -131,6 +131,27 @@ export class SuiAtomicLiquidityReader {
|
|
|
131
131
|
const fields = unwrapMoveFields(res.object?.json);
|
|
132
132
|
return toBig(unwrapMoveFields(fields?.rate)?.value);
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Platform fee a collection would settle at `atMs` (epoch ms), in collateral base units.
|
|
136
|
+
* @param vaultId The id of the atomic vault
|
|
137
|
+
* @param atMs Time to project the fee to
|
|
138
|
+
*/
|
|
139
|
+
async getPlatformFeeDue(vaultId, atMs) {
|
|
140
|
+
// collect_platform_fee charges the time since last_charged_at before settling:
|
|
141
|
+
// accrued + tvl' * fee_percentage * elapsed_ms / 31_536_000e12, where tvl' is
|
|
142
|
+
// TVL (div(total_shares, rate)) net of the already-accrued fee.
|
|
143
|
+
const fields = await this.vaultFields(vaultId);
|
|
144
|
+
const fee = unwrapMoveFields(fields.fee) ?? {};
|
|
145
|
+
const accrued = toBig(fee.accrued);
|
|
146
|
+
const lastChargedAt = toBig(fee.last_charged_at);
|
|
147
|
+
const feePercentage = toBig(fields.fee_percentage);
|
|
148
|
+
if (atMs <= lastChargedAt || feePercentage === 0n)
|
|
149
|
+
return accrued;
|
|
150
|
+
const tvl = divFloor(toBig(fields.total_shares), toBig(unwrapMoveFields(fields.rate)?.value));
|
|
151
|
+
const base = tvl > accrued ? tvl - accrued : 0n;
|
|
152
|
+
return (accrued +
|
|
153
|
+
(base * feePercentage * (atMs - lastChargedAt)) / 31536000000000000000n);
|
|
154
|
+
}
|
|
134
155
|
/** Per-source-share EmberShare config from the `ember_share_configs` table. */
|
|
135
156
|
async getEmberShareConfig(vaultId, sourceVaultId) {
|
|
136
157
|
const fields = await this.vaultFields(vaultId);
|
|
@@ -139,7 +139,8 @@ export declare class OperatorCalls extends OnChainCalls {
|
|
|
139
139
|
*/
|
|
140
140
|
atomicProcessWithdrawalRequestsUpToTimestamp(vaultId: string, timestamp: NumStr, options?: IVaultOptionalParams & SuiTransactionBlockResponseOptions): Promise<OnChainCallResponse>;
|
|
141
141
|
/**
|
|
142
|
-
* Collect the platform fee of an atomic vault
|
|
142
|
+
* Collect the platform fee of an atomic vault. On a strategy vault, pulls any
|
|
143
|
+
* shortfall from the strategy first, in the same transaction.
|
|
143
144
|
* @param vaultId The id of the atomic vault
|
|
144
145
|
* @param loss The reported loss amount
|
|
145
146
|
* @param options Optional tx execution params
|
|
@@ -244,6 +245,16 @@ export declare class OperatorCalls extends OnChainCalls {
|
|
|
244
245
|
* @returns OnChainCallResponse
|
|
245
246
|
*/
|
|
246
247
|
atomicDepositFromSubAccount(vaultId: string, tokenId: string, subAccount: string, options?: IVaultOptionalParams & SuiTransactionBlockResponseOptions): Promise<OnChainCallResponse>;
|
|
248
|
+
/**
|
|
249
|
+
* Deposit collateral back into an atomic vault from its accumulator
|
|
250
|
+
* (address) balance, where `send_funds` transfers land
|
|
251
|
+
* @param vaultId The id of the atomic vault
|
|
252
|
+
* @param amount The amount to redeem from the vault's accumulator balance
|
|
253
|
+
* @param subAccount The sub account address
|
|
254
|
+
* @param options Optional tx execution params
|
|
255
|
+
* @returns OnChainCallResponse
|
|
256
|
+
*/
|
|
257
|
+
atomicDepositFromSubAccountV2(vaultId: string, amount: NumStr, subAccount: string, options?: IVaultOptionalParams & SuiTransactionBlockResponseOptions): Promise<OnChainCallResponse>;
|
|
247
258
|
/**
|
|
248
259
|
* Redeem collected ember shares from an atomic vault against a source vault
|
|
249
260
|
* @param vaultId The id of the atomic vault
|
|
@@ -252,7 +252,8 @@ export class OperatorCalls extends OnChainCalls {
|
|
|
252
252
|
return this.execCall(txb, options);
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
|
-
* Collect the platform fee of an atomic vault
|
|
255
|
+
* Collect the platform fee of an atomic vault. On a strategy vault, pulls any
|
|
256
|
+
* shortfall from the strategy first, in the same transaction.
|
|
256
257
|
* @param vaultId The id of the atomic vault
|
|
257
258
|
* @param loss The reported loss amount
|
|
258
259
|
* @param options Optional tx execution params
|
|
@@ -260,6 +261,24 @@ export class OperatorCalls extends OnChainCalls {
|
|
|
260
261
|
*/
|
|
261
262
|
async atomicCollectPlatformFee(vaultId, loss, options) {
|
|
262
263
|
const txb = options?.txBlock || new TransactionBlock();
|
|
264
|
+
// Unlike EVM's collectPlatformFee, the Sui collection pays from idle balance only
|
|
265
|
+
// and aborts when it is short, so the strategy is drawn on first. The fee keeps
|
|
266
|
+
// accruing until the tx lands, so it is projected a few minutes ahead; whatever
|
|
267
|
+
// is pulled beyond the payout stays idle in the vault.
|
|
268
|
+
const reader = new SuiAtomicLiquidityReader(this.suiClient);
|
|
269
|
+
const target = await reader.getStrategyTarget(vaultId);
|
|
270
|
+
if (target.strategy === "suilend") {
|
|
271
|
+
const landsBy = BigInt(Date.now() + 10 * 60 * 1000);
|
|
272
|
+
const due = await reader.getPlatformFeeDue(vaultId, landsBy);
|
|
273
|
+
const payout = due > BigInt(loss) ? due - BigInt(loss) : 0n;
|
|
274
|
+
const shortfall = payout - target.idleCollateral;
|
|
275
|
+
if (shortfall > 0n) {
|
|
276
|
+
const withdraw = isSuiCoinType(target.collateralType)
|
|
277
|
+
? this.txBuilder.atomicWithdrawFromSuilendStrategySui.bind(this.txBuilder)
|
|
278
|
+
: this.txBuilder.atomicWithdrawFromSuilendStrategy.bind(this.txBuilder);
|
|
279
|
+
withdraw(vaultId, target.suilendPoolType, target.suilendMarketId, shortfall.toString(), { ...options, txBlock: txb });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
263
282
|
this.txBuilder.atomicCollectPlatformFee(vaultId, loss, {
|
|
264
283
|
...options,
|
|
265
284
|
txBlock: txb
|
|
@@ -405,6 +424,23 @@ export class OperatorCalls extends OnChainCalls {
|
|
|
405
424
|
});
|
|
406
425
|
return this.execCall(txb, options);
|
|
407
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* Deposit collateral back into an atomic vault from its accumulator
|
|
429
|
+
* (address) balance, where `send_funds` transfers land
|
|
430
|
+
* @param vaultId The id of the atomic vault
|
|
431
|
+
* @param amount The amount to redeem from the vault's accumulator balance
|
|
432
|
+
* @param subAccount The sub account address
|
|
433
|
+
* @param options Optional tx execution params
|
|
434
|
+
* @returns OnChainCallResponse
|
|
435
|
+
*/
|
|
436
|
+
async atomicDepositFromSubAccountV2(vaultId, amount, subAccount, options) {
|
|
437
|
+
const txb = options?.txBlock || new TransactionBlock();
|
|
438
|
+
this.txBuilder.atomicDepositFromSubAccountV2(vaultId, amount, subAccount, {
|
|
439
|
+
...options,
|
|
440
|
+
txBlock: txb
|
|
441
|
+
});
|
|
442
|
+
return this.execCall(txb, options);
|
|
443
|
+
}
|
|
408
444
|
/**
|
|
409
445
|
* Redeem collected ember shares from an atomic vault against a source vault
|
|
410
446
|
* @param vaultId The id of the atomic vault
|
|
@@ -758,6 +758,16 @@ export declare class TxBuilder {
|
|
|
758
758
|
* @returns TransactionBlock
|
|
759
759
|
*/
|
|
760
760
|
atomicDepositFromSubAccount(vaultId: string, tokenId: string, subAccount: string, options?: ITxBuilderOptionalParams): TransactionBlock;
|
|
761
|
+
/**
|
|
762
|
+
* Deposits collateral back into an atomic vault from its accumulator
|
|
763
|
+
* (address) balance, where `send_funds` transfers land
|
|
764
|
+
* @param vaultId Id of the atomic vault
|
|
765
|
+
* @param amount Amount to redeem from the vault's accumulator balance
|
|
766
|
+
* @param subAccount Sub account address
|
|
767
|
+
* @param options Optional tx building params
|
|
768
|
+
* @returns TransactionBlock
|
|
769
|
+
*/
|
|
770
|
+
atomicDepositFromSubAccountV2(vaultId: string, amount: NumStr, subAccount: string, options?: ITxBuilderOptionalParams): TransactionBlock;
|
|
761
771
|
/**
|
|
762
772
|
* Collects the platform fee of an atomic vault
|
|
763
773
|
* @param vaultId Id of the atomic vault
|
|
@@ -2184,6 +2184,33 @@ export class TxBuilder {
|
|
|
2184
2184
|
txb.setSenderIfNotSet(options.sender);
|
|
2185
2185
|
return txb;
|
|
2186
2186
|
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Deposits collateral back into an atomic vault from its accumulator
|
|
2189
|
+
* (address) balance, where `send_funds` transfers land
|
|
2190
|
+
* @param vaultId Id of the atomic vault
|
|
2191
|
+
* @param amount Amount to redeem from the vault's accumulator balance
|
|
2192
|
+
* @param subAccount Sub account address
|
|
2193
|
+
* @param options Optional tx building params
|
|
2194
|
+
* @returns TransactionBlock
|
|
2195
|
+
*/
|
|
2196
|
+
atomicDepositFromSubAccountV2(vaultId, amount, subAccount, options) {
|
|
2197
|
+
const txb = options?.txBlock || new TransactionBlock();
|
|
2198
|
+
txb.moveCall({
|
|
2199
|
+
arguments: [
|
|
2200
|
+
txb.object(vaultId),
|
|
2201
|
+
txb.object(this.parser.getProtocolConfig()),
|
|
2202
|
+
txb.pure.u64(amount),
|
|
2203
|
+
txb.pure.address(subAccount)
|
|
2204
|
+
],
|
|
2205
|
+
typeArguments: [this.parser.getAtomicCollateralType(vaultId)],
|
|
2206
|
+
target: `${this.parser.getPackageId()}::gateway::atomic_deposit_from_sub_account_v2`
|
|
2207
|
+
});
|
|
2208
|
+
if (options?.gasBudget)
|
|
2209
|
+
txb.setGasBudget(options.gasBudget);
|
|
2210
|
+
if (options?.sender)
|
|
2211
|
+
txb.setSenderIfNotSet(options.sender);
|
|
2212
|
+
return txb;
|
|
2213
|
+
}
|
|
2187
2214
|
/**
|
|
2188
2215
|
* Collects the platform fee of an atomic vault
|
|
2189
2216
|
* @param vaultId Id of the atomic vault
|
|
@@ -5,6 +5,7 @@ import { OnChainCallResponse, Signer, SuiAddress, SuiTransactionBlockResponseOpt
|
|
|
5
5
|
import { TransactionObjectArgument } from "@mysten/sui/transactions";
|
|
6
6
|
export declare class UserCalls extends OnChainCalls {
|
|
7
7
|
constructor(_network: string, _suiClient: SuiClient, _deployment: ISuiDeployment, _signer?: Signer, _walletAddress?: string, _isUIWallet?: boolean);
|
|
8
|
+
private walletCoin;
|
|
8
9
|
/**
|
|
9
10
|
* Deposit asset into a vault
|
|
10
11
|
* @param vaultId The id of the vault to deposit into
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { OnChainCalls } from "./onchain-calls.js";
|
|
2
2
|
import { TransactionBlock, bigNumber, CoinUtils, SUI_NATIVE_BASE } from "@firefly-exchange/library-sui";
|
|
3
3
|
import { Vault } from "./vault.js";
|
|
4
|
+
import { coinWithBalance } from "@mysten/sui/transactions";
|
|
4
5
|
import { SuiAtomicLiquidityReader } from "./atomic-liquidity.js";
|
|
5
6
|
import { isSuiCoinType } from "../utils/common.js";
|
|
6
7
|
export class UserCalls extends OnChainCalls {
|
|
7
8
|
constructor(_network, _suiClient, _deployment, _signer, _walletAddress, _isUIWallet) {
|
|
8
9
|
super(_network, _suiClient, _deployment, _signer, _walletAddress, _isUIWallet);
|
|
9
10
|
}
|
|
11
|
+
walletCoin(txb, coinType, amount) {
|
|
12
|
+
// `send_funds` credits the wallet's address balance, which coin
|
|
13
|
+
// enumeration cannot see. The intent draws on coin objects and that
|
|
14
|
+
// balance together, resolved when the tx is built.
|
|
15
|
+
txb.setSenderIfNotSet(this.walletAddress);
|
|
16
|
+
return txb.add(coinWithBalance({
|
|
17
|
+
type: coinType,
|
|
18
|
+
balance: BigInt(bigNumber(amount).toFixed(0))
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
10
21
|
/**
|
|
11
22
|
* Deposit asset into a vault
|
|
12
23
|
* @param vaultId The id of the vault to deposit into
|
|
@@ -21,7 +32,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
21
32
|
let merged;
|
|
22
33
|
if (!coinId) {
|
|
23
34
|
const coinType = this.parser.getDepositCoinType(vaultId);
|
|
24
|
-
|
|
35
|
+
split = this.walletCoin(txb, coinType, bigNumber(amount).toFixed(0));
|
|
25
36
|
coinId = split;
|
|
26
37
|
}
|
|
27
38
|
else {
|
|
@@ -71,7 +82,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
71
82
|
let merged;
|
|
72
83
|
if (!coinId) {
|
|
73
84
|
const coinType = this.parser.getDepositCoinType(vaultId);
|
|
74
|
-
|
|
85
|
+
split = this.walletCoin(txb, coinType, assetAmountRequired);
|
|
75
86
|
coinId = split;
|
|
76
87
|
}
|
|
77
88
|
else {
|
|
@@ -98,7 +109,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
98
109
|
let split;
|
|
99
110
|
if (!coinId) {
|
|
100
111
|
const coinType = this.parser.getReceiptCoinType(vaultId);
|
|
101
|
-
|
|
112
|
+
split = this.walletCoin(txb, coinType, bigNumber(amountOfShares).toFixed(0));
|
|
102
113
|
coinId = split;
|
|
103
114
|
}
|
|
104
115
|
else {
|
|
@@ -144,7 +155,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
144
155
|
let merged;
|
|
145
156
|
if (!coinId) {
|
|
146
157
|
const coinType = this.parser.getAtomicCollateralType(vaultId);
|
|
147
|
-
|
|
158
|
+
split = this.walletCoin(txb, coinType, bigNumber(amount).toFixed(0));
|
|
148
159
|
coinId = split;
|
|
149
160
|
}
|
|
150
161
|
else {
|
|
@@ -249,7 +260,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
249
260
|
let split;
|
|
250
261
|
let merged;
|
|
251
262
|
if (!coinId) {
|
|
252
|
-
|
|
263
|
+
split = this.walletCoin(txb, sourceReceiptType, bigNumber(amount).toFixed(0));
|
|
253
264
|
coinId = split;
|
|
254
265
|
}
|
|
255
266
|
else {
|
|
@@ -298,7 +309,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
298
309
|
let split;
|
|
299
310
|
let merged;
|
|
300
311
|
if (!coinId) {
|
|
301
|
-
|
|
312
|
+
split = this.walletCoin(txb, sourceReceiptType, bigNumber(amount).toFixed(0));
|
|
302
313
|
coinId = split;
|
|
303
314
|
}
|
|
304
315
|
else {
|
|
@@ -343,7 +354,7 @@ export class UserCalls extends OnChainCalls {
|
|
|
343
354
|
let split;
|
|
344
355
|
let merged;
|
|
345
356
|
if (!coinId) {
|
|
346
|
-
|
|
357
|
+
split = this.walletCoin(txb, sourceReceiptType, bigNumber(amount).toFixed(0));
|
|
347
358
|
coinId = split;
|
|
348
359
|
}
|
|
349
360
|
else {
|