@tradeport/sui-trading-sdk 0.4.39 → 0.4.40

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 (34) hide show
  1. package/dist/index.d.mts +19 -2
  2. package/dist/index.d.ts +19 -2
  3. package/dist/index.js +310 -160
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +270 -130
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +7 -4
  8. package/src/SuiTradingClient.ts +18 -4
  9. package/src/helpers/kiosk/getKioskIdFromKioskTx.ts +1 -1
  10. package/src/helpers/kiosk/kioskTxWrapper.ts +3 -3
  11. package/src/helpers/kiosk/lockNftInsideKioskIfNotLocked.ts +1 -1
  12. package/src/helpers/kiosk/resolveRoyaltyRule.ts +5 -0
  13. package/src/helpers/kiosk/resolveTransferPolicies.ts +3 -0
  14. package/src/helpers/kiosk/takeLockedNftFromKiosk.ts +12 -4
  15. package/src/helpers/swap/swap.ts +147 -0
  16. package/src/methods/acceptCollectionBid/acceptCollectionBid.ts +1 -1
  17. package/src/methods/acceptNftBids/acceptNftBids.ts +1 -1
  18. package/src/methods/buyListings/addBuyListingTxs.ts +5 -0
  19. package/src/methods/buyListings/buyListings.ts +20 -7
  20. package/src/methods/cancelNftTransfers/cancelNftTransfers.ts +1 -1
  21. package/src/methods/claimNfts/claimNfts.ts +1 -1
  22. package/src/methods/createMultiBid/createMultiBid.ts +6 -7
  23. package/src/methods/listNfts/listNfts.ts +1 -1
  24. package/src/methods/migrateNftsFromUnsharedToSharedKiosks/migrateNftsFromUnsharedToSharedKiosks.ts +1 -1
  25. package/src/methods/placeCollectionBids/placeCollectionBids.ts +28 -8
  26. package/src/methods/placeNftBids/addPlaceNftBidTxs.ts +8 -7
  27. package/src/methods/placeNftBids/placeNftBids.ts +27 -8
  28. package/src/methods/removeCollectionBids/removeCollectionBids.ts +1 -1
  29. package/src/methods/removeNftBids/removeNftBids.ts +1 -1
  30. package/src/methods/transferNfts/transferNfts.ts +1 -1
  31. package/src/methods/unlistListings/unlistListings.ts +1 -2
  32. package/src/methods/updateMultiBid/updateMultiBid.ts +35 -4
  33. package/src/methods/withdrawProfitsFromKiosks/withdrawProfitsFromKiosks.ts +3 -3
  34. package/src/helpers/extractSwapResultCoin.ts +0 -17
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tradeport/sui-trading-sdk",
3
3
  "license": "MIT",
4
- "version": "0.4.39",
4
+ "version": "0.4.40",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -10,6 +10,7 @@
10
10
  "@babel/preset-env": "^7.23.3",
11
11
  "@changesets/cli": "^2.26.2",
12
12
  "@types/jest": "^29.5.10",
13
+ "@types/ms": "^2.1.0",
13
14
  "@types/node": "^20.10.0",
14
15
  "@typescript-eslint/eslint-plugin": "^6.13.1",
15
16
  "@typescript-eslint/parser": "^6.13.1",
@@ -27,12 +28,14 @@
27
28
  "typescript": "^5.3.2"
28
29
  },
29
30
  "dependencies": {
30
- "@mysten/kiosk": "^0.7.13",
31
- "@mysten/sui": "^1.17.0",
31
+ "@flowx-finance/sdk": "^1.13.5",
32
+ "@mysten/kiosk": "^0.12.26",
33
+ "@mysten/sui": "^1.39.1",
32
34
  "@mysten/sui.js": "^0.47.0",
33
35
  "@types/analytics-node": "^3.1.14",
34
36
  "analytics-node": "^6.2.0",
35
- "graphql-request": "^6.1.0"
37
+ "graphql-request": "^6.1.0",
38
+ "ms": "^2.1.3"
36
39
  },
37
40
  "publishConfig": {
38
41
  "access": "public",
@@ -105,7 +105,12 @@ class SuiTradingClient {
105
105
  // trackMethodCall({ apiUser, apiKey, event: 'INITIALIZE_CLIENT' });
106
106
  }
107
107
 
108
- public async buyListings({ listingIds, walletAddress, tx }: BuyListings): Promise<Transaction> {
108
+ public async buyListings({
109
+ listingIds,
110
+ walletAddress,
111
+ tx,
112
+ swapAndPayOptions,
113
+ }: BuyListings): Promise<Transaction> {
109
114
  const context: RequestContext = {
110
115
  apiUser: this.apiUser,
111
116
  apiKey: this.apiKey,
@@ -113,7 +118,7 @@ class SuiTradingClient {
113
118
  kioskClient: this.kioskClient,
114
119
  };
115
120
 
116
- return buyListings({ listingIds, walletAddress, tx }, context);
121
+ return buyListings({ listingIds, walletAddress, tx, swapAndPayOptions }, context);
117
122
  }
118
123
 
119
124
  public async listNfts({ nfts, walletAddress }: ListNfts) {
@@ -180,6 +185,7 @@ class SuiTradingClient {
180
185
  multiBidChainId,
181
186
  expireAt,
182
187
  tx,
188
+ swapAndPayOptions,
183
189
  }: PlaceCollectionBid): Promise<Transaction> {
184
190
  const context: RequestContext = {
185
191
  apiUser: this.apiUser,
@@ -202,6 +208,7 @@ class SuiTradingClient {
202
208
  multiBidId,
203
209
  multiBidChainId,
204
210
  tx,
211
+ swapAndPayOptions,
205
212
  },
206
213
  context,
207
214
  );
@@ -474,7 +481,14 @@ class SuiTradingClient {
474
481
  }
475
482
 
476
483
  public async createMultiBid(args: CreateMultiBid) {
477
- return createMultiBid(args);
484
+ const context: RequestContext = {
485
+ apiUser: this.apiUser,
486
+ apiKey: this.apiKey,
487
+ suiClient: this.suiClient,
488
+ kioskClient: this.kioskClient,
489
+ };
490
+
491
+ return createMultiBid(args, context);
478
492
  }
479
493
 
480
494
  public async cancelMultiBid(args: CancelMultiBid) {
@@ -482,7 +496,7 @@ class SuiTradingClient {
482
496
  }
483
497
 
484
498
  public async updateMultiBid(args: UpdateMultiBid) {
485
- return updateMultiBid(args);
499
+ return updateMultiBid({ ...args, suiClient: this.suiClient });
486
500
  }
487
501
  }
488
502
 
@@ -17,5 +17,5 @@ export const getKioskIdFromKioskTx = ({
17
17
  throw new Error('Invalid kiosk transaction structure');
18
18
  })();
19
19
 
20
- return kioskId;
20
+ return kioskId as string;
21
21
  };
@@ -105,7 +105,7 @@ export const kioskTxWrapper = async ({
105
105
  })
106
106
  ).personalCap.id;
107
107
  kioskTx = new KioskTransaction({
108
- transactionBlock: tx as any,
108
+ transaction: tx as any,
109
109
  kioskClient,
110
110
  cap: {
111
111
  isPersonal: true,
@@ -124,7 +124,7 @@ export const kioskTxWrapper = async ({
124
124
  })
125
125
  ).ownerCap?.id;
126
126
  kioskTx = new KioskTransaction({
127
- transactionBlock: tx as any,
127
+ transaction: tx as any,
128
128
  kioskClient,
129
129
  cap: {
130
130
  isPersonal: false,
@@ -136,7 +136,7 @@ export const kioskTxWrapper = async ({
136
136
  });
137
137
  } else {
138
138
  // creating new personal kiosk
139
- kioskTx = new KioskTransaction({ transactionBlock: tx as any, kioskClient });
139
+ kioskTx = new KioskTransaction({ transaction: tx as any, kioskClient });
140
140
  kioskTx.createPersonal(true);
141
141
  }
142
142
 
@@ -54,7 +54,7 @@ export const lockNftInsideKioskIfNotLocked = async ({
54
54
  }
55
55
 
56
56
  kioskTx.lock({
57
- itemId: takenNftId ?? nftTokenId,
57
+ item: (takenNftId as string) ?? nftTokenId,
58
58
  itemType: nftType,
59
59
  policy: transferPolicyId,
60
60
  });
@@ -4,6 +4,7 @@ import {
4
4
  type TransactionArgument,
5
5
  type TransactionObjectInput,
6
6
  } from '@mysten/sui/transactions';
7
+ import { mergeSwapCoinWithSuiBalance } from '../swap/swap';
7
8
  import { getKioskCollectionRoyaltyFeeAmount } from './getKioskCollectionRoyaltyFeeAmount';
8
9
 
9
10
  type Args = {
@@ -18,6 +19,7 @@ type Args = {
18
19
  price: string;
19
20
  coinToSplit?: any;
20
21
  royaltyFeeAmount?: bigint;
22
+ amountToSplitFromSuiBalance?: bigint;
21
23
  };
22
24
 
23
25
  export async function resolveRoyaltyRule({
@@ -32,6 +34,7 @@ export async function resolveRoyaltyRule({
32
34
  price,
33
35
  coinToSplit,
34
36
  royaltyFeeAmount,
37
+ amountToSplitFromSuiBalance,
35
38
  }: Args) {
36
39
  let feeAmount: bigint | TransactionArgument | undefined = royaltyFeeAmount;
37
40
  if (!feeAmount) {
@@ -47,6 +50,8 @@ export async function resolveRoyaltyRule({
47
50
  });
48
51
  }
49
52
 
53
+ mergeSwapCoinWithSuiBalance(tx, coinToSplit, amountToSplitFromSuiBalance);
54
+
50
55
  const feeCoin = tx.splitCoins(coinToSplit ? coinToSplit : tx.gas, [feeAmount]);
51
56
 
52
57
  tx.moveCall({
@@ -37,6 +37,7 @@ type Props = {
37
37
  beforeResolveKioskTransferRequest?: (transferRequest: any) => void | Promise<void>;
38
38
  transferPoliciesToResolve?: any[];
39
39
  royaltyFeeAmount?: bigint;
40
+ amountToSplitFromSuiBalance?: bigint;
40
41
  };
41
42
 
42
43
  export const resolveTransferPolicies = async ({
@@ -58,6 +59,7 @@ export const resolveTransferPolicies = async ({
58
59
  beforeResolveKioskTransferRequest,
59
60
  transferPoliciesToResolve,
60
61
  royaltyFeeAmount,
62
+ amountToSplitFromSuiBalance,
61
63
  }: Props) => {
62
64
  const policies =
63
65
  transferPoliciesToResolve ??
@@ -111,6 +113,7 @@ export const resolveTransferPolicies = async ({
111
113
  price,
112
114
  coinToSplit,
113
115
  royaltyFeeAmount,
116
+ amountToSplitFromSuiBalance,
114
117
  });
115
118
  break;
116
119
  case 'floor_price_rule':
@@ -1,6 +1,6 @@
1
1
  import { type KioskClient, type KioskTransaction, type TransferPolicy } from '@mysten/kiosk';
2
2
  import { type SuiClient } from '@mysten/sui/client';
3
- import { type Transaction } from '@mysten/sui/transactions';
3
+ import { type Transaction, type TransactionObjectInput } from '@mysten/sui/transactions';
4
4
  import { getNativeKioskTransferPolicies } from './getNativeKioskTransferPolicies';
5
5
  import { resolveTransferPolicies } from './resolveTransferPolicies';
6
6
 
@@ -36,8 +36,14 @@ export const takeLockedNftFromKiosk = async ({
36
36
  const [purchase_cap] = tx.moveCall({
37
37
  target: '0x2::kiosk::list_with_purchase_cap',
38
38
  arguments: [
39
- tx.object('value' in kioskTx.kiosk ? kioskTx.kiosk.value : kioskTx.kiosk),
40
- tx.object('value' in kioskTx.kioskCap ? kioskTx.kioskCap.value : kioskTx.kioskCap),
39
+ tx.object(
40
+ ('value' in kioskTx.kiosk ? kioskTx.kiosk.value : kioskTx.kiosk) as TransactionObjectInput,
41
+ ),
42
+ tx.object(
43
+ ('value' in kioskTx.kioskCap
44
+ ? kioskTx.kioskCap.value
45
+ : kioskTx.kioskCap) as TransactionObjectInput,
46
+ ),
41
47
  tx.pure.address(nftTokenId),
42
48
  tx.pure.u64(0),
43
49
  ],
@@ -53,7 +59,9 @@ export const takeLockedNftFromKiosk = async ({
53
59
  const [nft, transferRequest] = tx.moveCall({
54
60
  target: '0x2::kiosk::purchase_with_cap',
55
61
  arguments: [
56
- tx.object('value' in kioskTx.kiosk ? kioskTx.kiosk.value : kioskTx.kiosk),
62
+ tx.object(
63
+ ('value' in kioskTx.kiosk ? kioskTx.kiosk.value : kioskTx.kiosk) as TransactionObjectInput,
64
+ ),
57
65
  purchase_cap,
58
66
  zeroCoin,
59
67
  ],
@@ -0,0 +1,147 @@
1
+ import { AggregatorQuoter, Protocol, TradeBuilder } from '@flowx-finance/sdk';
2
+ import { type SuiClient } from '@mysten/sui/client';
3
+ import { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';
4
+ import { normalizeStructTag, normalizeSuiAddress } from '@mysten/sui/utils';
5
+ import ms, { type StringValue } from 'ms';
6
+
7
+ const aggregatorQuoter = new AggregatorQuoter('mainnet');
8
+
9
+ const suiCointType = '0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI';
10
+
11
+ export interface SwapAndPayOptions {
12
+ coinType?: string;
13
+ coinAmount?: string;
14
+ slippage?: number;
15
+ ttl?: StringValue;
16
+ excludeSources?: Protocol[];
17
+ amountToSplitFromSuiBalance?: string;
18
+ }
19
+
20
+ export async function createBuyTransaction(
21
+ client: SuiClient,
22
+ walletAddress: string,
23
+ suiAmount: bigint,
24
+ options?: {
25
+ transaction: Transaction;
26
+ coinType?: string;
27
+ coinAmount?: bigint;
28
+ slippage?: number;
29
+ ttl?: StringValue;
30
+ excludeSources?: Protocol[];
31
+ },
32
+ ): Promise<{
33
+ transaction: Transaction;
34
+ suiCoin: TransactionObjectArgument;
35
+ }> {
36
+ const transaction = options?.transaction ?? new Transaction();
37
+ transaction.setSender(normalizeSuiAddress(walletAddress));
38
+ const {
39
+ coinType,
40
+ coinAmount = 0n,
41
+ slippage = 1,
42
+ ttl = '15m',
43
+ excludeSources = [Protocol.STEAMM],
44
+ } = options ?? {};
45
+ if (!coinType || normalizeStructTag(coinType) === suiCointType) {
46
+ const [coin] = transaction.splitCoins(transaction.gas, [suiAmount]);
47
+ return {
48
+ transaction,
49
+ suiCoin: coin,
50
+ };
51
+ }
52
+
53
+ const { routes } = await aggregatorQuoter.getRoutes({
54
+ tokenIn: coinType,
55
+ tokenOut: suiCointType,
56
+ amountIn: coinAmount.toString(),
57
+ excludeSources,
58
+ });
59
+
60
+ const tradeBuilder = new TradeBuilder('mainnet', routes);
61
+
62
+ const trade = tradeBuilder
63
+ .sender(normalizeSuiAddress(walletAddress))
64
+ .slippage(slippage)
65
+ .deadline(Date.now() + ms(ttl))
66
+ .build();
67
+
68
+ const swappedSuiCoin = await trade.swap({
69
+ client: client as any,
70
+ tx: transaction as any,
71
+ });
72
+
73
+ if (!swappedSuiCoin) {
74
+ throw new Error('Swap did not return a valid SUI coin.');
75
+ }
76
+
77
+ return { transaction, suiCoin: swappedSuiCoin };
78
+ }
79
+
80
+ /**
81
+ * Handles swap setup for transactions that need to convert tokens to SUI
82
+ * @returns Updated transaction and the swapped coin (if swap was needed)
83
+ */
84
+ export async function handleSwapSetup(
85
+ client: SuiClient,
86
+ walletAddress: string,
87
+ transaction: Transaction,
88
+ swapAndPayOptions?: SwapAndPayOptions,
89
+ ): Promise<{
90
+ transaction: Transaction;
91
+ swapResultCoin?: TransactionObjectArgument;
92
+ }> {
93
+ if (!swapAndPayOptions?.coinType || !swapAndPayOptions?.coinAmount) {
94
+ return { transaction };
95
+ }
96
+
97
+ const { transaction: updatedTx, suiCoin } = await createBuyTransaction(
98
+ client,
99
+ walletAddress,
100
+ BigInt(swapAndPayOptions.coinAmount),
101
+ {
102
+ transaction,
103
+ coinType: swapAndPayOptions.coinType,
104
+ coinAmount: BigInt(swapAndPayOptions.coinAmount),
105
+ slippage: swapAndPayOptions.slippage,
106
+ ttl: swapAndPayOptions.ttl,
107
+ excludeSources: swapAndPayOptions.excludeSources,
108
+ },
109
+ );
110
+
111
+ return {
112
+ transaction: updatedTx,
113
+ swapResultCoin: suiCoin,
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Handles cleanup after swap by transferring remaining coins back to wallet
119
+ */
120
+ export function handleSwapCleanup(
121
+ transaction: Transaction,
122
+ swapResultCoin: TransactionObjectArgument | undefined,
123
+ walletAddress: string,
124
+ ): void {
125
+ if (swapResultCoin) {
126
+ transaction.transferObjects([swapResultCoin], walletAddress);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Merges a coin with an amount split from the gas balance
132
+ * @param transaction - The transaction to add the split and merge operations to
133
+ * @param coinToMergeInto - The coin to merge the gas balance into (optional)
134
+ * @param amountToSplitFromGas - The amount to split from the gas balance
135
+ */
136
+ export function mergeSwapCoinWithSuiBalance(
137
+ transaction: Transaction,
138
+ coinToMergeInto: TransactionObjectArgument | undefined,
139
+ amountToSplitFromGas: bigint | undefined,
140
+ ): void {
141
+ if (coinToMergeInto && amountToSplitFromGas && amountToSplitFromGas > 0n) {
142
+ const [coinFromSuiBalance] = transaction.splitCoins(transaction.gas, [
143
+ transaction.pure.u64(amountToSplitFromGas),
144
+ ]);
145
+ transaction.mergeCoins(coinToMergeInto, [coinFromSuiBalance]);
146
+ }
147
+ }
@@ -185,5 +185,5 @@ export const acceptCollectionBid = async (
185
185
  // });
186
186
  // }
187
187
 
188
- return Transaction.from(tx);
188
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
189
189
  };
@@ -170,5 +170,5 @@ export const acceptNftBids = async (
170
170
  // });
171
171
  // }
172
172
 
173
- return Transaction.from(tx);
173
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
174
174
  };
@@ -29,6 +29,7 @@ import { confirmOBTranfer } from '../../helpers/originByte/confirmOBTranfer';
29
29
  import { getOrCreateOBKiosk } from '../../helpers/originByte/getOrCreateOBKiosk';
30
30
  import { isOriginByteCollection } from '../../helpers/originByte/isOriginByteCollection';
31
31
  import { shareOriginByteKiosk } from '../../helpers/originByte/shareOriginByteKiosk';
32
+ import { mergeSwapCoinWithSuiBalance } from '../../helpers/swap/swap';
32
33
  import { addLeadingZerosAfter0x } from '../../utils/addLeadingZerosAfter0x';
33
34
  import { type BuyTx, type TocenBuyTx } from './buyListings';
34
35
 
@@ -89,6 +90,7 @@ export const addTradeportKioskBuyTx = async ({
89
90
  beforeResolveKioskTransferRequest,
90
91
  sharedBulkBuyingDataByNftType,
91
92
  collectionId,
93
+ amountToSplitFromSuiBalance,
92
94
  }: BuyTx) => {
93
95
  let commissionFeeAmount: number =
94
96
  sharedBulkBuyingDataByNftType?.[nftType]?.commissionFeeAmountsByListingId?.[listingId] ?? 0;
@@ -111,6 +113,8 @@ export const addTradeportKioskBuyTx = async ({
111
113
  commissionFeeAmount = getMarketFeePrice({ price, collectionId });
112
114
  }
113
115
 
116
+ mergeSwapCoinWithSuiBalance(tx, coinToSplit, amountToSplitFromSuiBalance);
117
+
114
118
  const coin = tx.splitCoins(coinToSplit ? coinToSplit : tx.gas, [
115
119
  tx.pure.u64(price + commissionFeeAmount),
116
120
  ]);
@@ -146,6 +150,7 @@ export const addTradeportKioskBuyTx = async ({
146
150
  transferPoliciesToResolve: sharedBulkBuyingDataByNftType?.[nftType]?.transferPoliciesToResolve,
147
151
  royaltyFeeAmount:
148
152
  sharedBulkBuyingDataByNftType?.[nftType]?.royaltyFeeAmountsByListingId?.[listingId],
153
+ amountToSplitFromSuiBalance,
149
154
  });
150
155
 
151
156
  destroyZeroCoin({ tx, coin });
@@ -10,13 +10,17 @@ import { gqlChainRequest } from '../../graphql/gqlChainRequest';
10
10
  import { fetchListingsById } from '../../graphql/queries/fetchListingsById';
11
11
  import { addThirdPartyTxFee } from '../../helpers/addThirdPartyTxFee';
12
12
  import { deserializeOrCreateTxBlock } from '../../helpers/deserializeOrCreateTxBlock';
13
- import { extractSwapResultCoinFromTxBlock } from '../../helpers/extractSwapResultCoin';
14
13
  import { getNftType } from '../../helpers/getNftType';
15
14
  import {
16
15
  preProcessSharedBulkBuyingData,
17
16
  type SharedBulkBuyingDataByNftType,
18
17
  } from '../../helpers/kiosk/preProcessSharedBulkBuyingData';
19
18
  import { type SharedKioskState } from '../../helpers/kiosk/sharedKioskState.type';
19
+ import {
20
+ handleSwapCleanup,
21
+ handleSwapSetup,
22
+ type SwapAndPayOptions,
23
+ } from '../../helpers/swap/swap';
20
24
  import {
21
25
  addBluemoveBuyTxHandler,
22
26
  addClutchyBuyTxHandler,
@@ -49,6 +53,7 @@ type BuyTxBase = {
49
53
  remainingAccountBalance?: number;
50
54
  royalty?: number;
51
55
  sharedBulkBuyingDataByNftType?: SharedBulkBuyingDataByNftType;
56
+ amountToSplitFromSuiBalance?: bigint;
52
57
  };
53
58
 
54
59
  type NormalBuyTx = {
@@ -77,6 +82,7 @@ export type BuyListings = {
77
82
  tx?: Transaction | string;
78
83
  kioskTx?: KioskTransaction;
79
84
  coinToSplit?: any;
85
+ swapAndPayOptions?: SwapAndPayOptions;
80
86
  beforeResolveKioskTransferRequest?: (transferRequest: any) => void | Promise<void>;
81
87
  };
82
88
 
@@ -88,6 +94,7 @@ export const buyListings = async (
88
94
  kioskTx,
89
95
  coinToSplit,
90
96
  beforeResolveKioskTransferRequest,
97
+ swapAndPayOptions,
91
98
  }: BuyListings,
92
99
  context: RequestContext,
93
100
  marketFeeDecimalPercent?: number,
@@ -103,8 +110,15 @@ export const buyListings = async (
103
110
  }
104
111
 
105
112
  const listingsForTracking = [];
106
- const tx = deserializeOrCreateTxBlock({ existingTx });
107
- const swapResultCoin = extractSwapResultCoinFromTxBlock(tx);
113
+ let tx = deserializeOrCreateTxBlock({ existingTx });
114
+
115
+ const { transaction: updatedTx, swapResultCoin } = await handleSwapSetup(
116
+ context.suiClient,
117
+ walletAddress,
118
+ tx,
119
+ swapAndPayOptions,
120
+ );
121
+ tx = updatedTx;
108
122
 
109
123
  const tocenTokenIds: string[] = [];
110
124
  let tocenNftType = '';
@@ -162,6 +176,7 @@ export const buyListings = async (
162
176
  beforeResolveKioskTransferRequest,
163
177
  sharedKioskState,
164
178
  sharedBulkBuyingDataByNftType,
179
+ amountToSplitFromSuiBalance: BigInt(swapAndPayOptions?.amountToSplitFromSuiBalance ?? 0n),
165
180
  };
166
181
 
167
182
  switch (listing?.market_name) {
@@ -211,9 +226,7 @@ export const buyListings = async (
211
226
 
212
227
  sharedKioskState?.kioskTx?.finalize();
213
228
 
214
- if (swapResultCoin) {
215
- tx.transferObjects([swapResultCoin], walletAddress);
216
- }
229
+ handleSwapCleanup(tx, swapResultCoin, walletAddress);
217
230
 
218
231
  if (tocenTokenIds?.length > 0) {
219
232
  addTocenBuyTxHandler({
@@ -233,5 +246,5 @@ export const buyListings = async (
233
246
  // });
234
247
  // }
235
248
 
236
- return Transaction.from(tx);
249
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
237
250
  };
@@ -114,5 +114,5 @@ export const cancelNftTransfers = async (
114
114
  // });
115
115
  // }
116
116
 
117
- return Transaction.from(tx);
117
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
118
118
  };
@@ -266,5 +266,5 @@ export const claimNfts = async (
266
266
  // });
267
267
  // }
268
268
 
269
- return Transaction.from(tx);
269
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
270
270
  };
@@ -1,8 +1,8 @@
1
1
  import { type Transaction } from '@mysten/sui/transactions';
2
2
  import { TRADEPORT_MULTI_BID_PACKAGE, TRADEPORT_MULTI_BID_STORE } from '../../constants';
3
3
  import { deserializeOrCreateTxBlock } from '../../helpers/deserializeOrCreateTxBlock';
4
+ import { type RequestContext } from '../../SuiTradingClient';
4
5
  import { updateMultiBid } from '../updateMultiBid/updateMultiBid';
5
-
6
6
  export interface CreateMultiBid {
7
7
  walletAddress: string;
8
8
  name?: string;
@@ -10,12 +10,10 @@ export interface CreateMultiBid {
10
10
  tx?: Transaction | string;
11
11
  }
12
12
 
13
- export async function createMultiBid({
14
- walletAddress,
15
- name,
16
- amount,
17
- tx: existingTx,
18
- }: CreateMultiBid): Promise<{ multiBidChainId: any; tx: Transaction }> {
13
+ export async function createMultiBid(
14
+ { walletAddress, name, amount, tx: existingTx }: CreateMultiBid,
15
+ context: RequestContext,
16
+ ): Promise<{ multiBidChainId: any; tx: Transaction }> {
19
17
  const tx = deserializeOrCreateTxBlock({ existingTx });
20
18
 
21
19
  const multiBidChainId = tx.moveCall({
@@ -30,6 +28,7 @@ export async function createMultiBid({
30
28
  amount,
31
29
  name,
32
30
  tx,
31
+ suiClient: context.suiClient,
33
32
  });
34
33
  }
35
34
 
@@ -138,5 +138,5 @@ export const listNfts = async (
138
138
  // });
139
139
  // }
140
140
 
141
- return Transaction.from(tx);
141
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
142
142
  };
@@ -222,5 +222,5 @@ export async function migrateNftsFromUnsharedToSharedKiosks(
222
222
 
223
223
  sharedKioskState?.kioskTx?.finalize();
224
224
 
225
- return Transaction.from(tx);
225
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
226
226
  }
@@ -6,12 +6,16 @@ import { ORIGIN_BYTE_NFT_TYPES_MISSING_ORDERBOOK } from '../../constants';
6
6
  import { gqlChainRequest } from '../../graphql/gqlChainRequest';
7
7
  import { fetchCollectionsByIdWithOneNft } from '../../graphql/queries/fetchCollectionsById';
8
8
  import { deserializeOrCreateTxBlock } from '../../helpers/deserializeOrCreateTxBlock';
9
- import { extractSwapResultCoinFromTxBlock } from '../../helpers/extractSwapResultCoin';
10
9
  import { getNftType } from '../../helpers/getNftType';
11
10
  import { getSharedObjects } from '../../helpers/getSharedObjects';
12
11
  import { getOrCreateOBKiosk } from '../../helpers/originByte/getOrCreateOBKiosk';
13
12
  import { isOriginByteCollection } from '../../helpers/originByte/isOriginByteCollection';
14
13
  import { shareOriginByteKiosk } from '../../helpers/originByte/shareOriginByteKiosk';
14
+ import {
15
+ handleSwapCleanup,
16
+ handleSwapSetup,
17
+ type SwapAndPayOptions,
18
+ } from '../../helpers/swap/swap';
15
19
  import { normalizedNftType } from '../../utils/normalizeNftType';
16
20
  import { addTradePortPlaceNftBidTxHandler } from '../placeNftBids/addPlaceNftBidTxs';
17
21
  import { addOriginByteCollectionBidTx } from './addPlaceCollectionBidTxs';
@@ -33,6 +37,7 @@ export type PlaceCollectionBidTx = {
33
37
  multiBidChainId?: any;
34
38
  expireAt?: Date;
35
39
  coinToSplit?: any;
40
+ amountToSplitFromSuiBalance?: bigint;
36
41
  };
37
42
 
38
43
  export type PlaceCollectionBid = {
@@ -44,6 +49,7 @@ export type PlaceCollectionBid = {
44
49
  multiBidChainId?: any;
45
50
  expireAt?: Date;
46
51
  tx?: Transaction | string;
52
+ swapAndPayOptions?: SwapAndPayOptions;
47
53
  };
48
54
 
49
55
  export type PlaceCollectionBids = {
@@ -57,10 +63,18 @@ export type PlaceCollectionBids = {
57
63
  multiBidId?: string;
58
64
  multiBidChainId?: any;
59
65
  tx?: Transaction | string;
66
+ swapAndPayOptions?: SwapAndPayOptions;
60
67
  };
61
68
 
62
69
  export const placeCollectionBids = async (
63
- { collections, walletAddress, multiBidId, multiBidChainId, tx: existingTx }: PlaceCollectionBids,
70
+ {
71
+ collections,
72
+ walletAddress,
73
+ multiBidId,
74
+ multiBidChainId,
75
+ tx: existingTx,
76
+ swapAndPayOptions,
77
+ }: PlaceCollectionBids,
64
78
  context: RequestContext,
65
79
  ): Promise<Transaction> => {
66
80
  const res = await gqlChainRequest({
@@ -74,8 +88,15 @@ export const placeCollectionBids = async (
74
88
  }
75
89
 
76
90
  const collectionsForTracking = [];
77
- const tx = deserializeOrCreateTxBlock({ existingTx });
78
- const swapResultCoin = extractSwapResultCoinFromTxBlock(tx);
91
+ let tx = deserializeOrCreateTxBlock({ existingTx });
92
+
93
+ const { transaction: updatedTx, swapResultCoin } = await handleSwapSetup(
94
+ context.suiClient,
95
+ walletAddress,
96
+ tx,
97
+ swapAndPayOptions,
98
+ );
99
+ tx = updatedTx;
79
100
 
80
101
  for (const collection of res.collections) {
81
102
  const nftType = getNftType({
@@ -99,6 +120,7 @@ export const placeCollectionBids = async (
99
120
  multiBidChainId,
100
121
  expireAt: collections?.find((c) => c.id === collection?.id)?.expireAt,
101
122
  coinToSplit: swapResultCoin,
123
+ amountToSplitFromSuiBalance: BigInt(swapAndPayOptions?.amountToSplitFromSuiBalance ?? 0n),
102
124
  };
103
125
 
104
126
  const numOfBids = collections?.find((c) => c.id === collection?.id)?.numOfBids;
@@ -135,9 +157,7 @@ export const placeCollectionBids = async (
135
157
  });
136
158
  }
137
159
 
138
- if (swapResultCoin) {
139
- tx.transferObjects([swapResultCoin], walletAddress);
140
- }
160
+ handleSwapCleanup(tx, swapResultCoin, walletAddress);
141
161
 
142
162
  // if (process.env.ENABLE_SEGMENT_TRACKING === 'true' && collectionsForTracking.length > 0) {
143
163
  // trackMethodCall({
@@ -148,5 +168,5 @@ export const placeCollectionBids = async (
148
168
  // });
149
169
  // }
150
170
 
151
- return Transaction.from(tx);
171
+ return tx instanceof Transaction ? tx : Transaction.from(tx);
152
172
  };