@tradeport/sui-trading-sdk 0.2.1 → 0.3.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tradeport/sui-trading-sdk",
3
3
  "license": "MIT",
4
- "version": "0.2.1",
4
+ "version": "0.3.0",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -1,9 +1,23 @@
1
+ import { type Transaction } from '@mysten/sui/dist/cjs/transactions';
1
2
  import { TRADEPORT_KIOSK_TRANSFERS_STORE } from '../../constants';
3
+ import { destroyZeroCoin } from '../../helpers/destroyZeroCoin';
4
+ import { getNftType } from '../../helpers/getNftType';
2
5
  import { assertNftInSharedKiosk } from '../../helpers/kiosk/assertNftInSharedKiosk';
3
6
  import { getKioskTransferPolicies } from '../../helpers/kiosk/getKioskTransferPolicies';
7
+ import { kioskTxWrapper } from '../../helpers/kiosk/kioskTxWrapper';
4
8
  import { getOBKiosk } from '../../helpers/originByte/getOBKiosk';
5
9
  import { addLeadingZerosAfter0x } from '../../utils/addLeadingZerosAfter0x';
6
10
  import { type TransferNftTx } from './transferNfts';
11
+ import { type KioskClient } from '@mysten/kiosk';
12
+
13
+ type CollectionChainState = {
14
+ transfer_policies: TransferPolicy[];
15
+ };
16
+ type TransferPolicy = {
17
+ id: string;
18
+ rules: Array<{ type: string; min_amount?: string }>;
19
+ is_origin_byte: boolean;
20
+ };
7
21
 
8
22
  export async function addOriginByteTransferNftTx({
9
23
  tx,
@@ -69,3 +83,97 @@ export async function addTradeportKioskTransferTx({
69
83
  typeArguments: [nftType],
70
84
  });
71
85
  }
86
+
87
+ export async function addTradeportKioskDirectTransferTx(
88
+ txData: {
89
+ tx: Transaction;
90
+ recipientAddress: string;
91
+ kioskClient: KioskClient;
92
+ senderAddress: string;
93
+ },
94
+ nfts: any[],
95
+ ) {
96
+ const { tx, recipientAddress, kioskClient, senderAddress } = txData;
97
+ if (nfts.length === 0) {
98
+ return;
99
+ }
100
+
101
+ const [receiverKiosk, receiverKioskCap] = tx.moveCall({
102
+ target: '0x2::kiosk::new',
103
+ arguments: [],
104
+ });
105
+ const recipientAddressWithPrefix = addLeadingZerosAfter0x(recipientAddress);
106
+ tx.moveCall({
107
+ target: '0x2::kiosk::set_owner_custom',
108
+ arguments: [
109
+ tx.object(receiverKiosk),
110
+ tx.object(receiverKioskCap),
111
+ tx.pure.address(recipientAddressWithPrefix),
112
+ ],
113
+ });
114
+ const totalRoyaltyAmount = nfts.reduce(
115
+ (sum: bigint, nft) =>
116
+ sum +
117
+ BigInt(
118
+ getTransferPolicyForDirectTransfer(nft.collection.chain_state)?.rules?.find(
119
+ (rule) => rule.type === 'royalty_rule',
120
+ )?.min_amount ?? 0n,
121
+ ),
122
+ 0n,
123
+ );
124
+ const [royaltyCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(totalRoyaltyAmount)]);
125
+ for (const nft of nfts) {
126
+ const nftType = getNftType({
127
+ collectionId: nft?.collection?.id,
128
+ collectionChainState: nft?.collection?.chain_state,
129
+ nft,
130
+ });
131
+
132
+ await kioskTxWrapper({
133
+ tx,
134
+ kioskClient,
135
+ kioskOwner: senderAddress,
136
+ kiosk: nft?.chain_state?.kiosk_id,
137
+ async runCommands(kioskTx) {
138
+ tx.moveCall({
139
+ target:
140
+ '0xd0ad5bf7ac7d372cdcfee5273d5e487dabad724040e089c626cba2a01127ccd6::kiosk_transfers::direct_transfer',
141
+ arguments: [
142
+ tx.object(kioskTx.getKiosk() as any),
143
+ tx.object(kioskTx.getKioskCap() as any),
144
+ tx.object(receiverKiosk),
145
+ tx.object(receiverKioskCap),
146
+ tx.pure.id(nft.token_id),
147
+ tx.object(getTransferPolicyForDirectTransfer(nft.collection.chain_state).id),
148
+ royaltyCoin,
149
+ ],
150
+ typeArguments: [nftType],
151
+ });
152
+ },
153
+ });
154
+ }
155
+
156
+ tx.transferObjects([receiverKioskCap], tx.pure.address(recipientAddressWithPrefix));
157
+ tx.moveCall({
158
+ target: '0x2::transfer::public_share_object',
159
+ arguments: [receiverKiosk],
160
+ typeArguments: ['0x2::kiosk::Kiosk'],
161
+ });
162
+ destroyZeroCoin({ tx, coin: royaltyCoin });
163
+ }
164
+
165
+ export function canBeTransferedDirectly(collectionChainState?: CollectionChainState) {
166
+ return getTransferPolicyForDirectTransfer(collectionChainState) !== undefined;
167
+ }
168
+
169
+ export function getTransferPolicyForDirectTransfer(
170
+ collectionChainState?: CollectionChainState,
171
+ ): TransferPolicy | undefined {
172
+ return collectionChainState?.transfer_policies?.find(
173
+ (policy) =>
174
+ !policy.is_origin_byte &&
175
+ policy.rules?.filter(
176
+ (rule) => rule.type !== 'kiosk_lock_rule' && rule.type !== 'royalty_rule',
177
+ ).length === 0,
178
+ );
179
+ }
@@ -7,14 +7,18 @@ import {
7
7
  } from '../../constants';
8
8
  import { gqlChainRequest } from '../../graphql/gqlChainRequest';
9
9
  import { fetchNftsById } from '../../graphql/queries/fetchNftsById';
10
- import { addOneDollarFee } from '../../helpers/addOneDollarFee';
11
10
  import { getNftType } from '../../helpers/getNftType';
12
11
  import { getSharedObjects } from '../../helpers/getSharedObjects';
13
12
  import { kioskTxWrapper } from '../../helpers/kiosk/kioskTxWrapper';
14
13
  import { isOBKiosk } from '../../helpers/originByte/isOBKiosk';
15
14
  import { getAccountBalance } from '../../helpers/rpc/getAcountBalance';
16
15
  import { addLeadingZerosAfter0x } from '../../utils/addLeadingZerosAfter0x';
17
- import { addOriginByteTransferNftTx, addTradeportKioskTransferTx } from './addTransferNftTx';
16
+ import {
17
+ addOriginByteTransferNftTx,
18
+ addTradeportKioskDirectTransferTx,
19
+ addTradeportKioskTransferTx,
20
+ canBeTransferedDirectly,
21
+ } from './addTransferNftTx';
18
22
 
19
23
  export type TransferNftTx = {
20
24
  tx: Transaction;
@@ -67,6 +71,7 @@ export const transferNfts = async (
67
71
  }
68
72
 
69
73
  const nftsForTracking = [];
74
+ const nftsToTransferDirectly = [];
70
75
  const tx = new Transaction();
71
76
 
72
77
  for (const nft of res.nfts) {
@@ -116,16 +121,22 @@ export const transferNfts = async (
116
121
  }
117
122
 
118
123
  // If NFT is inside native kiosk
119
- await kioskTxWrapper({
120
- tx: txData?.tx,
121
- kioskClient: txData?.kioskClient,
122
- kioskOwner: txData?.senderAddress,
123
- kiosk: txData?.senderKiosk,
124
- shouldAssertNftInSharedKiosk: true,
125
- async runCommands(kioskTx) {
126
- await addTradeportKioskTransferTx({ ...txData, kioskTx });
127
- },
128
- });
124
+
125
+ // If NFT can be transfered directly by creating new kiosk for receiver
126
+ if (canBeTransferedDirectly(nft?.collection?.chain_state)) {
127
+ nftsToTransferDirectly.push(nft);
128
+ } else {
129
+ await kioskTxWrapper({
130
+ tx: txData?.tx,
131
+ kioskClient: txData?.kioskClient,
132
+ kioskOwner: txData?.senderAddress,
133
+ kiosk: txData?.senderKiosk,
134
+ shouldAssertNftInSharedKiosk: true,
135
+ async runCommands(kioskTx) {
136
+ await addTradeportKioskTransferTx({ ...txData, kioskTx });
137
+ },
138
+ });
139
+ }
129
140
 
130
141
  nftsForTracking.push({
131
142
  nftType,
@@ -134,9 +145,15 @@ export const transferNfts = async (
134
145
  });
135
146
  }
136
147
 
137
- if (res?.nfts?.length > 1) {
138
- await addOneDollarFee(tx);
139
- }
148
+ await addTradeportKioskDirectTransferTx(
149
+ { tx, kioskClient: context.kioskClient, senderAddress: walletAddress, recipientAddress },
150
+ nftsToTransferDirectly,
151
+ );
152
+
153
+ // currently turned off $1 bulk transfer fee
154
+ // if (res?.nfts?.length > 1) {
155
+ // await addOneDollarFee(tx);
156
+ // }
140
157
 
141
158
  // if (process.env.ENABLE_SEGMENT_TRACKING === 'true' && nftsForTracking.length > 0) {
142
159
  // trackMethodCall({