@tradeport/sui-trading-sdk 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/.babel.config.js +3 -0
  2. package/.claude/settings.json +5 -0
  3. package/.claude/settings.local.json +5 -0
  4. package/.env.demo +5 -0
  5. package/.eslintrc.json +46 -0
  6. package/.prettierignore +4 -0
  7. package/.prettierrc.json +7 -0
  8. package/.vscode/launch.json +23 -0
  9. package/CHANGELOG.md +746 -0
  10. package/jest.config.js +12 -0
  11. package/package.json +66 -71
  12. package/src/SuiTradingClient.ts +442 -0
  13. package/src/apiClients/createKioskClient.ts +10 -0
  14. package/src/apiClients/createSuiClient.ts +5 -0
  15. package/src/apiClients/graphqlClient.ts +17 -0
  16. package/src/bigNumberConfig.ts +10 -0
  17. package/src/constants.ts +1052 -0
  18. package/src/graphql/createChainGQLQuery.ts +27 -0
  19. package/src/graphql/gqlChainRequest.ts +21 -0
  20. package/src/graphql/queries/fetchAccountKiosks.ts +12 -0
  21. package/src/graphql/queries/fetchActiveLockStateByNftId.ts +15 -0
  22. package/src/graphql/queries/fetchBidsById.ts +36 -0
  23. package/src/graphql/queries/fetchCollectionBidById.ts +21 -0
  24. package/src/graphql/queries/fetchCollectionBidsAtSamePrice.ts +29 -0
  25. package/src/graphql/queries/fetchCollectionChainState.ts +17 -0
  26. package/src/graphql/queries/fetchCollectionFloorListingForMarket.ts +28 -0
  27. package/src/graphql/queries/fetchCollectionFloorListings.ts +15 -0
  28. package/src/graphql/queries/fetchCollectionsById.ts +39 -0
  29. package/src/graphql/queries/fetchCommissionByListingId.ts +13 -0
  30. package/src/graphql/queries/fetchCryptoToUsdRate.ts +13 -0
  31. package/src/graphql/queries/fetchKiosksByOwner.ts +14 -0
  32. package/src/graphql/queries/fetchListingsById.ts +29 -0
  33. package/src/graphql/queries/fetchListingsByNftId.ts +23 -0
  34. package/src/graphql/queries/fetchLockById.ts +23 -0
  35. package/src/graphql/queries/fetchMultibidById.ts +34 -0
  36. package/src/graphql/queries/fetchNftCollectionChainState.ts +12 -0
  37. package/src/graphql/queries/fetchNftsById.ts +75 -0
  38. package/src/graphql/queries/fetchNftsByKioskId.ts +45 -0
  39. package/src/graphql/queries/fetchOwnerCapByKiosk.ts +10 -0
  40. package/src/graphql/queries/fetchPersonalCapByKiosk.ts +10 -0
  41. package/src/graphql/queries/fetchSharedObjectsByType.ts +12 -0
  42. package/src/graphql/queries/fetchTransferPoliciesByType.ts +12 -0
  43. package/src/graphql/queries/fetchWalletKiosks.ts +14 -0
  44. package/src/graphql/queries/getCommissionByListingId.ts +15 -0
  45. package/src/helpers/addOneDollarFee.ts +17 -0
  46. package/src/helpers/addThirdPartyTxFee.ts +17 -0
  47. package/src/helpers/calculatePremium.ts +9 -0
  48. package/src/helpers/calculateRoyaltyFee.ts +28 -0
  49. package/src/helpers/destroyZeroCoin.ts +14 -0
  50. package/src/helpers/getActiveLockStateByNftId.ts +15 -0
  51. package/src/helpers/getCollectionChainState.ts +31 -0
  52. package/src/helpers/getCollectionFloorPrice.ts +12 -0
  53. package/src/helpers/getLockById.ts +29 -0
  54. package/src/helpers/getMarketFeePrice.ts +82 -0
  55. package/src/helpers/getNftType.ts +38 -0
  56. package/src/helpers/getRoyaltyRuleModule.ts +7 -0
  57. package/src/helpers/getSharedObjects.ts +119 -0
  58. package/src/helpers/getSuiToUsdRate.ts +14 -0
  59. package/src/helpers/getTradeportBiddingContractBidAmount.ts +31 -0
  60. package/src/helpers/getTransferPolicyRuleNamesFromSuiObject.ts +24 -0
  61. package/src/helpers/hasPersonalKioskRule.ts +7 -0
  62. package/src/helpers/hasRoyaltyRule.ts +7 -0
  63. package/src/helpers/hasTransferPolicyRules.ts +6 -0
  64. package/src/helpers/isExpiredListing.ts +9 -0
  65. package/src/helpers/isNonKioskListing.ts +14 -0
  66. package/src/helpers/isSIngleBid.ts +13 -0
  67. package/src/helpers/kiosk/assertNftInSharedKiosk.ts +31 -0
  68. package/src/helpers/kiosk/getKioskCollectionRoyaltyFeeAmount.ts +71 -0
  69. package/src/helpers/kiosk/getKioskIdFromKioskTx.ts +29 -0
  70. package/src/helpers/kiosk/getKioskPlaceBidCoin.ts +59 -0
  71. package/src/helpers/kiosk/getNativeKioskTransferPolicies.ts +29 -0
  72. package/src/helpers/kiosk/getNativeKioskTransferPoliciesByNftType.ts +21 -0
  73. package/src/helpers/kiosk/getRulePackageId.ts +59 -0
  74. package/src/helpers/kiosk/getTransferPoliciesToResolve.ts +154 -0
  75. package/src/helpers/kiosk/isBluemoveKioskBid.ts +1 -0
  76. package/src/helpers/kiosk/isTradePortKioskBid.ts +4 -0
  77. package/src/helpers/kiosk/kioskListingBcs.ts +19 -0
  78. package/src/helpers/kiosk/kioskTxWrapper.ts +152 -0
  79. package/src/helpers/kiosk/lockNftInsideKioskIfNotLocked.ts +100 -0
  80. package/src/helpers/kiosk/preProcessSharedBulkBuyingData.ts +171 -0
  81. package/src/helpers/kiosk/resolveCustomTransferPolicyRules.ts +75 -0
  82. package/src/helpers/kiosk/resolveFloorPriceRule.ts +21 -0
  83. package/src/helpers/kiosk/resolveKioskLockRule.ts +47 -0
  84. package/src/helpers/kiosk/resolvePersonalKioskRule.ts +23 -0
  85. package/src/helpers/kiosk/resolveRoyaltyRule.ts +57 -0
  86. package/src/helpers/kiosk/resolveTableAllowlistRule.ts +34 -0
  87. package/src/helpers/kiosk/resolveTransferPolicies.ts +158 -0
  88. package/src/helpers/kiosk/sharedKioskState.type.ts +11 -0
  89. package/src/helpers/kiosk/takeAndBorrowNftFromKiosk.ts +50 -0
  90. package/src/helpers/kiosk/takeLockedNftFromKiosk.ts +73 -0
  91. package/src/helpers/kiosk/upgradeKioskRulesPackageId.ts +17 -0
  92. package/src/helpers/originByte/confirmOBTranfer.ts +33 -0
  93. package/src/helpers/originByte/createOBKiosk.ts +14 -0
  94. package/src/helpers/originByte/depositNftIntoOBKiosk.ts +16 -0
  95. package/src/helpers/originByte/getOBBidderKiosk.ts +12 -0
  96. package/src/helpers/originByte/getOBKiosk.ts +24 -0
  97. package/src/helpers/originByte/getOrCreateOBKiosk.ts +42 -0
  98. package/src/helpers/originByte/isOBKiosk.ts +13 -0
  99. package/src/helpers/originByte/isOriginByteBid.ts +30 -0
  100. package/src/helpers/originByte/isOriginByteCollection.ts +11 -0
  101. package/src/helpers/originByte/shareOriginByteKiosk.ts +14 -0
  102. package/src/helpers/rpc/getAcountBalance.ts +18 -0
  103. package/src/helpers/rpc/getObjectType.ts +25 -0
  104. package/src/helpers/splitCoins.ts +12 -0
  105. package/src/helpers/track.ts +20 -0
  106. package/src/helpers/validateMinFloorPrice.ts +22 -0
  107. package/src/index.ts +2 -0
  108. package/src/methods/acceptCollectionBid/acceptCollectionBid.ts +189 -0
  109. package/src/methods/acceptCollectionBid/addAcceptCollectionBIdTxs.ts +398 -0
  110. package/src/methods/acceptNftBids/acceptNftBids.ts +174 -0
  111. package/src/methods/acceptNftBids/addAcceptNftBidTxs.ts +438 -0
  112. package/src/methods/applyFtStrategy/applyFtStrategy.ts +55 -0
  113. package/src/methods/applyNftStrategy/applyNftStrategy.ts +90 -0
  114. package/src/methods/buyListings/addBuyListingTxs.ts +806 -0
  115. package/src/methods/buyListings/buyListings.ts +230 -0
  116. package/src/methods/cancelMultiBid/cancelMultiBid.ts +51 -0
  117. package/src/methods/cancelNftTransfers/addCancelNftTransfersTx.ts +20 -0
  118. package/src/methods/cancelNftTransfers/cancelNftTransfers.ts +118 -0
  119. package/src/methods/claimNfts/addClaimNftsTxs.ts +247 -0
  120. package/src/methods/claimNfts/claimNfts.ts +270 -0
  121. package/src/methods/createMultiBid/createMultiBid.ts +36 -0
  122. package/src/methods/listNfts/addListTxs.ts +210 -0
  123. package/src/methods/listNfts/addRelistTxs.ts +87 -0
  124. package/src/methods/listNfts/listNfts.ts +152 -0
  125. package/src/methods/migrateNftsFromUnsharedToSharedKiosks/migrateNftsFromUnsharedToSharedKiosks.ts +226 -0
  126. package/src/methods/placeCollectionBids/addPlaceCollectionBidTxs.ts +149 -0
  127. package/src/methods/placeCollectionBids/placeCollectionBids.ts +153 -0
  128. package/src/methods/placeNftBids/addPlaceNftBidTxs.ts +154 -0
  129. package/src/methods/placeNftBids/placeNftBids.ts +111 -0
  130. package/src/methods/relistNft/relistNft.ts +153 -0
  131. package/src/methods/removeCollectionBids/addRemoveCollectionBidsTxs.ts +132 -0
  132. package/src/methods/removeCollectionBids/removeCollectionBids.ts +117 -0
  133. package/src/methods/removeNftBids/addRemoveNftBidTxs.ts +122 -0
  134. package/src/methods/removeNftBids/removeNftBids.ts +116 -0
  135. package/src/methods/sponsorNftListing/addSponsorNftListingTx.ts +40 -0
  136. package/src/methods/sponsorNftListing/sponsorNftListing.ts +60 -0
  137. package/src/methods/transferNfts/addTransferNftTx.ts +220 -0
  138. package/src/methods/transferNfts/transferNfts.ts +216 -0
  139. package/src/methods/unlistListings/addUnlistListingTxs.ts +399 -0
  140. package/src/methods/unlistListings/unlistListings.ts +158 -0
  141. package/src/methods/updateMultiBid/updateMultiBid.ts +66 -0
  142. package/src/methods/withdrawProfitsFromKiosks/withdrawProfitsFromKiosks.ts +100 -0
  143. package/src/tests/SuiWallet.ts +83 -0
  144. package/src/utils/addHexPrefix.ts +7 -0
  145. package/src/utils/addLeadingZerosAfter0x.ts +9 -0
  146. package/src/utils/normalizeNftType.ts +7 -0
  147. package/src/utils/printTxBlockTxs.ts +11 -0
  148. package/src/utils/pureValues.ts +13 -0
  149. package/src/utils/toUint8Array.ts +12 -0
  150. package/tsconfig.json +16 -0
  151. package/dist/index.d.ts +0 -194
  152. package/dist/index.js +0 -7419
  153. package/dist/index.js.map +0 -1
@@ -0,0 +1,230 @@
1
+ import type { KioskClient, KioskTransaction } from '@mysten/kiosk';
2
+ import { type SuiGrpcClient } from '@mysten/sui/grpc';
3
+ import { Transaction } from '@mysten/sui/transactions';
4
+ import { type RequestContext } from '../../SuiTradingClient';
5
+ import {
6
+ DELOREAN_TOKEN_IDS_TO_DISABLE,
7
+ DELOREAN_TOKEN_IDS_TO_DISABLE_MESSAGE,
8
+ } from '../../constants';
9
+ import { gqlChainRequest } from '../../graphql/gqlChainRequest';
10
+ import { fetchListingsById } from '../../graphql/queries/fetchListingsById';
11
+ import { addThirdPartyTxFee } from '../../helpers/addThirdPartyTxFee';
12
+ import { getNftType } from '../../helpers/getNftType';
13
+ import {
14
+ preProcessSharedBulkBuyingData,
15
+ type SharedBulkBuyingDataByNftType,
16
+ } from '../../helpers/kiosk/preProcessSharedBulkBuyingData';
17
+ import { type SharedKioskState } from '../../helpers/kiosk/sharedKioskState.type';
18
+ import {
19
+ addBluemoveBuyTxHandler,
20
+ addClutchyBuyTxHandler,
21
+ addHyperspaceBuyTxHandler,
22
+ addKeepsakeBuyTxHandler,
23
+ addSomisBuyTxHandler,
24
+ addSouffl3BuyTxHandler,
25
+ addTocenBuyTxHandler,
26
+ addTradePortBuyTxHandler,
27
+ } from './addBuyListingTxs';
28
+
29
+ type BuyTxBase = {
30
+ tx: Transaction;
31
+ sharedObjects?: any;
32
+ transferPolicies: any;
33
+ suiClient: SuiGrpcClient;
34
+ kioskClient: KioskClient;
35
+ kioskTx?: any;
36
+ sharedKioskState?: SharedKioskState;
37
+ buyer: string;
38
+ seller: string;
39
+ nftTokenId: string;
40
+ nftType: string;
41
+ listingId: string;
42
+ listingNonce: string;
43
+ price: number;
44
+ sellerKiosk: string;
45
+ collectionId: string;
46
+ nftContractId: string;
47
+ remainingAccountBalance?: number;
48
+ royalty?: number;
49
+ sharedBulkBuyingDataByNftType?: SharedBulkBuyingDataByNftType;
50
+ };
51
+
52
+ type NormalBuyTx = {
53
+ coinToSplit?: any;
54
+ nftTokenIds?: never;
55
+ } & BuyTxBase;
56
+
57
+ export type TocenBuyTx = {
58
+ coinToSplit?: any;
59
+ nftTokenIds: string[];
60
+ } & BuyTxBase;
61
+
62
+ export type BuyTx = (NormalBuyTx | TocenBuyTx) & {
63
+ marketFeeDecimalPercent?: number;
64
+ beforeResolveKioskTransferRequest?: (transferRequest: any) => void | Promise<void>;
65
+ };
66
+
67
+ export type BuyListing = {
68
+ listingId: string;
69
+ walletAddress: string;
70
+ };
71
+
72
+ export type BuyListings = {
73
+ listingIds: string[];
74
+ walletAddress: string;
75
+ tx?: Transaction;
76
+ kioskTx?: KioskTransaction;
77
+ coinToSplit?: any;
78
+ beforeResolveKioskTransferRequest?: (transferRequest: any) => void | Promise<void>;
79
+ };
80
+
81
+ export const buyListings = async (
82
+ {
83
+ listingIds,
84
+ walletAddress,
85
+ tx: existingTx,
86
+ kioskTx,
87
+ coinToSplit,
88
+ beforeResolveKioskTransferRequest,
89
+ }: BuyListings,
90
+ context: RequestContext,
91
+ marketFeeDecimalPercent?: number,
92
+ ): Promise<Transaction> => {
93
+ const res = await gqlChainRequest({
94
+ chain: 'sui',
95
+ query: fetchListingsById,
96
+ variables: { listingIds },
97
+ });
98
+
99
+ if (res?.listings?.length === 0) {
100
+ throw new Error('No listings found');
101
+ }
102
+
103
+ const listingsForTracking = [];
104
+ const tx = existingTx ?? new Transaction();
105
+
106
+ const tocenTokenIds: string[] = [];
107
+ let tocenNftType = '';
108
+ let tocenTotalPrice = 0;
109
+
110
+ const sharedKioskState: SharedKioskState = {
111
+ kioskTx: kioskTx ?? undefined,
112
+ };
113
+
114
+ let sharedBulkBuyingDataByNftType: SharedBulkBuyingDataByNftType;
115
+ if (res.listings.length > 1) {
116
+ sharedBulkBuyingDataByNftType = await preProcessSharedBulkBuyingData({
117
+ listings: res.listings,
118
+ suiClient: context.suiClient,
119
+ kioskClient: context.kioskClient,
120
+ walletAddress,
121
+ });
122
+ }
123
+
124
+ for (const listing of res.listings) {
125
+ if (DELOREAN_TOKEN_IDS_TO_DISABLE?.includes(listing?.nft?.token_id)) {
126
+ throw new Error(DELOREAN_TOKEN_IDS_TO_DISABLE_MESSAGE);
127
+ }
128
+
129
+ if (!listing?.listed) {
130
+ throw new Error(`Listing ${listing?.id} is not listed`);
131
+ }
132
+
133
+ const nftType = getNftType({
134
+ collectionId: listing?.collection?.id,
135
+ collectionChainState: listing?.collection?.chain_state,
136
+ nft: listing?.nft,
137
+ });
138
+
139
+ const transferPolicies = listing?.collection?.chain_state?.transfer_policies;
140
+
141
+ const buyTxData: BuyTx = {
142
+ tx,
143
+ kioskTx,
144
+ transferPolicies,
145
+ suiClient: context.suiClient,
146
+ kioskClient: context.kioskClient,
147
+ buyer: walletAddress,
148
+ seller: listing?.seller,
149
+ nftTokenId: listing.nft?.token_id,
150
+ nftType,
151
+ listingId: listing?.id,
152
+ listingNonce: listing?.nonce,
153
+ price: listing?.price,
154
+ sellerKiosk: listing.nft?.chain_state?.kiosk_id,
155
+ collectionId: listing?.nft?.collection_id,
156
+ nftContractId: listing?.nft?.contract_id,
157
+ coinToSplit,
158
+ marketFeeDecimalPercent,
159
+ beforeResolveKioskTransferRequest,
160
+ sharedKioskState,
161
+ sharedBulkBuyingDataByNftType,
162
+ };
163
+
164
+ switch (listing?.market_name) {
165
+ case 'tradeport':
166
+ await addTradePortBuyTxHandler(buyTxData);
167
+ break;
168
+ case 'hyperspace':
169
+ await addHyperspaceBuyTxHandler(buyTxData);
170
+ break;
171
+ case 'bluemove':
172
+ await addBluemoveBuyTxHandler(buyTxData);
173
+ break;
174
+ case 'clutchy':
175
+ await addClutchyBuyTxHandler(buyTxData);
176
+ break;
177
+ case 'souffl3':
178
+ await addSouffl3BuyTxHandler(buyTxData);
179
+ break;
180
+ case 'somis':
181
+ await addSomisBuyTxHandler(buyTxData);
182
+ break;
183
+ case 'keepsake':
184
+ await addKeepsakeBuyTxHandler(buyTxData);
185
+ break;
186
+ case 'tocen':
187
+ tocenTokenIds.push(buyTxData?.nftTokenId);
188
+ tocenNftType = buyTxData?.nftType;
189
+ tocenTotalPrice += Number(listing.price);
190
+ break;
191
+ default:
192
+ throw new Error('Marketplace not supported');
193
+ }
194
+
195
+ if (listing?.market_name !== 'tradeport') {
196
+ await addThirdPartyTxFee(tx, listing?.price);
197
+ }
198
+
199
+ listingsForTracking.push({
200
+ walletAddress,
201
+ nftType,
202
+ collectionId: listing?.nft?.collection_id,
203
+ price: listing?.price,
204
+ seller: listing?.seller,
205
+ marketName: listing?.market_name,
206
+ });
207
+ }
208
+
209
+ sharedKioskState?.kioskTx?.finalize();
210
+
211
+ if (tocenTokenIds?.length > 0) {
212
+ addTocenBuyTxHandler({
213
+ tx,
214
+ nftType: tocenNftType,
215
+ nftTokenIds: tocenTokenIds,
216
+ price: tocenTotalPrice,
217
+ } as TocenBuyTx);
218
+ }
219
+
220
+ // if (process.env.ENABLE_SEGMENT_TRACKING === 'true' && listingsForTracking.length > 0) {
221
+ // trackMethodCall({
222
+ // apiUser: context.apiUser,
223
+ // apiKey: context.apiKey,
224
+ // event: 'BUY_LISTINGS',
225
+ // items: listingsForTracking,
226
+ // });
227
+ // }
228
+
229
+ return tx;
230
+ };
@@ -0,0 +1,51 @@
1
+ import { Transaction } from '@mysten/sui/transactions';
2
+ import { TRADEPORT_MULTI_BID_PACKAGE, TRADEPORT_MULTI_BID_STORE } from '../../constants';
3
+ import {
4
+ fetchMultibidChainIdAndSingleBidsById,
5
+ fetchMultibidChainIdById,
6
+ } from '../../graphql/queries/fetchMultibidById';
7
+ import { gqlChainRequest } from '../../graphql/gqlChainRequest';
8
+ import { addCancelSingleBidForMultibidChainId } from '../removeNftBids/addRemoveNftBidTxs';
9
+
10
+ export interface CancelMultiBid {
11
+ walletAddress: string;
12
+ multiBidId: string;
13
+ }
14
+
15
+ export async function cancelMultiBid({ multiBidId }: CancelMultiBid): Promise<Transaction> {
16
+ const {
17
+ chain_id: multiBidChainId,
18
+ cancelled_at,
19
+ bids,
20
+ } = (
21
+ await gqlChainRequest({
22
+ chain: 'sui',
23
+ query: fetchMultibidChainIdAndSingleBidsById,
24
+ variables: { multiBidId },
25
+ })
26
+ )?.multi_bids?.[0] ?? {};
27
+ if (!multiBidChainId) {
28
+ throw new Error(`MultiBid ${multiBidId} not found`);
29
+ }
30
+
31
+ if (cancelled_at) {
32
+ throw new Error(`MultiBid ${multiBidId} already cancelled`);
33
+ }
34
+
35
+ const tx = new Transaction();
36
+ if (bids.length > 1022) {
37
+ // Transaction block is limited to 1024 txs
38
+ throw new Error(`Too many bids to cancel in one transaction`);
39
+ }
40
+
41
+ for (const bid of bids ?? []) {
42
+ addCancelSingleBidForMultibidChainId(tx, bid.nonce, multiBidChainId);
43
+ }
44
+
45
+ tx.moveCall({
46
+ target: `${TRADEPORT_MULTI_BID_PACKAGE}::tradeport_biddings::cancel_multi_bid`,
47
+ arguments: [tx.object(TRADEPORT_MULTI_BID_STORE), tx.pure.id(multiBidChainId)],
48
+ });
49
+
50
+ return tx;
51
+ }
@@ -0,0 +1,20 @@
1
+ import { TRADEPORT_KIOSK_TRANSFERS_STORE } from '../../constants';
2
+ import { type CancelNftTransfersTx } from './cancelNftTransfers';
3
+
4
+ export async function addTradeportKioskCancelNftTransferTx({
5
+ tx,
6
+ kioskTx,
7
+ nftTokenId,
8
+ nftType,
9
+ }: CancelNftTransfersTx) {
10
+ tx.moveCall({
11
+ target:
12
+ '0x49642273ca7db3d942f9fd810c93467974c40e73ea7f03e8e7a632f1222aca73::kiosk_transfers::cancel_with_purchase_cap',
13
+ arguments: [
14
+ tx.object(TRADEPORT_KIOSK_TRANSFERS_STORE),
15
+ tx.object(kioskTx.kiosk),
16
+ tx.pure.address(nftTokenId),
17
+ ],
18
+ typeArguments: [nftType],
19
+ });
20
+ }
@@ -0,0 +1,118 @@
1
+ import { Transaction } from '@mysten/sui/transactions';
2
+ import { type RequestContext } from '../../SuiTradingClient';
3
+ import {
4
+ DELOREAN_TOKEN_IDS_TO_DISABLE,
5
+ DELOREAN_TOKEN_IDS_TO_DISABLE_MESSAGE,
6
+ } from '../../constants';
7
+ import { gqlChainRequest } from '../../graphql/gqlChainRequest';
8
+ import { fetchNftsById } from '../../graphql/queries/fetchNftsById';
9
+ import { getNftType } from '../../helpers/getNftType';
10
+ import { getSharedObjects } from '../../helpers/getSharedObjects';
11
+ import { kioskTxWrapper } from '../../helpers/kiosk/kioskTxWrapper';
12
+ import { type SharedKioskState } from '../../helpers/kiosk/sharedKioskState.type';
13
+ import { isOBKiosk } from '../../helpers/originByte/isOBKiosk';
14
+ import { addTradeportKioskCancelNftTransferTx } from './addCancelNftTransfersTx';
15
+
16
+ export type CancelNftTransfersTx = {
17
+ tx: Transaction;
18
+ nftType: string;
19
+ nftTokenId: string;
20
+ senderKiosk: string;
21
+ senderAddress: string;
22
+ sharedObjects?: any;
23
+ kioskTx?: any;
24
+ sharedKioskState?: SharedKioskState;
25
+ };
26
+
27
+ export type CancelNftTransfers = {
28
+ nftIds: string[];
29
+ walletAddress: string;
30
+ };
31
+
32
+ export const cancelNftTransfers = async (
33
+ { nftIds, walletAddress }: CancelNftTransfers,
34
+ context: RequestContext,
35
+ ): Promise<Transaction> => {
36
+ const res = await gqlChainRequest({
37
+ chain: 'sui',
38
+ query: fetchNftsById,
39
+ variables: { nftIds },
40
+ });
41
+
42
+ if (res?.nfts?.length === 0) {
43
+ throw new Error('No nfts found');
44
+ }
45
+
46
+ const nftsForTracking = [];
47
+ const tx = new Transaction();
48
+
49
+ const sharedKioskState: SharedKioskState = {
50
+ kioskTx: undefined,
51
+ };
52
+
53
+ for (const nft of res.nfts) {
54
+ if (DELOREAN_TOKEN_IDS_TO_DISABLE?.includes(nft?.token_id)) {
55
+ throw new Error(DELOREAN_TOKEN_IDS_TO_DISABLE_MESSAGE);
56
+ }
57
+
58
+ if (nft?.chain_state?.claimable_reason !== 'offer-transfer') {
59
+ throw new Error('Cannot cancel transfer of NFT that is not currently transferring');
60
+ }
61
+
62
+ const nftType = getNftType({
63
+ collectionId: nft?.collection?.id,
64
+ collectionChainState: nft?.collection?.chain_state,
65
+ nft,
66
+ });
67
+
68
+ const sharedObjects = await getSharedObjects(nftType);
69
+
70
+ const txData: CancelNftTransfersTx = {
71
+ tx,
72
+ sharedKioskState,
73
+ nftType,
74
+ nftTokenId: nft?.token_id,
75
+ senderKiosk: nft?.chain_state?.kiosk_id,
76
+ senderAddress: walletAddress,
77
+ sharedObjects,
78
+ };
79
+
80
+ const isSenderKioskOriginByte = await isOBKiosk(txData.senderAddress, txData.senderKiosk);
81
+
82
+ // If NFT is not inside native kiosk, throw error
83
+ if (!txData.senderKiosk || isSenderKioskOriginByte) {
84
+ throw new Error('NFT is not inside a native kiosk, cannot cancel transfer');
85
+ }
86
+
87
+ await kioskTxWrapper({
88
+ tx: txData?.tx,
89
+ kioskClient: context.kioskClient,
90
+ kioskOwner: txData?.senderAddress,
91
+ kiosk: txData?.senderKiosk,
92
+ shouldAllowNftUnsharedKiosk: true,
93
+ sharedKioskState: txData?.sharedKioskState,
94
+ shouldUseSharedKioskTx: false,
95
+ async runCommands(kioskTx) {
96
+ await addTradeportKioskCancelNftTransferTx({ ...txData, kioskTx });
97
+ },
98
+ });
99
+
100
+ // nftsForTracking.push({
101
+ // nftType,
102
+ // senderAddress: walletAddress,
103
+ // });
104
+ }
105
+
106
+ sharedKioskState?.kioskTx?.finalize();
107
+
108
+ // if (process.env.ENABLE_SEGMENT_TRACKING === 'true' && nftsForTracking.length > 0) {
109
+ // trackMethodCall({
110
+ // apiUser: context.apiUser,
111
+ // apiKey: context.apiKey,
112
+ // event: 'CANCEL_NFT_TRANSFERS',
113
+ // items: nftsForTracking,
114
+ // });
115
+ // }
116
+
117
+ return Transaction.from(tx);
118
+ };
@@ -0,0 +1,247 @@
1
+ import {
2
+ BLUEMOVE_KIOSK_OFFER_COLLECTION_BIDDER_BAG,
3
+ TRADEPORT_KIOSK_BIDDING_ESCROW_KIOSK,
4
+ TRADEPORT_KIOSK_BIDDING_STORE,
5
+ TRADEPORT_KIOSK_TRANSFERS_ESCROW_KIOSK,
6
+ TRADEPORT_KIOSK_TRANSFERS_STORE,
7
+ } from '../../constants';
8
+ import { getKioskCollectionRoyaltyFeeAmount } from '../../helpers/kiosk/getKioskCollectionRoyaltyFeeAmount';
9
+ import { getNativeKioskTransferPolicies } from '../../helpers/kiosk/getNativeKioskTransferPolicies';
10
+ import { resolveTransferPolicies } from '../../helpers/kiosk/resolveTransferPolicies';
11
+ import { confirmOBTranfer } from '../../helpers/originByte/confirmOBTranfer';
12
+ import { splitCoins } from '../../helpers/splitCoins';
13
+ import {
14
+ type ClaimAcceptedBidNftTx,
15
+ type ClaimTradeHoldTx,
16
+ type ClaimTransferredNftTx,
17
+ } from './claimNfts';
18
+
19
+ export const addClaimTradeHoldTx = ({
20
+ tx,
21
+ sharedObjects,
22
+ nftType,
23
+ claimableTradeId,
24
+ claimableSellerKiosk,
25
+ claimableBuyerKiosk,
26
+ }: ClaimTradeHoldTx) => {
27
+ const { orderbook } = sharedObjects;
28
+
29
+ const transferRequest = tx.moveCall({
30
+ target:
31
+ '0x8534e4cdfd28709c94330a9783c3d5fe6f5daba0bffb69102ce303c5b38aed5a::orderbook::finish_trade',
32
+ arguments: [
33
+ tx.object(orderbook),
34
+ tx.pure.address(claimableTradeId),
35
+ tx.object(claimableSellerKiosk),
36
+ tx.object(claimableBuyerKiosk),
37
+ ],
38
+ typeArguments: [nftType, '0x2::sui::SUI'],
39
+ });
40
+
41
+ confirmOBTranfer({ tx, sharedObjects, transferRequest, nftType });
42
+ };
43
+
44
+ export const addClaimAcceptedBidNftTx = async ({
45
+ tx,
46
+ suiClient,
47
+ claimer,
48
+ kioskTx,
49
+ kioskClient,
50
+ nftTokenId,
51
+ nftType,
52
+ transferPolicies,
53
+ }: ClaimAcceptedBidNftTx) => {
54
+ const transferPolicyId = getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
55
+
56
+ const [transferRequest] = tx.moveCall({
57
+ target:
58
+ '0x475e98e9c436ec118909f3b9e241d86bcbbc2cf9fba05e99a934823fefb375b7::kiosk_biddings::claim_bid',
59
+ arguments: [
60
+ tx.object(TRADEPORT_KIOSK_BIDDING_STORE),
61
+ tx.object(TRADEPORT_KIOSK_BIDDING_ESCROW_KIOSK),
62
+ tx.object(kioskTx.kiosk),
63
+ tx.object(kioskTx.kioskCap),
64
+ tx.pure.address(nftTokenId),
65
+ tx.object(transferPolicyId),
66
+ ],
67
+ typeArguments: [nftType],
68
+ });
69
+
70
+ await resolveTransferPolicies({
71
+ tx,
72
+ transferPolicies,
73
+ suiClient,
74
+ walletAddress: claimer,
75
+ kioskTx,
76
+ kioskClient,
77
+ nftType,
78
+ price: '0',
79
+ transferRequest,
80
+ shouldSkipKioskLocking: true,
81
+ });
82
+ };
83
+
84
+ export const addClaimAcceptedBidNftWithPurchaseCapTx = async ({
85
+ tx,
86
+ suiClient,
87
+ claimer,
88
+ kioskTx,
89
+ kioskClient,
90
+ nftTokenId,
91
+ nftType,
92
+ sellerKiosk,
93
+ transferPolicies,
94
+ }: ClaimAcceptedBidNftTx) => {
95
+ const transferPolicyId = getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
96
+
97
+ const [transferRequest] = tx.moveCall({
98
+ target:
99
+ '0x475e98e9c436ec118909f3b9e241d86bcbbc2cf9fba05e99a934823fefb375b7::kiosk_biddings::claim_bid_with_purchase_cap',
100
+ arguments: [
101
+ tx.object(TRADEPORT_KIOSK_BIDDING_STORE),
102
+ tx.object(sellerKiosk),
103
+ tx.object(kioskTx.kiosk),
104
+ tx.object(kioskTx.kioskCap),
105
+ tx.pure.address(nftTokenId),
106
+ tx.object(transferPolicyId),
107
+ ],
108
+ typeArguments: [nftType],
109
+ });
110
+
111
+ await resolveTransferPolicies({
112
+ tx,
113
+ transferPolicies,
114
+ suiClient,
115
+ walletAddress: claimer,
116
+ kioskTx,
117
+ kioskClient,
118
+ nftType,
119
+ price: '0',
120
+ transferRequest,
121
+ shouldSkipKioskLocking: true,
122
+ });
123
+ };
124
+
125
+ export const addClaimTransferredNftTx = async ({
126
+ tx,
127
+ suiClient,
128
+ claimer,
129
+ kioskTx,
130
+ kioskClient,
131
+ nftTokenId,
132
+ nftType,
133
+ transferPolicies,
134
+ }: ClaimTransferredNftTx) => {
135
+ const transferPolicyId = getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
136
+
137
+ const [transferRequest] = tx.moveCall({
138
+ target:
139
+ '0x49642273ca7db3d942f9fd810c93467974c40e73ea7f03e8e7a632f1222aca73::kiosk_transfers::claim',
140
+ arguments: [
141
+ tx.object(TRADEPORT_KIOSK_TRANSFERS_STORE),
142
+ tx.object(TRADEPORT_KIOSK_TRANSFERS_ESCROW_KIOSK),
143
+ tx.object(kioskTx.kiosk),
144
+ tx.object(kioskTx.kioskCap),
145
+ tx.pure.address(nftTokenId),
146
+ tx.object(transferPolicyId),
147
+ ],
148
+ typeArguments: [nftType],
149
+ });
150
+
151
+ await resolveTransferPolicies({
152
+ tx,
153
+ transferPolicies,
154
+ suiClient,
155
+ walletAddress: claimer,
156
+ kioskTx,
157
+ kioskClient,
158
+ nftType,
159
+ price: '0',
160
+ transferRequest,
161
+ shouldSkipKioskLocking: true,
162
+ });
163
+ };
164
+
165
+ export const addClaimTransferredNftWithPurchaseCapTx = async ({
166
+ tx,
167
+ suiClient,
168
+ claimer,
169
+ kioskTx,
170
+ kioskClient,
171
+ nftTokenId,
172
+ nftType,
173
+ sellerKiosk,
174
+ transferPolicies,
175
+ preloadedTransferPolicyId,
176
+ }: ClaimTransferredNftTx) => {
177
+ const transferPolicyId =
178
+ preloadedTransferPolicyId ?? getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
179
+
180
+ const [transferRequest] = tx.moveCall({
181
+ target:
182
+ '0x49642273ca7db3d942f9fd810c93467974c40e73ea7f03e8e7a632f1222aca73::kiosk_transfers::claim_with_purchase_cap',
183
+ arguments: [
184
+ tx.object(TRADEPORT_KIOSK_TRANSFERS_STORE),
185
+ tx.object(sellerKiosk),
186
+ kioskTx.kiosk,
187
+ kioskTx.kioskCap,
188
+ tx.pure.address(nftTokenId),
189
+ tx.object(transferPolicyId),
190
+ ],
191
+ typeArguments: [nftType],
192
+ });
193
+
194
+ await resolveTransferPolicies({
195
+ tx,
196
+ transferPolicies,
197
+ suiClient,
198
+ walletAddress: claimer,
199
+ kioskTx,
200
+ kioskClient,
201
+ nftType,
202
+ price: '0',
203
+ transferRequest,
204
+ shouldSkipKioskLocking: true,
205
+ });
206
+ };
207
+
208
+ export const addBluemoveClaimAcceptedBidNft = async ({
209
+ tx,
210
+ suiClient,
211
+ claimer,
212
+ kioskTx,
213
+ nftTokenId,
214
+ nftType,
215
+ sellerKiosk,
216
+ transferPolicies,
217
+ }: ClaimTransferredNftTx) => {
218
+ const transferPolicyId = getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
219
+
220
+ const royaltyFeeAmount = await getKioskCollectionRoyaltyFeeAmount({
221
+ tx,
222
+ suiClient,
223
+ walletAddress: claimer,
224
+ royaltyRulePackageId: '0x434b5bd8f6a7b05fede0ff46c6e511d71ea326ed38056e3bcd681d2d7c2a7879',
225
+ royaltyRuleModule: 'royalty_rule',
226
+ transferPolicyId,
227
+ price: '0',
228
+ nftType,
229
+ });
230
+
231
+ const [coin] = splitCoins({ tx, amounts: [royaltyFeeAmount] });
232
+
233
+ tx.moveCall({
234
+ target:
235
+ '0xcc97b74ed95c8e8a3ed88050a898727dee37896da579fc400d482b64db6149ff::kiosk_offer_collection_v2::claim_nft_v2',
236
+ arguments: [
237
+ tx.object(BLUEMOVE_KIOSK_OFFER_COLLECTION_BIDDER_BAG),
238
+ tx.object(transferPolicyId),
239
+ tx.object(sellerKiosk),
240
+ tx.object(kioskTx.kiosk),
241
+ tx.object(kioskTx.kioskCap),
242
+ tx.pure.address(nftTokenId),
243
+ tx.object(coin),
244
+ ],
245
+ typeArguments: [nftType],
246
+ });
247
+ };