dipcoin-cli 1.3.3 → 1.3.4
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/cli.cjs +529 -94
- package/dist/cli.cjs.map +1 -1
- package/dist/config/deployed/mainnet/main_contract.json +4 -3
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -16653,21 +16653,45 @@ function buildAddMarginTx(deployment, args, tx, gasBudget, sender) {
|
|
|
16653
16653
|
if (sender)
|
|
16654
16654
|
t.setSender(sender);
|
|
16655
16655
|
const packageId = getPackageId(deployment);
|
|
16656
|
-
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
|
|
16660
|
-
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
16670
|
-
|
|
16656
|
+
const signed = args.signedPayload;
|
|
16657
|
+
if (signed) {
|
|
16658
|
+
t.moveCall({
|
|
16659
|
+
target: `${packageId}::exchange::add_margin_v4`,
|
|
16660
|
+
arguments: [
|
|
16661
|
+
t.object(getProtocolConfigId(deployment)),
|
|
16662
|
+
t.object(CLOCK_OBJECT_ID),
|
|
16663
|
+
t.object(args.perpID || getPerpetualId(deployment, args.market)),
|
|
16664
|
+
t.object(getBankId(deployment)),
|
|
16665
|
+
t.object(args.subAccountsMapID || getSubAccountsId(deployment)),
|
|
16666
|
+
t.object(getTxIndexerId(deployment)),
|
|
16667
|
+
t.object(getPriceFeedId(deployment)),
|
|
16668
|
+
t.pure.vector("u8", signed.userAddress),
|
|
16669
|
+
t.pure.u128(args.amount.toString()),
|
|
16670
|
+
t.pure.u128(signed.salt.toString()),
|
|
16671
|
+
t.pure.u64(signed.expiration.toString()),
|
|
16672
|
+
t.pure.vector("u8", signed.signature),
|
|
16673
|
+
t.pure.vector("u8", signed.publicKey),
|
|
16674
|
+
],
|
|
16675
|
+
typeArguments: [getCurrencyType(deployment)],
|
|
16676
|
+
});
|
|
16677
|
+
}
|
|
16678
|
+
else {
|
|
16679
|
+
t.moveCall({
|
|
16680
|
+
target: `${packageId}::exchange::add_margin_v3`,
|
|
16681
|
+
arguments: [
|
|
16682
|
+
t.object(getProtocolConfigId(deployment)),
|
|
16683
|
+
t.object(CLOCK_OBJECT_ID),
|
|
16684
|
+
t.object(args.perpID || getPerpetualId(deployment, args.market)),
|
|
16685
|
+
t.object(getBankId(deployment)),
|
|
16686
|
+
t.object(args.subAccountsMapID || getSubAccountsId(deployment)),
|
|
16687
|
+
t.object(getTxIndexerId(deployment)),
|
|
16688
|
+
t.object(getPriceFeedId(deployment)),
|
|
16689
|
+
t.pure.address(args.account || sender || ""),
|
|
16690
|
+
t.pure.u128(args.amount.toString()),
|
|
16691
|
+
],
|
|
16692
|
+
typeArguments: [getCurrencyType(deployment)],
|
|
16693
|
+
});
|
|
16694
|
+
}
|
|
16671
16695
|
return t;
|
|
16672
16696
|
}
|
|
16673
16697
|
function buildRemoveMarginTx(deployment, args, tx, gasBudget, sender) {
|
|
@@ -16677,21 +16701,45 @@ function buildRemoveMarginTx(deployment, args, tx, gasBudget, sender) {
|
|
|
16677
16701
|
if (sender)
|
|
16678
16702
|
t.setSender(sender);
|
|
16679
16703
|
const packageId = getPackageId(deployment);
|
|
16680
|
-
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16684
|
-
|
|
16685
|
-
|
|
16686
|
-
|
|
16687
|
-
|
|
16688
|
-
|
|
16689
|
-
|
|
16690
|
-
|
|
16691
|
-
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
|
|
16704
|
+
const signed = args.signedPayload;
|
|
16705
|
+
if (signed) {
|
|
16706
|
+
t.moveCall({
|
|
16707
|
+
target: `${packageId}::exchange::remove_margin_v4`,
|
|
16708
|
+
arguments: [
|
|
16709
|
+
t.object(getProtocolConfigId(deployment)),
|
|
16710
|
+
t.object(CLOCK_OBJECT_ID),
|
|
16711
|
+
t.object(args.perpID || getPerpetualId(deployment, args.market)),
|
|
16712
|
+
t.object(getBankId(deployment)),
|
|
16713
|
+
t.object(args.subAccountsMapID || getSubAccountsId(deployment)),
|
|
16714
|
+
t.object(getTxIndexerId(deployment)),
|
|
16715
|
+
t.object(getPriceFeedId(deployment)),
|
|
16716
|
+
t.pure.vector("u8", signed.userAddress),
|
|
16717
|
+
t.pure.u128(args.amount.toString()),
|
|
16718
|
+
t.pure.u128(signed.salt.toString()),
|
|
16719
|
+
t.pure.u64(signed.expiration.toString()),
|
|
16720
|
+
t.pure.vector("u8", signed.signature),
|
|
16721
|
+
t.pure.vector("u8", signed.publicKey),
|
|
16722
|
+
],
|
|
16723
|
+
typeArguments: [getCurrencyType(deployment)],
|
|
16724
|
+
});
|
|
16725
|
+
}
|
|
16726
|
+
else {
|
|
16727
|
+
t.moveCall({
|
|
16728
|
+
target: `${packageId}::exchange::remove_margin_v3`,
|
|
16729
|
+
arguments: [
|
|
16730
|
+
t.object(getProtocolConfigId(deployment)),
|
|
16731
|
+
t.object(CLOCK_OBJECT_ID),
|
|
16732
|
+
t.object(args.perpID || getPerpetualId(deployment, args.market)),
|
|
16733
|
+
t.object(getBankId(deployment)),
|
|
16734
|
+
t.object(args.subAccountsMapID || getSubAccountsId(deployment)),
|
|
16735
|
+
t.object(getTxIndexerId(deployment)),
|
|
16736
|
+
t.object(getPriceFeedId(deployment)),
|
|
16737
|
+
t.pure.address(args.account || sender || ""),
|
|
16738
|
+
t.pure.u128(args.amount.toString()),
|
|
16739
|
+
],
|
|
16740
|
+
typeArguments: [getCurrencyType(deployment)],
|
|
16741
|
+
});
|
|
16742
|
+
}
|
|
16695
16743
|
return t;
|
|
16696
16744
|
}
|
|
16697
16745
|
function buildWithdrawTx(deployment, args, tx, gasBudget, sender) {
|
|
@@ -18688,6 +18736,130 @@ class DipCoinPerpSDK {
|
|
|
18688
18736
|
txHash,
|
|
18689
18737
|
};
|
|
18690
18738
|
}
|
|
18739
|
+
packPayload(fields) {
|
|
18740
|
+
let result = "{\n";
|
|
18741
|
+
for (const [key, value] of fields) {
|
|
18742
|
+
result += `"${key}":"${value}",\n`;
|
|
18743
|
+
}
|
|
18744
|
+
result += '"domain":"dipcoin.io"\n';
|
|
18745
|
+
result += "}";
|
|
18746
|
+
return result;
|
|
18747
|
+
}
|
|
18748
|
+
normalizeSuiAddress(address) {
|
|
18749
|
+
const hex = address.startsWith("0x") ? address.slice(2) : address;
|
|
18750
|
+
if (!/^[0-9a-fA-F]+$/.test(hex) || hex.length > 64) {
|
|
18751
|
+
throw new Error(`Invalid Sui address: ${address}`);
|
|
18752
|
+
}
|
|
18753
|
+
return `0x${hex.toLowerCase().padStart(64, "0")}`;
|
|
18754
|
+
}
|
|
18755
|
+
toUnifiedSuiAddress(address) {
|
|
18756
|
+
const normalized = this.normalizeSuiAddress(address);
|
|
18757
|
+
return `Sui:0x${normalized.slice(2)}`;
|
|
18758
|
+
}
|
|
18759
|
+
toUnifiedSuiAddressBytes(address) {
|
|
18760
|
+
const normalized = this.normalizeSuiAddress(address);
|
|
18761
|
+
return [0, ...Array.from(Buffer.from(normalized.slice(2), "hex"))];
|
|
18762
|
+
}
|
|
18763
|
+
async signDipcoinActionPayload(fields, addressForVector) {
|
|
18764
|
+
const salt = Date.now();
|
|
18765
|
+
const expiration = salt + 1_800_000;
|
|
18766
|
+
const message = this.packPayload([
|
|
18767
|
+
...fields,
|
|
18768
|
+
["salt", String(salt)],
|
|
18769
|
+
["expiration", String(expiration)],
|
|
18770
|
+
]);
|
|
18771
|
+
const signed = await this.keypair.signPersonalMessage(new TextEncoder().encode(message));
|
|
18772
|
+
const parsed = cryptography.parseSerializedSignature(typeof signed === "string" ? signed : signed.signature);
|
|
18773
|
+
const scheme = String(parsed.signatureScheme);
|
|
18774
|
+
const flag = /ed25519/i.test(scheme) ? 1 : 0;
|
|
18775
|
+
if (!/ed25519|secp256k1|secp256r1/i.test(scheme)) {
|
|
18776
|
+
throw new Error(`Unsupported signature scheme for signed payload: ${scheme}`);
|
|
18777
|
+
}
|
|
18778
|
+
return {
|
|
18779
|
+
userAddress: this.toUnifiedSuiAddressBytes(addressForVector),
|
|
18780
|
+
salt: String(salt),
|
|
18781
|
+
expiration: String(expiration),
|
|
18782
|
+
signature: [...Array.from(Buffer.from(parsed.signature)), flag],
|
|
18783
|
+
publicKey: Array.from(Buffer.from(parsed.publicKey)),
|
|
18784
|
+
};
|
|
18785
|
+
}
|
|
18786
|
+
async signUserAmountActionPayload(args) {
|
|
18787
|
+
return this.signDipcoinActionPayload([
|
|
18788
|
+
["action", args.action],
|
|
18789
|
+
["market", this.normalizeSuiAddress(args.market)],
|
|
18790
|
+
["user", this.toUnifiedSuiAddress(args.user)],
|
|
18791
|
+
["amount", args.amount],
|
|
18792
|
+
], args.user);
|
|
18793
|
+
}
|
|
18794
|
+
async signVaultCreatePayload(args) {
|
|
18795
|
+
return this.signDipcoinActionPayload([
|
|
18796
|
+
["action", "VaultCreate"],
|
|
18797
|
+
["creator", this.toUnifiedSuiAddress(args.creator)],
|
|
18798
|
+
["name", args.name],
|
|
18799
|
+
["trader", this.toUnifiedSuiAddress(args.trader)],
|
|
18800
|
+
["maxCap", args.maxCap],
|
|
18801
|
+
["minDepositAmount", args.minDepositAmount],
|
|
18802
|
+
["creatorMinimumShareRatio", args.creatorMinimumShareRatio],
|
|
18803
|
+
["creatorProfitShareRatio", args.creatorProfitShareRatio],
|
|
18804
|
+
["initialAmount", args.initialAmount],
|
|
18805
|
+
], args.creator);
|
|
18806
|
+
}
|
|
18807
|
+
async signVaultUserAmountPayload(action, vaultID, user, amount) {
|
|
18808
|
+
return this.signDipcoinActionPayload([
|
|
18809
|
+
["action", action],
|
|
18810
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18811
|
+
["user", this.toUnifiedSuiAddress(user)],
|
|
18812
|
+
["amount", amount],
|
|
18813
|
+
], user);
|
|
18814
|
+
}
|
|
18815
|
+
async signVaultUserPayload(action, vaultID, user) {
|
|
18816
|
+
return this.signDipcoinActionPayload([
|
|
18817
|
+
["action", action],
|
|
18818
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18819
|
+
["user", this.toUnifiedSuiAddress(user)],
|
|
18820
|
+
], user);
|
|
18821
|
+
}
|
|
18822
|
+
async signVaultSetTraderPayload(vaultID, creator, newTrader) {
|
|
18823
|
+
return this.signDipcoinActionPayload([
|
|
18824
|
+
["action", "VaultSetTrader"],
|
|
18825
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18826
|
+
["creator", this.toUnifiedSuiAddress(creator)],
|
|
18827
|
+
["newTrader", this.toUnifiedSuiAddress(newTrader)],
|
|
18828
|
+
], creator);
|
|
18829
|
+
}
|
|
18830
|
+
async signVaultSetSubTraderPayload(vaultID, trader, subTrader, status) {
|
|
18831
|
+
return this.signDipcoinActionPayload([
|
|
18832
|
+
["action", "VaultSetSubTrader"],
|
|
18833
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18834
|
+
["trader", this.toUnifiedSuiAddress(trader)],
|
|
18835
|
+
["subTrader", this.toUnifiedSuiAddress(subTrader)],
|
|
18836
|
+
["status", String(status)],
|
|
18837
|
+
], trader);
|
|
18838
|
+
}
|
|
18839
|
+
async signVaultDepositStatusPayload(vaultID, creator, status) {
|
|
18840
|
+
return this.signDipcoinActionPayload([
|
|
18841
|
+
["action", "VaultSetDepositStatus"],
|
|
18842
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18843
|
+
["creator", this.toUnifiedSuiAddress(creator)],
|
|
18844
|
+
["status", String(status)],
|
|
18845
|
+
], creator);
|
|
18846
|
+
}
|
|
18847
|
+
async signVaultCreatorAmountPayload(action, vaultID, creator, amount) {
|
|
18848
|
+
return this.signDipcoinActionPayload([
|
|
18849
|
+
["action", action],
|
|
18850
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18851
|
+
["creator", this.toUnifiedSuiAddress(creator)],
|
|
18852
|
+
["amount", amount],
|
|
18853
|
+
], creator);
|
|
18854
|
+
}
|
|
18855
|
+
async signVaultAutoClosePayload(vaultID, creator, autoCloseOnWithdraw) {
|
|
18856
|
+
return this.signDipcoinActionPayload([
|
|
18857
|
+
["action", "VaultSetAutoCloseOnWithdraw"],
|
|
18858
|
+
["vault", this.normalizeSuiAddress(vaultID)],
|
|
18859
|
+
["creator", this.toUnifiedSuiAddress(creator)],
|
|
18860
|
+
["autoCloseOnWithdraw", String(autoCloseOnWithdraw)],
|
|
18861
|
+
], creator);
|
|
18862
|
+
}
|
|
18691
18863
|
getDeploymentProtocolConfigId() {
|
|
18692
18864
|
const protocolId = this.deploymentConfig?.objects?.ProtocolConfig?.id;
|
|
18693
18865
|
if (!protocolId) {
|
|
@@ -18697,6 +18869,16 @@ class DipCoinPerpSDK {
|
|
|
18697
18869
|
}
|
|
18698
18870
|
async buildMarginTransaction(params, action) {
|
|
18699
18871
|
const payload = this.buildMarginCallArgs(params, action);
|
|
18872
|
+
const signedMarket = payload.perpID || (payload.market ? this.resolvePerpIdFromDeployment(payload.market) : undefined);
|
|
18873
|
+
if (!signedMarket) {
|
|
18874
|
+
throw new Error("PerpetualID is required for signed margin payload");
|
|
18875
|
+
}
|
|
18876
|
+
const signedPayload = await this.signUserAmountActionPayload({
|
|
18877
|
+
action: action === "add" ? "AddMargin" : "RemoveMargin",
|
|
18878
|
+
market: signedMarket,
|
|
18879
|
+
user: payload.account,
|
|
18880
|
+
amount: payload.amount,
|
|
18881
|
+
});
|
|
18700
18882
|
// v6+ requires PriceFeed to be fresh (~60s) before the margin call. Operator updates
|
|
18701
18883
|
// are only hourly so we always fetch + prepend our own update_price_feed step.
|
|
18702
18884
|
const sym = payload.market || params.symbol;
|
|
@@ -18706,9 +18888,9 @@ class DipCoinPerpSDK {
|
|
|
18706
18888
|
const baseTx = new transactions.Transaction();
|
|
18707
18889
|
this.appendPriceFeedUpdates(baseTx, Array.from(feeds.values()));
|
|
18708
18890
|
if (action === "add") {
|
|
18709
|
-
return buildAddMarginTx(this.deploymentConfig, payload, baseTx, params.gasBudget);
|
|
18891
|
+
return buildAddMarginTx(this.deploymentConfig, { ...payload, signedPayload }, baseTx, params.gasBudget);
|
|
18710
18892
|
}
|
|
18711
|
-
return buildRemoveMarginTx(this.deploymentConfig, payload, baseTx, params.gasBudget);
|
|
18893
|
+
return buildRemoveMarginTx(this.deploymentConfig, { ...payload, signedPayload }, baseTx, params.gasBudget);
|
|
18712
18894
|
}
|
|
18713
18895
|
async buildUpdatePriceTransaction(symbol) {
|
|
18714
18896
|
if (!symbol) {
|
|
@@ -18997,6 +19179,105 @@ class DipCoinPerpSDK {
|
|
|
18997
19179
|
}
|
|
18998
19180
|
return id;
|
|
18999
19181
|
}
|
|
19182
|
+
sleep(ms) {
|
|
19183
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
19184
|
+
}
|
|
19185
|
+
getSignedPriceFeedTimestamps(payload) {
|
|
19186
|
+
let offset = 0;
|
|
19187
|
+
let length = 0;
|
|
19188
|
+
let shift = 0;
|
|
19189
|
+
while (offset < payload.length) {
|
|
19190
|
+
const byte = payload[offset++];
|
|
19191
|
+
length |= (byte & 0x7f) << shift;
|
|
19192
|
+
if ((byte & 0x80) === 0)
|
|
19193
|
+
break;
|
|
19194
|
+
shift += 7;
|
|
19195
|
+
}
|
|
19196
|
+
if (length <= 0)
|
|
19197
|
+
return [];
|
|
19198
|
+
const timestamps = [];
|
|
19199
|
+
for (let i = 0; i < length; i++) {
|
|
19200
|
+
const timestampOffset = offset + 32 + 16;
|
|
19201
|
+
if (timestampOffset + 8 > payload.length)
|
|
19202
|
+
return [];
|
|
19203
|
+
const view = new DataView(payload.buffer, payload.byteOffset + timestampOffset, 8);
|
|
19204
|
+
timestamps.push(Number(view.getBigUint64(0, true)));
|
|
19205
|
+
offset = timestampOffset + 8 + 2;
|
|
19206
|
+
}
|
|
19207
|
+
return timestamps;
|
|
19208
|
+
}
|
|
19209
|
+
getSignedPriceFeedMaxTimestamp(payload) {
|
|
19210
|
+
const timestamps = this.getSignedPriceFeedTimestamps(payload);
|
|
19211
|
+
return timestamps.length ? Math.max(...timestamps) : undefined;
|
|
19212
|
+
}
|
|
19213
|
+
async waitForSignedPriceFeedClock(payload) {
|
|
19214
|
+
const timestamp = this.getSignedPriceFeedMaxTimestamp(payload);
|
|
19215
|
+
if (!timestamp)
|
|
19216
|
+
return;
|
|
19217
|
+
// price_feed::collect_price_updates accepts timestamps no more than 1500ms
|
|
19218
|
+
// ahead of Sui Clock and no more than 60000ms behind it. The DipCoin API can
|
|
19219
|
+
// sign with wall-clock time while Sui Clock lags, so wait for the chain clock
|
|
19220
|
+
// to catch up before submitting the PTB. Public RPC backends can disagree by
|
|
19221
|
+
// a few seconds, so target a timestamp that is already ~10s old.
|
|
19222
|
+
const start = Date.now();
|
|
19223
|
+
while (true) {
|
|
19224
|
+
const clock = await this.suiClient.getObject({
|
|
19225
|
+
id: "0x6",
|
|
19226
|
+
options: { showContent: true },
|
|
19227
|
+
});
|
|
19228
|
+
const clockMs = Number(clock.data?.content?.fields?.timestamp_ms);
|
|
19229
|
+
if (!Number.isFinite(clockMs))
|
|
19230
|
+
return;
|
|
19231
|
+
const waitMs = timestamp - clockMs + 10_000;
|
|
19232
|
+
if (waitMs <= 0)
|
|
19233
|
+
return;
|
|
19234
|
+
if (Date.now() - start + waitMs > 180_000) {
|
|
19235
|
+
throw new Error(`Signed price feed is too far ahead of Sui Clock (${Math.ceil(waitMs / 1000)}s). Try again later.`);
|
|
19236
|
+
}
|
|
19237
|
+
await this.sleep(Math.min(waitMs, 15_000));
|
|
19238
|
+
}
|
|
19239
|
+
}
|
|
19240
|
+
async waitForSignedPriceFeedEntries(entries) {
|
|
19241
|
+
const timestamps = entries.flatMap((entry) => this.getSignedPriceFeedTimestamps(entry.payload));
|
|
19242
|
+
if (!timestamps.length)
|
|
19243
|
+
return;
|
|
19244
|
+
const maxTimestamp = Math.max(...timestamps);
|
|
19245
|
+
const minTimestamp = Math.min(...timestamps);
|
|
19246
|
+
const start = Date.now();
|
|
19247
|
+
while (true) {
|
|
19248
|
+
const clock = await this.suiClient.getObject({
|
|
19249
|
+
id: "0x6",
|
|
19250
|
+
options: { showContent: true },
|
|
19251
|
+
});
|
|
19252
|
+
const clockMs = Number(clock.data?.content?.fields?.timestamp_ms);
|
|
19253
|
+
if (!Number.isFinite(clockMs))
|
|
19254
|
+
return;
|
|
19255
|
+
const waitMs = maxTimestamp - clockMs + 10_000;
|
|
19256
|
+
if (waitMs <= 0) {
|
|
19257
|
+
if (clockMs - minTimestamp > 55_000) {
|
|
19258
|
+
throw new Error("Signed price feed expired while waiting for Sui Clock");
|
|
19259
|
+
}
|
|
19260
|
+
return;
|
|
19261
|
+
}
|
|
19262
|
+
if (Date.now() - start + waitMs > 180_000) {
|
|
19263
|
+
throw new Error(`Signed price feed is too far ahead of Sui Clock (${Math.ceil(waitMs / 1000)}s). Try again later.`);
|
|
19264
|
+
}
|
|
19265
|
+
await this.sleep(Math.min(waitMs, 15_000));
|
|
19266
|
+
}
|
|
19267
|
+
}
|
|
19268
|
+
async requestSignedPriceFeedEntry(symbols) {
|
|
19269
|
+
const qs = symbols.map((s) => `symbols=${encodeURIComponent(s)}`).join("&");
|
|
19270
|
+
const resp = await this.httpClient.get(`${API_ENDPOINTS.SIGNED_PRICE_LATEST}?${qs}`);
|
|
19271
|
+
if (resp.code !== 200 || !resp.data) {
|
|
19272
|
+
throw new Error(`Failed to fetch signed price feed for [${symbols.join(",")}]: ${resp.message || `code ${resp.code}`}`);
|
|
19273
|
+
}
|
|
19274
|
+
const d = resp.data;
|
|
19275
|
+
const b64 = (s) => Uint8Array.from(Buffer.from(s, "base64"));
|
|
19276
|
+
if (!d.payload || !d.signature || !d.publicKey) {
|
|
19277
|
+
throw new Error("Signed price feed response missing payload/signature/publicKey");
|
|
19278
|
+
}
|
|
19279
|
+
return { payload: b64(d.payload), signature: b64(d.signature), publicKey: b64(d.publicKey) };
|
|
19280
|
+
}
|
|
19000
19281
|
/**
|
|
19001
19282
|
* Fetch signed price update bytes for the given markets from the DipCoin pricing service.
|
|
19002
19283
|
* Each entry's payload/signature/publicKey is consumed by
|
|
@@ -19010,22 +19291,75 @@ class DipCoinPerpSDK {
|
|
|
19010
19291
|
const out = new Map();
|
|
19011
19292
|
if (symbols.length === 0)
|
|
19012
19293
|
return out;
|
|
19013
|
-
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19294
|
+
let lastClockError;
|
|
19295
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
19296
|
+
const entry = await this.requestSignedPriceFeedEntry(symbols);
|
|
19297
|
+
try {
|
|
19298
|
+
await this.waitForSignedPriceFeedEntries([entry]);
|
|
19299
|
+
}
|
|
19300
|
+
catch (error) {
|
|
19301
|
+
const message = String(error?.message || error);
|
|
19302
|
+
if (!message.includes("too far ahead") && !message.includes("expired")) {
|
|
19303
|
+
throw error;
|
|
19304
|
+
}
|
|
19305
|
+
lastClockError = error;
|
|
19306
|
+
await this.sleep(2_000 * (attempt + 1));
|
|
19307
|
+
continue;
|
|
19308
|
+
}
|
|
19309
|
+
// API returns a single bundle covering all requested symbols' prices in priceList,
|
|
19310
|
+
// but only one (payload, signature, publicKey) tuple. Map every requested symbol to it.
|
|
19311
|
+
for (const sym of symbols)
|
|
19312
|
+
out.set(sym, entry);
|
|
19313
|
+
return out;
|
|
19017
19314
|
}
|
|
19018
|
-
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
|
|
19315
|
+
throw lastClockError || new Error("Failed to fetch a usable signed price feed");
|
|
19316
|
+
}
|
|
19317
|
+
async fetchSignedPriceFeedChunks(symbols, chunkSize = 20) {
|
|
19318
|
+
if (symbols.length === 0)
|
|
19319
|
+
return [];
|
|
19320
|
+
let lastClockError;
|
|
19321
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
19322
|
+
const entries = [];
|
|
19323
|
+
for (let i = 0; i < symbols.length; i += chunkSize) {
|
|
19324
|
+
entries.push(await this.requestSignedPriceFeedEntry(symbols.slice(i, i + chunkSize)));
|
|
19325
|
+
}
|
|
19326
|
+
try {
|
|
19327
|
+
await this.waitForSignedPriceFeedEntries(entries);
|
|
19328
|
+
await this.validateSignedPriceFeedEntries(entries);
|
|
19329
|
+
}
|
|
19330
|
+
catch (error) {
|
|
19331
|
+
const message = String(error?.message || error);
|
|
19332
|
+
if (!message.includes("too far ahead") &&
|
|
19333
|
+
!message.includes("expired") &&
|
|
19334
|
+
!message.includes("price_feed")) {
|
|
19335
|
+
throw error;
|
|
19336
|
+
}
|
|
19337
|
+
lastClockError = error;
|
|
19338
|
+
await this.sleep(2_000 * (attempt + 1));
|
|
19339
|
+
continue;
|
|
19340
|
+
}
|
|
19341
|
+
return Array.from(new Map(entries.map((feed) => [
|
|
19342
|
+
Buffer.from(feed.payload).toString("hex"),
|
|
19343
|
+
feed,
|
|
19344
|
+
])).values());
|
|
19022
19345
|
}
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19346
|
+
throw lastClockError || new Error("Failed to fetch usable signed price feed chunks");
|
|
19347
|
+
}
|
|
19348
|
+
async validateSignedPriceFeedEntries(entries) {
|
|
19349
|
+
if (!entries.length)
|
|
19350
|
+
return;
|
|
19351
|
+
const tx = new transactions.Transaction();
|
|
19352
|
+
this.appendPriceFeedUpdates(tx, entries);
|
|
19353
|
+
tx.setSender(this.walletAddress);
|
|
19354
|
+
const result = await this.suiClient.devInspectTransactionBlock({
|
|
19355
|
+
sender: this.walletAddress,
|
|
19356
|
+
transactionBlock: tx,
|
|
19357
|
+
});
|
|
19358
|
+
const status = result.effects?.status?.status;
|
|
19359
|
+
if (status === "success")
|
|
19360
|
+
return;
|
|
19361
|
+
const error = result.effects?.status?.error || result.error || "unknown price_feed error";
|
|
19362
|
+
throw new Error(`price_feed validation failed: ${error}`);
|
|
19029
19363
|
}
|
|
19030
19364
|
/**
|
|
19031
19365
|
* Build a `price_feed::update_price_feed` PTB command for each provided signed feed
|
|
@@ -19079,11 +19413,16 @@ class DipCoinPerpSDK {
|
|
|
19079
19413
|
// a single update_price_feed step. Then iterate the on-chain perpetual_registry (which is
|
|
19080
19414
|
// what new_vault_nav populates, and is_nav_filled requires every entry to be computed).
|
|
19081
19415
|
const priceFeedId = this.getPriceFeedId();
|
|
19082
|
-
const
|
|
19083
|
-
const
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19416
|
+
const configSymbols = this.getMarketSymbols();
|
|
19417
|
+
const configSymbolSet = new Set(configSymbols);
|
|
19418
|
+
const apiSymbols = (await this.getCachedTradingPairs())
|
|
19419
|
+
.map((pair) => pair.symbol)
|
|
19420
|
+
.filter((symbol) => Boolean(symbol) && !configSymbolSet.has(symbol));
|
|
19421
|
+
const updateFeeds = [
|
|
19422
|
+
...(await this.fetchSignedPriceFeedChunks(configSymbols, 40)),
|
|
19423
|
+
...(await this.fetchSignedPriceFeedChunks(apiSymbols, 40)),
|
|
19424
|
+
];
|
|
19425
|
+
this.appendPriceFeedUpdates(t, updateFeeds);
|
|
19087
19426
|
const perpetualIds = await this.getOnChainPerpetualIds();
|
|
19088
19427
|
const [nav] = t.moveCall({
|
|
19089
19428
|
target: `${vaultPkg}::vault::new_vault_nav`,
|
|
@@ -19118,8 +19457,22 @@ class DipCoinPerpSDK {
|
|
|
19118
19457
|
async createVault(args) {
|
|
19119
19458
|
const tx = new transactions.Transaction();
|
|
19120
19459
|
const vaultPkg = this.getVaultPackageId();
|
|
19460
|
+
const creator = this.walletAddress;
|
|
19461
|
+
const maxCap = formatNormalToWei(args.maxCap);
|
|
19462
|
+
const minDepositAmount = formatNormalToWei(args.minDepositAmount);
|
|
19463
|
+
const initialAmount = formatNormalToWei(args.initialAmount);
|
|
19464
|
+
const signed = await this.signVaultCreatePayload({
|
|
19465
|
+
creator,
|
|
19466
|
+
name: args.name,
|
|
19467
|
+
trader: args.trader,
|
|
19468
|
+
maxCap,
|
|
19469
|
+
minDepositAmount,
|
|
19470
|
+
creatorMinimumShareRatio: args.creatorMinimumShareRatio,
|
|
19471
|
+
creatorProfitShareRatio: args.creatorProfitShareRatio,
|
|
19472
|
+
initialAmount,
|
|
19473
|
+
});
|
|
19121
19474
|
tx.moveCall({
|
|
19122
|
-
target: `${vaultPkg}::vault::
|
|
19475
|
+
target: `${vaultPkg}::vault::create_vault_v2`,
|
|
19123
19476
|
arguments: [
|
|
19124
19477
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19125
19478
|
tx.object("0x6"),
|
|
@@ -19127,13 +19480,18 @@ class DipCoinPerpSDK {
|
|
|
19127
19480
|
tx.object(this.getSubAccountsId()),
|
|
19128
19481
|
tx.object(this.getBankId()),
|
|
19129
19482
|
tx.object(this.getTxIndexerId()),
|
|
19483
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19130
19484
|
tx.pure.string(args.name),
|
|
19131
|
-
tx.pure.
|
|
19132
|
-
tx.pure.u128(
|
|
19133
|
-
tx.pure.u128(
|
|
19485
|
+
tx.pure.vector("u8", this.toUnifiedSuiAddressBytes(args.trader)),
|
|
19486
|
+
tx.pure.u128(maxCap),
|
|
19487
|
+
tx.pure.u128(minDepositAmount),
|
|
19134
19488
|
tx.pure.u128(args.creatorMinimumShareRatio),
|
|
19135
19489
|
tx.pure.u128(args.creatorProfitShareRatio),
|
|
19136
|
-
tx.pure.u128(
|
|
19490
|
+
tx.pure.u128(initialAmount),
|
|
19491
|
+
tx.pure.u128(signed.salt),
|
|
19492
|
+
tx.pure.u64(signed.expiration),
|
|
19493
|
+
tx.pure.vector("u8", signed.signature),
|
|
19494
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19137
19495
|
],
|
|
19138
19496
|
typeArguments: [this.getCurrencyType()],
|
|
19139
19497
|
});
|
|
@@ -19145,17 +19503,25 @@ class DipCoinPerpSDK {
|
|
|
19145
19503
|
async depositToVault(args) {
|
|
19146
19504
|
const { nav, tx } = await this.buildVaultNavTransaction(args.vaultID, args.markets);
|
|
19147
19505
|
const vaultPkg = this.getVaultPackageId();
|
|
19506
|
+
const amount = formatNormalToWei(args.amount);
|
|
19507
|
+
const signed = await this.signVaultUserAmountPayload("VaultDeposit", args.vaultID, this.walletAddress, amount);
|
|
19148
19508
|
tx.moveCall({
|
|
19149
|
-
target: `${vaultPkg}::vault::
|
|
19509
|
+
target: `${vaultPkg}::vault::deposit_v2`,
|
|
19150
19510
|
arguments: [
|
|
19151
19511
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19152
19512
|
tx.object(this.getVaultConfigId()),
|
|
19153
19513
|
tx.object("0x6"),
|
|
19154
19514
|
tx.object(this.getBankId()),
|
|
19515
|
+
tx.object(this.getSubAccountsId()),
|
|
19155
19516
|
tx.object(this.getTxIndexerId()),
|
|
19156
19517
|
tx.object(args.vaultID),
|
|
19157
19518
|
nav,
|
|
19158
|
-
tx.pure.
|
|
19519
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19520
|
+
tx.pure.u128(amount),
|
|
19521
|
+
tx.pure.u128(signed.salt),
|
|
19522
|
+
tx.pure.u64(signed.expiration),
|
|
19523
|
+
tx.pure.vector("u8", signed.signature),
|
|
19524
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19159
19525
|
],
|
|
19160
19526
|
typeArguments: [this.getCurrencyType()],
|
|
19161
19527
|
});
|
|
@@ -19166,32 +19532,25 @@ class DipCoinPerpSDK {
|
|
|
19166
19532
|
*/
|
|
19167
19533
|
async requestWithdrawFromVault(args) {
|
|
19168
19534
|
const tx = new transactions.Transaction();
|
|
19169
|
-
// On mainnet, update Pyth oracle prices before withdraw (contract checks freshness)
|
|
19170
|
-
if (this.options.network === "mainnet") {
|
|
19171
|
-
this.ensurePythClients();
|
|
19172
|
-
if (this.priceServiceConnection && this.pythClient) {
|
|
19173
|
-
const symbols = this.getMarketSymbols();
|
|
19174
|
-
const priceIds = [];
|
|
19175
|
-
for (const sym of symbols) {
|
|
19176
|
-
const feedId = await this.resolvePriceFeedId(sym);
|
|
19177
|
-
if (feedId)
|
|
19178
|
-
priceIds.push(feedId);
|
|
19179
|
-
}
|
|
19180
|
-
if (priceIds.length > 0) {
|
|
19181
|
-
const priceUpdateData = await this.priceServiceConnection.getPriceFeedsUpdateData(priceIds);
|
|
19182
|
-
await this.pythClient.updatePriceFeeds(tx, priceUpdateData, priceIds);
|
|
19183
|
-
}
|
|
19184
|
-
}
|
|
19185
|
-
}
|
|
19186
19535
|
const vaultPkg = this.getVaultPackageId();
|
|
19536
|
+
const shares = formatNormalToWei(args.shares);
|
|
19537
|
+
const signed = await this.signVaultUserAmountPayload("VaultRequestWithdraw", args.vaultID, this.walletAddress, shares);
|
|
19187
19538
|
tx.moveCall({
|
|
19188
|
-
target: `${vaultPkg}::vault::
|
|
19539
|
+
target: `${vaultPkg}::vault::request_withdraw_v2`,
|
|
19189
19540
|
arguments: [
|
|
19190
19541
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19191
19542
|
tx.object(this.getVaultConfigId()),
|
|
19192
19543
|
tx.object("0x6"),
|
|
19544
|
+
tx.object(this.getBankId()),
|
|
19545
|
+
tx.object(this.getSubAccountsId()),
|
|
19546
|
+
tx.object(this.getTxIndexerId()),
|
|
19193
19547
|
tx.object(args.vaultID),
|
|
19194
|
-
tx.pure.
|
|
19548
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19549
|
+
tx.pure.u128(shares),
|
|
19550
|
+
tx.pure.u128(signed.salt),
|
|
19551
|
+
tx.pure.u64(signed.expiration),
|
|
19552
|
+
tx.pure.vector("u8", signed.signature),
|
|
19553
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19195
19554
|
],
|
|
19196
19555
|
typeArguments: [this.getCurrencyType()],
|
|
19197
19556
|
});
|
|
@@ -19207,7 +19566,7 @@ class DipCoinPerpSDK {
|
|
|
19207
19566
|
elements: args.withdrawalRequestIDs.map((id) => tx.object(id)),
|
|
19208
19567
|
});
|
|
19209
19568
|
tx.moveCall({
|
|
19210
|
-
target: `${vaultPkg}::vault::
|
|
19569
|
+
target: `${vaultPkg}::vault::fill_withdrawal_requests_v2`,
|
|
19211
19570
|
arguments: [
|
|
19212
19571
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19213
19572
|
tx.object(this.getVaultConfigId()),
|
|
@@ -19228,16 +19587,23 @@ class DipCoinPerpSDK {
|
|
|
19228
19587
|
async closeVault(args) {
|
|
19229
19588
|
const { nav, tx } = await this.buildVaultNavTransaction(args.vaultID, args.markets);
|
|
19230
19589
|
const vaultPkg = this.getVaultPackageId();
|
|
19590
|
+
const signed = await this.signVaultUserPayload("VaultClose", args.vaultID, this.walletAddress);
|
|
19231
19591
|
tx.moveCall({
|
|
19232
|
-
target: `${vaultPkg}::vault::
|
|
19592
|
+
target: `${vaultPkg}::vault::close_vault_v3`,
|
|
19233
19593
|
arguments: [
|
|
19234
19594
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19235
19595
|
tx.object(this.getVaultConfigId()),
|
|
19236
19596
|
tx.object(this.getSubAccountsId()),
|
|
19597
|
+
tx.object(this.getTxIndexerId()),
|
|
19237
19598
|
tx.object(args.vaultID),
|
|
19238
19599
|
tx.object(this.getBankId()),
|
|
19239
19600
|
tx.object("0x6"),
|
|
19240
19601
|
nav,
|
|
19602
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19603
|
+
tx.pure.u128(signed.salt),
|
|
19604
|
+
tx.pure.u64(signed.expiration),
|
|
19605
|
+
tx.pure.vector("u8", signed.signature),
|
|
19606
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19241
19607
|
],
|
|
19242
19608
|
typeArguments: [this.getCurrencyType()],
|
|
19243
19609
|
});
|
|
@@ -19267,14 +19633,22 @@ class DipCoinPerpSDK {
|
|
|
19267
19633
|
async claimClosedVaultFunds(args) {
|
|
19268
19634
|
const tx = new transactions.Transaction();
|
|
19269
19635
|
const vaultPkg = this.getVaultPackageId();
|
|
19636
|
+
const signed = await this.signVaultUserPayload("VaultClaimClosedFunds", args.vaultID, this.walletAddress);
|
|
19270
19637
|
tx.moveCall({
|
|
19271
|
-
target: `${vaultPkg}::vault::
|
|
19638
|
+
target: `${vaultPkg}::vault::claim_closed_vault_funds_v2`,
|
|
19272
19639
|
arguments: [
|
|
19273
19640
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19274
19641
|
tx.object(this.getVaultConfigId()),
|
|
19275
19642
|
tx.object(this.getBankId()),
|
|
19643
|
+
tx.object(this.getSubAccountsId()),
|
|
19276
19644
|
tx.object(this.getTxIndexerId()),
|
|
19277
19645
|
tx.object(args.vaultID),
|
|
19646
|
+
tx.object("0x6"),
|
|
19647
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19648
|
+
tx.pure.u128(signed.salt),
|
|
19649
|
+
tx.pure.u64(signed.expiration),
|
|
19650
|
+
tx.pure.vector("u8", signed.signature),
|
|
19651
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19278
19652
|
],
|
|
19279
19653
|
typeArguments: [this.getCurrencyType()],
|
|
19280
19654
|
});
|
|
@@ -19286,14 +19660,23 @@ class DipCoinPerpSDK {
|
|
|
19286
19660
|
async setVaultTrader(args) {
|
|
19287
19661
|
const tx = new transactions.Transaction();
|
|
19288
19662
|
const vaultPkg = this.getVaultPackageId();
|
|
19663
|
+
const signed = await this.signVaultSetTraderPayload(args.vaultID, this.walletAddress, args.newTrader);
|
|
19289
19664
|
tx.moveCall({
|
|
19290
|
-
target: `${vaultPkg}::vault::
|
|
19665
|
+
target: `${vaultPkg}::vault::set_trader_v2`,
|
|
19291
19666
|
arguments: [
|
|
19292
19667
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19293
19668
|
tx.object(this.getVaultConfigId()),
|
|
19294
19669
|
tx.object(args.vaultID),
|
|
19295
19670
|
tx.object(this.getSubAccountsId()),
|
|
19296
|
-
tx.
|
|
19671
|
+
tx.object(this.getTxIndexerId()),
|
|
19672
|
+
tx.object(this.getBankId()),
|
|
19673
|
+
tx.object("0x6"),
|
|
19674
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19675
|
+
tx.pure.vector("u8", this.toUnifiedSuiAddressBytes(args.newTrader)),
|
|
19676
|
+
tx.pure.u128(signed.salt),
|
|
19677
|
+
tx.pure.u64(signed.expiration),
|
|
19678
|
+
tx.pure.vector("u8", signed.signature),
|
|
19679
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19297
19680
|
],
|
|
19298
19681
|
typeArguments: [this.getCurrencyType()],
|
|
19299
19682
|
});
|
|
@@ -19305,15 +19688,24 @@ class DipCoinPerpSDK {
|
|
|
19305
19688
|
async setVaultSubTrader(args) {
|
|
19306
19689
|
const tx = new transactions.Transaction();
|
|
19307
19690
|
const vaultPkg = this.getVaultPackageId();
|
|
19691
|
+
const signed = await this.signVaultSetSubTraderPayload(args.vaultID, this.walletAddress, args.subTrader, args.status);
|
|
19308
19692
|
tx.moveCall({
|
|
19309
|
-
target: `${vaultPkg}::vault::
|
|
19693
|
+
target: `${vaultPkg}::vault::set_sub_trader_v2`,
|
|
19310
19694
|
arguments: [
|
|
19311
19695
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19312
19696
|
tx.object(this.getVaultConfigId()),
|
|
19313
19697
|
tx.object(args.vaultID),
|
|
19314
19698
|
tx.object(this.getSubAccountsId()),
|
|
19315
|
-
tx.
|
|
19699
|
+
tx.object(this.getTxIndexerId()),
|
|
19700
|
+
tx.object(this.getBankId()),
|
|
19701
|
+
tx.object("0x6"),
|
|
19702
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19703
|
+
tx.pure.vector("u8", this.toUnifiedSuiAddressBytes(args.subTrader)),
|
|
19316
19704
|
tx.pure.bool(args.status),
|
|
19705
|
+
tx.pure.u128(signed.salt),
|
|
19706
|
+
tx.pure.u64(signed.expiration),
|
|
19707
|
+
tx.pure.vector("u8", signed.signature),
|
|
19708
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19317
19709
|
],
|
|
19318
19710
|
typeArguments: [this.getCurrencyType()],
|
|
19319
19711
|
});
|
|
@@ -19325,13 +19717,23 @@ class DipCoinPerpSDK {
|
|
|
19325
19717
|
async setVaultDepositStatus(args) {
|
|
19326
19718
|
const tx = new transactions.Transaction();
|
|
19327
19719
|
const vaultPkg = this.getVaultPackageId();
|
|
19720
|
+
const signed = await this.signVaultDepositStatusPayload(args.vaultID, this.walletAddress, args.status);
|
|
19328
19721
|
tx.moveCall({
|
|
19329
|
-
target: `${vaultPkg}::vault::
|
|
19722
|
+
target: `${vaultPkg}::vault::set_deposit_status_v2`,
|
|
19330
19723
|
arguments: [
|
|
19331
19724
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19332
19725
|
tx.object(this.getVaultConfigId()),
|
|
19333
19726
|
tx.object(args.vaultID),
|
|
19727
|
+
tx.object(this.getSubAccountsId()),
|
|
19728
|
+
tx.object(this.getTxIndexerId()),
|
|
19729
|
+
tx.object(this.getBankId()),
|
|
19730
|
+
tx.object("0x6"),
|
|
19731
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19334
19732
|
tx.pure.bool(args.status),
|
|
19733
|
+
tx.pure.u128(signed.salt),
|
|
19734
|
+
tx.pure.u64(signed.expiration),
|
|
19735
|
+
tx.pure.vector("u8", signed.signature),
|
|
19736
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19335
19737
|
],
|
|
19336
19738
|
typeArguments: [this.getCurrencyType()],
|
|
19337
19739
|
});
|
|
@@ -19343,13 +19745,24 @@ class DipCoinPerpSDK {
|
|
|
19343
19745
|
async setVaultMaxCap(args) {
|
|
19344
19746
|
const tx = new transactions.Transaction();
|
|
19345
19747
|
const vaultPkg = this.getVaultPackageId();
|
|
19748
|
+
const amount = formatNormalToWei(args.maxCap);
|
|
19749
|
+
const signed = await this.signVaultCreatorAmountPayload("VaultSetMaxCap", args.vaultID, this.walletAddress, amount);
|
|
19346
19750
|
tx.moveCall({
|
|
19347
|
-
target: `${vaultPkg}::vault::
|
|
19751
|
+
target: `${vaultPkg}::vault::set_max_cap_v2`,
|
|
19348
19752
|
arguments: [
|
|
19349
19753
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19350
19754
|
tx.object(this.getVaultConfigId()),
|
|
19351
19755
|
tx.object(args.vaultID),
|
|
19352
|
-
tx.
|
|
19756
|
+
tx.object(this.getSubAccountsId()),
|
|
19757
|
+
tx.object(this.getTxIndexerId()),
|
|
19758
|
+
tx.object(this.getBankId()),
|
|
19759
|
+
tx.object("0x6"),
|
|
19760
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19761
|
+
tx.pure.u128(amount),
|
|
19762
|
+
tx.pure.u128(signed.salt),
|
|
19763
|
+
tx.pure.u64(signed.expiration),
|
|
19764
|
+
tx.pure.vector("u8", signed.signature),
|
|
19765
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19353
19766
|
],
|
|
19354
19767
|
typeArguments: [this.getCurrencyType()],
|
|
19355
19768
|
});
|
|
@@ -19361,13 +19774,24 @@ class DipCoinPerpSDK {
|
|
|
19361
19774
|
async setVaultMinDepositAmount(args) {
|
|
19362
19775
|
const tx = new transactions.Transaction();
|
|
19363
19776
|
const vaultPkg = this.getVaultPackageId();
|
|
19777
|
+
const amount = formatNormalToWei(args.minDepositAmount);
|
|
19778
|
+
const signed = await this.signVaultCreatorAmountPayload("VaultSetMinDepositAmount", args.vaultID, this.walletAddress, amount);
|
|
19364
19779
|
tx.moveCall({
|
|
19365
|
-
target: `${vaultPkg}::vault::
|
|
19780
|
+
target: `${vaultPkg}::vault::set_min_deposit_amount_v2`,
|
|
19366
19781
|
arguments: [
|
|
19367
19782
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19368
19783
|
tx.object(this.getVaultConfigId()),
|
|
19369
19784
|
tx.object(args.vaultID),
|
|
19370
|
-
tx.
|
|
19785
|
+
tx.object(this.getSubAccountsId()),
|
|
19786
|
+
tx.object(this.getTxIndexerId()),
|
|
19787
|
+
tx.object(this.getBankId()),
|
|
19788
|
+
tx.object("0x6"),
|
|
19789
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19790
|
+
tx.pure.u128(amount),
|
|
19791
|
+
tx.pure.u128(signed.salt),
|
|
19792
|
+
tx.pure.u64(signed.expiration),
|
|
19793
|
+
tx.pure.vector("u8", signed.signature),
|
|
19794
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19371
19795
|
],
|
|
19372
19796
|
typeArguments: [this.getCurrencyType()],
|
|
19373
19797
|
});
|
|
@@ -19379,13 +19803,23 @@ class DipCoinPerpSDK {
|
|
|
19379
19803
|
async setVaultAutoCloseOnWithdraw(args) {
|
|
19380
19804
|
const tx = new transactions.Transaction();
|
|
19381
19805
|
const vaultPkg = this.getVaultPackageId();
|
|
19806
|
+
const signed = await this.signVaultAutoClosePayload(args.vaultID, this.walletAddress, args.autoCloseOnWithdraw);
|
|
19382
19807
|
tx.moveCall({
|
|
19383
|
-
target: `${vaultPkg}::vault::
|
|
19808
|
+
target: `${vaultPkg}::vault::set_auto_close_on_withdraw_v2`,
|
|
19384
19809
|
arguments: [
|
|
19385
19810
|
tx.object(this.getDeploymentProtocolConfigId()),
|
|
19386
19811
|
tx.object(this.getVaultConfigId()),
|
|
19387
19812
|
tx.object(args.vaultID),
|
|
19813
|
+
tx.object(this.getSubAccountsId()),
|
|
19814
|
+
tx.object(this.getTxIndexerId()),
|
|
19815
|
+
tx.object(this.getBankId()),
|
|
19816
|
+
tx.object("0x6"),
|
|
19817
|
+
tx.pure.vector("u8", signed.userAddress),
|
|
19388
19818
|
tx.pure.bool(args.autoCloseOnWithdraw),
|
|
19819
|
+
tx.pure.u128(signed.salt),
|
|
19820
|
+
tx.pure.u64(signed.expiration),
|
|
19821
|
+
tx.pure.vector("u8", signed.signature),
|
|
19822
|
+
tx.pure.vector("u8", signed.publicKey),
|
|
19389
19823
|
],
|
|
19390
19824
|
typeArguments: [this.getCurrencyType()],
|
|
19391
19825
|
});
|
|
@@ -19660,12 +20094,12 @@ function initDipCoinPerpSDK(privateKey, options) {
|
|
|
19660
20094
|
|
|
19661
20095
|
const globalEnv = path__default["default"].join(os__default["default"].homedir(), ".config", "dipcoin", "env");
|
|
19662
20096
|
const localEnv = path__default["default"].resolve(process.cwd(), ".env");
|
|
20097
|
+
if (fs__default["default"].existsSync(globalEnv)) {
|
|
20098
|
+
dotenv__default["default"].config({ path: globalEnv });
|
|
20099
|
+
}
|
|
19663
20100
|
if (fs__default["default"].existsSync(localEnv)) {
|
|
19664
20101
|
dotenv__default["default"].config({ path: localEnv });
|
|
19665
20102
|
}
|
|
19666
|
-
else if (fs__default["default"].existsSync(globalEnv)) {
|
|
19667
|
-
dotenv__default["default"].config({ path: globalEnv });
|
|
19668
|
-
}
|
|
19669
20103
|
// Cache SDK instance
|
|
19670
20104
|
let cachedSDK = null;
|
|
19671
20105
|
/**
|
|
@@ -19724,7 +20158,8 @@ function getSDK() {
|
|
|
19724
20158
|
return cachedSDK;
|
|
19725
20159
|
const keypair = getKeypair();
|
|
19726
20160
|
const network = getNetwork();
|
|
19727
|
-
|
|
20161
|
+
const customRpc = process.env.DIPCOIN_RPC_URL || process.env.SUI_RPC_URL;
|
|
20162
|
+
cachedSDK = initDipCoinPerpSDK(keypair, { network, customRpc });
|
|
19728
20163
|
tryAutoBindReferral(cachedSDK);
|
|
19729
20164
|
return cachedSDK;
|
|
19730
20165
|
}
|