@t2000/sdk 0.16.0 → 0.16.2
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/index.cjs +80 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +80 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3097,15 +3097,14 @@ var StrategyManager = class {
|
|
|
3097
3097
|
}
|
|
3098
3098
|
}
|
|
3099
3099
|
validateMinAmount(allocations, totalUsd) {
|
|
3100
|
-
const
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
}
|
|
3100
|
+
const smallestPct = Math.min(...Object.values(allocations));
|
|
3101
|
+
const minRequired = Math.ceil(100 / smallestPct);
|
|
3102
|
+
if (totalUsd < minRequired) {
|
|
3103
|
+
const smallestAsset = Object.entries(allocations).find(([, p]) => p === smallestPct)?.[0] ?? "?";
|
|
3104
|
+
throw new T2000Error(
|
|
3105
|
+
"STRATEGY_MIN_AMOUNT",
|
|
3106
|
+
`Minimum $${minRequired} for this strategy (${smallestAsset} at ${smallestPct}% needs at least $1)`
|
|
3107
|
+
);
|
|
3109
3108
|
}
|
|
3110
3109
|
}
|
|
3111
3110
|
};
|
|
@@ -4341,20 +4340,22 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
|
|
|
4341
4340
|
if (!params.usdAmount || params.usdAmount <= 0) {
|
|
4342
4341
|
throw new T2000Error("INVALID_AMOUNT", "Strategy investment must be > $0");
|
|
4343
4342
|
}
|
|
4343
|
+
this.enforcer.check({ operation: "invest", amount: params.usdAmount });
|
|
4344
4344
|
const bal = await queryBalance(this.client, this._address);
|
|
4345
4345
|
if (bal.available < params.usdAmount) {
|
|
4346
4346
|
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient balance. Available: $${bal.available.toFixed(2)}, requested: $${params.usdAmount.toFixed(2)}`);
|
|
4347
4347
|
}
|
|
4348
4348
|
const buys = [];
|
|
4349
|
+
const allocEntries = Object.entries(definition.allocations);
|
|
4349
4350
|
if (params.dryRun) {
|
|
4350
|
-
const
|
|
4351
|
-
for (const [asset, pct] of
|
|
4351
|
+
const swapAdapter2 = this.registry.listSwap()[0];
|
|
4352
|
+
for (const [asset, pct] of allocEntries) {
|
|
4352
4353
|
const assetUsd = params.usdAmount * (pct / 100);
|
|
4353
4354
|
let estAmount = 0;
|
|
4354
4355
|
let estPrice = 0;
|
|
4355
4356
|
try {
|
|
4356
|
-
if (
|
|
4357
|
-
const quote = await
|
|
4357
|
+
if (swapAdapter2) {
|
|
4358
|
+
const quote = await swapAdapter2.getQuote("USDC", asset, assetUsd);
|
|
4358
4359
|
estAmount = quote.expectedOutput;
|
|
4359
4360
|
estPrice = assetUsd / estAmount;
|
|
4360
4361
|
}
|
|
@@ -4364,27 +4365,76 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
|
|
|
4364
4365
|
}
|
|
4365
4366
|
return { success: true, strategy: params.strategy, totalInvested: params.usdAmount, buys, gasCost: 0, gasMethod: "self-funded" };
|
|
4366
4367
|
}
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4368
|
+
const swapAdapter = this.registry.listSwap()[0];
|
|
4369
|
+
if (!swapAdapter?.addSwapToTx) {
|
|
4370
|
+
throw new T2000Error("PROTOCOL_UNAVAILABLE", "Swap adapter does not support composable PTB");
|
|
4371
|
+
}
|
|
4372
|
+
const swapMetas = [];
|
|
4373
|
+
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
4374
|
+
const tx = new transactions.Transaction();
|
|
4375
|
+
tx.setSender(this._address);
|
|
4376
|
+
const usdcCoins = await this._fetchCoins(SUPPORTED_ASSETS.USDC.type);
|
|
4377
|
+
if (usdcCoins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC coins found");
|
|
4378
|
+
const mergedUsdc = this._mergeCoinsInTx(tx, usdcCoins);
|
|
4379
|
+
const splitAmounts = allocEntries.map(
|
|
4380
|
+
([, pct]) => BigInt(Math.floor(params.usdAmount * (pct / 100) * 10 ** SUPPORTED_ASSETS.USDC.decimals))
|
|
4381
|
+
);
|
|
4382
|
+
const splitCoins = tx.splitCoins(mergedUsdc, splitAmounts);
|
|
4383
|
+
const outputCoins = [];
|
|
4384
|
+
for (let i = 0; i < allocEntries.length; i++) {
|
|
4385
|
+
const [asset] = allocEntries[i];
|
|
4386
|
+
const assetUsd = params.usdAmount * (allocEntries[i][1] / 100);
|
|
4387
|
+
const { outputCoin, estimatedOut, toDecimals } = await swapAdapter.addSwapToTx(
|
|
4388
|
+
tx,
|
|
4389
|
+
this._address,
|
|
4390
|
+
splitCoins[i],
|
|
4391
|
+
"USDC",
|
|
4392
|
+
asset,
|
|
4393
|
+
assetUsd
|
|
4394
|
+
);
|
|
4395
|
+
outputCoins.push(outputCoin);
|
|
4396
|
+
swapMetas.push({ asset, usdAmount: assetUsd, estimatedOut, toDecimals });
|
|
4397
|
+
}
|
|
4398
|
+
tx.transferObjects(outputCoins, this._address);
|
|
4399
|
+
return tx;
|
|
4400
|
+
});
|
|
4401
|
+
const digest = gasResult.digest;
|
|
4402
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4403
|
+
for (const meta of swapMetas) {
|
|
4404
|
+
const amount = meta.estimatedOut / 10 ** meta.toDecimals;
|
|
4405
|
+
const price = meta.usdAmount / amount;
|
|
4406
|
+
this.portfolio.recordBuy({
|
|
4407
|
+
id: `inv_${Date.now()}_${meta.asset}`,
|
|
4408
|
+
type: "buy",
|
|
4409
|
+
asset: meta.asset,
|
|
4410
|
+
amount,
|
|
4411
|
+
price,
|
|
4412
|
+
usdValue: meta.usdAmount,
|
|
4413
|
+
fee: 0,
|
|
4414
|
+
tx: digest,
|
|
4415
|
+
timestamp: now
|
|
4416
|
+
});
|
|
4372
4417
|
this.portfolio.recordStrategyBuy(params.strategy, {
|
|
4373
|
-
id: `strat_${Date.now()}_${asset}`,
|
|
4418
|
+
id: `strat_${Date.now()}_${meta.asset}`,
|
|
4374
4419
|
type: "buy",
|
|
4375
|
-
asset,
|
|
4376
|
-
amount
|
|
4377
|
-
price
|
|
4378
|
-
usdValue:
|
|
4379
|
-
fee:
|
|
4380
|
-
tx:
|
|
4381
|
-
timestamp:
|
|
4420
|
+
asset: meta.asset,
|
|
4421
|
+
amount,
|
|
4422
|
+
price,
|
|
4423
|
+
usdValue: meta.usdAmount,
|
|
4424
|
+
fee: 0,
|
|
4425
|
+
tx: digest,
|
|
4426
|
+
timestamp: now
|
|
4382
4427
|
});
|
|
4383
|
-
buys.push({ asset, usdAmount:
|
|
4384
|
-
totalGas += result.gasCost;
|
|
4385
|
-
gasMethod = result.gasMethod;
|
|
4428
|
+
buys.push({ asset: meta.asset, usdAmount: meta.usdAmount, amount, price, tx: digest });
|
|
4386
4429
|
}
|
|
4387
|
-
return {
|
|
4430
|
+
return {
|
|
4431
|
+
success: true,
|
|
4432
|
+
strategy: params.strategy,
|
|
4433
|
+
totalInvested: params.usdAmount,
|
|
4434
|
+
buys,
|
|
4435
|
+
gasCost: gasResult.gasCostSui,
|
|
4436
|
+
gasMethod: gasResult.gasMethod
|
|
4437
|
+
};
|
|
4388
4438
|
}
|
|
4389
4439
|
async sellStrategy(params) {
|
|
4390
4440
|
this.enforcer.assertNotLocked();
|