@7kprotocol/sdk-ts 3.5.2 → 3.6.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/lib/cjs/config/index.js +9 -0
- package/lib/cjs/constants/apiEndpoints.js +1 -1
- package/lib/cjs/features/metaAg/common.js +103 -0
- package/lib/cjs/features/metaAg/error.js +35 -0
- package/lib/cjs/features/metaAg/index.js +99 -115
- package/lib/cjs/features/metaAg/providers/bluefin7k.js +57 -0
- package/lib/cjs/features/metaAg/providers/{bluefin.js → bluefin7kLegacy.js} +13 -13
- package/lib/cjs/features/metaAg/providers/cetus.js +7 -7
- package/lib/cjs/features/metaAg/providers/flowx.js +6 -6
- package/lib/cjs/features/metaAg/providers/okx.js +182 -0
- package/lib/cjs/features/swap/buildTx.js +3 -0
- package/lib/cjs/features/swap/buildTxV2.js +10 -6
- package/lib/cjs/features/swap/config.js +2 -1
- package/lib/cjs/features/swap/getQuote.js +3 -2
- package/lib/cjs/libs/protocols/bluefinx/client.js +1 -1
- package/lib/cjs/types/config/index.d.ts +4 -0
- package/lib/cjs/types/config/index.d.ts.map +1 -1
- package/lib/cjs/types/features/metaAg/common.d.ts +24 -0
- package/lib/cjs/types/features/metaAg/common.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/error.d.ts +60 -0
- package/lib/cjs/types/features/metaAg/error.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/index.d.ts +11 -2
- package/lib/cjs/types/features/metaAg/index.d.ts.map +1 -1
- package/lib/cjs/types/features/metaAg/providers/bluefin7k.d.ts +11 -0
- package/lib/cjs/types/features/metaAg/providers/bluefin7k.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/providers/bluefin7kLegacy.d.ts +11 -0
- package/lib/cjs/types/features/metaAg/providers/bluefin7kLegacy.d.ts.map +1 -0
- package/lib/cjs/types/features/metaAg/providers/cetus.d.ts +4 -5
- package/lib/cjs/types/features/metaAg/providers/cetus.d.ts.map +1 -1
- package/lib/cjs/types/features/metaAg/providers/flowx.d.ts +3 -3
- package/lib/cjs/types/features/metaAg/providers/flowx.d.ts.map +1 -1
- package/lib/cjs/types/features/metaAg/providers/okx.d.ts +21 -0
- package/lib/cjs/types/features/metaAg/providers/okx.d.ts.map +1 -0
- package/lib/cjs/types/features/swap/buildTx.d.ts.map +1 -1
- package/lib/cjs/types/features/swap/buildTxV2.d.ts +3 -3
- package/lib/cjs/types/features/swap/buildTxV2.d.ts.map +1 -1
- package/lib/cjs/types/features/swap/config.d.ts.map +1 -1
- package/lib/cjs/types/features/swap/getQuote.d.ts +1 -3
- package/lib/cjs/types/features/swap/getQuote.d.ts.map +1 -1
- package/lib/cjs/types/index.d.ts +3 -1
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/metaAg.js +10 -4
- package/lib/cjs/types/okx.js +6 -0
- package/lib/cjs/types/types/metaAg.d.ts +62 -12
- package/lib/cjs/types/types/metaAg.d.ts.map +1 -1
- package/lib/cjs/types/types/okx.d.ts +206 -0
- package/lib/cjs/types/types/okx.d.ts.map +1 -0
- package/lib/cjs/types/utils/sui.d.ts +1 -0
- package/lib/cjs/types/utils/sui.d.ts.map +1 -1
- package/lib/cjs/utils/sui.js +17 -1
- package/lib/esm/config/index.js +9 -0
- package/lib/esm/constants/apiEndpoints.js +1 -1
- package/lib/esm/features/metaAg/common.js +96 -0
- package/lib/esm/features/metaAg/error.js +33 -0
- package/lib/esm/features/metaAg/index.js +100 -116
- package/lib/esm/features/metaAg/providers/bluefin7k.js +55 -0
- package/lib/esm/features/metaAg/providers/{bluefin.js → bluefin7kLegacy.js} +11 -11
- package/lib/esm/features/metaAg/providers/cetus.js +7 -7
- package/lib/esm/features/metaAg/providers/flowx.js +6 -6
- package/lib/esm/features/metaAg/providers/okx.js +147 -0
- package/lib/esm/features/swap/buildTx.js +3 -0
- package/lib/esm/features/swap/buildTxV2.js +6 -2
- package/lib/esm/features/swap/config.js +2 -1
- package/lib/esm/features/swap/getQuote.js +3 -2
- package/lib/esm/libs/protocols/bluefinx/client.js +1 -1
- package/lib/esm/types/config/index.d.ts +4 -0
- package/lib/esm/types/config/index.d.ts.map +1 -1
- package/lib/esm/types/features/metaAg/common.d.ts +24 -0
- package/lib/esm/types/features/metaAg/common.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/error.d.ts +60 -0
- package/lib/esm/types/features/metaAg/error.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/index.d.ts +11 -2
- package/lib/esm/types/features/metaAg/index.d.ts.map +1 -1
- package/lib/esm/types/features/metaAg/providers/bluefin7k.d.ts +11 -0
- package/lib/esm/types/features/metaAg/providers/bluefin7k.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/providers/bluefin7kLegacy.d.ts +11 -0
- package/lib/esm/types/features/metaAg/providers/bluefin7kLegacy.d.ts.map +1 -0
- package/lib/esm/types/features/metaAg/providers/cetus.d.ts +4 -5
- package/lib/esm/types/features/metaAg/providers/cetus.d.ts.map +1 -1
- package/lib/esm/types/features/metaAg/providers/flowx.d.ts +3 -3
- package/lib/esm/types/features/metaAg/providers/flowx.d.ts.map +1 -1
- package/lib/esm/types/features/metaAg/providers/okx.d.ts +21 -0
- package/lib/esm/types/features/metaAg/providers/okx.d.ts.map +1 -0
- package/lib/esm/types/features/swap/buildTx.d.ts.map +1 -1
- package/lib/esm/types/features/swap/buildTxV2.d.ts +3 -3
- package/lib/esm/types/features/swap/buildTxV2.d.ts.map +1 -1
- package/lib/esm/types/features/swap/config.d.ts.map +1 -1
- package/lib/esm/types/features/swap/getQuote.d.ts +1 -3
- package/lib/esm/types/features/swap/getQuote.d.ts.map +1 -1
- package/lib/esm/types/index.d.ts +3 -1
- package/lib/esm/types/index.d.ts.map +1 -1
- package/lib/esm/types/metaAg.js +7 -2
- package/lib/esm/types/okx.js +5 -0
- package/lib/esm/types/types/metaAg.d.ts +62 -12
- package/lib/esm/types/types/metaAg.d.ts.map +1 -1
- package/lib/esm/types/types/okx.d.ts +206 -0
- package/lib/esm/types/types/okx.d.ts.map +1 -0
- package/lib/esm/types/utils/sui.d.ts +1 -0
- package/lib/esm/types/utils/sui.d.ts.map +1 -1
- package/lib/esm/utils/sui.js +16 -1
- package/package.json +3 -1
- package/lib/cjs/types/features/metaAg/providers/bluefin.d.ts +0 -11
- package/lib/cjs/types/features/metaAg/providers/bluefin.d.ts.map +0 -1
- package/lib/cjs/types/utils/condition.d.ts +0 -2
- package/lib/cjs/types/utils/condition.d.ts.map +0 -1
- package/lib/cjs/utils/condition.js +0 -8
- package/lib/esm/types/features/metaAg/providers/bluefin.d.ts +0 -11
- package/lib/esm/types/features/metaAg/providers/bluefin.d.ts.map +0 -1
- package/lib/esm/types/utils/condition.d.ts +0 -2
- package/lib/esm/types/utils/condition.d.ts.map +0 -1
- package/lib/esm/utils/condition.js +0 -5
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { coinWithBalance, Transaction, } from "@mysten/sui/transactions";
|
|
2
|
+
import { _7K_META_CONFIG, _7K_META_PACKAGE_ID, _7K_META_PUBLISHED_AT, _7K_META_VAULT, } from "../../constants/_7k";
|
|
3
|
+
import { getExpectedReturn } from "../swap/buildTx";
|
|
4
|
+
import { MetaAgError, MetaAgErrorCode } from "./error";
|
|
5
|
+
export const simulateSwapTx = async (tx, inspector, simulation) => {
|
|
6
|
+
const res = await timeout(() => inspector.devInspectTransactionBlock({
|
|
7
|
+
sender: simulation.sender,
|
|
8
|
+
transactionBlock: tx,
|
|
9
|
+
}), simulation.timeout ?? 2000);
|
|
10
|
+
if (res.effects.status.status === "failure") {
|
|
11
|
+
throw new MetaAgError(res.error ?? "Simulation failed", MetaAgErrorCode.SIMULATION_FAILED, { error: res.error });
|
|
12
|
+
}
|
|
13
|
+
const amountOut = extractAmountOutWrapper(res.events);
|
|
14
|
+
return {
|
|
15
|
+
simulatedAmountOut: amountOut,
|
|
16
|
+
gasUsed: res.effects.gasUsed,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export const simulateAggregator = async (provider, quote, simulation, inspector, options) => {
|
|
20
|
+
const tx = new Transaction();
|
|
21
|
+
const coinOut = await provider.swap({
|
|
22
|
+
quote,
|
|
23
|
+
coinIn: coinWithBalance({
|
|
24
|
+
balance: BigInt(quote.amountIn),
|
|
25
|
+
type: quote.coinTypeIn,
|
|
26
|
+
useGasCoin: false,
|
|
27
|
+
}),
|
|
28
|
+
signer: simulation.sender,
|
|
29
|
+
tx,
|
|
30
|
+
});
|
|
31
|
+
tx.add(metaSettle(quote, coinOut, 10000, options.tipBps, options.partner, options.partnerCommissionBps));
|
|
32
|
+
tx.transferObjects([coinOut], simulation.sender);
|
|
33
|
+
const res = await simulateSwapTx(tx, inspector, simulation);
|
|
34
|
+
return {
|
|
35
|
+
id: quote.id,
|
|
36
|
+
provider: provider.kind,
|
|
37
|
+
...res,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* this settlement does not charge commission fee for partner, since all integrated aggregators already charge commission fee for partner
|
|
42
|
+
* @param quote Meta Aggregator Quote
|
|
43
|
+
* @param coinOut Coin Out Object
|
|
44
|
+
* @param slippageBps Slippage Bps
|
|
45
|
+
* @param tipBps Tip Bps default = 0
|
|
46
|
+
* @param partner address of partner for analytic default is zero address
|
|
47
|
+
*/
|
|
48
|
+
export const metaSettle = (quote, coinOut, slippageBps = 100, tipBps = 0, partner, commissionBps = 0) => {
|
|
49
|
+
return (tx) => {
|
|
50
|
+
const { minAmount, expectedAmount } = getExpectedReturn(quote.rawAmountOut, slippageBps, commissionBps, tipBps);
|
|
51
|
+
if (tipBps > 0) {
|
|
52
|
+
tx.moveCall({
|
|
53
|
+
target: `${_7K_META_PUBLISHED_AT}::vault::collect_tip`,
|
|
54
|
+
typeArguments: [quote.coinTypeOut],
|
|
55
|
+
arguments: [
|
|
56
|
+
tx.object(_7K_META_VAULT),
|
|
57
|
+
tx.object(_7K_META_CONFIG),
|
|
58
|
+
coinOut,
|
|
59
|
+
tx.pure.u64(tipBps),
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
tx.moveCall({
|
|
64
|
+
target: `${_7K_META_PUBLISHED_AT}::settle::settle`,
|
|
65
|
+
typeArguments: [quote.coinTypeIn, quote.coinTypeOut],
|
|
66
|
+
arguments: [
|
|
67
|
+
tx.object(_7K_META_CONFIG),
|
|
68
|
+
tx.object(_7K_META_VAULT),
|
|
69
|
+
tx.pure.u64(quote.amountIn),
|
|
70
|
+
coinOut,
|
|
71
|
+
tx.pure.u64(minAmount),
|
|
72
|
+
tx.pure.u64(expectedAmount),
|
|
73
|
+
tx.pure.option("address", partner),
|
|
74
|
+
tx.pure.u64(commissionBps),
|
|
75
|
+
tx.pure.u64(0), // ps
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const extractAmountOutWrapper = (events) => {
|
|
81
|
+
const swapEvent = events
|
|
82
|
+
.filter((event) => event.type === `${_7K_META_PACKAGE_ID}::settle::Swap`)
|
|
83
|
+
?.pop();
|
|
84
|
+
return swapEvent?.parsedJson?.amount_out;
|
|
85
|
+
};
|
|
86
|
+
export const timeout = async (fn, timeout, msg) => {
|
|
87
|
+
if (timeout <= 0)
|
|
88
|
+
return fn();
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
const timer = setTimeout(() => reject(new MetaAgError(`Timeout ${msg ?? "operation"}`, MetaAgErrorCode.TIMEOUT, { timeout })), timeout);
|
|
91
|
+
fn()
|
|
92
|
+
.then(resolve)
|
|
93
|
+
.catch(reject)
|
|
94
|
+
.finally(() => clearTimeout(timer));
|
|
95
|
+
});
|
|
96
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export var MetaAgErrorCode;
|
|
2
|
+
(function (MetaAgErrorCode) {
|
|
3
|
+
MetaAgErrorCode[MetaAgErrorCode["UNKNOWN"] = 1000] = "UNKNOWN";
|
|
4
|
+
MetaAgErrorCode[MetaAgErrorCode["TIMEOUT"] = 1001] = "TIMEOUT";
|
|
5
|
+
MetaAgErrorCode[MetaAgErrorCode["PROVIDER_NOT_FOUND"] = 1002] = "PROVIDER_NOT_FOUND";
|
|
6
|
+
MetaAgErrorCode[MetaAgErrorCode["PROVIDER_NOT_SUPPORTED"] = 1003] = "PROVIDER_NOT_SUPPORTED";
|
|
7
|
+
MetaAgErrorCode[MetaAgErrorCode["INVALID_QUOTE"] = 1004] = "INVALID_QUOTE";
|
|
8
|
+
MetaAgErrorCode[MetaAgErrorCode["QUOTE_NOT_FOUND"] = 1005] = "QUOTE_NOT_FOUND";
|
|
9
|
+
MetaAgErrorCode[MetaAgErrorCode["INVALID_SIGNER_ADDRESS"] = 1006] = "INVALID_SIGNER_ADDRESS";
|
|
10
|
+
MetaAgErrorCode[MetaAgErrorCode["PROVIDER_NOT_SUPPORT_SWAP"] = 1007] = "PROVIDER_NOT_SUPPORT_SWAP";
|
|
11
|
+
MetaAgErrorCode[MetaAgErrorCode["SIMULATION_FAILED"] = 1008] = "SIMULATION_FAILED";
|
|
12
|
+
// OKX error
|
|
13
|
+
MetaAgErrorCode[MetaAgErrorCode["OKX_FINALIZE_COMMAND_NOT_FOUND"] = 1100] = "OKX_FINALIZE_COMMAND_NOT_FOUND";
|
|
14
|
+
// BluefinX error
|
|
15
|
+
MetaAgErrorCode[MetaAgErrorCode["BLUEFINX_TRANSACTION_NOT_FOUND"] = 1200] = "BLUEFINX_TRANSACTION_NOT_FOUND";
|
|
16
|
+
MetaAgErrorCode[MetaAgErrorCode["BLUEFINX_TRANSACTION_NOT_APPROVED"] = 1201] = "BLUEFINX_TRANSACTION_NOT_APPROVED";
|
|
17
|
+
MetaAgErrorCode[MetaAgErrorCode["BLUEFINX_TRANSACTION_DIGEST_NOT_FOUND"] = 1202] = "BLUEFINX_TRANSACTION_DIGEST_NOT_FOUND";
|
|
18
|
+
})(MetaAgErrorCode || (MetaAgErrorCode = {}));
|
|
19
|
+
export class MetaAgError extends Error {
|
|
20
|
+
code;
|
|
21
|
+
details;
|
|
22
|
+
constructor(message, code, details) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "MetaAgError";
|
|
25
|
+
this.code = code ?? MetaAgErrorCode.UNKNOWN;
|
|
26
|
+
this.details = details;
|
|
27
|
+
}
|
|
28
|
+
static assert(condition, message, code, details) {
|
|
29
|
+
if (!condition) {
|
|
30
|
+
throw new MetaAgError(message ?? "Assertion failed", code, details);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { getFullnodeUrl, SuiClient } from "@mysten/sui/client";
|
|
1
|
+
import { getFullnodeUrl, SuiClient, } from "@mysten/sui/client";
|
|
2
2
|
import { coinWithBalance, Transaction, } from "@mysten/sui/transactions";
|
|
3
|
-
import { normalizeStructTag } from "@mysten/sui/utils";
|
|
4
|
-
import { _7K_META_CONFIG, _7K_META_PACKAGE_ID, _7K_META_PUBLISHED_AT, _7K_META_VAULT, } from "../../constants/_7k";
|
|
3
|
+
import { normalizeStructTag, toBase64 } from "@mysten/sui/utils";
|
|
5
4
|
import { SUI_ADDRESS_ZERO } from "../../constants/sui";
|
|
6
|
-
import { EProvider, } from "../../types/metaAg";
|
|
7
|
-
import {
|
|
5
|
+
import { EProvider, isAggregatorProvider, isSwapAPIProvider, } from "../../types/metaAg";
|
|
6
|
+
import { isSystemAddress } from "../../utils/sui";
|
|
8
7
|
import { SuiClientUtils } from "../../utils/SuiClientUtils";
|
|
9
8
|
import { getExpectedReturn } from "../swap/buildTx";
|
|
10
|
-
import {
|
|
9
|
+
import { metaSettle, simulateAggregator, timeout } from "./common";
|
|
10
|
+
import { MetaAgError, MetaAgErrorCode } from "./error";
|
|
11
|
+
import { BluefinLegacyProvider } from "./providers/bluefin7kLegacy";
|
|
12
|
+
import { OkxProvider, simulateOKXSwap } from "./providers/okx";
|
|
11
13
|
const HERMES_API = "https://hermes.pyth.network";
|
|
12
14
|
const DEFAULT_PROVIDERS = {
|
|
13
15
|
[EProvider.BLUEFIN7K]: {},
|
|
@@ -39,10 +41,14 @@ export class MetaAg {
|
|
|
39
41
|
if (p)
|
|
40
42
|
return p;
|
|
41
43
|
const providerOptions = this.options.providers[provider];
|
|
42
|
-
assert(!!providerOptions, `Provider not found: ${provider}
|
|
44
|
+
MetaAgError.assert(!!providerOptions, `Provider not found: ${provider}`, MetaAgErrorCode.PROVIDER_NOT_FOUND, { provider });
|
|
43
45
|
switch (provider) {
|
|
46
|
+
case EProvider.BLUEFIN7K_LEGACY:
|
|
47
|
+
this.providers[EProvider.BLUEFIN7K_LEGACY] = new BluefinLegacyProvider(providerOptions, this.options, this.client);
|
|
48
|
+
break;
|
|
44
49
|
case EProvider.BLUEFIN7K:
|
|
45
|
-
|
|
50
|
+
const { Bluefin7kProvider } = await import("./providers/bluefin7k").catch(catchImportError(EProvider.BLUEFIN7K));
|
|
51
|
+
this.providers[EProvider.BLUEFIN7K] = new Bluefin7kProvider(providerOptions, this.options, this.client);
|
|
46
52
|
break;
|
|
47
53
|
case EProvider.FLOWX:
|
|
48
54
|
const { FlowxProvider } = await import("./providers/flowx").catch(catchImportError(EProvider.FLOWX));
|
|
@@ -52,69 +58,64 @@ export class MetaAg {
|
|
|
52
58
|
const { CetusProvider } = await import("./providers/cetus").catch(catchImportError(EProvider.CETUS));
|
|
53
59
|
this.providers[EProvider.CETUS] = new CetusProvider(providerOptions, this.options, this.client);
|
|
54
60
|
break;
|
|
61
|
+
case EProvider.OKX:
|
|
62
|
+
this.providers[EProvider.OKX] = new OkxProvider(providerOptions, this.options, this.client);
|
|
63
|
+
break;
|
|
55
64
|
default:
|
|
56
|
-
throw new
|
|
65
|
+
throw new MetaAgError(`Provider not supported: ${provider}`, MetaAgErrorCode.PROVIDER_NOT_SUPPORTED, { provider });
|
|
57
66
|
}
|
|
58
67
|
return this.providers[provider];
|
|
59
68
|
}
|
|
60
69
|
async _simulate(provider, quote, simulation) {
|
|
61
70
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}),
|
|
71
|
-
signer: simulation.sender,
|
|
72
|
-
tx,
|
|
73
|
-
});
|
|
74
|
-
tx.add(metaSettle(quote, coinOut, 10000, this.options.tipBps, this.options.partner, this.options.partnerCommissionBps));
|
|
75
|
-
tx.transferObjects([coinOut], simulation.sender);
|
|
76
|
-
const res = await timeout(() => this.inspector.devInspectTransactionBlock({
|
|
77
|
-
sender: simulation.sender,
|
|
78
|
-
transactionBlock: tx,
|
|
79
|
-
}), simulation.timeout ?? 2000, `simulation for ${provider.kind} provider with id ${id}`);
|
|
80
|
-
if (res.effects.status.status === "failure") {
|
|
81
|
-
throw new Error(res.error ?? "Simulation failed");
|
|
71
|
+
if (isAggregatorProvider(provider)) {
|
|
72
|
+
return simulateAggregator(provider, quote, simulation, this.inspector, this.options);
|
|
73
|
+
}
|
|
74
|
+
switch (quote.provider) {
|
|
75
|
+
case EProvider.OKX:
|
|
76
|
+
return simulateOKXSwap(quote, this.inspector, simulation, this.options);
|
|
77
|
+
default:
|
|
78
|
+
throw new MetaAgError(`Provider not supported: ${provider.kind}`, MetaAgErrorCode.PROVIDER_NOT_SUPPORTED, { provider: provider.kind });
|
|
82
79
|
}
|
|
83
|
-
const amountOut = extractAmountOutWrapper(res.events);
|
|
84
|
-
return {
|
|
85
|
-
id,
|
|
86
|
-
simulatedAmountOut: amountOut,
|
|
87
|
-
gasUsed: res.effects.gasUsed,
|
|
88
|
-
provider: provider.kind,
|
|
89
|
-
};
|
|
90
80
|
}
|
|
91
81
|
catch (error) {
|
|
92
|
-
console.warn(
|
|
82
|
+
console.warn(error, { provider: provider.kind, quote: quote.id });
|
|
93
83
|
}
|
|
94
84
|
}
|
|
95
|
-
async _quote(provider, options
|
|
85
|
+
async _quote(provider, options) {
|
|
96
86
|
const quote = await timeout(async () => {
|
|
97
87
|
const quote = await provider.quote(options);
|
|
88
|
+
if (!quote)
|
|
89
|
+
return null;
|
|
98
90
|
const { expectedAmount } = getExpectedReturn(quote.rawAmountOut, 0, this.options.partnerCommissionBps, this.options.tipBps);
|
|
99
91
|
quote.amountOut = expectedAmount;
|
|
100
92
|
return quote;
|
|
101
|
-
}, options.timeout ?? 2000, `quote for ${provider.kind} provider from ${options.
|
|
102
|
-
if (simulation) {
|
|
103
|
-
if (simulation.onSimulated) {
|
|
104
|
-
this._simulate(provider, quote, simulation).then((payload) => {
|
|
105
|
-
if (payload) {
|
|
106
|
-
simulation.onSimulated?.(payload);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
const updated = await this._simulate(provider, quote, simulation);
|
|
112
|
-
quote.simulatedAmountOut = updated?.simulatedAmountOut;
|
|
113
|
-
quote.gasUsed = updated?.gasUsed;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
93
|
+
}, options.timeout ?? 2000, `quote for ${provider.kind} provider from ${options.coinTypeIn} to ${options.coinTypeOut}`);
|
|
116
94
|
return quote;
|
|
117
95
|
}
|
|
96
|
+
async _fastSwap({ quote, signer, useGasCoin, signTransaction }, getTransactionBlockParams) {
|
|
97
|
+
const tx = new Transaction();
|
|
98
|
+
const coin = await this.swap({
|
|
99
|
+
quote,
|
|
100
|
+
signer,
|
|
101
|
+
tx,
|
|
102
|
+
coinIn: coinWithBalance({
|
|
103
|
+
type: quote.coinTypeIn,
|
|
104
|
+
balance: BigInt(quote.amountIn),
|
|
105
|
+
useGasCoin,
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
tx.transferObjects([coin], signer);
|
|
109
|
+
tx.setSenderIfNotSet(signer);
|
|
110
|
+
const txBytes = await tx.build({ client: this.client });
|
|
111
|
+
const { signature, bytes } = await signTransaction(toBase64(txBytes));
|
|
112
|
+
return this.client.executeTransactionBlock({
|
|
113
|
+
transactionBlock: bytes,
|
|
114
|
+
signature,
|
|
115
|
+
options: getTransactionBlockParams?.options,
|
|
116
|
+
signal: getTransactionBlockParams?.signal,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
118
119
|
/**
|
|
119
120
|
* Get quotes from all providers
|
|
120
121
|
* @param options - quote options
|
|
@@ -124,35 +125,73 @@ export class MetaAg {
|
|
|
124
125
|
async quote(options, simulation) {
|
|
125
126
|
const opts = {
|
|
126
127
|
...options,
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
coinTypeIn: normalizeStructTag(options.coinTypeIn),
|
|
129
|
+
coinTypeOut: normalizeStructTag(options.coinTypeOut),
|
|
129
130
|
};
|
|
130
131
|
const quotes = await Promise.allSettled(Object.entries(this.options.providers)
|
|
131
132
|
.filter(([_k, v]) => !v.disabled)
|
|
132
133
|
.map(async ([provider]) => {
|
|
133
134
|
const p = await this._getProvider(provider);
|
|
134
|
-
return this._quote(p, opts
|
|
135
|
+
return this._quote(p, opts);
|
|
135
136
|
}));
|
|
136
|
-
|
|
137
|
+
const result = quotes
|
|
137
138
|
.map((quote) => quote.status === "fulfilled"
|
|
138
139
|
? quote.value
|
|
139
140
|
: (console.log(quote.reason), null))
|
|
140
141
|
.filter((quote) => quote !== null);
|
|
142
|
+
if (simulation) {
|
|
143
|
+
const requests = result.map(async (quote) => {
|
|
144
|
+
const provider = await this._getProvider(quote.provider);
|
|
145
|
+
const updated = await this._simulate(provider, quote, simulation);
|
|
146
|
+
quote.simulatedAmountOut = updated?.simulatedAmountOut;
|
|
147
|
+
quote.gasUsed = updated?.gasUsed;
|
|
148
|
+
simulation?.onSimulated?.({ ...quote });
|
|
149
|
+
});
|
|
150
|
+
if (!simulation.onSimulated) {
|
|
151
|
+
await Promise.all(requests);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
141
155
|
}
|
|
142
156
|
/**
|
|
143
157
|
* Build transaction from quote
|
|
158
|
+
* @info Use this function to build composable transaction (ie: add more commands after the swap, consume the coin out object)
|
|
159
|
+
* @warning Providers that build transaction on the fly (typically RFQ, Swap-API providers ie: BluefinX, Okx, ...) are not supported, please use `fastSwap` instead
|
|
144
160
|
* @param options - build tx options
|
|
145
161
|
* @param slippageBps - slippage bps if not specified, fallback to global slippage bps, if none of them specified, default to 100
|
|
146
162
|
* @returns coin out object, you must consume it by transferObjects, or other sub sequence commands
|
|
147
163
|
*/
|
|
148
164
|
async swap(options, slippageBps) {
|
|
149
165
|
const provider = await this._getProvider(options.quote.provider);
|
|
150
|
-
assert(!!provider, `Provider not found: ${options.quote.provider}
|
|
166
|
+
MetaAgError.assert(!!provider, `Provider not found: ${options.quote.provider}`, MetaAgErrorCode.PROVIDER_NOT_FOUND, { provider: options.quote.provider });
|
|
167
|
+
MetaAgError.assert(isAggregatorProvider(provider), `Provider does not support swap: ${provider.kind}, use fastSwap instead`, MetaAgErrorCode.PROVIDER_NOT_SUPPORT_SWAP, { provider: provider.kind });
|
|
168
|
+
MetaAgError.assert(!isSystemAddress(options.signer), "Invalid signer address", MetaAgErrorCode.INVALID_SIGNER_ADDRESS, { signer: options.signer });
|
|
151
169
|
const coinOut = await provider.swap(options);
|
|
152
170
|
options.tx.add(metaSettle(options.quote, coinOut, slippageBps ?? this.options.slippageBps ?? 100, this.options.tipBps, this.options.partner, this.options.partnerCommissionBps));
|
|
153
171
|
options.tx.setSenderIfNotSet(options.signer);
|
|
154
172
|
return coinOut;
|
|
155
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Build, Sign, and Execute transaction in one step
|
|
176
|
+
* @param options - fast swap options
|
|
177
|
+
* @returns - txDigest of the transaction
|
|
178
|
+
*/
|
|
179
|
+
async fastSwap(options, getTransactionBlockParams) {
|
|
180
|
+
MetaAgError.assert(!isSystemAddress(options.signer), "Invalid signer address", MetaAgErrorCode.INVALID_SIGNER_ADDRESS, { signer: options.signer });
|
|
181
|
+
const provider = await this._getProvider(options.quote.provider);
|
|
182
|
+
if (isAggregatorProvider(provider)) {
|
|
183
|
+
return this._fastSwap(options, getTransactionBlockParams);
|
|
184
|
+
}
|
|
185
|
+
else if (isSwapAPIProvider(provider)) {
|
|
186
|
+
return this.client.waitForTransaction({
|
|
187
|
+
...getTransactionBlockParams,
|
|
188
|
+
digest: await provider.fastSwap(options),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
throw new MetaAgError(`Provider not supported: ${provider.kind}`, MetaAgErrorCode.PROVIDER_NOT_SUPPORTED, { provider: provider.kind });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
156
195
|
/**
|
|
157
196
|
* Update meta aggregator options
|
|
158
197
|
* @param options - update options payload
|
|
@@ -185,71 +224,16 @@ export class MetaAg {
|
|
|
185
224
|
}
|
|
186
225
|
}
|
|
187
226
|
}
|
|
188
|
-
/**
|
|
189
|
-
* this settlement does not charge commission fee for partner, since all integrated aggregators already charge commission fee for partner
|
|
190
|
-
* @param quote Meta Aggregator Quote
|
|
191
|
-
* @param coinOut Coin Out Object
|
|
192
|
-
* @param slippageBps Slippage Bps
|
|
193
|
-
* @param tipBps Tip Bps default = 0
|
|
194
|
-
* @param partner address of partner for analytic default is zero address
|
|
195
|
-
*/
|
|
196
|
-
const metaSettle = (quote, coinOut, slippageBps = 100, tipBps = 0, partner, commissionBps = 0) => {
|
|
197
|
-
return (tx) => {
|
|
198
|
-
const { minAmount, expectedAmount } = getExpectedReturn(quote.rawAmountOut, slippageBps, commissionBps, tipBps);
|
|
199
|
-
if (tipBps > 0) {
|
|
200
|
-
tx.moveCall({
|
|
201
|
-
target: `${_7K_META_PUBLISHED_AT}::vault::collect_tip`,
|
|
202
|
-
typeArguments: [quote.coinTypeOut],
|
|
203
|
-
arguments: [
|
|
204
|
-
tx.object(_7K_META_VAULT),
|
|
205
|
-
tx.object(_7K_META_CONFIG),
|
|
206
|
-
coinOut,
|
|
207
|
-
tx.pure.u64(tipBps),
|
|
208
|
-
],
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
tx.moveCall({
|
|
212
|
-
target: `${_7K_META_PUBLISHED_AT}::settle::settle`,
|
|
213
|
-
typeArguments: [quote.coinTypeIn, quote.coinTypeOut],
|
|
214
|
-
arguments: [
|
|
215
|
-
tx.object(_7K_META_CONFIG),
|
|
216
|
-
tx.object(_7K_META_VAULT),
|
|
217
|
-
tx.pure.u64(quote.amountIn),
|
|
218
|
-
coinOut,
|
|
219
|
-
tx.pure.u64(minAmount),
|
|
220
|
-
tx.pure.u64(expectedAmount),
|
|
221
|
-
tx.pure.option("address", partner),
|
|
222
|
-
tx.pure.u64(commissionBps),
|
|
223
|
-
tx.pure.u64(0), // ps
|
|
224
|
-
],
|
|
225
|
-
});
|
|
226
|
-
};
|
|
227
|
-
};
|
|
228
|
-
const extractAmountOutWrapper = (events) => {
|
|
229
|
-
const swapEvent = events
|
|
230
|
-
.filter((event) => event.type === `${_7K_META_PACKAGE_ID}::settle::Swap`)
|
|
231
|
-
?.pop();
|
|
232
|
-
return swapEvent?.parsedJson?.amount_out;
|
|
233
|
-
};
|
|
234
227
|
const catchImportError = (provider) => {
|
|
235
228
|
return (e) => {
|
|
236
229
|
const map = {
|
|
237
230
|
[EProvider.CETUS]: "@cetusprotocol/aggregator-sdk",
|
|
238
231
|
[EProvider.FLOWX]: "@flowx-finance/sdk",
|
|
239
|
-
[EProvider.
|
|
232
|
+
[EProvider.BLUEFIN7K_LEGACY]: "@7kprotocol/sdk-ts",
|
|
233
|
+
[EProvider.BLUEFIN7K]: "@bluefin-exchange/bluefin7k-aggregator-sdk",
|
|
234
|
+
[EProvider.OKX]: "",
|
|
240
235
|
};
|
|
241
236
|
console.warn(`Please install ${map[provider]} to use ${provider} provider`);
|
|
242
237
|
throw e;
|
|
243
238
|
};
|
|
244
239
|
};
|
|
245
|
-
const timeout = async (fn, timeout, msg) => {
|
|
246
|
-
if (timeout <= 0)
|
|
247
|
-
return fn();
|
|
248
|
-
return new Promise((resolve, reject) => {
|
|
249
|
-
const timer = setTimeout(() => reject(new Error(`Timeout ${msg ?? "operation"}`)), timeout);
|
|
250
|
-
fn()
|
|
251
|
-
.then(resolve)
|
|
252
|
-
.catch(reject)
|
|
253
|
-
.finally(() => clearTimeout(timer));
|
|
254
|
-
});
|
|
255
|
-
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { buildTx, Config, getQuote, } from "@bluefin-exchange/bluefin7k-aggregator-sdk";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
import { _7K_PARTNER_ADDRESS } from "../../../constants/_7k";
|
|
4
|
+
import { EProvider, } from "../../../types/metaAg";
|
|
5
|
+
import { MetaAgError, MetaAgErrorCode } from "../error";
|
|
6
|
+
export class Bluefin7kProvider {
|
|
7
|
+
options;
|
|
8
|
+
metaOptions;
|
|
9
|
+
kind = EProvider.BLUEFIN7K;
|
|
10
|
+
constructor(options, metaOptions, client) {
|
|
11
|
+
this.options = options;
|
|
12
|
+
this.metaOptions = metaOptions;
|
|
13
|
+
if (options.apiKey)
|
|
14
|
+
Config.setApiKey(options.apiKey);
|
|
15
|
+
Config.setSuiClient(client);
|
|
16
|
+
}
|
|
17
|
+
async quote(quoteOptions) {
|
|
18
|
+
const quote = await getQuote({
|
|
19
|
+
tokenIn: quoteOptions.coinTypeIn,
|
|
20
|
+
tokenOut: quoteOptions.coinTypeOut,
|
|
21
|
+
amountIn: quoteOptions.amountIn,
|
|
22
|
+
sources: this.options.sources,
|
|
23
|
+
excludedPools: this.options.excludedPools,
|
|
24
|
+
targetPools: this.options.targetPools,
|
|
25
|
+
});
|
|
26
|
+
MetaAgError.assert(!!quote, "No quote found", MetaAgErrorCode.QUOTE_NOT_FOUND, { provider: this.kind });
|
|
27
|
+
return {
|
|
28
|
+
id: v4(),
|
|
29
|
+
provider: EProvider.BLUEFIN7K,
|
|
30
|
+
quote,
|
|
31
|
+
amountIn: quote.swapAmountWithDecimal,
|
|
32
|
+
rawAmountOut: quote.returnAmountWithDecimal,
|
|
33
|
+
amountOut: quote.returnAmountWithDecimal,
|
|
34
|
+
coinTypeIn: quoteOptions.coinTypeIn,
|
|
35
|
+
coinTypeOut: quoteOptions.coinTypeOut,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async swap({ quote, signer, tx, coinIn }) {
|
|
39
|
+
MetaAgError.assert(quote.provider === EProvider.BLUEFIN7K, "Invalid quote", MetaAgErrorCode.INVALID_QUOTE, { quote, expectedProvider: EProvider.BLUEFIN7K });
|
|
40
|
+
const { coinOut } = await buildTx({
|
|
41
|
+
quoteResponse: quote.quote,
|
|
42
|
+
accountAddress: signer,
|
|
43
|
+
commission: {
|
|
44
|
+
commissionBps: 0,
|
|
45
|
+
partner: _7K_PARTNER_ADDRESS,
|
|
46
|
+
},
|
|
47
|
+
slippage: 1,
|
|
48
|
+
extendTx: {
|
|
49
|
+
tx,
|
|
50
|
+
coinIn,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
return coinOut;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -2,17 +2,16 @@ import { SuiPriceServiceConnection, SuiPythClient, } from "@pythnetwork/pyth-sui
|
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { Config } from "../../../config";
|
|
4
4
|
import { _7K_PARTNER_ADDRESS } from "../../../constants/_7k";
|
|
5
|
-
import { API_ENDPOINTS } from "../../../constants/apiEndpoints";
|
|
6
5
|
import { EProvider, } from "../../../types/metaAg";
|
|
7
|
-
import { assert } from "../../../utils/condition";
|
|
8
6
|
import { buildTxV2 } from "../../swap/buildTxV2";
|
|
9
7
|
import { getQuote } from "../../swap/getQuote";
|
|
8
|
+
import { MetaAgError, MetaAgErrorCode } from "../error";
|
|
10
9
|
const WORMHOLE_STATE_ID = "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c";
|
|
11
10
|
const PYTH_STATE_ID = "0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8";
|
|
12
|
-
export class
|
|
11
|
+
export class BluefinLegacyProvider {
|
|
13
12
|
options;
|
|
14
13
|
metaOptions;
|
|
15
|
-
kind = EProvider.
|
|
14
|
+
kind = EProvider.BLUEFIN7K_LEGACY;
|
|
16
15
|
constructor(options, metaOptions, client) {
|
|
17
16
|
this.options = options;
|
|
18
17
|
this.metaOptions = metaOptions;
|
|
@@ -20,6 +19,8 @@ export class BluefinProvider {
|
|
|
20
19
|
const pythConnection = new SuiPriceServiceConnection(this.metaOptions.hermesApi);
|
|
21
20
|
if (options.apiKey)
|
|
22
21
|
Config.setApiKey(options.apiKey);
|
|
22
|
+
if (options.api)
|
|
23
|
+
Config.setApi(options.api);
|
|
23
24
|
Config.setSuiClient(client);
|
|
24
25
|
Config.setPythClient(pythClient);
|
|
25
26
|
Config.setPythConnection(pythConnection);
|
|
@@ -27,9 +28,8 @@ export class BluefinProvider {
|
|
|
27
28
|
async quote(options) {
|
|
28
29
|
const quote = await getQuote({
|
|
29
30
|
amountIn: options.amountIn,
|
|
30
|
-
tokenIn: options.
|
|
31
|
-
tokenOut: options.
|
|
32
|
-
api: this.options.api || API_ENDPOINTS.MAIN,
|
|
31
|
+
tokenIn: options.coinTypeIn,
|
|
32
|
+
tokenOut: options.coinTypeOut,
|
|
33
33
|
sources: this.options.sources,
|
|
34
34
|
maxPaths: this.options.maxPaths,
|
|
35
35
|
excludedPools: this.options.excludedPools,
|
|
@@ -37,17 +37,17 @@ export class BluefinProvider {
|
|
|
37
37
|
});
|
|
38
38
|
return {
|
|
39
39
|
id: v4(),
|
|
40
|
-
provider: EProvider.
|
|
40
|
+
provider: EProvider.BLUEFIN7K_LEGACY,
|
|
41
41
|
quote,
|
|
42
42
|
amountIn: quote.swapAmountWithDecimal,
|
|
43
43
|
rawAmountOut: quote.returnAmountWithDecimal,
|
|
44
44
|
amountOut: quote.returnAmountWithDecimal,
|
|
45
|
-
coinTypeIn: options.
|
|
46
|
-
coinTypeOut: options.
|
|
45
|
+
coinTypeIn: options.coinTypeIn,
|
|
46
|
+
coinTypeOut: options.coinTypeOut,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
async swap({ quote, signer, tx, coinIn }) {
|
|
50
|
-
assert(quote.provider === EProvider.
|
|
50
|
+
MetaAgError.assert(quote.provider === EProvider.BLUEFIN7K_LEGACY, "Invalid quote", MetaAgErrorCode.INVALID_QUOTE, { quote, expectedProvider: EProvider.BLUEFIN7K_LEGACY });
|
|
51
51
|
const { coinOut } = await buildTxV2({
|
|
52
52
|
quoteResponse: quote.quote,
|
|
53
53
|
accountAddress: signer,
|
|
@@ -2,7 +2,7 @@ import { AggregatorClient, Env } from "@cetusprotocol/aggregator-sdk";
|
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { _7K_PARTNER_ADDRESS } from "../../../constants/_7k";
|
|
4
4
|
import { EProvider, } from "../../../types/metaAg";
|
|
5
|
-
import {
|
|
5
|
+
import { MetaAgError, MetaAgErrorCode } from "../error";
|
|
6
6
|
export class CetusProvider {
|
|
7
7
|
options;
|
|
8
8
|
kind = EProvider.CETUS;
|
|
@@ -23,8 +23,8 @@ export class CetusProvider {
|
|
|
23
23
|
const quote = await this.cetusClient.findRouters({
|
|
24
24
|
amount: quoteOptions.amountIn,
|
|
25
25
|
byAmountIn: true,
|
|
26
|
-
from: quoteOptions.
|
|
27
|
-
target: quoteOptions.
|
|
26
|
+
from: quoteOptions.coinTypeIn,
|
|
27
|
+
target: quoteOptions.coinTypeOut,
|
|
28
28
|
providers: this.options.sources,
|
|
29
29
|
splitCount: this.options.splitCount,
|
|
30
30
|
splitAlgorithm: this.options.splitAlgorithm,
|
|
@@ -32,7 +32,7 @@ export class CetusProvider {
|
|
|
32
32
|
depth: this.options.depth,
|
|
33
33
|
liquidityChanges: this.options.liquidityChanges,
|
|
34
34
|
});
|
|
35
|
-
assert(!!quote, "No quote found");
|
|
35
|
+
MetaAgError.assert(!!quote, "No quote found", MetaAgErrorCode.QUOTE_NOT_FOUND, { provider: this.kind });
|
|
36
36
|
return {
|
|
37
37
|
id: v4(),
|
|
38
38
|
provider: EProvider.CETUS,
|
|
@@ -40,12 +40,12 @@ export class CetusProvider {
|
|
|
40
40
|
amountIn: quote.amountIn.toString() || "0",
|
|
41
41
|
rawAmountOut: quote.amountOut.toString() || "0",
|
|
42
42
|
amountOut: quote.amountOut.toString() || "0",
|
|
43
|
-
coinTypeIn: quoteOptions.
|
|
44
|
-
coinTypeOut: quoteOptions.
|
|
43
|
+
coinTypeIn: quoteOptions.coinTypeIn,
|
|
44
|
+
coinTypeOut: quoteOptions.coinTypeOut,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
async swap(options) {
|
|
48
|
-
assert(options.quote.provider === EProvider.CETUS, "Expect Cetus quote");
|
|
48
|
+
MetaAgError.assert(options.quote.provider === EProvider.CETUS, "Expect Cetus quote", MetaAgErrorCode.INVALID_QUOTE, { quote: options.quote, expectedProvider: EProvider.CETUS });
|
|
49
49
|
const coinOut = await this.cetusClient.routerSwap({
|
|
50
50
|
inputCoin: options.coinIn,
|
|
51
51
|
router: options.quote.quote,
|
|
@@ -2,7 +2,7 @@ import { AggregatorQuoter, Commission, CommissionType, TradeBuilder, } from "@fl
|
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { _7K_PARTNER_ADDRESS } from "../../../constants/_7k";
|
|
4
4
|
import { EProvider, } from "../../../types/metaAg";
|
|
5
|
-
import {
|
|
5
|
+
import { MetaAgError, MetaAgErrorCode } from "../error";
|
|
6
6
|
export class FlowxProvider {
|
|
7
7
|
options;
|
|
8
8
|
client;
|
|
@@ -16,8 +16,8 @@ export class FlowxProvider {
|
|
|
16
16
|
async quote(quoteOptions) {
|
|
17
17
|
const quote = await this.quoter.getRoutes({
|
|
18
18
|
amountIn: quoteOptions.amountIn,
|
|
19
|
-
tokenIn: quoteOptions.
|
|
20
|
-
tokenOut: quoteOptions.
|
|
19
|
+
tokenIn: quoteOptions.coinTypeIn,
|
|
20
|
+
tokenOut: quoteOptions.coinTypeOut,
|
|
21
21
|
includeSources: this.options.sources,
|
|
22
22
|
excludePools: this.options.excludePools,
|
|
23
23
|
excludeSources: this.options.excludeSources,
|
|
@@ -31,12 +31,12 @@ export class FlowxProvider {
|
|
|
31
31
|
amountIn: quote.amountIn?.toString() ?? "0",
|
|
32
32
|
rawAmountOut: quote.amountOut?.toString() ?? "0",
|
|
33
33
|
amountOut: quote.amountOut?.toString() ?? "0",
|
|
34
|
-
coinTypeIn: quoteOptions.
|
|
35
|
-
coinTypeOut: quoteOptions.
|
|
34
|
+
coinTypeIn: quoteOptions.coinTypeIn,
|
|
35
|
+
coinTypeOut: quoteOptions.coinTypeOut,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
async swap(options) {
|
|
39
|
-
assert(options.quote.provider === EProvider.FLOWX, "Invalid quote");
|
|
39
|
+
MetaAgError.assert(options.quote.provider === EProvider.FLOWX, "Invalid quote", MetaAgErrorCode.INVALID_QUOTE, { quote: options.quote, expectedProvider: EProvider.FLOWX });
|
|
40
40
|
const builder = new TradeBuilder("mainnet", options.quote.quote.routes);
|
|
41
41
|
builder.sender(options.signer);
|
|
42
42
|
builder.slippage(10000 * 100);
|