@tradeport/sui-trading-sdk 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babel.config.js +3 -0
- package/.env.demo +4 -0
- package/.eslintrc.json +46 -0
- package/.prettierignore +4 -0
- package/.prettierrc.json +7 -0
- package/README.md +1 -0
- package/dist/index.d.mts +90 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +3760 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3733 -0
- package/dist/index.mjs.map +1 -0
- package/jest.config.js +7 -0
- package/package.json +45 -0
- package/src/SuiTradingClient.ts +158 -0
- package/src/apiClients/graphqlClient.ts +5 -0
- package/src/apiClients/kioskClient.ts +10 -0
- package/src/apiClients/suiClient.ts +5 -0
- package/src/constants.ts +74 -0
- package/src/graphql/createChainGQLQuery.ts +25 -0
- package/src/graphql/gqlChainRequest.ts +20 -0
- package/src/graphql/queries/fetchAccountKiosks.ts +12 -0
- package/src/graphql/queries/fetchBidsById.ts +28 -0
- package/src/graphql/queries/fetchCollectionBidById.ts +20 -0
- package/src/graphql/queries/fetchCollectionBidsAtSamePrice.ts +28 -0
- package/src/graphql/queries/fetchCollectionsById.ts +30 -0
- package/src/graphql/queries/fetchCommissionByListingId.ts +13 -0
- package/src/graphql/queries/fetchCryptoToUsdRate.ts +13 -0
- package/src/graphql/queries/fetchKiosksByOwner.ts +13 -0
- package/src/graphql/queries/fetchListingsById.ts +24 -0
- package/src/graphql/queries/fetchListingsByNftId.ts +23 -0
- package/src/graphql/queries/fetchNftsById.ts +61 -0
- package/src/graphql/queries/fetchOwnerCapByKiosk.ts +10 -0
- package/src/graphql/queries/fetchPersonalCapByKiosk.ts +10 -0
- package/src/graphql/queries/fetchSharedObjectsByType.ts +12 -0
- package/src/graphql/queries/fetchTransferPoliciesByType.ts +12 -0
- package/src/graphql/queries/getCommissionByListingId.ts +15 -0
- package/src/helpers/addOneDollarFee.ts +17 -0
- package/src/helpers/addThirdPartyTxFee.ts +17 -0
- package/src/helpers/destroyZeroCoin.ts +14 -0
- package/src/helpers/getMarketFeePrice.ts +78 -0
- package/src/helpers/getNftTypeFromNft.ts +8 -0
- package/src/helpers/getSharedObjects.ts +113 -0
- package/src/helpers/getSuiToUsdRate.ts +17 -0
- package/src/helpers/getTradeportBiddingContractParsedBidAmount.ts +32 -0
- package/src/helpers/hasRoyaltyRule.ts +14 -0
- package/src/helpers/hasTransferPolicyRules.ts +21 -0
- package/src/helpers/isNonKioskListing.ts +7 -0
- package/src/helpers/kiosk/getRulePackageId.ts +26 -0
- package/src/helpers/kiosk/isBluemoveKioskBid.ts +1 -0
- package/src/helpers/kiosk/isTradePortKioskBid.ts +4 -0
- package/src/helpers/kiosk/kioskTxWrapper.ts +102 -0
- package/src/helpers/kiosk/resolveFloorPriceRule.ts +25 -0
- package/src/helpers/kiosk/resolveKioskLockRule.ts +49 -0
- package/src/helpers/kiosk/resolvePersonalKioskRule.ts +26 -0
- package/src/helpers/kiosk/resolveRoyaltyRule.ts +41 -0
- package/src/helpers/kiosk/resolveTransferPolicies.ts +150 -0
- package/src/helpers/originByte/confirmOBTranfer.ts +33 -0
- package/src/helpers/originByte/createOBKiosk.ts +14 -0
- package/src/helpers/originByte/depositNftIntoOBKiosk.ts +14 -0
- package/src/helpers/originByte/getOBBidderKiosk.ts +9 -0
- package/src/helpers/originByte/getOBKiosk.ts +24 -0
- package/src/helpers/originByte/getOrCreateOBKiosk.ts +37 -0
- package/src/helpers/originByte/isOBKiosk.ts +13 -0
- package/src/helpers/originByte/isOriginByteBid.ts +6 -0
- package/src/helpers/originByte/isOriginByteTx.ts +2 -0
- package/src/helpers/originByte/shareOriginByteKiosk.ts +14 -0
- package/src/helpers/rpc/getAcountBalance.ts +17 -0
- package/src/helpers/rpc/getObjectType.ts +10 -0
- package/src/helpers/splitCoins.ts +12 -0
- package/src/index.ts +3 -0
- package/src/methods/acceptCollectionBid/acceptCollectionBid.ts +119 -0
- package/src/methods/acceptCollectionBid/addAcceptCollectionBIdTxs.ts +359 -0
- package/src/methods/acceptNftBids/acceptNftBids.ts +100 -0
- package/src/methods/acceptNftBids/addAcceptNftBidTxs.ts +214 -0
- package/src/methods/buyListings/addBuyListingTxs.ts +503 -0
- package/src/methods/buyListings/buyListings.ts +143 -0
- package/src/methods/claimNfts/addClaimNftsTxs.ts +104 -0
- package/src/methods/claimNfts/claimNfts.ts +139 -0
- package/src/methods/listNfts/addListTxs.ts +186 -0
- package/src/methods/listNfts/addRelistTxs.ts +79 -0
- package/src/methods/listNfts/listNfts.ts +80 -0
- package/src/methods/placeCollectionBids/addPlaceCollectionBidTxs.ts +146 -0
- package/src/methods/placeCollectionBids/placeCollectionBids.ts +120 -0
- package/src/methods/placeNftBids/addPlaceNftBidTxs.ts +146 -0
- package/src/methods/placeNftBids/placeNftBids.ts +69 -0
- package/src/methods/relistNft/relistNft.ts +104 -0
- package/src/methods/removeCollectionBid/addRemoveCollectionBidTxs.ts +119 -0
- package/src/methods/removeCollectionBid/removeCollectionBid.ts +97 -0
- package/src/methods/removeNftBids/addRemoveNftBidTxs.ts +84 -0
- package/src/methods/removeNftBids/removeNftBids.ts +80 -0
- package/src/methods/transferNfts/addTransferNftTx.ts +78 -0
- package/src/methods/transferNfts/transferNfts.ts +107 -0
- package/src/methods/unlistListings/addUnlistListingTxs.ts +258 -0
- package/src/methods/unlistListings/unlistListings.ts +108 -0
- package/src/methods/withdrawKioskProfits/withdrawKioskProfits.ts +25 -0
- package/src/tests/SuiWallet.ts +49 -0
- package/src/utils/addHexPrefix.ts +7 -0
- package/src/utils/addLeadingZerosAfter0x.ts +2 -0
- package/src/utils/parseSUI.ts +1 -0
- package/src/utils/printTxBlockTxs.ts +5 -0
- package/src/utils/toUint8Array.ts +12 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { gqlChainRequest } from '../gqlChainRequest';
|
|
2
|
+
import { fetchCommissionByNftContractId } from './fetchCommissionByListingId';
|
|
3
|
+
|
|
4
|
+
export const getCommissionByNftContractId = async (nftContractId: string) => {
|
|
5
|
+
try {
|
|
6
|
+
const res = await gqlChainRequest({
|
|
7
|
+
chain: 'sui',
|
|
8
|
+
query: fetchCommissionByNftContractId,
|
|
9
|
+
variables: { nftContractId },
|
|
10
|
+
});
|
|
11
|
+
return res?.commissions?.[0];
|
|
12
|
+
} catch (err) {
|
|
13
|
+
throw new Error(`Failed to fetch commission for listing ${nftContractId}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TransactionBlock } from '@mysten/sui.js/transactions';
|
|
2
|
+
import { TRADEPORT_BENEFICIARY_ADDRESS } from '../constants';
|
|
3
|
+
import { addLeadingZerosAfter0x } from '../utils/addLeadingZerosAfter0x';
|
|
4
|
+
import { getSuiToUsdRate } from './getSuiToUsdRate';
|
|
5
|
+
|
|
6
|
+
export const addOneDollarFee = async (txBlock: TransactionBlock) => {
|
|
7
|
+
const rate = await getSuiToUsdRate();
|
|
8
|
+
|
|
9
|
+
const companyFee = BigInt(Math.ceil(1_000_000_000 / rate));
|
|
10
|
+
|
|
11
|
+
const [microTxFee] = txBlock.splitCoins(txBlock.gas, [txBlock.pure(Number(companyFee))]);
|
|
12
|
+
|
|
13
|
+
txBlock.transferObjects(
|
|
14
|
+
[txBlock.object(microTxFee)],
|
|
15
|
+
txBlock.pure(addLeadingZerosAfter0x(TRADEPORT_BENEFICIARY_ADDRESS)),
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TransactionBlock } from '@mysten/sui.js/transactions';
|
|
2
|
+
import {
|
|
3
|
+
TRADEPORT_BENEFICIARY_ADDRESS,
|
|
4
|
+
TRADEPORT_THIRD_PARTY_FEE_DECIMAL_PERCENT,
|
|
5
|
+
} from '../constants';
|
|
6
|
+
import { addLeadingZerosAfter0x } from '../utils/addLeadingZerosAfter0x';
|
|
7
|
+
|
|
8
|
+
export const addThirdPartyTxFee = async (txBlock: TransactionBlock, price: number) => {
|
|
9
|
+
const [microTxFee] = txBlock.splitCoins(txBlock.gas, [
|
|
10
|
+
txBlock.pure(price * TRADEPORT_THIRD_PARTY_FEE_DECIMAL_PERCENT),
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
txBlock.transferObjects(
|
|
14
|
+
[txBlock.object(microTxFee)],
|
|
15
|
+
txBlock.pure(addLeadingZerosAfter0x(TRADEPORT_BENEFICIARY_ADDRESS)),
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type TransactionBlock, type TransactionObjectArgument } from '@mysten/sui.js/transactions';
|
|
2
|
+
|
|
3
|
+
type Args = {
|
|
4
|
+
txBlock: TransactionBlock;
|
|
5
|
+
coin: string | TransactionObjectArgument;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const destroyZeroCoin = ({ txBlock, coin }: Args) => {
|
|
9
|
+
txBlock.moveCall({
|
|
10
|
+
target: '0x2::coin::destroy_zero',
|
|
11
|
+
arguments: [txBlock.object(coin)],
|
|
12
|
+
typeArguments: ['0x2::sui::SUI'],
|
|
13
|
+
});
|
|
14
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASC_ROYALTY_DECIMAL_PERCENT,
|
|
3
|
+
COLLECTION_IDS_WITH_ZERO_COMMISSION,
|
|
4
|
+
DSL_LEGACY_ROYALTY_DECIMAL_PERCENT,
|
|
5
|
+
MASC_ROYALTY_DECIMAL_PERCENT,
|
|
6
|
+
TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT,
|
|
7
|
+
} from '../constants';
|
|
8
|
+
|
|
9
|
+
export const getMASCMarketFeePrice = (price: number) => {
|
|
10
|
+
if (price * (MASC_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT) < 1) {
|
|
11
|
+
return price * (MASC_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return parseInt(
|
|
15
|
+
(price * (MASC_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT))?.toFixed(0),
|
|
16
|
+
10,
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getBASCMarketFeePrice = (price: number) => {
|
|
21
|
+
if (price * (BASC_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT) < 1) {
|
|
22
|
+
return price * (BASC_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return parseInt(
|
|
26
|
+
(price * (BASC_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT))?.toFixed(0),
|
|
27
|
+
10,
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const getDSLLegacyMarketFeePrice = (price: number) => {
|
|
32
|
+
if (price * (DSL_LEGACY_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT) < 1) {
|
|
33
|
+
return price * (DSL_LEGACY_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return parseInt(
|
|
37
|
+
(price * (DSL_LEGACY_ROYALTY_DECIMAL_PERCENT + TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT))?.toFixed(
|
|
38
|
+
0,
|
|
39
|
+
),
|
|
40
|
+
10,
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type GetMarketFeePrice = {
|
|
45
|
+
price: number;
|
|
46
|
+
collectionId: string;
|
|
47
|
+
walletId: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const getMarketFeePrice = ({ price, collectionId, walletId }: GetMarketFeePrice) => {
|
|
51
|
+
if (collectionId === '6824e1ff-477e-4810-9ba7-8d6387b68c7d') {
|
|
52
|
+
return getBASCMarketFeePrice(price);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (collectionId === '8568521c-73a3-4beb-b830-d1ff27a3f1ca') {
|
|
56
|
+
return getMASCMarketFeePrice(price);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (collectionId === '307c7e7a-be3a-43a5-ae44-37f3a37d01f9') {
|
|
60
|
+
return getDSLLegacyMarketFeePrice(price);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// if (collectionId === 'c3d1ce36-6afd-4336-b619-44c745dd7569') {
|
|
64
|
+
// return getEggMarketFeePrice(price);
|
|
65
|
+
// }
|
|
66
|
+
|
|
67
|
+
let marketFeePrice = 0;
|
|
68
|
+
|
|
69
|
+
if (!COLLECTION_IDS_WITH_ZERO_COMMISSION?.includes(collectionId)) {
|
|
70
|
+
marketFeePrice = price * TRADEPORT_DEFAULT_FEE_DECIMAL_PERCENT;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (marketFeePrice < 1) {
|
|
74
|
+
return marketFeePrice;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return parseInt(marketFeePrice?.toFixed(0), 10);
|
|
78
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CRYPTOPEDIA_ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
3
|
+
FUDDIES_ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
4
|
+
GNOMES_ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
5
|
+
ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
6
|
+
SACABAM_ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
7
|
+
STORKS_ORIGIN_BYTE_ALLOW_LIST,
|
|
8
|
+
SUISHI_ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
9
|
+
SUI_ECOSYSTEM_ORIGIN_BYTE_ALLOW_LIST_OBJECT,
|
|
10
|
+
} from '../constants';
|
|
11
|
+
import { gqlChainRequest } from '../graphql/gqlChainRequest';
|
|
12
|
+
import { fetchSharedObjectsByType } from '../graphql/queries/fetchSharedObjectsByType';
|
|
13
|
+
import { addLeadingZerosAfter0x } from '../utils/addLeadingZerosAfter0x';
|
|
14
|
+
|
|
15
|
+
export type SuiSharedObjects = {
|
|
16
|
+
orderbook: string;
|
|
17
|
+
collection: string;
|
|
18
|
+
royaltyStrategy: string;
|
|
19
|
+
keepsakeRoyaltyStrategy: string;
|
|
20
|
+
transferPolicy: string;
|
|
21
|
+
marketplace: string;
|
|
22
|
+
allowList: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const getSharedObjects = async (nftType: string): Promise<SuiSharedObjects> => {
|
|
26
|
+
const nftTypeSplit = nftType?.split('::');
|
|
27
|
+
if (nftTypeSplit?.[0]) nftTypeSplit[0] = addLeadingZerosAfter0x(nftTypeSplit[0]);
|
|
28
|
+
|
|
29
|
+
const res = await gqlChainRequest({
|
|
30
|
+
chain: 'sui',
|
|
31
|
+
query: fetchSharedObjectsByType,
|
|
32
|
+
variables: { type: nftTypeSplit?.join('::') },
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
let allowList = res?.sharedObjects?.filter((object: any) => object?.module === 'allowlist')?.[0]
|
|
36
|
+
?.id;
|
|
37
|
+
if (!allowList) allowList = ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
38
|
+
if (
|
|
39
|
+
nftType === '0x5f1fa51a6d5c52df7dfe0ff7efaab7cc769d81e51cf208a424e455575aa1ed7a::stork::Stork'
|
|
40
|
+
) {
|
|
41
|
+
allowList = STORKS_ORIGIN_BYTE_ALLOW_LIST;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
nftType === '0xf1681f601a1c021a0b4c8c8859d50917308fcbebfd19364c4e856ac670bb8496::suishi::Suishi'
|
|
46
|
+
) {
|
|
47
|
+
allowList = SUISHI_ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
nftType?.includes(
|
|
52
|
+
'ac176715abe5bcdaae627c5048958bbe320a8474f524674f3278e31af3c8b86b::fuddies::Fuddies',
|
|
53
|
+
)
|
|
54
|
+
) {
|
|
55
|
+
allowList = FUDDIES_ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (
|
|
59
|
+
nftType ===
|
|
60
|
+
'0x71bd3651e47a7590e607b976a332338e2230e995fa96de430703af537086b643::cryptopedia::Cryptopedia'
|
|
61
|
+
) {
|
|
62
|
+
allowList = CRYPTOPEDIA_ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
nftType === '0xe81341eba87d19f8d53ee237b3666cff6a74c9fd7a960cf5753af69bc7c6a221::gnomes::Gnome'
|
|
67
|
+
) {
|
|
68
|
+
allowList = GNOMES_ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
nftType ===
|
|
73
|
+
'0x7f481ffff2b72f3f1d9b70d5ad999d8b514a6281aa29aedbb6c537bd4b0d04ad::sacabam::Sacabam'
|
|
74
|
+
) {
|
|
75
|
+
allowList = SACABAM_ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
nftType ===
|
|
80
|
+
'0x5fe8e884960f6977f813d871a3d43049d72d19d4ad07819b979c06434f60af4d::mint::SuiEcosystemNFT'
|
|
81
|
+
) {
|
|
82
|
+
allowList = SUI_ECOSYSTEM_ORIGIN_BYTE_ALLOW_LIST_OBJECT;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let transferPolicy = res?.sharedObjects?.filter(
|
|
86
|
+
(object: any) => object?.module === 'transfer_policy',
|
|
87
|
+
)?.[0]?.id;
|
|
88
|
+
|
|
89
|
+
if (nftTypeSplit?.join('::')?.includes('keepsake_nft::KEEPSAKE')) {
|
|
90
|
+
transferPolicy = res?.sharedObjects?.filter(
|
|
91
|
+
(object: any) =>
|
|
92
|
+
object?.type?.includes(
|
|
93
|
+
'0x02be8c4a1a3cea4d3255d870d367c87838a8cc2bfe4f216a6b67b153027087a7::transfer_policy::TransferPolicy',
|
|
94
|
+
),
|
|
95
|
+
)?.[0]?.id;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
orderbook: res?.sharedObjects?.filter((object: any) => object?.module === 'orderbook')?.[0]?.id,
|
|
100
|
+
collection: res?.sharedObjects?.filter((object: any) => object?.module === 'collection')?.[0]
|
|
101
|
+
?.id,
|
|
102
|
+
marketplace: res?.sharedObjects?.filter((object: any) => object?.module === 'marketplace')?.[0]
|
|
103
|
+
?.id,
|
|
104
|
+
royaltyStrategy: res?.sharedObjects?.filter(
|
|
105
|
+
(object: any) => object?.module === 'royalty_strategy_bps',
|
|
106
|
+
)?.[0]?.id,
|
|
107
|
+
keepsakeRoyaltyStrategy: res?.sharedObjects?.filter(
|
|
108
|
+
(object: any) => object?.module === 'keepsake_royalties',
|
|
109
|
+
)?.[0]?.id,
|
|
110
|
+
transferPolicy,
|
|
111
|
+
allowList,
|
|
112
|
+
};
|
|
113
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { gqlChainRequest } from '../graphql/gqlChainRequest';
|
|
2
|
+
import { fetchCryptoToUsdRate } from '../graphql/queries/fetchCryptoToUsdRate';
|
|
3
|
+
|
|
4
|
+
export const getSuiToUsdRate = async (): Promise<number> => {
|
|
5
|
+
try {
|
|
6
|
+
const res = await gqlChainRequest({
|
|
7
|
+
chain: 'sui',
|
|
8
|
+
query: fetchCryptoToUsdRate,
|
|
9
|
+
variables: { crypto: 'sui' },
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return res?.crypto_rates?.[0]?.rate;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
console.log(e);
|
|
15
|
+
// TODO alert that the rate could not be fetched
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASC_ROYALTY_DECIMAL_PERCENT,
|
|
3
|
+
DSL_LEGACY_ROYALTY_DECIMAL_PERCENT,
|
|
4
|
+
MASC_ROYALTY_DECIMAL_PERCENT,
|
|
5
|
+
} from '../constants';
|
|
6
|
+
import { parseSUI } from '../utils/parseSUI';
|
|
7
|
+
|
|
8
|
+
interface Args {
|
|
9
|
+
bidAmount: number;
|
|
10
|
+
collectionId: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const getTradeportBiddingContractParsedBidAmount = ({ bidAmount, collectionId }: Args) => {
|
|
14
|
+
let amount = bidAmount;
|
|
15
|
+
|
|
16
|
+
// MASC
|
|
17
|
+
if (collectionId === '8568521c-73a3-4beb-b830-d1ff27a3f1ca') {
|
|
18
|
+
amount = bidAmount - bidAmount * MASC_ROYALTY_DECIMAL_PERCENT;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// BASC
|
|
22
|
+
if (collectionId === '6824e1ff-477e-4810-9ba7-8d6387b68c7d') {
|
|
23
|
+
amount = bidAmount - bidAmount * BASC_ROYALTY_DECIMAL_PERCENT;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// DSL Legacy
|
|
27
|
+
if (collectionId === '307c7e7a-be3a-43a5-ae44-37f3a37d01f9') {
|
|
28
|
+
amount = bidAmount - bidAmount * DSL_LEGACY_ROYALTY_DECIMAL_PERCENT;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return Number(parseSUI(amount));
|
|
32
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import kioskClient from '../apiClients/kioskClient';
|
|
2
|
+
import { addLeadingZerosAfter0x } from '../utils/addLeadingZerosAfter0x';
|
|
3
|
+
|
|
4
|
+
export const hasRoyaltyRule = async (nftType: string): Promise<boolean> => {
|
|
5
|
+
const nftTypeSplit = nftType?.split('::');
|
|
6
|
+
if (nftTypeSplit?.[0]) nftTypeSplit[0] = addLeadingZerosAfter0x(nftTypeSplit[0]);
|
|
7
|
+
|
|
8
|
+
const res = await kioskClient.getTransferPolicies({ type: nftTypeSplit?.join('::') });
|
|
9
|
+
|
|
10
|
+
return res?.some(
|
|
11
|
+
(policy: any) =>
|
|
12
|
+
policy?.rules?.filter((rule: any) => rule?.includes('royalty_rule'))?.length > 0,
|
|
13
|
+
);
|
|
14
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import kioskClient from '../apiClients/kioskClient';
|
|
2
|
+
import { addLeadingZerosAfter0x } from '../utils/addLeadingZerosAfter0x';
|
|
3
|
+
|
|
4
|
+
export const hasTransferPolicyRules = async (nftType: string): Promise<boolean> => {
|
|
5
|
+
const nftTypeSplit = nftType?.split('::');
|
|
6
|
+
if (nftTypeSplit?.[0]) nftTypeSplit[0] = addLeadingZerosAfter0x(nftTypeSplit[0]);
|
|
7
|
+
|
|
8
|
+
// const res = await gqlChainRequest({
|
|
9
|
+
// chain: 'sui',
|
|
10
|
+
// query: fetchTransferPoliciesByType,
|
|
11
|
+
// variables: { type: nftTypeSplit?.join('::') },
|
|
12
|
+
// });
|
|
13
|
+
|
|
14
|
+
// return res?.transfer_policies_by_type
|
|
15
|
+
// ?.filter((policy: any) => !policy?.is_origin_byte)
|
|
16
|
+
// ?.some((policy: any) => policy?.rules?.length > 0);
|
|
17
|
+
|
|
18
|
+
const res = await kioskClient.getTransferPolicies({ type: nftTypeSplit?.join('::') });
|
|
19
|
+
|
|
20
|
+
return res?.some((policy: any) => policy?.rules?.length > 0);
|
|
21
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NON_KIOSK_LISTING_NONCE_TYPE } from '../constants';
|
|
2
|
+
import { getObjectType } from './rpc/getObjectType';
|
|
3
|
+
|
|
4
|
+
export const isNonKioskListing = async (listingNonce: string): Promise<boolean> => {
|
|
5
|
+
const listingType = await getObjectType(listingNonce);
|
|
6
|
+
return listingType === NON_KIOSK_LISTING_NONCE_TYPE;
|
|
7
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getNormalizedRuleType } from '@mysten/kiosk';
|
|
2
|
+
import kioskClient from '../../apiClients/kioskClient';
|
|
3
|
+
import { addHexPrefix } from '../../utils/addHexPrefix';
|
|
4
|
+
|
|
5
|
+
type RuleType = 'kiosk_royalty_rule' | 'royalty_rule' | 'personal_kiosk_rule' | 'kiosk_lock_rule';
|
|
6
|
+
|
|
7
|
+
export const getRulePackageId = async (nftType: string, ruleType: RuleType) => {
|
|
8
|
+
const transferPolicies = await kioskClient.getTransferPolicies({
|
|
9
|
+
type: nftType,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const rule = transferPolicies
|
|
13
|
+
.flatMap((policy) => policy.rules)
|
|
14
|
+
.filter((rule) => rule?.split('::')?.[1] === ruleType)?.[0];
|
|
15
|
+
|
|
16
|
+
const ruleDefinition = kioskClient.rules.find(
|
|
17
|
+
(x) => getNormalizedRuleType(x.rule) === getNormalizedRuleType(rule),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
let rulePackageId = ruleDefinition?.packageId;
|
|
21
|
+
if (!rulePackageId) {
|
|
22
|
+
rulePackageId = rule?.split('::')?.[0];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return addHexPrefix(rulePackageId);
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const isBluemoveKioskBid = (bidNonce: string): boolean => bidNonce?.startsWith('10000');
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { KioskTransaction } from '@mysten/kiosk';
|
|
2
|
+
import { type TransactionBlock } from '@mysten/sui.js/transactions';
|
|
3
|
+
import kioskClient from '../../apiClients/kioskClient';
|
|
4
|
+
import { gqlChainRequest } from '../../graphql/gqlChainRequest';
|
|
5
|
+
import { fetchKiosksByOwner } from '../../graphql/queries/fetchKiosksByOwner';
|
|
6
|
+
import { fetchOwnerCapByKiosk } from '../../graphql/queries/fetchOwnerCapByKiosk';
|
|
7
|
+
import { fetchPersonalCapByKiosk } from '../../graphql/queries/fetchPersonalCapByKiosk';
|
|
8
|
+
import { addLeadingZerosAfter0x } from '../../utils/addLeadingZerosAfter0x';
|
|
9
|
+
|
|
10
|
+
type Args = {
|
|
11
|
+
txBlock: TransactionBlock;
|
|
12
|
+
kioskOwner: string;
|
|
13
|
+
kiosk?: any;
|
|
14
|
+
tx: (kioskTx: KioskTransaction) => Promise<void>;
|
|
15
|
+
shouldConvertToPersonalKiosk?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const kioskTxWrapper = async ({
|
|
19
|
+
txBlock,
|
|
20
|
+
kioskOwner,
|
|
21
|
+
kiosk,
|
|
22
|
+
tx,
|
|
23
|
+
shouldConvertToPersonalKiosk,
|
|
24
|
+
}: Args) => {
|
|
25
|
+
let kioskTx: KioskTransaction;
|
|
26
|
+
let kiosks = ((
|
|
27
|
+
await gqlChainRequest({
|
|
28
|
+
chain: 'sui',
|
|
29
|
+
query: fetchKiosksByOwner,
|
|
30
|
+
variables: { ownerAddress: addLeadingZerosAfter0x(kioskOwner) },
|
|
31
|
+
})
|
|
32
|
+
).kiosks ?? []) as Array<{
|
|
33
|
+
id: string;
|
|
34
|
+
is_personal: boolean;
|
|
35
|
+
is_origin_byte: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
|
|
38
|
+
kiosks = kiosks?.filter((k) => !k.is_origin_byte);
|
|
39
|
+
|
|
40
|
+
if (kiosk) {
|
|
41
|
+
const filteredKiosks = kiosks.filter((k) => k?.id === kiosk);
|
|
42
|
+
if (filteredKiosks.length > 0) {
|
|
43
|
+
kiosks = filteredKiosks;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const personalKiosk = kiosks.find((k) => k.is_personal);
|
|
48
|
+
|
|
49
|
+
if (personalKiosk) {
|
|
50
|
+
// using existing personal kiosk
|
|
51
|
+
const personalKioskCapId = (
|
|
52
|
+
await gqlChainRequest({
|
|
53
|
+
chain: 'sui',
|
|
54
|
+
query: fetchPersonalCapByKiosk,
|
|
55
|
+
variables: { kioskId: personalKiosk.id },
|
|
56
|
+
})
|
|
57
|
+
).personalCap.id;
|
|
58
|
+
|
|
59
|
+
kioskTx = new KioskTransaction({
|
|
60
|
+
transactionBlock: txBlock as any,
|
|
61
|
+
kioskClient,
|
|
62
|
+
cap: {
|
|
63
|
+
isPersonal: true,
|
|
64
|
+
objectId: personalKioskCapId,
|
|
65
|
+
kioskId: personalKiosk.id,
|
|
66
|
+
digest: '',
|
|
67
|
+
version: '',
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
} else if (kiosks.length > 0) {
|
|
71
|
+
const kioskCapId = (
|
|
72
|
+
await gqlChainRequest({
|
|
73
|
+
chain: 'sui',
|
|
74
|
+
query: fetchOwnerCapByKiosk,
|
|
75
|
+
variables: { kioskId: kiosks[0].id },
|
|
76
|
+
})
|
|
77
|
+
).ownerCap?.id;
|
|
78
|
+
|
|
79
|
+
kioskTx = new KioskTransaction({
|
|
80
|
+
transactionBlock: txBlock as any,
|
|
81
|
+
kioskClient,
|
|
82
|
+
cap: {
|
|
83
|
+
isPersonal: false,
|
|
84
|
+
objectId: kioskCapId,
|
|
85
|
+
kioskId: kiosks[0].id,
|
|
86
|
+
digest: '',
|
|
87
|
+
version: '',
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (shouldConvertToPersonalKiosk) {
|
|
92
|
+
kioskTx.convertToPersonal(true);
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
// creating new personal kiosk
|
|
96
|
+
kioskTx = new KioskTransaction({ transactionBlock: txBlock as any, kioskClient });
|
|
97
|
+
kioskTx.createPersonal(true);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
await tx(kioskTx);
|
|
101
|
+
kioskTx.finalize();
|
|
102
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ObjectArgument } from '@mysten/kiosk';
|
|
2
|
+
import { type TransactionObjectArgument } from '@mysten/sui.js/dist/cjs/builder';
|
|
3
|
+
import { type TransactionBlock } from '@mysten/sui.js/transactions';
|
|
4
|
+
|
|
5
|
+
type Args = {
|
|
6
|
+
txBlock: TransactionBlock;
|
|
7
|
+
packageId: string;
|
|
8
|
+
transferRequest: TransactionObjectArgument;
|
|
9
|
+
nftType: string;
|
|
10
|
+
policyId: ObjectArgument;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function resolveFloorPriceRule({
|
|
14
|
+
txBlock,
|
|
15
|
+
packageId,
|
|
16
|
+
nftType,
|
|
17
|
+
policyId,
|
|
18
|
+
transferRequest,
|
|
19
|
+
}: Args) {
|
|
20
|
+
txBlock.moveCall({
|
|
21
|
+
target: `${packageId}::floor_price_rule::prove`,
|
|
22
|
+
typeArguments: [nftType],
|
|
23
|
+
arguments: [txBlock.object(policyId), transferRequest],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ObjectArgument } from '@mysten/kiosk';
|
|
2
|
+
import { type TransactionBlock, type TransactionObjectArgument } from '@mysten/sui.js/transactions';
|
|
3
|
+
|
|
4
|
+
type Args = {
|
|
5
|
+
txBlock: TransactionBlock;
|
|
6
|
+
policyId: ObjectArgument;
|
|
7
|
+
packageId: string;
|
|
8
|
+
transferRequest: TransactionObjectArgument;
|
|
9
|
+
nftType: string;
|
|
10
|
+
kiosk: ObjectArgument;
|
|
11
|
+
kioskCap: ObjectArgument;
|
|
12
|
+
kioskItem?: ObjectArgument;
|
|
13
|
+
shouldSkipLocking?: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function resolveKioskLockRule({
|
|
17
|
+
txBlock,
|
|
18
|
+
packageId,
|
|
19
|
+
policyId,
|
|
20
|
+
transferRequest,
|
|
21
|
+
nftType,
|
|
22
|
+
kiosk,
|
|
23
|
+
kioskCap,
|
|
24
|
+
kioskItem,
|
|
25
|
+
shouldSkipLocking,
|
|
26
|
+
}: Args) {
|
|
27
|
+
if (!kiosk || !kioskCap) throw new Error('Missing Owned Kiosk or Owned Kiosk Cap');
|
|
28
|
+
|
|
29
|
+
if (!shouldSkipLocking) {
|
|
30
|
+
if (!kioskItem) throw new Error('Missing Kiosk Item');
|
|
31
|
+
|
|
32
|
+
txBlock.moveCall({
|
|
33
|
+
target: '0x2::kiosk::lock',
|
|
34
|
+
typeArguments: [nftType],
|
|
35
|
+
arguments: [
|
|
36
|
+
txBlock.object(kiosk),
|
|
37
|
+
txBlock.object(kioskCap),
|
|
38
|
+
txBlock.object(policyId),
|
|
39
|
+
txBlock.object(kioskItem),
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
txBlock.moveCall({
|
|
45
|
+
target: `${packageId}::kiosk_lock_rule::prove`,
|
|
46
|
+
typeArguments: [nftType],
|
|
47
|
+
arguments: [transferRequest, txBlock.object(kiosk)],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ObjectArgument } from '@mysten/kiosk';
|
|
2
|
+
import { type TransactionBlock, type TransactionObjectArgument } from '@mysten/sui.js/transactions';
|
|
3
|
+
|
|
4
|
+
type Args = {
|
|
5
|
+
txBlock: TransactionBlock;
|
|
6
|
+
packageId: string;
|
|
7
|
+
transferRequest: TransactionObjectArgument;
|
|
8
|
+
nftType: string;
|
|
9
|
+
kiosk: ObjectArgument;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function resolvePersonalKioskRule({
|
|
13
|
+
txBlock,
|
|
14
|
+
packageId,
|
|
15
|
+
nftType,
|
|
16
|
+
kiosk,
|
|
17
|
+
transferRequest,
|
|
18
|
+
}: Args) {
|
|
19
|
+
if (!kiosk) throw new Error('Missing owned Kiosk.');
|
|
20
|
+
|
|
21
|
+
txBlock.moveCall({
|
|
22
|
+
target: `${packageId}::personal_kiosk_rule::prove`,
|
|
23
|
+
typeArguments: [nftType],
|
|
24
|
+
arguments: [txBlock.object(kiosk), transferRequest],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ObjectArgument } from '@mysten/kiosk';
|
|
2
|
+
import { type TransactionBlock, type TransactionObjectArgument } from '@mysten/sui.js/transactions';
|
|
3
|
+
|
|
4
|
+
type Args = {
|
|
5
|
+
txBlock: TransactionBlock;
|
|
6
|
+
policyId: ObjectArgument;
|
|
7
|
+
moduleName: string;
|
|
8
|
+
packageId: string;
|
|
9
|
+
transferRequest: TransactionObjectArgument;
|
|
10
|
+
nftType: string;
|
|
11
|
+
price?: string;
|
|
12
|
+
priceObjectArgument?: ObjectArgument;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function resolveRoyaltyRule({
|
|
16
|
+
txBlock,
|
|
17
|
+
packageId,
|
|
18
|
+
moduleName,
|
|
19
|
+
policyId,
|
|
20
|
+
transferRequest,
|
|
21
|
+
nftType,
|
|
22
|
+
price,
|
|
23
|
+
priceObjectArgument,
|
|
24
|
+
}: Args) {
|
|
25
|
+
const [amount] = txBlock.moveCall({
|
|
26
|
+
target: `${packageId}::${moduleName}::fee_amount`,
|
|
27
|
+
typeArguments: [nftType],
|
|
28
|
+
arguments: [
|
|
29
|
+
txBlock.object(policyId),
|
|
30
|
+
priceObjectArgument ? txBlock.object(priceObjectArgument) : txBlock.pure(price || '0'),
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const feeCoin = txBlock.splitCoins(txBlock.gas, [amount]);
|
|
35
|
+
|
|
36
|
+
txBlock.moveCall({
|
|
37
|
+
target: `${packageId}::${moduleName}::pay`,
|
|
38
|
+
typeArguments: [nftType],
|
|
39
|
+
arguments: [txBlock.object(policyId), transferRequest, feeCoin],
|
|
40
|
+
});
|
|
41
|
+
}
|