@0xsequence/marketplace-sdk 0.5.2 → 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.
- package/dist/builder-types-Jl3Ymws8.d.ts +73 -0
- package/dist/{chunk-XP3WY5AX.js → chunk-7C7ADZ2H.js} +3 -3
- package/dist/{chunk-XP3WY5AX.js.map → chunk-7C7ADZ2H.js.map} +1 -1
- package/dist/{chunk-FCF57DZI.js → chunk-7FN62HOP.js} +5 -9
- package/dist/chunk-7FN62HOP.js.map +1 -0
- package/dist/chunk-DZKPDV63.js +27 -0
- package/dist/chunk-DZKPDV63.js.map +1 -0
- package/dist/{chunk-ZUEQGPLO.js → chunk-J6F5QOW5.js} +2 -2
- package/dist/{chunk-ZUEQGPLO.js.map → chunk-J6F5QOW5.js.map} +1 -1
- package/dist/{chunk-I37CRQ4S.js → chunk-JWNONWD6.js} +259 -173
- package/dist/chunk-JWNONWD6.js.map +1 -0
- package/dist/{chunk-LJAB3S6U.js → chunk-TFRAOS7F.js} +22 -13
- package/dist/chunk-TFRAOS7F.js.map +1 -0
- package/dist/{chunk-MKGSGTQC.js → chunk-TLNRD4BQ.js} +3 -3
- package/dist/{chunk-5NORRVPM.js → chunk-UZIAX32Y.js} +1 -1
- package/dist/{chunk-5NORRVPM.js.map → chunk-UZIAX32Y.js.map} +1 -1
- package/dist/chunk-WGGZEQHL.js +56 -0
- package/dist/chunk-WGGZEQHL.js.map +1 -0
- package/dist/{chunk-MWDG7UTB.js → chunk-ZBLU3Q22.js} +1 -1
- package/dist/{chunk-MSTTVFVQ.js → chunk-ZGVCOQ4I.js} +383 -283
- package/dist/chunk-ZGVCOQ4I.js.map +1 -0
- package/dist/{create-config-BXvwUh55.d.ts → create-config-DOUq8Day.d.ts} +2 -2
- package/dist/index.css +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +10 -6
- package/dist/{sdk-config-B32_2bG3.d.ts → marketplace.gen-D0ADxbfH.d.ts} +1 -24
- package/dist/react/_internal/api/index.d.ts +3 -2
- package/dist/react/_internal/databeat/index.css +82 -0
- package/dist/react/_internal/databeat/index.css.map +1 -0
- package/dist/react/_internal/databeat/index.d.ts +68 -0
- package/dist/react/_internal/databeat/index.js +26 -0
- package/dist/react/_internal/databeat/index.js.map +1 -0
- package/dist/react/_internal/index.d.ts +6 -5
- package/dist/react/_internal/index.js +6 -6
- package/dist/react/_internal/wagmi/index.d.ts +4 -4
- package/dist/react/_internal/wagmi/index.js +1 -1
- package/dist/react/hooks/index.d.ts +367 -22
- package/dist/react/hooks/index.js +9 -7
- package/dist/react/index.css +1 -1
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.ts +7 -6
- package/dist/react/index.js +15 -12
- package/dist/react/ssr/index.d.ts +54 -41
- package/dist/react/ssr/index.js +5 -9
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/collectible-card/index.css +1 -1
- package/dist/react/ui/components/collectible-card/index.css.map +1 -1
- package/dist/react/ui/components/collectible-card/index.d.ts +4 -3
- package/dist/react/ui/components/collectible-card/index.js +9 -8
- package/dist/react/ui/components/marketplace-logos/index.js +1 -1
- package/dist/react/ui/index.css +1 -1
- package/dist/react/ui/index.css.map +1 -1
- package/dist/react/ui/index.d.ts +4 -3
- package/dist/react/ui/index.js +9 -8
- package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +4 -3
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +6 -6
- package/dist/react/ui/styles/index.d.ts +1 -1
- package/dist/sdk-config-xWkdBdrL.d.ts +24 -0
- package/dist/{services-BRBVE0mm.d.ts → services-Dd2MoBTM.d.ts} +2 -1
- package/dist/styles/index.css +1 -1
- package/dist/styles/index.css.map +1 -1
- package/dist/styles/index.d.ts +1 -1
- package/dist/styles/index.js +1 -1
- package/dist/types/index.d.ts +4 -5
- package/dist/types/index.js +9 -5
- package/dist/{types-Yto6KrTN.d.ts → types-vOfhbBkR.d.ts} +3 -2
- package/dist/utils/index.d.ts +4 -3
- package/dist/utils/index.js +4 -4
- package/package.json +12 -10
- package/src/react/_internal/api/__mocks__/indexer.msw.ts +197 -0
- package/src/react/_internal/api/__mocks__/marketplace.msw.ts +140 -1
- package/src/react/_internal/api/__mocks__/metadata.msw.ts +162 -0
- package/src/react/_internal/databeat/index.ts +63 -0
- package/src/react/_internal/databeat/types.ts +70 -0
- package/src/react/_internal/test/mocks/publicClient.ts +39 -0
- package/src/react/_internal/test/mocks/wagmi.ts +61 -0
- package/src/react/_internal/test/mocks/wallet.ts +61 -0
- package/src/react/_internal/test/setup.ts +28 -0
- package/src/react/_internal/test-utils.tsx +31 -2
- package/src/react/_internal/wagmi/__tests__/create-config.test.ts +53 -20
- package/src/react/_internal/wagmi/create-config.ts +3 -4
- package/src/react/_internal/wagmi/embedded.ts +1 -4
- package/src/react/_internal/wagmi/universal.ts +1 -4
- package/src/react/_internal/wallet/wallet.ts +1 -0
- package/src/react/hooks/__tests__/useAutoSelectFeeOption.test.tsx +314 -0
- package/src/react/hooks/__tests__/useBalanceOfCollectible.test.tsx +148 -0
- package/src/react/hooks/__tests__/useCancelOrder.test.tsx +410 -0
- package/src/react/hooks/__tests__/useCancelTransactionSteps.test.tsx +269 -0
- package/src/react/hooks/__tests__/useCollectible.test.tsx +120 -0
- package/src/react/hooks/__tests__/useCollection.test.tsx +101 -0
- package/src/react/hooks/__tests__/useCollectionBalanceDetails.test.tsx +175 -0
- package/src/react/hooks/__tests__/useCollectionDetails.test.tsx +82 -0
- package/src/react/hooks/__tests__/useCollectionDetailsPolling.test.tsx +133 -0
- package/src/react/hooks/__tests__/useCountListingsForCollectible.test.tsx +108 -0
- package/src/react/hooks/__tests__/useCountOfCollectables.test.tsx +129 -0
- package/src/react/hooks/__tests__/useCountOffersForCollectible.test.tsx +108 -0
- package/src/react/hooks/__tests__/useCurrencies.test.tsx +176 -0
- package/src/react/hooks/__tests__/useCurrency.test.tsx +153 -0
- package/src/react/hooks/__tests__/useCurrencyBalance.test.tsx +111 -0
- package/src/react/hooks/__tests__/useFilters.test.tsx +127 -0
- package/src/react/hooks/__tests__/useFloorOrder.test.tsx +101 -0
- package/src/react/hooks/__tests__/useGenerateBuyTransaction.test.tsx +173 -0
- package/src/react/hooks/__tests__/useGenerateCancelTransaction.test.tsx +207 -0
- package/src/react/hooks/__tests__/useGenerateListingTransaction.test.tsx +207 -0
- package/src/react/hooks/__tests__/useGenerateOfferTransaction.test.tsx +205 -0
- package/src/react/hooks/__tests__/useGenerateSellTransaction.test.tsx +181 -0
- package/src/react/hooks/__tests__/useHighestOffer.test.tsx +118 -0
- package/src/react/hooks/__tests__/useListBalances.test.tsx +136 -0
- package/src/react/hooks/__tests__/useListCollectibleActivities.test.tsx +200 -0
- package/src/react/hooks/__tests__/useListCollectibles.test.tsx +232 -0
- package/src/react/hooks/__tests__/useListCollectiblesPaginated.test.tsx +217 -0
- package/src/react/hooks/__tests__/useListCollectionActivities.test.tsx +235 -0
- package/src/react/hooks/__tests__/useListCollections.test.tsx +296 -0
- package/src/react/hooks/__tests__/useListListingsForCollectible.test.tsx +140 -0
- package/src/react/hooks/__tests__/useListOffersForCollectible.test.tsx +140 -0
- package/src/react/hooks/__tests__/useLowestListing.test.tsx +148 -0
- package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +106 -0
- package/src/react/hooks/__tests__/useRoyaltyPercentage.test.tsx +129 -0
- package/src/react/hooks/index.ts +1 -1
- package/src/react/hooks/options/__mocks__/marketplaceConfig.msw.ts +66 -10
- package/src/react/hooks/options/__tests__/marketplaceConfigOptions.test.tsx +2 -11
- package/src/react/hooks/options/marketplaceConfigOptions.ts +8 -3
- package/src/react/hooks/useAutoSelectFeeOption.tsx +4 -3
- package/src/react/hooks/useCancelTransactionSteps.tsx +17 -9
- package/src/react/hooks/useCollectionDetailsPolling.tsx +1 -1
- package/src/react/hooks/useCurrencies.tsx +29 -28
- package/src/react/hooks/useFilters.tsx +75 -2
- package/src/react/hooks/useGenerateBuyTransaction.tsx +13 -5
- package/src/react/hooks/useListCollectibleActivities.tsx +1 -0
- package/src/react/hooks/useListCollectibles.tsx +1 -0
- package/src/react/hooks/useListCollectiblesPaginated.tsx +78 -0
- package/src/react/hooks/useListCollectionActivities.tsx +1 -0
- package/src/react/hooks/useListCollections.tsx +2 -2
- package/src/react/ui/components/_internals/custom-select/__tests__/CustomSelect.test.tsx +6 -2
- package/src/react/ui/components/collectible-card/CollectibleCard.tsx +1 -1
- package/src/react/ui/components/collectible-card/Footer.tsx +9 -5
- package/src/react/ui/modals/BuyModal/Modal.tsx +9 -4
- package/src/react/ui/modals/BuyModal/__tests__/Modal.test.tsx +0 -1
- package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +4 -2
- package/src/react/ui/modals/BuyModal/hooks/__tests__/useBuyCollectable.test.tsx +1 -24
- package/src/react/ui/modals/BuyModal/hooks/__tests__/useCheckoutOptions.test.tsx +152 -210
- package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +19 -49
- package/src/react/ui/modals/BuyModal/hooks/useFees.ts +6 -6
- package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +4 -2
- package/src/react/ui/modals/BuyModal/modals/__tests__/Modal1155.test.tsx +161 -52
- package/src/react/ui/modals/BuyModal/store.ts +7 -0
- package/src/react/ui/modals/CreateListingModal/Modal.tsx +1 -3
- package/src/react/ui/modals/CreateListingModal/__tests__/Modal.test.tsx +59 -227
- package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +2 -1
- package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +47 -7
- package/src/react/ui/modals/MakeOfferModal/Modal.tsx +1 -8
- package/src/react/ui/modals/MakeOfferModal/__tests__/Modal.test.tsx +41 -118
- package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +2 -1
- package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +34 -6
- package/src/react/ui/modals/SellModal/Modal.tsx +3 -1
- package/src/react/ui/modals/SellModal/__tests__/Modal.test.tsx +4 -3
- package/src/react/ui/modals/SellModal/hooks/useGetTokenApproval.tsx +33 -31
- package/src/react/ui/modals/SellModal/hooks/useSell.tsx +11 -7
- package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +58 -16
- package/src/react/ui/modals/SuccessfulPurchaseModal/__tests__/Modal.test.tsx +0 -1
- package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +4 -2
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +129 -57
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +1 -3
- package/src/react/ui/modals/_internal/components/priceInput/__tests__/index.test.tsx +1 -3
- package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
- package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +8 -8
- package/src/react/ui/modals/_internal/components/transactionStatusModal/hooks/useTransactionStatus.ts +1 -0
- package/src/types/builder-types.ts +79 -0
- package/src/types/index.ts +1 -1
- package/src/utils/__tests__/get-public-rpc-client.test.ts +2 -0
- package/src/utils/getMarketplaceDetails.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.js +2 -1
- package/dist/chunk-FCF57DZI.js.map +0 -1
- package/dist/chunk-I37CRQ4S.js.map +0 -1
- package/dist/chunk-LJAB3S6U.js.map +0 -1
- package/dist/chunk-MSTTVFVQ.js.map +0 -1
- package/dist/chunk-RK6KYMZM.js +0 -18
- package/dist/chunk-RK6KYMZM.js.map +0 -1
- package/dist/marketplace-config-znEu4L0K.d.ts +0 -60
- package/src/react/hooks/useCurrencyOptions.tsx +0 -16
- package/src/types/marketplace-config.ts +0 -67
- /package/dist/{chunk-MKGSGTQC.js.map → chunk-TLNRD4BQ.js.map} +0 -0
- /package/dist/{chunk-MWDG7UTB.js.map → chunk-ZBLU3Q22.js.map} +0 -0
|
@@ -39,7 +39,7 @@ export const useCreateListing = ({
|
|
|
39
39
|
useMarketplaceConfig();
|
|
40
40
|
|
|
41
41
|
const collectionConfig = marketplaceConfig?.collections.find(
|
|
42
|
-
(c) => c.
|
|
42
|
+
(c) => c.address === collectionAddress,
|
|
43
43
|
);
|
|
44
44
|
|
|
45
45
|
orderbookKind =
|
|
@@ -60,6 +60,7 @@ export const useCreateListing = ({
|
|
|
60
60
|
},
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
63
64
|
useEffect(() => {
|
|
64
65
|
if (tokenApproval?.step && !tokenApprovalIsLoading) {
|
|
65
66
|
steps$.approval.exist.set(true);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Observable } from '@legendapp/state';
|
|
2
|
-
import type
|
|
2
|
+
import { type Address, type Hex, formatUnits } from 'viem';
|
|
3
3
|
import type { OrderbookKind } from '../../../../../types';
|
|
4
4
|
import {
|
|
5
5
|
ExecuteType,
|
|
@@ -10,14 +10,21 @@ import {
|
|
|
10
10
|
collectableKeys,
|
|
11
11
|
getMarketplaceClient,
|
|
12
12
|
} from '../../../../_internal';
|
|
13
|
+
import { useAnalytics } from '../../../../_internal/databeat';
|
|
13
14
|
import { TransactionType } from '../../../../_internal/types';
|
|
14
15
|
import type { ListingInput } from '../../../../_internal/types';
|
|
16
|
+
import type {
|
|
17
|
+
SignatureStep,
|
|
18
|
+
TransactionStep as WalletTransactionStep,
|
|
19
|
+
} from '../../../../_internal/utils';
|
|
15
20
|
import { useWallet } from '../../../../_internal/wallet/useWallet';
|
|
16
|
-
import
|
|
17
|
-
|
|
21
|
+
import {
|
|
22
|
+
useConfig,
|
|
23
|
+
useCurrencies,
|
|
24
|
+
useGenerateListingTransaction,
|
|
25
|
+
} from '../../../../hooks';
|
|
18
26
|
import { useTransactionStatusModal } from '../../_internal/components/transactionStatusModal';
|
|
19
27
|
import type { ModalCallbacks } from '../../_internal/types';
|
|
20
|
-
|
|
21
28
|
interface UseTransactionStepsArgs {
|
|
22
29
|
listingInput: ListingInput;
|
|
23
30
|
chainId: string;
|
|
@@ -41,7 +48,11 @@ export const useTransactionSteps = ({
|
|
|
41
48
|
const expiry = new Date(Number(listingInput.listing.expiry) * 1000);
|
|
42
49
|
const { show: showTransactionStatusModal } = useTransactionStatusModal();
|
|
43
50
|
const sdkConfig = useConfig();
|
|
51
|
+
const { data: currencies } = useCurrencies({
|
|
52
|
+
chainId: Number(chainId),
|
|
53
|
+
});
|
|
44
54
|
const marketplaceClient = getMarketplaceClient(chainId, sdkConfig);
|
|
55
|
+
const analytics = useAnalytics();
|
|
45
56
|
const { generateListingTransactionAsync, isPending: generatingSteps } =
|
|
46
57
|
useGenerateListingTransaction({
|
|
47
58
|
chainId,
|
|
@@ -89,7 +100,7 @@ export const useTransactionSteps = ({
|
|
|
89
100
|
|
|
90
101
|
const hash = await wallet.handleSendTransactionStep(
|
|
91
102
|
Number(chainId),
|
|
92
|
-
approvalStep as
|
|
103
|
+
approvalStep as WalletTransactionStep,
|
|
93
104
|
);
|
|
94
105
|
|
|
95
106
|
await wallet.handleConfirmTransactionStep(hash, Number(chainId));
|
|
@@ -120,7 +131,8 @@ export const useTransactionSteps = ({
|
|
|
120
131
|
throw new Error('No transaction or signature step found');
|
|
121
132
|
}
|
|
122
133
|
|
|
123
|
-
let hash
|
|
134
|
+
let hash: Hex | undefined;
|
|
135
|
+
let orderId: string | undefined;
|
|
124
136
|
|
|
125
137
|
if (transactionStep) {
|
|
126
138
|
hash = await executeTransaction({ transactionStep });
|
|
@@ -160,6 +172,34 @@ export const useTransactionSteps = ({
|
|
|
160
172
|
steps$.transaction.isExecuting.set(false);
|
|
161
173
|
steps$.transaction.exist.set(false);
|
|
162
174
|
}
|
|
175
|
+
|
|
176
|
+
if (hash || orderId) {
|
|
177
|
+
const currencyDecimal =
|
|
178
|
+
currencies?.find(
|
|
179
|
+
(currency) =>
|
|
180
|
+
currency.contractAddress === listingInput.listing.currencyAddress,
|
|
181
|
+
)?.decimals || 0;
|
|
182
|
+
|
|
183
|
+
const currencyValueRaw = Number(listingInput.listing.pricePerToken);
|
|
184
|
+
const currencyValueDecimal = Number(
|
|
185
|
+
formatUnits(BigInt(currencyValueRaw), currencyDecimal),
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
analytics.trackCreateListing({
|
|
189
|
+
props: {
|
|
190
|
+
orderbookKind,
|
|
191
|
+
collectionAddress,
|
|
192
|
+
currencyAddress: listingInput.listing.currencyAddress,
|
|
193
|
+
currencySymbol: '',
|
|
194
|
+
chainId,
|
|
195
|
+
txnHash: hash || '',
|
|
196
|
+
},
|
|
197
|
+
nums: {
|
|
198
|
+
currencyValueDecimal,
|
|
199
|
+
currencyValueRaw,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
}
|
|
163
203
|
} catch (error) {
|
|
164
204
|
steps$.transaction.isExecuting.set(false);
|
|
165
205
|
steps$.transaction.exist.set(false);
|
|
@@ -176,7 +216,7 @@ export const useTransactionSteps = ({
|
|
|
176
216
|
|
|
177
217
|
const hash = await wallet.handleSendTransactionStep(
|
|
178
218
|
Number(chainId),
|
|
179
|
-
transactionStep as
|
|
219
|
+
transactionStep as WalletTransactionStep,
|
|
180
220
|
);
|
|
181
221
|
|
|
182
222
|
return hash;
|
|
@@ -3,12 +3,7 @@ import { useState } from 'react';
|
|
|
3
3
|
import { parseUnits } from 'viem';
|
|
4
4
|
import { dateToUnixTime } from '../../../../utils/date';
|
|
5
5
|
import { ContractType } from '../../../_internal';
|
|
6
|
-
import {
|
|
7
|
-
useCollectible,
|
|
8
|
-
useCollection,
|
|
9
|
-
useCurrencies,
|
|
10
|
-
useCurrencyOptions,
|
|
11
|
-
} from '../../../hooks';
|
|
6
|
+
import { useCollectible, useCollection, useCurrencies } from '../../../hooks';
|
|
12
7
|
import { useMakeOffer } from './hooks/useMakeOffer';
|
|
13
8
|
import { ActionModal } from '../_internal/components/actionModal/ActionModal';
|
|
14
9
|
import { ErrorModal } from '../_internal/components/actionModal/ErrorModal';
|
|
@@ -56,14 +51,12 @@ const Modal = observer(() => {
|
|
|
56
51
|
chainId,
|
|
57
52
|
collectionAddress,
|
|
58
53
|
});
|
|
59
|
-
const currencyOptions = useCurrencyOptions({ collectionAddress });
|
|
60
54
|
const {
|
|
61
55
|
data: currencies,
|
|
62
56
|
isLoading: currenciesLoading,
|
|
63
57
|
isError: currenciesIsError,
|
|
64
58
|
} = useCurrencies({
|
|
65
59
|
chainId,
|
|
66
|
-
currencyOptions,
|
|
67
60
|
includeNativeCurrency: false,
|
|
68
61
|
});
|
|
69
62
|
|
|
@@ -1,96 +1,41 @@
|
|
|
1
|
-
import '@testing-library/jest-dom/vitest';
|
|
2
1
|
import {
|
|
3
2
|
render,
|
|
4
3
|
screen,
|
|
5
4
|
cleanup,
|
|
6
|
-
fireEvent,
|
|
7
5
|
waitFor,
|
|
6
|
+
fireEvent,
|
|
8
7
|
} from '../../../../_internal/test-utils';
|
|
9
8
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
10
9
|
import { MakeOfferModal } from '../Modal';
|
|
11
10
|
import { makeOfferModal$ } from '../store';
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
{
|
|
34
|
-
collectionAddress: '0x123',
|
|
35
|
-
marketplaceFeePercentage: 2.5,
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
isLoading: false,
|
|
40
|
-
isError: false,
|
|
41
|
-
}),
|
|
42
|
-
useLowestListing: vi.fn().mockReturnValue({
|
|
43
|
-
data: null,
|
|
44
|
-
isLoading: false,
|
|
45
|
-
isError: false,
|
|
46
|
-
}),
|
|
47
|
-
}));
|
|
48
|
-
|
|
49
|
-
vi.mock('../../../../_internal/wallet/useWallet', () => ({
|
|
50
|
-
useWallet: vi.fn(),
|
|
51
|
-
}));
|
|
52
|
-
|
|
53
|
-
vi.mock('../hooks/useMakeOffer', () => ({
|
|
54
|
-
useMakeOffer: vi.fn(),
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
vi.mock('@0xsequence/kit', () => ({
|
|
58
|
-
useWaasFeeOptions: vi.fn().mockReturnValue([false, vi.fn()]),
|
|
59
|
-
}));
|
|
11
|
+
import { zeroAddress } from 'viem';
|
|
12
|
+
import * as hooks from '../../../../hooks';
|
|
13
|
+
|
|
14
|
+
// TODO: This should be moved to a shared test file
|
|
15
|
+
vi.mock(import('../../../../hooks'), async (importOriginal) => {
|
|
16
|
+
const actual = await importOriginal();
|
|
17
|
+
return {
|
|
18
|
+
...actual,
|
|
19
|
+
useCollectible: vi.fn(actual.useCollectible),
|
|
20
|
+
useCollection: vi.fn(actual.useCollection),
|
|
21
|
+
useCurrencies: vi.fn(actual.useCurrencies),
|
|
22
|
+
useMarketplaceConfig: vi.fn(actual.useMarketplaceConfig),
|
|
23
|
+
useLowestListing: vi.fn(actual.useLowestListing),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const defaultArgs = {
|
|
28
|
+
collectionAddress: zeroAddress,
|
|
29
|
+
chainId: '1',
|
|
30
|
+
collectibleId: '1',
|
|
31
|
+
};
|
|
60
32
|
|
|
61
33
|
describe('MakeOfferModal', () => {
|
|
62
34
|
beforeEach(() => {
|
|
63
35
|
cleanup();
|
|
64
36
|
// Reset all mocks
|
|
65
37
|
vi.clearAllMocks();
|
|
66
|
-
|
|
67
|
-
// Setup default mock values
|
|
68
|
-
(useWallet as any).mockReturnValue({
|
|
69
|
-
wallet: {
|
|
70
|
-
address: () => Promise.resolve('0x123'),
|
|
71
|
-
},
|
|
72
|
-
isLoading: false,
|
|
73
|
-
isError: false,
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
(useCollectible as any).mockReturnValue({
|
|
77
|
-
data: { decimals: 18, name: 'Test NFT' },
|
|
78
|
-
isLoading: false,
|
|
79
|
-
isError: false,
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
(useCollection as any).mockReturnValue({
|
|
83
|
-
data: { type: 'ERC721', name: 'Test Collection' },
|
|
84
|
-
isLoading: false,
|
|
85
|
-
isError: false,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
(useMakeOffer as any).mockReturnValue({
|
|
89
|
-
isLoading: false,
|
|
90
|
-
executeApproval: vi.fn(),
|
|
91
|
-
makeOffer: vi.fn(),
|
|
92
|
-
tokenApprovalIsLoading: false,
|
|
93
|
-
});
|
|
38
|
+
vi.resetAllMocks();
|
|
94
39
|
});
|
|
95
40
|
|
|
96
41
|
it('should not render when modal is closed', () => {
|
|
@@ -99,56 +44,39 @@ describe('MakeOfferModal', () => {
|
|
|
99
44
|
});
|
|
100
45
|
|
|
101
46
|
it('should render loading state', () => {
|
|
102
|
-
(
|
|
103
|
-
isLoading: true,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
makeOfferModal$.open({
|
|
107
|
-
collectionAddress: '0x123',
|
|
108
|
-
chainId: '1',
|
|
109
|
-
collectibleId: '1',
|
|
110
|
-
});
|
|
47
|
+
makeOfferModal$.open(defaultArgs);
|
|
111
48
|
|
|
112
49
|
render(<MakeOfferModal />);
|
|
113
50
|
const loadingModal = screen.getByTestId('loading-modal');
|
|
114
51
|
expect(loadingModal).toBeVisible();
|
|
115
52
|
});
|
|
116
53
|
|
|
117
|
-
it('should render error state', () => {
|
|
118
|
-
|
|
54
|
+
it('should render error state', async () => {
|
|
55
|
+
// @ts-expect-error - TODO: Add a common mock object with the correct shape
|
|
56
|
+
vi.mocked(hooks.useCollection).mockReturnValue({
|
|
57
|
+
data: undefined,
|
|
58
|
+
isLoading: false,
|
|
119
59
|
isError: true,
|
|
120
60
|
});
|
|
121
61
|
|
|
122
|
-
makeOfferModal$.open(
|
|
123
|
-
collectionAddress: '0x123',
|
|
124
|
-
chainId: '1',
|
|
125
|
-
collectibleId: '1',
|
|
126
|
-
});
|
|
62
|
+
makeOfferModal$.open(defaultArgs);
|
|
127
63
|
|
|
128
64
|
render(<MakeOfferModal />);
|
|
129
|
-
const errorModal = screen.
|
|
65
|
+
const errorModal = await screen.findByTestId('error-modal');
|
|
130
66
|
expect(errorModal).toBeVisible();
|
|
131
67
|
});
|
|
132
68
|
|
|
133
|
-
it('should render main form when data is loaded', () => {
|
|
134
|
-
makeOfferModal$.open(
|
|
135
|
-
collectionAddress: '0x123',
|
|
136
|
-
chainId: '1',
|
|
137
|
-
collectibleId: '1',
|
|
138
|
-
});
|
|
69
|
+
it('should render main form when data is loaded', async () => {
|
|
70
|
+
makeOfferModal$.open(defaultArgs);
|
|
139
71
|
|
|
140
72
|
render(<MakeOfferModal />);
|
|
141
73
|
|
|
142
|
-
expect(screen.
|
|
74
|
+
expect(await screen.findByText('Enter price')).toBeInTheDocument();
|
|
143
75
|
});
|
|
144
76
|
|
|
145
77
|
it('should reset store values when modal is closed and reopened', () => {
|
|
146
78
|
// Open modal first time
|
|
147
|
-
makeOfferModal$.open(
|
|
148
|
-
collectionAddress: '0x123',
|
|
149
|
-
chainId: '1',
|
|
150
|
-
collectibleId: '1',
|
|
151
|
-
});
|
|
79
|
+
makeOfferModal$.open(defaultArgs);
|
|
152
80
|
|
|
153
81
|
// Set some values in the store
|
|
154
82
|
makeOfferModal$.offerPrice.amountRaw.set('1000000000000000000');
|
|
@@ -162,11 +90,7 @@ describe('MakeOfferModal', () => {
|
|
|
162
90
|
expect(makeOfferModal$.expiry.get()).toBeDefined();
|
|
163
91
|
|
|
164
92
|
// Reopen modal
|
|
165
|
-
makeOfferModal$.open(
|
|
166
|
-
collectionAddress: '0x456',
|
|
167
|
-
chainId: '1',
|
|
168
|
-
collectibleId: '2',
|
|
169
|
-
});
|
|
93
|
+
makeOfferModal$.open(defaultArgs);
|
|
170
94
|
|
|
171
95
|
// Verify store has default values
|
|
172
96
|
expect(makeOfferModal$.offerPrice.amountRaw.get()).toBe('0');
|
|
@@ -174,11 +98,7 @@ describe('MakeOfferModal', () => {
|
|
|
174
98
|
});
|
|
175
99
|
|
|
176
100
|
it('should update state based on price input', async () => {
|
|
177
|
-
makeOfferModal$.open(
|
|
178
|
-
collectionAddress: '0x123',
|
|
179
|
-
chainId: '1',
|
|
180
|
-
collectibleId: '1',
|
|
181
|
-
});
|
|
101
|
+
makeOfferModal$.open(defaultArgs);
|
|
182
102
|
|
|
183
103
|
render(<MakeOfferModal />);
|
|
184
104
|
|
|
@@ -186,7 +106,10 @@ describe('MakeOfferModal', () => {
|
|
|
186
106
|
expect(makeOfferModal$.offerPrice.amountRaw.get()).toBe('0');
|
|
187
107
|
|
|
188
108
|
// Find and interact with price input
|
|
189
|
-
|
|
109
|
+
|
|
110
|
+
const priceInput = await screen.findByRole('textbox', {
|
|
111
|
+
name: 'Enter price',
|
|
112
|
+
});
|
|
190
113
|
expect(priceInput).toBeInTheDocument();
|
|
191
114
|
|
|
192
115
|
fireEvent.change(priceInput, { target: { value: '1.5' } });
|
|
@@ -31,7 +31,7 @@ export const useMakeOffer = ({
|
|
|
31
31
|
useMarketplaceConfig();
|
|
32
32
|
|
|
33
33
|
const collectionConfig = marketplaceConfig?.collections.find(
|
|
34
|
-
(c) => c.
|
|
34
|
+
(c) => c.address === collectionAddress,
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
orderbookKind =
|
|
@@ -52,6 +52,7 @@ export const useMakeOffer = ({
|
|
|
52
52
|
},
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
55
56
|
useEffect(() => {
|
|
56
57
|
if (tokenApproval?.step && !tokenApprovalIsLoading) {
|
|
57
58
|
steps$.approval.exist.set(true);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Observable } from '@legendapp/state';
|
|
2
|
-
import type
|
|
2
|
+
import { type Address, type Hex, formatUnits } from 'viem';
|
|
3
3
|
import { OrderbookKind, type Price } from '../../../../../types';
|
|
4
4
|
import {
|
|
5
5
|
ExecuteType,
|
|
@@ -10,15 +10,18 @@ import {
|
|
|
10
10
|
collectableKeys,
|
|
11
11
|
getMarketplaceClient,
|
|
12
12
|
} from '../../../../_internal';
|
|
13
|
+
import { useAnalytics } from '../../../../_internal/databeat';
|
|
13
14
|
import { TransactionType } from '../../../../_internal/types';
|
|
14
15
|
import type { OfferInput } from '../../../../_internal/types';
|
|
15
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
SignatureStep,
|
|
18
|
+
TransactionStep,
|
|
19
|
+
} from '../../../../_internal/utils';
|
|
16
20
|
import { useWallet } from '../../../../_internal/wallet/useWallet';
|
|
17
21
|
import { useConfig, useCurrency } from '../../../../hooks';
|
|
18
22
|
import { useGenerateOfferTransaction } from '../../../../hooks/useGenerateOfferTransaction';
|
|
19
23
|
import { useTransactionStatusModal } from '../../_internal/components/transactionStatusModal';
|
|
20
24
|
import type { ModalCallbacks } from '../../_internal/types';
|
|
21
|
-
|
|
22
25
|
export type ExecutionState = 'approval' | 'offer' | null;
|
|
23
26
|
|
|
24
27
|
interface UseTransactionStepsArgs {
|
|
@@ -44,6 +47,7 @@ export const useTransactionSteps = ({
|
|
|
44
47
|
const expiry = new Date(Number(offerInput.offer.expiry) * 1000);
|
|
45
48
|
const { show: showTransactionStatusModal } = useTransactionStatusModal();
|
|
46
49
|
const sdkConfig = useConfig();
|
|
50
|
+
const analytics = useAnalytics();
|
|
47
51
|
const marketplaceClient = getMarketplaceClient(chainId, sdkConfig);
|
|
48
52
|
const { generateOfferTransactionAsync, isPending: generatingSteps } =
|
|
49
53
|
useGenerateOfferTransaction({
|
|
@@ -96,7 +100,7 @@ export const useTransactionSteps = ({
|
|
|
96
100
|
|
|
97
101
|
const hash = await wallet.handleSendTransactionStep(
|
|
98
102
|
Number(chainId),
|
|
99
|
-
approvalStep as
|
|
103
|
+
approvalStep as TransactionStep,
|
|
100
104
|
);
|
|
101
105
|
|
|
102
106
|
await wallet.handleConfirmTransactionStep(hash, Number(chainId));
|
|
@@ -127,7 +131,8 @@ export const useTransactionSteps = ({
|
|
|
127
131
|
throw new Error('No transaction or signature step found');
|
|
128
132
|
}
|
|
129
133
|
|
|
130
|
-
let hash
|
|
134
|
+
let hash: Hex | undefined;
|
|
135
|
+
let orderId: string | undefined;
|
|
131
136
|
|
|
132
137
|
if (transactionStep) {
|
|
133
138
|
hash = await executeTransaction({ transactionStep });
|
|
@@ -173,6 +178,29 @@ export const useTransactionSteps = ({
|
|
|
173
178
|
steps$.transaction.isExecuting.set(false);
|
|
174
179
|
steps$.transaction.exist.set(false);
|
|
175
180
|
}
|
|
181
|
+
|
|
182
|
+
if (hash || orderId) {
|
|
183
|
+
const currencyDecimal = currency?.decimals || 0;
|
|
184
|
+
const currencyValueRaw = Number(offerInput.offer.pricePerToken);
|
|
185
|
+
const currencyValueDecimal = Number(
|
|
186
|
+
formatUnits(BigInt(currencyValueRaw), currencyDecimal),
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
analytics.trackCreateOffer({
|
|
190
|
+
props: {
|
|
191
|
+
orderbookKind,
|
|
192
|
+
collectionAddress,
|
|
193
|
+
currencyAddress: offerInput.offer.currencyAddress,
|
|
194
|
+
currencySymbol: currency?.symbol || '',
|
|
195
|
+
chainId,
|
|
196
|
+
txnHash: hash || '',
|
|
197
|
+
},
|
|
198
|
+
nums: {
|
|
199
|
+
currencyValueDecimal,
|
|
200
|
+
currencyValueRaw,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
176
204
|
} catch (error) {
|
|
177
205
|
steps$.transaction.isExecuting.set(false);
|
|
178
206
|
steps$.transaction.exist.set(false);
|
|
@@ -191,7 +219,7 @@ export const useTransactionSteps = ({
|
|
|
191
219
|
|
|
192
220
|
const hash = await wallet.handleSendTransactionStep(
|
|
193
221
|
Number(chainId),
|
|
194
|
-
transactionStep as
|
|
222
|
+
transactionStep as TransactionStep,
|
|
195
223
|
);
|
|
196
224
|
|
|
197
225
|
return hash;
|
|
@@ -11,8 +11,8 @@ import { LoadingModal } from '../_internal/components/actionModal/LoadingModal';
|
|
|
11
11
|
import TokenPreview from '../_internal/components/tokenPreview';
|
|
12
12
|
import TransactionDetails from '../_internal/components/transactionDetails';
|
|
13
13
|
import TransactionHeader from '../_internal/components/transactionHeader';
|
|
14
|
-
import { sellModal$ } from './store';
|
|
15
14
|
import { useSell } from './hooks/useSell';
|
|
15
|
+
import { sellModal$ } from './store';
|
|
16
16
|
|
|
17
17
|
export const SellModal = () => {
|
|
18
18
|
return <Show if={sellModal$.isOpen}>{() => <Modal />}</Show>;
|
|
@@ -58,6 +58,8 @@ const Modal = observer(() => {
|
|
|
58
58
|
collectible?.decimals || 0,
|
|
59
59
|
).toString()
|
|
60
60
|
: '1',
|
|
61
|
+
pricePerToken: order?.priceAmount ?? '',
|
|
62
|
+
currencyAddress: order?.priceCurrencyAddress ?? '',
|
|
61
63
|
},
|
|
62
64
|
],
|
|
63
65
|
callbacks,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import '@testing-library/jest-dom/vitest';
|
|
2
1
|
import { render, screen, cleanup } from '../../../../_internal/test-utils';
|
|
3
2
|
import {
|
|
4
3
|
describe,
|
|
@@ -104,13 +103,15 @@ describe('SellModal', () => {
|
|
|
104
103
|
});
|
|
105
104
|
|
|
106
105
|
it('should render main modal when data is loaded', async () => {
|
|
107
|
-
vi.mocked(useCollection
|
|
106
|
+
vi.mocked(useCollection).mockReturnValue({
|
|
107
|
+
// @ts-expect-error - TODO: mock this better
|
|
108
108
|
data: {},
|
|
109
109
|
isLoading: false,
|
|
110
110
|
isError: false,
|
|
111
111
|
});
|
|
112
112
|
|
|
113
|
-
vi.mocked(useCurrency
|
|
113
|
+
vi.mocked(useCurrency).mockReturnValue({
|
|
114
|
+
// @ts-expect-error - TODO: mock this better
|
|
114
115
|
data: {},
|
|
115
116
|
isLoading: false,
|
|
116
117
|
isError: false,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type OrderData,
|
|
6
6
|
StepType,
|
|
7
7
|
} from '../../../../_internal';
|
|
8
|
-
import { useQuery } from '@tanstack/react-query';
|
|
8
|
+
import { skipToken, useQuery } from '@tanstack/react-query';
|
|
9
9
|
import { useWallet } from '../../../../_internal/wallet/useWallet';
|
|
10
10
|
import { useConfig } from '../../../../hooks/useConfig';
|
|
11
11
|
import { useFees } from '../../BuyModal/hooks/useFees';
|
|
@@ -30,38 +30,40 @@ export const useGetTokenApprovalData = (
|
|
|
30
30
|
|
|
31
31
|
const { data, isLoading, isSuccess } = useQuery({
|
|
32
32
|
queryKey: ['token-approval-data', params.ordersData],
|
|
33
|
-
queryFn:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
33
|
+
queryFn: wallet
|
|
34
|
+
? async () => {
|
|
35
|
+
const address = await wallet.address();
|
|
36
|
+
const args = {
|
|
37
|
+
collectionAddress: params.collectionAddress,
|
|
38
|
+
walletType: wallet.walletKind,
|
|
39
|
+
seller: address,
|
|
40
|
+
marketplace: params.marketplace,
|
|
41
|
+
ordersData: params.ordersData,
|
|
42
|
+
additionalFees: [
|
|
43
|
+
{
|
|
44
|
+
amount,
|
|
45
|
+
receiver,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
} satisfies GenerateSellTransactionArgs;
|
|
49
|
+
const steps = await marketplaceClient
|
|
50
|
+
.generateSellTransaction(args)
|
|
51
|
+
.then((resp) => resp.steps);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
const tokenApprovalStep = steps.find(
|
|
54
|
+
(step) => step.id === StepType.tokenApproval,
|
|
55
|
+
);
|
|
56
|
+
if (!tokenApprovalStep) {
|
|
57
|
+
return {
|
|
58
|
+
step: null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
return {
|
|
63
|
+
step: tokenApprovalStep,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
: skipToken,
|
|
65
67
|
enabled: !!wallet && !!params.collectionAddress,
|
|
66
68
|
});
|
|
67
69
|
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import type { Observable } from '@legendapp/state';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import type { MarketplaceKind, TransactionSteps } from '../../../../_internal';
|
|
2
4
|
import type { ModalCallbacks } from '../../_internal/types';
|
|
3
5
|
import { useGetTokenApprovalData } from './useGetTokenApproval';
|
|
4
6
|
import { useTransactionSteps } from './useTransactionSteps';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
|
|
8
|
+
export type SellOrder = {
|
|
9
|
+
orderId: string;
|
|
10
|
+
quantity: string;
|
|
11
|
+
pricePerToken: string;
|
|
12
|
+
currencyAddress: string;
|
|
13
|
+
};
|
|
11
14
|
|
|
12
15
|
interface UseSellArgs {
|
|
13
16
|
collectibleId: string;
|
|
14
17
|
chainId: string;
|
|
15
18
|
collectionAddress: string;
|
|
16
19
|
marketplace: MarketplaceKind;
|
|
17
|
-
ordersData: Array<
|
|
20
|
+
ordersData: Array<SellOrder>;
|
|
18
21
|
callbacks?: ModalCallbacks;
|
|
19
22
|
closeMainModal: () => void;
|
|
20
23
|
steps$: Observable<TransactionSteps>;
|
|
@@ -38,6 +41,7 @@ export const useSell = ({
|
|
|
38
41
|
marketplace,
|
|
39
42
|
});
|
|
40
43
|
|
|
44
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
41
45
|
useEffect(() => {
|
|
42
46
|
if (tokenApproval?.step && !tokenApprovalIsLoading) {
|
|
43
47
|
steps$.approval.exist.set(true);
|