@7kprotocol/sdk-ts 3.4.0 → 3.4.2-beta.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.
Files changed (65) hide show
  1. package/lib/cjs/features/limitDca/placeLimitOrder.js +8 -3
  2. package/lib/cjs/features/swap/buildTx.js +111 -65
  3. package/lib/cjs/features/swap/buildTxV2.js +227 -0
  4. package/lib/cjs/features/swap/getQuote.js +13 -2
  5. package/lib/cjs/features/swap/index.js +1 -0
  6. package/lib/cjs/index.js +6 -2
  7. package/lib/cjs/types/features/limitDca/placeLimitOrder.d.ts +2 -1
  8. package/lib/cjs/types/features/limitDca/placeLimitOrder.d.ts.map +1 -1
  9. package/lib/cjs/types/features/swap/buildTx.d.ts +14 -1
  10. package/lib/cjs/types/features/swap/buildTx.d.ts.map +1 -1
  11. package/lib/cjs/types/features/swap/buildTxV2.d.ts +20 -0
  12. package/lib/cjs/types/features/swap/buildTxV2.d.ts.map +1 -0
  13. package/lib/cjs/types/features/swap/getQuote.d.ts +4 -1
  14. package/lib/cjs/types/features/swap/getQuote.d.ts.map +1 -1
  15. package/lib/cjs/types/features/swap/index.d.ts +1 -0
  16. package/lib/cjs/types/features/swap/index.d.ts.map +1 -1
  17. package/lib/cjs/types/index.d.ts +4 -2
  18. package/lib/cjs/types/index.d.ts.map +1 -1
  19. package/lib/cjs/types/libs/protocols/base.d.ts +4 -5
  20. package/lib/cjs/types/libs/protocols/base.d.ts.map +1 -1
  21. package/lib/cjs/types/libs/protocols/steamm/index.d.ts +3 -12
  22. package/lib/cjs/types/libs/protocols/steamm/index.d.ts.map +1 -1
  23. package/lib/cjs/types/libs/swapWithRoute.d.ts +3 -4
  24. package/lib/cjs/types/libs/swapWithRoute.d.ts.map +1 -1
  25. package/lib/cjs/types/types/tx.d.ts +13 -0
  26. package/lib/cjs/types/types/tx.d.ts.map +1 -1
  27. package/lib/esm/features/limitDca/placeLimitOrder.js +8 -3
  28. package/lib/esm/features/swap/buildTx.js +105 -65
  29. package/lib/esm/features/swap/buildTxV2.js +221 -0
  30. package/lib/esm/features/swap/getQuote.js +12 -1
  31. package/lib/esm/features/swap/index.js +1 -0
  32. package/lib/esm/index.mjs +12 -10
  33. package/lib/esm/types/features/limitDca/placeLimitOrder.d.ts +2 -1
  34. package/lib/esm/types/features/limitDca/placeLimitOrder.d.ts.map +1 -1
  35. package/lib/esm/types/features/swap/buildTx.d.ts +14 -1
  36. package/lib/esm/types/features/swap/buildTx.d.ts.map +1 -1
  37. package/lib/esm/types/features/swap/buildTxV2.d.ts +20 -0
  38. package/lib/esm/types/features/swap/buildTxV2.d.ts.map +1 -0
  39. package/lib/esm/types/features/swap/getQuote.d.ts +4 -1
  40. package/lib/esm/types/features/swap/getQuote.d.ts.map +1 -1
  41. package/lib/esm/types/features/swap/index.d.ts +1 -0
  42. package/lib/esm/types/features/swap/index.d.ts.map +1 -1
  43. package/lib/esm/types/index.d.ts +4 -2
  44. package/lib/esm/types/index.d.ts.map +1 -1
  45. package/lib/esm/types/libs/protocols/base.d.ts +4 -5
  46. package/lib/esm/types/libs/protocols/base.d.ts.map +1 -1
  47. package/lib/esm/types/libs/protocols/steamm/index.d.ts +3 -12
  48. package/lib/esm/types/libs/protocols/steamm/index.d.ts.map +1 -1
  49. package/lib/esm/types/libs/swapWithRoute.d.ts +3 -4
  50. package/lib/esm/types/libs/swapWithRoute.d.ts.map +1 -1
  51. package/lib/esm/types/types/tx.d.ts +13 -0
  52. package/lib/esm/types/types/tx.d.ts.map +1 -1
  53. package/package.json +3 -3
  54. package/lib/cjs/libs/getCoinOjectIdsByAmount.js +0 -65
  55. package/lib/cjs/libs/getSplitCoinForTx.js +0 -33
  56. package/lib/cjs/types/libs/getCoinOjectIdsByAmount.d.ts +0 -7
  57. package/lib/cjs/types/libs/getCoinOjectIdsByAmount.d.ts.map +0 -1
  58. package/lib/cjs/types/libs/getSplitCoinForTx.d.ts +0 -6
  59. package/lib/cjs/types/libs/getSplitCoinForTx.d.ts.map +0 -1
  60. package/lib/esm/libs/getCoinOjectIdsByAmount.js +0 -61
  61. package/lib/esm/libs/getSplitCoinForTx.js +0 -29
  62. package/lib/esm/types/libs/getCoinOjectIdsByAmount.d.ts +0 -7
  63. package/lib/esm/types/libs/getCoinOjectIdsByAmount.d.ts.map +0 -1
  64. package/lib/esm/types/libs/getSplitCoinForTx.d.ts +0 -6
  65. package/lib/esm/types/libs/getSplitCoinForTx.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"getQuote.d.ts","sourceRoot":"","sources":["../../../../../src/features/swap/getQuote.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,UAAU,MAAM;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;kEAG8D;IAC9D,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,EAuBtC,CAAC;AAEF,wBAAsB,QAAQ,CAAC,EAC7B,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAyB,EACzB,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,GACN,EAAE,MAAM,0BAqCR"}
1
+ {"version":3,"file":"getQuote.d.ts","sourceRoot":"","sources":["../../../../../src/features/swap/getQuote.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,aAAa,EACb,SAAS,EACV,MAAM,wBAAwB,CAAC;AAEhC,UAAU,MAAM;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;kEAG8D;IAC9D,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qHAAqH;IACrH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,EAuBtC,CAAC;AAEF,eAAO,MAAM,oBAAoB,gBAM/B,CAAC;AAEH,wBAAsB,QAAQ,CAAC,EAC7B,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EAAE,QAA0B,EACnC,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,EACL,WAAW,GACZ,EAAE,MAAM,0BAyCR"}
@@ -1,4 +1,5 @@
1
1
  export * from "./buildTx";
2
+ export * from "./buildTxV2";
2
3
  export * from "./estimateGasFee";
3
4
  export * from "./executeTx";
4
5
  export * from "./getQuote";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/swap/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/swap/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -2,11 +2,11 @@ export * from "./types/aggregator";
2
2
  import { Config } from "./config";
3
3
  import { getSuiPrice, getTokenPrice, getTokenPrices } from "./features/prices";
4
4
  import { executeBluefinTx } from "./libs/protocols/bluefinx/client";
5
- import { buildTx, estimateGasFee, executeTx, getQuote, getSwapHistory, DEFAULT_SOURCES } from "./features/swap";
5
+ import { buildTx, buildTxV2, DEFAULT_SOURCES, estimateGasFee, executeTx, getQuote, getSwapHistory, multiSwap } from "./features/swap";
6
6
  import { cancelDcaOrder, cancelLimitOrder, claimExpiredLimitOrder, getClosedDcaOrders, getClosedLimitOrders, getDcaOrderExecutions, getOpenDcaOrders, getOpenLimitOrders, placeDcaOrder, placeLimitOrder } from "./features/limitDca";
7
7
  declare const getSuiClient: () => import("@mysten/sui/dist/cjs/client").SuiClient;
8
8
  declare const setSuiClient: (client: import("@mysten/sui/dist/cjs/client").SuiClient) => void;
9
- export { Config, getSuiClient, setSuiClient, getTokenPrice, getTokenPrices, getSuiPrice, getQuote, estimateGasFee, buildTx, getSwapHistory, executeTx, executeBluefinTx, DEFAULT_SOURCES, placeLimitOrder, getOpenLimitOrders, cancelLimitOrder, claimExpiredLimitOrder, getClosedLimitOrders, placeDcaOrder, getOpenDcaOrders, cancelDcaOrder, getClosedDcaOrders, getDcaOrderExecutions, };
9
+ export { buildTx, buildTxV2, cancelDcaOrder, cancelLimitOrder, claimExpiredLimitOrder, Config, DEFAULT_SOURCES, estimateGasFee, executeBluefinTx, executeTx, getClosedDcaOrders, getClosedLimitOrders, getDcaOrderExecutions, getOpenDcaOrders, getOpenLimitOrders, getQuote, getSuiClient, getSuiPrice, getSwapHistory, getTokenPrice, getTokenPrices, multiSwap, placeDcaOrder, placeLimitOrder, setSuiClient, };
10
10
  declare const _default: {
11
11
  Config: {
12
12
  setApiKey: (key: string) => void;
@@ -28,6 +28,8 @@ declare const _default: {
28
28
  getQuote: typeof getQuote;
29
29
  estimateGasFee: typeof estimateGasFee;
30
30
  buildTx: ({ quoteResponse, accountAddress, slippage, commission: __commission, devInspect, extendTx, isSponsored, }: import("./types/tx").BuildTxParams) => Promise<import("./types/aggregator").BuildTxResult>;
31
+ buildTxV2: ({ quoteResponse, accountAddress, slippage, commission: __commission, devInspect, extendTx, isSponsored, }: import("./types/tx").BuildTxParams) => Promise<import("./types/aggregator").BuildTxResult>;
32
+ multiSwap: ({ sender, slippageBps, swaps, tx, commission, }: import("./types/tx").MultiSwapParams) => Promise<Record<string, import("@mysten/sui/dist/cjs/transactions").TransactionObjectArgument>>;
31
33
  getSwapHistory: typeof getSwapHistory;
32
34
  executeTx: (tx: import("./types/aggregator").AggregatorTx, signature: string, signedTxBytes: string, options?: import("@mysten/sui/dist/cjs/client").SuiTransactionBlockResponseOptions) => Promise<import("@mysten/sui/dist/cjs/client").SuiTransactionBlockResponse>;
33
35
  executeBluefinTx: (tx: import("./types/aggregator").BluefinXTx, signature: string) => Promise<import("./libs/protocols/bluefinx/types").SwapResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AAEnC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEpE,OAAO,EACL,OAAO,EACP,cAAc,EACd,SAAS,EACT,QAAQ,EACR,cAAc,EACd,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAG7B,QAAA,MAAM,YAAY,uDAAsB,CAAC;AACzC,QAAA,MAAM,YAAY,mEAAsB,CAAC;AAEzC,OAAO,EAEL,MAAM,EAGN,YAAY,EACZ,YAAY,EAGZ,aAAa,EACb,cAAc,EACd,WAAW,EAGX,QAAQ,EACR,cAAc,EACd,OAAO,EACP,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,eAAe,EAGf,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EAGpB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,GACtB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEF,wBAmCE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AAEnC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEpE,OAAO,EACL,OAAO,EACP,SAAS,EACT,eAAe,EACf,cAAc,EACd,SAAS,EACT,QAAQ,EACR,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAG7B,QAAA,MAAM,YAAY,uDAAsB,CAAC;AACzC,QAAA,MAAM,YAAY,mEAAsB,CAAC;AAEzC,OAAO,EACL,OAAO,EACP,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EAEtB,MAAM,EACN,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAElB,QAAQ,EAER,YAAY,EACZ,WAAW,EACX,cAAc,EAEd,aAAa,EACb,cAAc,EACd,SAAS,EAET,aAAa,EAEb,eAAe,EACf,YAAY,GACb,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEF,wBAqCE"}
@@ -1,9 +1,8 @@
1
- import { Transaction } from "@mysten/sui/transactions";
1
+ import { Transaction, TransactionObjectArgument } from "@mysten/sui/transactions";
2
2
  import { Config, ExtraOracle, TxSorSwap } from "../../types/aggregator";
3
- import { TransactionResultItem } from "../../types/sui";
4
3
  export interface BaseContractParams {
5
4
  swapInfo: TxSorSwap;
6
- inputCoinObject: TransactionResultItem;
5
+ inputCoinObject: TransactionObjectArgument;
7
6
  currentAccount: string;
8
7
  config: Config;
9
8
  /** map price feed id to onchain priceInfoObject id */
@@ -11,12 +10,12 @@ export interface BaseContractParams {
11
10
  }
12
11
  export declare abstract class BaseContract<T = any> {
13
12
  protected swapInfo: TxSorSwap;
14
- protected inputCoinObject: TransactionResultItem;
13
+ protected inputCoinObject: TransactionObjectArgument;
15
14
  protected currentAccount: string;
16
15
  protected config: Config;
17
16
  protected pythMap: Record<string, string>;
18
17
  constructor({ swapInfo, inputCoinObject, currentAccount, config, pythMap, }: BaseContractParams);
19
- abstract swap(tx: Transaction): Promise<TransactionResultItem>;
18
+ abstract swap(tx: Transaction): Promise<TransactionObjectArgument>;
20
19
  protected getInputCoinValue(tx: Transaction): import("@mysten/sui/transactions").TransactionArgument;
21
20
  protected getTypeParams(): string[];
22
21
  protected get extra(): NonNullable<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../../src/libs/protocols/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,eAAe,EAAE,qBAAqB,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,8BAAsB,YAAY,CAAC,CAAC,GAAG,GAAG;IACxC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,SAAS,CAAC,eAAe,EAAE,qBAAqB,CAAC;IACjD,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAE9B,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACd,MAAM,EACN,OAAO,GACR,EAAE,kBAAkB;IAQrB,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAE9D,SAAS,CAAC,iBAAiB,CAAC,EAAE,EAAE,WAAW;IAQ3C,SAAS,CAAC,aAAa;IAMvB,SAAS,KAAK,KAAK,mBAMlB;IAED,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW;CAclD"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../../src/libs/protocols/base.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGxE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,eAAe,EAAE,yBAAyB,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,8BAAsB,YAAY,CAAC,CAAC,GAAG,GAAG;IACxC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,SAAS,CAAC,eAAe,EAAE,yBAAyB,CAAC;IACrD,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAE9B,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACd,MAAM,EACN,OAAO,GACR,EAAE,kBAAkB;IAQrB,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAElE,SAAS,CAAC,iBAAiB,CAAC,EAAE,EAAE,WAAW;IAQ3C,SAAS,CAAC,aAAa;IAMvB,SAAS,KAAK,KAAK,mBAMlB;IAED,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW;CAclD"}
@@ -14,18 +14,9 @@ export type SteamExtra = {
14
14
  oracleIndexes?: number[];
15
15
  };
16
16
  export declare class SteammContract extends BaseContract<SteamExtra> {
17
- swap(tx: Transaction): Promise<{
18
- $kind: "NestedResult";
19
- NestedResult: [number, number];
20
- }>;
21
- cpmmSwap(tx: Transaction): {
22
- $kind: "NestedResult";
23
- NestedResult: [number, number];
24
- };
25
- ommSwap(tx: Transaction, version: "v1" | "v2"): {
26
- $kind: "NestedResult";
27
- NestedResult: [number, number];
28
- };
17
+ swap(tx: Transaction): Promise<import("@mysten/sui/transactions").TransactionObjectArgument>;
18
+ cpmmSwap(tx: Transaction): import("@mysten/sui/transactions").TransactionObjectArgument;
19
+ ommSwap(tx: Transaction, version: "v1" | "v2"): import("@mysten/sui/transactions").TransactionObjectArgument;
29
20
  getOraclePriceUpdate(tx: Transaction): readonly [{
30
21
  $kind: "NestedResult";
31
22
  NestedResult: [number, number];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/libs/protocols/steamm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAMvD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,MAAM,UAAU,GAAG;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AACF,qBAAa,cAAe,SAAQ,YAAY,CAAC,UAAU,CAAC;IACpD,IAAI,CAAC,EAAE,EAAE,WAAW;;;;IAW1B,QAAQ,CAAC,EAAE,EAAE,WAAW;;;;IAmExB,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,GAAG,IAAI;;;;IAuE7C,oBAAoB,CAAC,EAAE,EAAE,WAAW;;;;;;;CA8BrC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/libs/protocols/steamm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAMvD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,MAAM,UAAU,GAAG;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AACF,qBAAa,cAAe,SAAQ,YAAY,CAAC,UAAU,CAAC;IACpD,IAAI,CAAC,EAAE,EAAE,WAAW;IAW1B,QAAQ,CAAC,EAAE,EAAE,WAAW;IAmExB,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,GAAG,IAAI;IAuE7C,oBAAoB,CAAC,EAAE,EAAE,WAAW;;;;;;;CA8BrC"}
@@ -1,13 +1,12 @@
1
- import { Transaction } from "@mysten/sui/transactions";
1
+ import { Transaction, TransactionObjectArgument } from "@mysten/sui/transactions";
2
2
  import { Config, TxSorSwap } from "../types/aggregator";
3
- import { TransactionResultItem } from "../types/sui";
4
3
  export declare function swapWithRoute({ route, inputCoinObject, currentAccount, config, pythMap, tx, }: {
5
4
  route: TxSorSwap[];
6
- inputCoinObject: TransactionResultItem;
5
+ inputCoinObject: TransactionObjectArgument;
7
6
  currentAccount: string;
8
7
  config: Config;
9
8
  /** map price feed id to onchain priceInfoObject id */
10
9
  pythMap: Record<string, string>;
11
10
  tx: Transaction;
12
- }): Promise<TransactionResultItem | undefined>;
11
+ }): Promise<TransactionObjectArgument | undefined>;
13
12
  //# sourceMappingURL=swapWithRoute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"swapWithRoute.d.ts","sourceRoot":"","sources":["../../../../src/libs/swapWithRoute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,wBAAsB,aAAa,CAAC,EAClC,KAAK,EACL,eAAe,EACf,cAAc,EACd,MAAM,EACN,OAAO,EACP,EAAE,GACH,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,eAAe,EAAE,qBAAqB,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,EAAE,EAAE,WAAW,CAAC;CACjB,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAmB7C"}
1
+ {"version":3,"file":"swapWithRoute.d.ts","sourceRoot":"","sources":["../../../../src/libs/swapWithRoute.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGxD,wBAAsB,aAAa,CAAC,EAClC,KAAK,EACL,eAAe,EACf,cAAc,EACd,MAAM,EACN,OAAO,EACP,EAAE,GACH,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,eAAe,EAAE,yBAAyB,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,EAAE,EAAE,WAAW,CAAC;CACjB,GAAG,OAAO,CAAC,yBAAyB,GAAG,SAAS,CAAC,CAmBjD"}
@@ -51,4 +51,17 @@ export interface EstimateGasFeeParams extends CommonParams {
51
51
  /** Sui price in usd for gas estimation */
52
52
  suiPrice?: number;
53
53
  }
54
+ export interface SwapInfo {
55
+ quote: QuoteResponse;
56
+ /** @warning this `coinIn` will be consumed completely, no `coinIn` left, user must pass the coinIn object with the balance required for the swap - ie in quote */
57
+ coinIn: TransactionObjectArgument;
58
+ }
59
+ export interface MultiSwapParams {
60
+ swaps: SwapInfo[];
61
+ sender: string;
62
+ slippageBps: number;
63
+ tx: Transaction;
64
+ /** Commission for partner */
65
+ commission: Commission;
66
+ }
54
67
  //# sourceMappingURL=tx.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../../../src/types/tx.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,mBAAmB;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,WAAW,CAAC;QAChB,MAAM,CAAC,EAAE,yBAAyB,CAAC;KACpC,CAAC;IACF;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,gCAAgC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../../../src/types/tx.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,mBAAmB;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,WAAW,CAAC;QAChB,MAAM,CAAC,EAAE,yBAAyB,CAAC;KACpC,CAAC;IACF;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,gCAAgC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,kKAAkK;IAClK,MAAM,EAAE,yBAAyB,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,WAAW,CAAC;IAChB,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAC;CACxB"}
@@ -1,8 +1,12 @@
1
- import { getSplitCoinForTx } from "../../libs/getSplitCoinForTx";
2
- import { denormalizeTokenType } from "../../utils/token";
1
+ import { coinWithBalance, Transaction } from "@mysten/sui/transactions";
3
2
  import { GLOBAL_CONFIG_ID, LIMIT_ORDER_MODULE_ID } from "./constants";
4
3
  export async function placeLimitOrder({ accountAddress, payCoinType, targetCoinType, payCoinAmount, rate, slippage, expireTs, devInspect, }) {
5
- const { tx, coinData: payCoin } = await getSplitCoinForTx(accountAddress, payCoinAmount.toString(), [payCoinAmount.toString()], denormalizeTokenType(payCoinType), undefined, devInspect);
4
+ const tx = new Transaction();
5
+ const payCoin = tx.add(coinWithBalance({
6
+ type: payCoinType,
7
+ balance: payCoinAmount,
8
+ useGasCoin: !devInspect,
9
+ }));
6
10
  tx.moveCall({
7
11
  target: `${LIMIT_ORDER_MODULE_ID}::place_limit_order`,
8
12
  arguments: [
@@ -15,5 +19,6 @@ export async function placeLimitOrder({ accountAddress, payCoinType, targetCoinT
15
19
  ],
16
20
  typeArguments: [payCoinType, targetCoinType],
17
21
  });
22
+ tx.setSenderIfNotSet(accountAddress);
18
23
  return tx;
19
24
  }
@@ -1,16 +1,15 @@
1
- import { Transaction, } from "@mysten/sui/transactions";
1
+ import { coinWithBalance, Transaction, } from "@mysten/sui/transactions";
2
2
  import { isValidSuiAddress, toBase64, toHex } from "@mysten/sui/utils";
3
3
  import { Config } from "../../config";
4
4
  import { _7K_CONFIG, _7K_PACKAGE_ID, _7K_VAULT } from "../../constants/_7k";
5
- import { getSplitCoinForTx } from "../../libs/getSplitCoinForTx";
6
5
  import { groupSwapRoutes } from "../../libs/groupSwapRoutes";
7
6
  import { sponsorBluefinX } from "../../libs/protocols/bluefinx/client";
8
7
  import { BluefinXTx } from "../../libs/protocols/bluefinx/types";
9
8
  import { swapWithRoute } from "../../libs/swapWithRoute";
10
9
  import { isBluefinXRouting, } from "../../types/aggregator";
11
10
  import { SuiUtils } from "../../utils/sui";
12
- import { denormalizeTokenType } from "../../utils/token";
13
11
  import { getConfig } from "./config";
12
+ import { ORACLE_BASED_SOURCES } from "./getQuote";
14
13
  export const buildTx = async ({ quoteResponse, accountAddress, slippage, commission: __commission, devInspect, extendTx, isSponsored, }) => {
15
14
  const isBluefinX = isBluefinXRouting(quoteResponse);
16
15
  const _commission = {
@@ -18,7 +17,7 @@ export const buildTx = async ({ quoteResponse, accountAddress, slippage, commiss
18
17
  // commission is ignored for bluefinx
19
18
  commissionBps: isBluefinX ? 0 : __commission.commissionBps,
20
19
  };
21
- const { tx: _tx, coinIn } = extendTx || {};
20
+ const { tx: _tx, coinIn: _coinIn } = extendTx || {};
22
21
  let coinOut;
23
22
  if (isBluefinX && devInspect) {
24
23
  throw new Error("BluefinX tx is sponsored, skip devInspect");
@@ -34,17 +33,17 @@ export const buildTx = async ({ quoteResponse, accountAddress, slippage, commiss
34
33
  }
35
34
  const tx = _tx || new Transaction();
36
35
  const routes = groupSwapRoutes(quoteResponse);
36
+ validateRoutes(routes, isSponsored);
37
37
  const splits = routes.map((group) => group[0]?.amount ?? "0");
38
- let coinData;
39
- if (coinIn) {
40
- coinData = tx.splitCoins(coinIn, splits);
41
- SuiUtils.transferOrDestroyZeroCoin(tx, quoteResponse.tokenIn, coinIn, accountAddress);
42
- }
43
- else {
44
- const { coinData: _data } = await getSplitCoinForTx(accountAddress, quoteResponse.swapAmountWithDecimal, splits, denormalizeTokenType(quoteResponse.tokenIn), tx, devInspect, isSponsored || isBluefinX);
45
- coinData = _data;
46
- }
47
- const pythMap = await updatePythPriceFeedsIfAny(tx, quoteResponse);
38
+ const coinIn = _coinIn ||
39
+ tx.add(coinWithBalance({
40
+ type: quoteResponse.tokenIn,
41
+ balance: BigInt(quoteResponse.swapAmountWithDecimal),
42
+ useGasCoin: !isSponsored && !isBluefinX,
43
+ }));
44
+ const coinData = tx.splitCoins(coinIn, splits);
45
+ SuiUtils.transferOrDestroyZeroCoin(tx, quoteResponse.tokenIn, coinIn, accountAddress);
46
+ const pythMap = await updatePythPriceFeedsIfAny(tx, [quoteResponse]);
48
47
  const coinObjects = [];
49
48
  const config = await getConfig();
50
49
  await Promise.all(routes.map(async (route, index) => {
@@ -62,75 +61,38 @@ export const buildTx = async ({ quoteResponse, accountAddress, slippage, commiss
62
61
  }
63
62
  }));
64
63
  if (coinObjects.length > 0) {
65
- const mergeCoin = coinObjects.length > 1
66
- ? SuiUtils.mergeCoins(coinObjects, tx)
67
- : coinObjects[0];
68
- const returnAmountAfterCommission = (BigInt(10000 - _commission.commissionBps) *
69
- BigInt(quoteResponse.returnAmountWithDecimal)) /
70
- BigInt(10000);
71
- const minReceived = (BigInt(1e9 - +slippage * 1e9) * BigInt(returnAmountAfterCommission)) /
72
- BigInt(1e9);
73
- tx.moveCall({
74
- target: `${_7K_PACKAGE_ID}::settle::settle`,
75
- typeArguments: [quoteResponse.tokenIn, quoteResponse.tokenOut],
76
- arguments: [
77
- tx.object(_7K_CONFIG),
78
- tx.object(_7K_VAULT),
79
- tx.pure.u64(quoteResponse.swapAmountWithDecimal),
80
- mergeCoin,
81
- tx.pure.u64(minReceived), // minimum received
82
- tx.pure.u64(returnAmountAfterCommission), // expected amount out
83
- tx.pure.option("address", isValidSuiAddress(_commission.partner) ? _commission.partner : null),
84
- tx.pure.u64(_commission.commissionBps),
85
- tx.pure.u64(0),
86
- ],
87
- });
64
+ const mergedCoin = tx.add(settle(coinObjects, quoteResponse, Math.floor(+slippage * 10000), _commission));
88
65
  if (!extendTx) {
89
- tx.transferObjects([mergeCoin], tx.pure.address(accountAddress));
66
+ tx.transferObjects([mergedCoin], tx.pure.address(accountAddress));
90
67
  }
91
68
  else {
92
- coinOut = mergeCoin;
69
+ coinOut = mergedCoin;
93
70
  }
94
71
  }
95
72
  if (isBluefinX) {
96
- const extra = quoteResponse.swaps[0].extra;
97
- if (extra.quoteExpiresAtUtcMillis < Date.now()) {
98
- throw new Error("Quote expired");
99
- }
100
- tx.setSenderIfNotSet(accountAddress);
101
- const bytes = await tx.build({
102
- client: Config.getSuiClient(),
103
- onlyTransactionKind: true,
104
- });
105
- const res = await sponsorBluefinX({
106
- quoteId: extra.quoteId,
107
- txBytes: toBase64(bytes),
108
- sender: accountAddress,
109
- });
110
- if (!res.success) {
111
- throw new Error("Sponsor failed");
112
- }
113
73
  return {
114
- tx: new BluefinXTx(res.quoteId, res.data.txBytes),
74
+ tx: await buildBluefinXTx(tx, accountAddress, quoteResponse),
115
75
  coinOut,
116
76
  };
117
77
  }
78
+ tx.setSenderIfNotSet(accountAddress);
118
79
  return { tx, coinOut };
119
80
  };
120
- const getPythPriceFeeds = (res) => {
81
+ export const getPythPriceFeeds = (responses) => {
121
82
  const ids = new Set();
122
- for (const s of res.swaps) {
123
- for (const o of (s.extra?.oracles || [])) {
124
- // FIXME: deprecation price_identifier in the next version
125
- const bytes = o.Pyth?.bytes || o.Pyth?.price_identifier?.bytes;
126
- if (bytes) {
127
- ids.add("0x" + toHex(Uint8Array.from(bytes)));
83
+ for (const res of responses) {
84
+ for (const s of res.swaps) {
85
+ for (const o of s.extra?.oracles || []) {
86
+ const bytes = o.Pyth?.price_identifier?.bytes || o.Pyth?.bytes;
87
+ if (bytes) {
88
+ ids.add("0x" + toHex(Uint8Array.from(bytes)));
89
+ }
128
90
  }
129
91
  }
130
92
  }
131
93
  return Array.from(ids);
132
94
  };
133
- const updatePythPriceFeedsIfAny = async (tx, quoteResponse) => {
95
+ export const updatePythPriceFeedsIfAny = async (tx, quoteResponse) => {
134
96
  // update oracles price if any
135
97
  const pythMap = {};
136
98
  const pythIds = getPythPriceFeeds(quoteResponse);
@@ -143,3 +105,81 @@ const updatePythPriceFeedsIfAny = async (tx, quoteResponse) => {
143
105
  }
144
106
  return pythMap;
145
107
  };
108
+ export const validateRoutes = (routes, isSponsored) => {
109
+ if (!isSponsored) {
110
+ return;
111
+ }
112
+ const hasOracleBasedSource = routes.some((g) => g.some((s) => ORACLE_BASED_SOURCES.has(s.pool.type)));
113
+ if (hasOracleBasedSource) {
114
+ throw new Error("Oracle based sources are not supported for sponsored tx");
115
+ }
116
+ };
117
+ export const getExpectedReturn = (returnAmount, slippageBps, commissionBps, tipBps = 0) => {
118
+ if (slippageBps > 10000) {
119
+ throw new Error("Slippage must be less than 100%");
120
+ }
121
+ if (commissionBps > 10000) {
122
+ throw new Error("Commission must be less than 100%");
123
+ }
124
+ if (tipBps > 10000) {
125
+ throw new Error("Tip must be less than 100%");
126
+ }
127
+ const returnAmountWithDecimal = BigInt(returnAmount);
128
+ const tipAmountWithDecimal = (returnAmountWithDecimal * BigInt(tipBps || 0)) / 10000n;
129
+ const commissionAmountWithDecimal = ((returnAmountWithDecimal - tipAmountWithDecimal) * BigInt(commissionBps)) /
130
+ 10000n;
131
+ const expectedReturnWithDecimal = returnAmountWithDecimal -
132
+ tipAmountWithDecimal -
133
+ commissionAmountWithDecimal;
134
+ const minAmountWithDecimal = (expectedReturnWithDecimal * BigInt(1e4 - slippageBps)) / 10000n;
135
+ return {
136
+ tipAmount: tipAmountWithDecimal,
137
+ minAmount: minAmountWithDecimal,
138
+ commissionAmount: commissionAmountWithDecimal,
139
+ expectedAmount: expectedReturnWithDecimal.toString(10),
140
+ };
141
+ };
142
+ export const settle = (coinObjects, quoteResponse, slippageBps, _commission) => {
143
+ return (tx) => {
144
+ const mergeCoin = coinObjects.length > 1
145
+ ? (tx.mergeCoins(coinObjects[0], coinObjects.slice(1)), coinObjects[0])
146
+ : coinObjects[0];
147
+ const { minAmount, expectedAmount } = getExpectedReturn(quoteResponse.returnAmountWithDecimal, slippageBps, _commission.commissionBps);
148
+ tx.moveCall({
149
+ target: `${_7K_PACKAGE_ID}::settle::settle`,
150
+ typeArguments: [quoteResponse.tokenIn, quoteResponse.tokenOut],
151
+ arguments: [
152
+ tx.object(_7K_CONFIG),
153
+ tx.object(_7K_VAULT),
154
+ tx.pure.u64(quoteResponse.swapAmountWithDecimal),
155
+ mergeCoin,
156
+ tx.pure.u64(minAmount), // minimum received
157
+ tx.pure.u64(expectedAmount), // expected amount out
158
+ tx.pure.option("address", isValidSuiAddress(_commission.partner) ? _commission.partner : null),
159
+ tx.pure.u64(_commission.commissionBps),
160
+ tx.pure.u64(0),
161
+ ],
162
+ });
163
+ return mergeCoin;
164
+ };
165
+ };
166
+ export const buildBluefinXTx = async (tx, accountAddress, quoteResponse) => {
167
+ const extra = quoteResponse.swaps[0].extra;
168
+ if (extra.quoteExpiresAtUtcMillis < Date.now()) {
169
+ throw new Error("Quote expired");
170
+ }
171
+ tx.setSenderIfNotSet(accountAddress);
172
+ const bytes = await tx.build({
173
+ client: Config.getSuiClient(),
174
+ onlyTransactionKind: true,
175
+ });
176
+ const res = await sponsorBluefinX({
177
+ quoteId: extra.quoteId,
178
+ txBytes: toBase64(bytes),
179
+ sender: accountAddress,
180
+ });
181
+ if (!res.success) {
182
+ throw new Error("Sponsor failed");
183
+ }
184
+ return new BluefinXTx(res.quoteId, res.data.txBytes);
185
+ };
@@ -0,0 +1,221 @@
1
+ import { coinWithBalance, Transaction, } from "@mysten/sui/transactions";
2
+ import { isValidSuiAddress, normalizeStructTag } from "@mysten/sui/utils";
3
+ import { groupSwapRoutes } from "../../libs/groupSwapRoutes";
4
+ import { swapWithRoute } from "../../libs/swapWithRoute";
5
+ import { isBluefinXRouting, } from "../../types/aggregator";
6
+ import { SuiUtils } from "../../utils/sui";
7
+ import { buildBluefinXTx, settle, updatePythPriceFeedsIfAny, validateRoutes, } from "./buildTx";
8
+ import { getConfig } from "./config";
9
+ /**
10
+ * Wave-based transaction builder that optimizes swap execution by:
11
+ * 1. Grouping swaps into execution waves based on readiness
12
+ * 2. Merging redundant swaps to the same pool within each wave
13
+ * 3. Processing waves sequentially, passing intermediate tokens between waves
14
+ */
15
+ export const buildTxV2 = async ({ quoteResponse, accountAddress, slippage, commission: __commission, devInspect, extendTx, isSponsored, }) => {
16
+ const isBluefinX = isBluefinXRouting(quoteResponse);
17
+ const _commission = {
18
+ ...__commission,
19
+ commissionBps: isBluefinX ? 0 : __commission.commissionBps,
20
+ };
21
+ const { tx: _tx, coinIn: _coinIn } = extendTx || {};
22
+ let coinOut;
23
+ if (isBluefinX && devInspect) {
24
+ throw new Error("BluefinX tx is sponsored, skip devInspect");
25
+ }
26
+ if (!accountAddress) {
27
+ throw new Error("Sender address is required");
28
+ }
29
+ if (!quoteResponse.routes) {
30
+ throw new Error("Invalid quote response: 'routes' are required");
31
+ }
32
+ if (!isValidSuiAddress(_commission.partner)) {
33
+ throw new Error("Invalid commission partner address");
34
+ }
35
+ const tx = _tx || new Transaction();
36
+ const routes = groupSwapRoutes(quoteResponse);
37
+ validateRoutes(routes, isSponsored);
38
+ const splits = routes.map((group) => group[0]?.amount ?? "0");
39
+ const coinIn = _coinIn ||
40
+ tx.add(coinWithBalance({
41
+ type: quoteResponse.tokenIn,
42
+ balance: BigInt(quoteResponse.swapAmountWithDecimal),
43
+ useGasCoin: !isSponsored && !isBluefinX,
44
+ }));
45
+ const coinData = tx.splitCoins(coinIn, splits);
46
+ SuiUtils.transferOrDestroyZeroCoin(tx, quoteResponse.tokenIn, coinIn, accountAddress);
47
+ const pythMap = await updatePythPriceFeedsIfAny(tx, [quoteResponse]);
48
+ const config = await getConfig();
49
+ const finalCoins = await optimize(pythMap, config, routes, coinData, tx, accountAddress);
50
+ // Merge all final coins
51
+ if (finalCoins.length > 0) {
52
+ let mergeCoin = tx.add(settle(finalCoins, quoteResponse, Math.floor(+slippage * 10000), _commission));
53
+ if (!extendTx) {
54
+ tx.transferObjects([mergeCoin], tx.pure.address(accountAddress));
55
+ }
56
+ else {
57
+ coinOut = mergeCoin;
58
+ }
59
+ }
60
+ if (isBluefinX) {
61
+ return {
62
+ tx: await buildBluefinXTx(tx, accountAddress, quoteResponse),
63
+ coinOut,
64
+ };
65
+ }
66
+ tx.setSenderIfNotSet(accountAddress);
67
+ return { tx, coinOut };
68
+ };
69
+ export const optimize = async (pythMap, config, routes, coinData, tx, accountAddress) => {
70
+ // Initialize route states with split coins
71
+ const routeStates = routes.map((route, index) => ({
72
+ routeIndex: index,
73
+ currentHopIndex: 0,
74
+ currentCoin: coinData[index],
75
+ swaps: route,
76
+ completed: false,
77
+ }));
78
+ const finalCoins = [];
79
+ const coinTypeOut = routes[0][routes[0].length - 1].assetOut;
80
+ // Execute swaps in waves
81
+ let waveNumber = 0;
82
+ while (true) {
83
+ const readyHops = [];
84
+ routeStates.forEach((state) => {
85
+ if (state.completed)
86
+ return;
87
+ if (state.currentHopIndex >= state.swaps.length) {
88
+ state.completed = true;
89
+ finalCoins.push(state.currentCoin);
90
+ return;
91
+ }
92
+ const swap = state.swaps[state.currentHopIndex];
93
+ readyHops.push({
94
+ routeIndex: state.routeIndex,
95
+ hopIndex: state.currentHopIndex,
96
+ swap,
97
+ inputCoin: state.currentCoin,
98
+ });
99
+ });
100
+ if (readyHops.length === 0)
101
+ break;
102
+ // Group hops by pool for merging opportunities
103
+ const poolGroups = new Map();
104
+ readyHops.forEach((hop) => {
105
+ const poolKey = `${hop.swap.poolId}|${hop.swap.assetIn}|${hop.swap.assetOut}`;
106
+ if (!poolGroups.has(poolKey)) {
107
+ poolGroups.set(poolKey, {
108
+ swap: hop.swap,
109
+ hops: [],
110
+ });
111
+ }
112
+ poolGroups.get(poolKey).hops.push(hop);
113
+ });
114
+ // Execute each pool group in this wave
115
+ const wavePromises = [];
116
+ for (const group of poolGroups.values()) {
117
+ const { swap, hops } = group;
118
+ // For merged swaps, we need to combine input coins first
119
+ const wavePromise = (async () => {
120
+ let combinedCoin;
121
+ if (hops.length > 1) {
122
+ // Merge all input coins for this pool
123
+ const inputCoins = hops.map((h) => h.inputCoin);
124
+ tx.mergeCoins(inputCoins[0], inputCoins.slice(1));
125
+ combinedCoin = inputCoins[0];
126
+ }
127
+ else {
128
+ combinedCoin = hops[0].inputCoin;
129
+ }
130
+ // Execute the swap with the combined coin
131
+ const resultCoin = await swapWithRoute({
132
+ route: [swap],
133
+ inputCoinObject: combinedCoin,
134
+ currentAccount: accountAddress,
135
+ tx,
136
+ config,
137
+ pythMap,
138
+ });
139
+ if (!resultCoin) {
140
+ throw new Error(`Swap failed for pool ${swap.poolId}`);
141
+ }
142
+ if (hops[0].swap.assetOut === coinTypeOut) {
143
+ finalCoins.push(resultCoin);
144
+ hops.forEach((hop) => {
145
+ const state = routeStates[hop.routeIndex];
146
+ state.completed = true;
147
+ state.currentHopIndex++;
148
+ });
149
+ return;
150
+ }
151
+ // For merged swaps, we need to split the output proportionally
152
+ if (hops.length > 1) {
153
+ // Split output proportionally (except the last one which gets the remainder)
154
+ const splitAmounts = hops
155
+ .slice(1)
156
+ .map((hop) => hop.swap.returnAmount);
157
+ const splitCoins = splitAmounts.length > 0
158
+ ? [resultCoin, ...tx.splitCoins(resultCoin, splitAmounts)]
159
+ : [resultCoin];
160
+ // Assign split coins back to routes
161
+ hops.forEach((hop, index) => {
162
+ const state = routeStates[hop.routeIndex];
163
+ state.currentCoin = splitCoins[index];
164
+ state.currentHopIndex++;
165
+ });
166
+ }
167
+ else {
168
+ // Single swap - simply update the route state
169
+ const state = routeStates[hops[0].routeIndex];
170
+ state.currentCoin = resultCoin;
171
+ state.currentHopIndex++;
172
+ }
173
+ })();
174
+ wavePromises.push(wavePromise);
175
+ }
176
+ // Wait for all swaps in this wave to complete
177
+ await Promise.all(wavePromises);
178
+ waveNumber++;
179
+ }
180
+ return finalCoins;
181
+ };
182
+ /**
183
+ * execute multiple swap in single transaction
184
+ *
185
+ * User must handle the coins from return
186
+ * @param param - MultiSwapParams
187
+ * @returns a map of coinType to coinObject
188
+ */
189
+ export const multiSwap = async ({ sender, slippageBps, swaps, tx, commission, }) => {
190
+ if (swaps.some((s) => isBluefinXRouting(s.quote))) {
191
+ throw Error("BluefinX routing not supported yet");
192
+ }
193
+ // update oracles price if any
194
+ const pythMap = await updatePythPriceFeedsIfAny(tx, swaps.map((s) => s.quote));
195
+ const map = {};
196
+ const config = await getConfig();
197
+ for (const { quote: sorResponse, coinIn } of swaps) {
198
+ const routes = groupSwapRoutes(sorResponse);
199
+ const splits = routes.map((group) => group[0]?.amount ?? "0");
200
+ const coinData = splits.length === 1
201
+ ? [coinIn]
202
+ : [coinIn, ...tx.splitCoins(coinIn, splits.slice(1))];
203
+ const coinObjects = await optimize(pythMap, config, routes, coinData, tx, sender);
204
+ if (coinObjects.length > 0) {
205
+ const mergeCoin = tx.add(settle(coinObjects, sorResponse, slippageBps, commission));
206
+ if (!map[normalizeStructTag(sorResponse.tokenOut)]) {
207
+ map[normalizeStructTag(sorResponse.tokenOut)] = [];
208
+ }
209
+ map[normalizeStructTag(sorResponse.tokenOut)].push(mergeCoin);
210
+ }
211
+ }
212
+ const result = {};
213
+ for (const [tokenOut, coins] of Object.entries(map)) {
214
+ if (coins.length > 1) {
215
+ tx.mergeCoins(coins[0], coins.slice(1));
216
+ }
217
+ result[tokenOut] = coins[0];
218
+ }
219
+ tx.setSenderIfNotSet(sender);
220
+ return result;
221
+ };