@tradeport/sui-trading-sdk 0.5.3 → 0.5.5

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,59 @@
1
+ import { type SuiGrpcClient } from '@mysten/sui/grpc';
2
+ import { type Transaction } from '@mysten/sui/transactions';
3
+ import { splitCoins } from '../splitCoins';
4
+ import { getKioskCollectionRoyaltyFeeAmount } from './getKioskCollectionRoyaltyFeeAmount';
5
+
6
+ export async function getKioskPlaceBidCoin({
7
+ tx,
8
+ suiClient,
9
+ bidder,
10
+ nftType,
11
+ bidAmount,
12
+ marketFeePrice,
13
+ royaltyRulePackageId,
14
+ royaltyRuleModule,
15
+ transferPolicyId,
16
+ }: {
17
+ tx: Transaction;
18
+ suiClient: SuiGrpcClient;
19
+ bidder: string;
20
+ nftType: string;
21
+ bidAmount: number;
22
+ marketFeePrice: number;
23
+ royaltyRulePackageId?: string;
24
+ royaltyRuleModule?: string;
25
+ transferPolicyId: string;
26
+ }) {
27
+ let coin;
28
+
29
+ if (royaltyRulePackageId && royaltyRuleModule) {
30
+ const royaltyFeeAmount = await getKioskCollectionRoyaltyFeeAmount({
31
+ tx,
32
+ suiClient,
33
+ walletAddress: bidder,
34
+ royaltyRulePackageId,
35
+ royaltyRuleModule,
36
+ transferPolicyId,
37
+ price: bidAmount,
38
+ nftType,
39
+ });
40
+
41
+ const [coin1, coin2] = splitCoins({
42
+ tx,
43
+ amounts: [tx.pure.u64(bidAmount + marketFeePrice), royaltyFeeAmount],
44
+ });
45
+ coin = coin1;
46
+
47
+ if (!coin1 || !coin2) throw new Error('Coin could not be split');
48
+
49
+ tx.mergeCoins(tx.object(coin1), [tx.object(coin2)]);
50
+ } else {
51
+ const [coin1] = splitCoins({
52
+ tx,
53
+ amounts: [tx.pure.u64(bidAmount + marketFeePrice)],
54
+ });
55
+ coin = coin1;
56
+ }
57
+
58
+ return coin;
59
+ }
@@ -0,0 +1,29 @@
1
+ export const getNativeKioskTransferPolicies = (transferPolicies: any) => {
2
+ let nativeKioskTransferPolicies = transferPolicies?.filter(
3
+ (policy: any) =>
4
+ !policy?.is_origin_byte &&
5
+ !policy?.is_disabled &&
6
+ policy?.rules?.filter(
7
+ (rule: any) =>
8
+ rule?.type?.includes('royalty_rule') ||
9
+ rule?.type?.includes('kiosk_lock_rule') ||
10
+ rule?.type?.includes('personal_kiosk_rule') ||
11
+ rule?.type?.includes('floor_price_rule'),
12
+ )?.length > 0,
13
+ );
14
+
15
+ if (nativeKioskTransferPolicies?.length === 0 && transferPolicies?.length > 0) {
16
+ nativeKioskTransferPolicies = transferPolicies?.filter(
17
+ (policy: any) => !policy?.is_origin_byte && !policy?.is_disabled,
18
+ );
19
+ }
20
+
21
+ return nativeKioskTransferPolicies;
22
+ };
23
+
24
+ export const knownTransferPolicyRules = [
25
+ 'royalty_rule',
26
+ 'kiosk_lock_rule',
27
+ 'personal_kiosk_rule',
28
+ 'floor_price_rule',
29
+ ];
@@ -0,0 +1,21 @@
1
+ import { gqlChainRequest } from '../../graphql/gqlChainRequest';
2
+ import { fetchTransferPoliciesByType } from '../../graphql/queries/fetchTransferPoliciesByType';
3
+ import { normalizedNftType } from '../../utils/normalizeNftType';
4
+ import { getNativeKioskTransferPolicies } from './getNativeKioskTransferPolicies';
5
+
6
+ export const getNativeKioskTransferPoliciesByNftType = async (nftType: string) => {
7
+ const res = await gqlChainRequest({
8
+ chain: 'sui',
9
+ query: fetchTransferPoliciesByType,
10
+ variables: { type: normalizedNftType(nftType) },
11
+ });
12
+
13
+ return getNativeKioskTransferPolicies(res?.transfer_policies_by_type);
14
+ };
15
+
16
+ export const knownTransferPolicyRules = [
17
+ 'royalty_rule',
18
+ 'kiosk_lock_rule',
19
+ 'personal_kiosk_rule',
20
+ 'floor_price_rule',
21
+ ];
@@ -0,0 +1,59 @@
1
+ import { getNormalizedRuleType, type KioskClient } from '@mysten/kiosk';
2
+ import { type SuiGrpcClient } from '@mysten/sui/grpc';
3
+ import { addHexPrefix } from '../../utils/addHexPrefix';
4
+ import { normalizedNftType } from '../../utils/normalizeNftType';
5
+ import { getTransferPolicyRuleNamesFromSuiObject } from '../getTransferPolicyRuleNamesFromSuiObject';
6
+ import { getNativeKioskTransferPolicies } from './getNativeKioskTransferPolicies';
7
+ import { upgradeKioskRulesPackageId } from './upgradeKioskRulesPackageId';
8
+
9
+ type RuleType = 'kiosk_royalty_rule' | 'royalty_rule' | 'personal_kiosk_rule' | 'kiosk_lock_rule';
10
+
11
+ export const getRulePackageId = async ({
12
+ transferPolicies,
13
+ nftType,
14
+ ruleType,
15
+ kioskClient,
16
+ suiClient,
17
+ }: {
18
+ transferPolicies: any[];
19
+ suiClient: SuiGrpcClient;
20
+ nftType: string;
21
+ ruleType: RuleType;
22
+ kioskClient: KioskClient;
23
+ }) => {
24
+ let rule: string | undefined;
25
+
26
+ if (transferPolicies.length > 0) {
27
+ const transferPolicyId = getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
28
+
29
+ const ruleNames = await getTransferPolicyRuleNamesFromSuiObject({
30
+ suiClient,
31
+ transferPolicyId,
32
+ });
33
+
34
+ rule = ruleNames.filter((ruleName) => ruleName?.split('::')?.[1] === ruleType)?.[0];
35
+ } else {
36
+ const transferPoliciesFromMystenSdk = await kioskClient.getTransferPolicies({
37
+ type: normalizedNftType(nftType),
38
+ });
39
+
40
+ if (transferPoliciesFromMystenSdk.length > 0) {
41
+ rule = transferPoliciesFromMystenSdk
42
+ .flatMap((policy) => policy.rules)
43
+ .filter((rule) => rule?.split('::')?.[1] === ruleType)?.[0];
44
+ } else {
45
+ throw new Error(`No transfer policy found for ${nftType}`);
46
+ }
47
+ }
48
+
49
+ const ruleDefinition = kioskClient.rules.find(
50
+ (x) => getNormalizedRuleType(x.rule) === getNormalizedRuleType(rule),
51
+ );
52
+
53
+ let rulePackageId = ruleDefinition?.packageId;
54
+ if (!rulePackageId) {
55
+ rulePackageId = rule?.split('::')?.[0];
56
+ }
57
+
58
+ return upgradeKioskRulesPackageId(addHexPrefix(rulePackageId));
59
+ };
@@ -0,0 +1,154 @@
1
+ import { getNormalizedRuleType, type KioskClient } from '@mysten/kiosk';
2
+ import { type SuiGrpcClient } from '@mysten/sui/grpc';
3
+ import { normalizedNftType } from '../../utils/normalizeNftType';
4
+ import { getTransferPolicyRuleNamesFromSuiObject } from '../getTransferPolicyRuleNamesFromSuiObject';
5
+ import {
6
+ getNativeKioskTransferPolicies,
7
+ knownTransferPolicyRules,
8
+ } from './getNativeKioskTransferPolicies';
9
+ import { upgradeKioskRulesPackageId } from './upgradeKioskRulesPackageId';
10
+
11
+ interface RuleData {
12
+ rule: string;
13
+ rulePackageId?: string;
14
+ moduleName?: string;
15
+ }
16
+
17
+ export type Policy = {
18
+ id: string;
19
+ type?: string;
20
+ isCustom: boolean;
21
+ rules: RuleData[];
22
+ };
23
+
24
+ type Props = {
25
+ transferPolicies: any[];
26
+ suiClient: SuiGrpcClient;
27
+ kioskClient: KioskClient;
28
+ nftType: string;
29
+ customTransferPolicies?: any;
30
+ };
31
+
32
+ const originByteRuleModules = ['royalty_strategy_bps', 'transfer_allowlist'];
33
+
34
+ export const getTransferPoliciesToResolve = async ({
35
+ transferPolicies,
36
+ suiClient,
37
+ kioskClient,
38
+ nftType,
39
+ customTransferPolicies,
40
+ }: Props): Promise<Policy[]> => {
41
+ let policies: Policy[] = [];
42
+
43
+ if (transferPolicies.length > 0) {
44
+ const transferPolicyId = getNativeKioskTransferPolicies(transferPolicies)?.at(0)?.id;
45
+
46
+ if (transferPolicyId) {
47
+ const ruleNames = await getTransferPolicyRuleNamesFromSuiObject({
48
+ suiClient,
49
+ transferPolicyId,
50
+ });
51
+
52
+ policies = [
53
+ {
54
+ id: transferPolicyId,
55
+ rules: ruleNames?.map((rule) => ({
56
+ rule,
57
+ })),
58
+ isCustom: false,
59
+ },
60
+ ];
61
+ }
62
+ } else {
63
+ const transferPoliciesFromMystenSdk = await kioskClient.getTransferPolicies({
64
+ type: normalizedNftType(nftType),
65
+ });
66
+
67
+ if (transferPoliciesFromMystenSdk.length > 0) {
68
+ const policy =
69
+ transferPoliciesFromMystenSdk.find((policy) =>
70
+ policy?.rules?.some((rule) =>
71
+ knownTransferPolicyRules.some((ruleType) => rule?.includes(ruleType)),
72
+ ),
73
+ ) ?? transferPoliciesFromMystenSdk[0];
74
+
75
+ policies = [
76
+ {
77
+ id: policy.id,
78
+ rules: policy.rules?.map((rule) => ({
79
+ rule,
80
+ })),
81
+ isCustom: false,
82
+ },
83
+ ];
84
+ } else {
85
+ throw new Error(
86
+ `Missing transfer policy of ${nftType}. No way to resolve the transfer request.`,
87
+ );
88
+ }
89
+ }
90
+
91
+ if (customTransferPolicies) {
92
+ for (const customTransferPolicy of customTransferPolicies) {
93
+ const customPolicy = await kioskClient.getTransferPolicies({
94
+ type: normalizedNftType(customTransferPolicy?.type),
95
+ });
96
+ policies = [
97
+ ...policies,
98
+ {
99
+ id: customPolicy[0].id,
100
+ rules: customPolicy[0].rules?.map((rule) => ({
101
+ rule,
102
+ })),
103
+ isCustom: true,
104
+ type: customTransferPolicy?.type,
105
+ },
106
+ ];
107
+ }
108
+ }
109
+
110
+ return policies.map((policy) => {
111
+ const kioskLockRule = policy?.rules.find((rule: RuleData) =>
112
+ rule?.rule?.includes('kiosk_lock_rule'),
113
+ );
114
+
115
+ const personalKioskRule = policy?.rules.find((rule: RuleData) =>
116
+ rule.rule.includes('personal_kiosk_rule'),
117
+ );
118
+
119
+ const otherRules = policy?.rules.filter(
120
+ (rule: RuleData) =>
121
+ !rule?.rule?.includes('kiosk_lock_rule') && !rule?.rule?.includes('personal_kiosk_rule'),
122
+ );
123
+
124
+ return {
125
+ ...policy,
126
+ rules: [kioskLockRule, personalKioskRule, ...otherRules].filter(Boolean)?.map((ruleData) => {
127
+ const ruleDefinition = kioskClient.rules.find(
128
+ (x: any) => getNormalizedRuleType(x.rule) === getNormalizedRuleType(ruleData.rule),
129
+ );
130
+
131
+ let rulePackageId = ruleDefinition?.packageId;
132
+ if (!rulePackageId) {
133
+ rulePackageId = ruleData?.rule?.split('::')?.[0];
134
+ }
135
+
136
+ rulePackageId = upgradeKioskRulesPackageId(rulePackageId);
137
+
138
+ const moduleName = ruleData?.rule?.split('::')?.[1];
139
+
140
+ if (originByteRuleModules.includes(moduleName)) {
141
+ throw new Error(
142
+ `Using Origin Byte rule ${ruleData.rule} inside the native kiosk transaction`,
143
+ );
144
+ }
145
+
146
+ return {
147
+ ...ruleData,
148
+ rulePackageId,
149
+ moduleName,
150
+ };
151
+ }),
152
+ };
153
+ });
154
+ };
@@ -0,0 +1 @@
1
+ export const isBluemoveKioskBid = (bidNonce: string): boolean => bidNonce?.startsWith('10000');
@@ -0,0 +1,4 @@
1
+ import { TRADEPORT_KIOSK_BID_NONCE_TYPE } from '../../constants';
2
+
3
+ export const isTradePortKioskBid = (bidType: string): boolean =>
4
+ bidType === TRADEPORT_KIOSK_BID_NONCE_TYPE;
@@ -0,0 +1,19 @@
1
+ import { bcs } from '@mysten/sui/bcs';
2
+
3
+ const PurchaseCap = bcs.struct('PurchaseCap', {
4
+ id: bcs.Address,
5
+ kiosk_id: bcs.Address,
6
+ item_id: bcs.Address,
7
+ min_price: bcs.u64(),
8
+ });
9
+
10
+ export const KioskListing = bcs.struct('KioskListing', {
11
+ id: bcs.Address,
12
+ seller: bcs.Address,
13
+ kiosk_id: bcs.Address,
14
+ nft_id: bcs.Address,
15
+ cap: PurchaseCap,
16
+ price: bcs.u64(),
17
+ commission: bcs.u64(),
18
+ beneficiary: bcs.Address,
19
+ });
@@ -0,0 +1,152 @@
1
+ import { type KioskClient, KioskTransaction } from '@mysten/kiosk';
2
+ import { type Transaction } from '@mysten/sui/transactions';
3
+ import { gqlChainRequest } from '../../graphql/gqlChainRequest';
4
+ import { fetchKiosksByOwner } from '../../graphql/queries/fetchKiosksByOwner';
5
+ import { fetchOwnerCapByKiosk } from '../../graphql/queries/fetchOwnerCapByKiosk';
6
+ import { fetchPersonalCapByKiosk } from '../../graphql/queries/fetchPersonalCapByKiosk';
7
+ import { addLeadingZerosAfter0x } from '../../utils/addLeadingZerosAfter0x';
8
+ import { assertNftInSharedKiosk } from './assertNftInSharedKiosk';
9
+ import { type SharedKioskState } from './sharedKioskState.type';
10
+
11
+ type Args = {
12
+ tx: Transaction;
13
+ kioskClient: KioskClient;
14
+ kioskOwner: string;
15
+ kiosk?: any;
16
+ runCommands: (kioskTx: KioskTransaction) => Promise<void>;
17
+ shouldConvertToPersonalKiosk?: boolean;
18
+ shouldAssertNftInSharedKiosk?: boolean;
19
+ shouldAllowNftUnsharedKiosk?: boolean;
20
+ kioskStrategy?: 'include' | 'exclude';
21
+ failIfNoKiosk?: boolean;
22
+ sharedKioskState?: SharedKioskState;
23
+ shouldUseSharedKioskTx?: boolean;
24
+ };
25
+
26
+ export const kioskTxWrapper = async ({
27
+ tx,
28
+ kioskClient,
29
+ kioskOwner,
30
+ kiosk,
31
+ runCommands,
32
+ shouldConvertToPersonalKiosk,
33
+ shouldAssertNftInSharedKiosk,
34
+ shouldAllowNftUnsharedKiosk,
35
+ kioskStrategy,
36
+ failIfNoKiosk,
37
+ sharedKioskState,
38
+ shouldUseSharedKioskTx = true,
39
+ }: Args) => {
40
+ if (shouldUseSharedKioskTx && sharedKioskState?.kioskTx) {
41
+ await runCommands(sharedKioskState.kioskTx);
42
+ return;
43
+ }
44
+
45
+ if (!kioskOwner) {
46
+ throw new Error('No kiosk owner provided');
47
+ }
48
+
49
+ let kioskTx: KioskTransaction;
50
+
51
+ let kiosks =
52
+ sharedKioskState?.ownerKiosks ??
53
+ (((
54
+ await gqlChainRequest({
55
+ chain: 'sui',
56
+ query: fetchKiosksByOwner,
57
+ variables: { ownerAddress: addLeadingZerosAfter0x(kioskOwner) },
58
+ })
59
+ ).kiosks ?? []) as Array<{
60
+ id: string;
61
+ is_personal: boolean;
62
+ is_origin_byte: boolean;
63
+ is_shared: boolean;
64
+ }>);
65
+
66
+ if (sharedKioskState) {
67
+ sharedKioskState.ownerKiosks = kiosks;
68
+ }
69
+
70
+ if (shouldAssertNftInSharedKiosk) {
71
+ await assertNftInSharedKiosk({ kioskId: kiosk, walletAddress: kioskOwner, sharedKioskState });
72
+ }
73
+
74
+ kiosks = kiosks?.filter((k) => !k.is_origin_byte && (shouldAllowNftUnsharedKiosk || k.is_shared));
75
+
76
+ if (kiosk) {
77
+ let filteredKiosks = [];
78
+ switch (kioskStrategy ?? 'include') {
79
+ case 'include':
80
+ filteredKiosks = kiosks.filter((k) => k?.id === kiosk);
81
+ break;
82
+ case 'exclude':
83
+ filteredKiosks = kiosks.filter((k) => k?.id !== kiosk);
84
+ break;
85
+ default:
86
+ throw new Error(`Unsupported kiosk strategy ${kioskStrategy}`);
87
+ }
88
+
89
+ if (filteredKiosks.length > 0) {
90
+ kiosks = filteredKiosks;
91
+ } else if (failIfNoKiosk ?? false) {
92
+ throw new Error(`Kiosk ${kiosk} not found for account ${kioskOwner}`);
93
+ }
94
+ }
95
+
96
+ const personalKiosk = kiosks.find((k) => k.is_personal);
97
+
98
+ if (personalKiosk) {
99
+ // using existing personal kiosk
100
+ const personalKioskCapId = (
101
+ await gqlChainRequest({
102
+ chain: 'sui',
103
+ query: fetchPersonalCapByKiosk,
104
+ variables: { kioskId: personalKiosk.id },
105
+ })
106
+ ).personalCap.id;
107
+ kioskTx = new KioskTransaction({
108
+ transaction: tx,
109
+ kioskClient,
110
+ cap: {
111
+ isPersonal: true,
112
+ objectId: personalKioskCapId,
113
+ kioskId: personalKiosk.id,
114
+ digest: '',
115
+ version: '',
116
+ },
117
+ });
118
+ } else if (kiosks.length > 0 && !shouldConvertToPersonalKiosk) {
119
+ const kioskCapId = (
120
+ await gqlChainRequest({
121
+ chain: 'sui',
122
+ query: fetchOwnerCapByKiosk,
123
+ variables: { kioskId: kiosks[0].id },
124
+ })
125
+ ).ownerCap?.id;
126
+ kioskTx = new KioskTransaction({
127
+ transaction: tx,
128
+ kioskClient,
129
+ cap: {
130
+ isPersonal: false,
131
+ objectId: kioskCapId,
132
+ kioskId: kiosks[0].id,
133
+ digest: '',
134
+ version: '',
135
+ },
136
+ });
137
+ } else {
138
+ // creating new personal kiosk
139
+ kioskTx = new KioskTransaction({ transaction: tx, kioskClient });
140
+ kioskTx.createPersonal(true);
141
+ }
142
+
143
+ if (shouldUseSharedKioskTx && sharedKioskState) {
144
+ sharedKioskState.kioskTx = kioskTx;
145
+ }
146
+
147
+ await runCommands(kioskTx);
148
+
149
+ if (!sharedKioskState?.kioskTx) {
150
+ kioskTx.finalize();
151
+ }
152
+ };
@@ -0,0 +1,100 @@
1
+ import { type KioskClient, type KioskTransaction } from '@mysten/kiosk';
2
+ import { type Transaction } from '@mysten/sui/transactions';
3
+ import { getKioskIdFromKioskTx } from './getKioskIdFromKioskTx';
4
+
5
+ export const lockNftInsideKioskIfNotLocked = async ({
6
+ tx,
7
+ kioskClient,
8
+ kioskTx,
9
+ nftTokenId,
10
+ nftType,
11
+ transferPolicyId,
12
+ }: {
13
+ tx: Transaction;
14
+ kioskClient: KioskClient;
15
+ kioskTx: KioskTransaction;
16
+ nftTokenId: string;
17
+ nftType: string;
18
+ transferPolicyId: string;
19
+ }) => {
20
+ if (
21
+ lockNftInsideKioskIfKioskCreatedInThisTx({ tx, kioskTx, nftTokenId, nftType, transferPolicyId })
22
+ ) {
23
+ return;
24
+ }
25
+
26
+ const kioskId = getKioskIdFromKioskTx({ kioskTx, tx });
27
+ const res = await kioskClient.getKiosk({ id: kioskId });
28
+ const nftInKiosk = res.items.find((i) => i.objectId === nftTokenId);
29
+ let takeFromKiosk = true;
30
+
31
+ if (!nftInKiosk) {
32
+ const { object } = await (kioskClient.client as any).getObject({
33
+ objectId: nftTokenId,
34
+ include: {},
35
+ });
36
+ if (object?.owner?.$kind === 'AddressOwner') {
37
+ // NFT is owned by account
38
+ takeFromKiosk = false;
39
+ } else {
40
+ throw new Error(`NFT ${nftTokenId} is not found in kiosk ${kioskId}`);
41
+ }
42
+ }
43
+
44
+ if (!nftInKiosk?.isLocked) {
45
+ let takenNftId;
46
+
47
+ if (takeFromKiosk) {
48
+ const takenNft = kioskTx.take({
49
+ itemId: nftTokenId,
50
+ itemType: nftType,
51
+ });
52
+
53
+ takenNftId = (takenNft as any).value ?? takenNft;
54
+ }
55
+
56
+ kioskTx.lock({
57
+ item: takenNftId ?? nftTokenId,
58
+ itemType: nftType,
59
+ policy: transferPolicyId,
60
+ });
61
+ }
62
+ };
63
+
64
+ function lockNftInsideKioskIfKioskCreatedInThisTx({
65
+ tx,
66
+ kioskTx,
67
+ nftTokenId,
68
+ nftType,
69
+ transferPolicyId,
70
+ }: {
71
+ tx: Transaction;
72
+ kioskTx: any;
73
+ nftTokenId: string;
74
+ nftType: string;
75
+ transferPolicyId: string;
76
+ }) {
77
+ if (Array.isArray(kioskTx.kiosk.NestedResult)) {
78
+ const transaction = (tx as any).getData().commands[kioskTx.kiosk.NestedResult[0]] as {
79
+ target: string;
80
+ };
81
+ if (
82
+ transaction.target ===
83
+ '0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::new' ||
84
+ transaction.target ===
85
+ '0x0000000000000000000000000000000000000000000000000000000000000002::personal_kiosk::new'
86
+ ) {
87
+ // just created in this transaction block kiosk
88
+ kioskTx.lock({
89
+ item: nftTokenId,
90
+ itemType: nftType,
91
+ policy: transferPolicyId,
92
+ });
93
+ return true;
94
+ }
95
+
96
+ throw new Error(`Unsupported kiosk move call ${transaction.target}`);
97
+ }
98
+
99
+ return false;
100
+ }