@0xsequence/marketplace-sdk 0.4.3 → 0.4.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.
- package/dist/{chunk-VYSWBIWC.js → chunk-CKOWM2ZR.js} +3 -3
- package/dist/{chunk-4VS5NKDD.js → chunk-FT3J32ZV.js} +2 -2
- package/dist/{chunk-IQXJZBMR.js → chunk-HTFBQVLV.js} +2 -2
- package/dist/{chunk-URX7ZHX4.js → chunk-KILOCWY2.js} +2 -2
- package/dist/{chunk-YZE7RXC2.js → chunk-KL5JPUPS.js} +10 -8
- package/dist/chunk-KL5JPUPS.js.map +1 -0
- package/dist/{chunk-ST6RH2IB.js → chunk-KZGDOIZY.js} +24 -575
- package/dist/chunk-KZGDOIZY.js.map +1 -0
- package/dist/{chunk-2AMLJ2TA.js → chunk-SEISACMH.js} +461 -251
- package/dist/chunk-SEISACMH.js.map +1 -0
- package/dist/{chunk-DNDPYQKV.js → chunk-YUETNNZQ.js} +1 -144
- package/dist/{chunk-DNDPYQKV.js.map → chunk-YUETNNZQ.js.map} +1 -1
- package/dist/{create-config-8sffBvlt.d.ts → create-config-DMBOGsJp.d.ts} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -16
- package/dist/{marketplace-config-Bbxl-uKX.d.ts → marketplace-config-0Rft6_Hv.d.ts} +2 -0
- package/dist/react/_internal/api/index.js +2 -2
- package/dist/react/_internal/index.d.ts +2 -2
- package/dist/react/_internal/index.js +8 -8
- package/dist/react/_internal/wagmi/index.d.ts +3 -2
- package/dist/react/_internal/wagmi/index.js +2 -2
- package/dist/react/hooks/index.d.ts +4 -205
- package/dist/react/hooks/index.js +8 -11
- package/dist/react/index.d.ts +7 -4
- package/dist/react/index.js +16 -16
- package/dist/react/ssr/index.d.ts +14 -0
- package/dist/react/ssr/index.js +10 -32
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/index.js +11 -11
- package/dist/react/ui/index.d.ts +4 -1
- package/dist/react/ui/index.js +11 -11
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +8 -8
- package/dist/react/ui/styles/index.d.ts +1 -1
- package/dist/styles/index.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +3 -3
- package/dist/utils/abi/index.js +5 -5
- package/dist/utils/index.js +7 -7
- package/package.json +1 -1
- package/src/react/hooks/index.ts +0 -1
- package/src/react/hooks/useCancelTransactionSteps.tsx +7 -4
- package/src/react/hooks/useCurrency.tsx +1 -1
- package/src/react/provider.tsx +18 -3
- package/src/react/ssr/create-ssr-client.ts +9 -5
- package/src/react/ui/modals/BuyModal/Modal.tsx +4 -0
- package/src/react/ui/modals/BuyModal/hooks/useBuyCollectable.ts +29 -2
- package/src/react/ui/modals/BuyModal/modals/Modal1155.tsx +8 -3
- package/src/react/ui/modals/BuyModal/store.ts +14 -0
- package/src/react/ui/modals/CreateListingModal/Modal.tsx +1 -1
- package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +21 -5
- package/src/react/ui/modals/CreateListingModal/hooks/useGetTokenApproval.ts +34 -28
- package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +43 -16
- package/src/react/ui/modals/MakeOfferModal/Modal.tsx +43 -9
- package/src/react/ui/modals/MakeOfferModal/hooks/useGetTokenApproval.tsx +34 -28
- package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +8 -8
- package/src/react/ui/modals/MakeOfferModal/hooks/useTransactionSteps.tsx +64 -22
- package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +30 -12
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +38 -54
- package/src/react/ui/modals/_internal/components/currencyImage/index.tsx +8 -10
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +9 -1
- package/src/react/ui/modals/_internal/components/priceInput/hooks/useBalanceCheck.ts +67 -0
- package/src/react/ui/modals/_internal/components/priceInput/hooks/usePriceInput.ts +54 -0
- package/src/react/ui/modals/_internal/components/priceInput/index.tsx +48 -71
- package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +2 -1
- package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +2 -2
- package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +18 -9
- package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getMessage.ts +12 -1
- package/src/react/ui/modals/_internal/types.ts +1 -1
- package/src/types/marketplace-config.ts +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-2AMLJ2TA.js.map +0 -1
- package/dist/chunk-ST6RH2IB.js.map +0 -1
- package/dist/chunk-YZE7RXC2.js.map +0 -1
- package/src/react/hooks/useBuyCollectable.tsx +0 -61
- /package/dist/{chunk-VYSWBIWC.js.map → chunk-CKOWM2ZR.js.map} +0 -0
- /package/dist/{chunk-4VS5NKDD.js.map → chunk-FT3J32ZV.js.map} +0 -0
- /package/dist/{chunk-IQXJZBMR.js.map → chunk-HTFBQVLV.js.map} +0 -0
- /package/dist/{chunk-URX7ZHX4.js.map → chunk-KILOCWY2.js.map} +0 -0
|
@@ -2,8 +2,11 @@ import { useSelectPaymentModal } from '@0xsequence/kit-checkout';
|
|
|
2
2
|
import type { Hash, Hex } from 'viem';
|
|
3
3
|
import type { ModalCallbacks } from '../../_internal/types';
|
|
4
4
|
import {
|
|
5
|
+
balanceQueries,
|
|
5
6
|
type CheckoutOptions,
|
|
7
|
+
collectableKeys,
|
|
6
8
|
getMarketplaceClient,
|
|
9
|
+
getQueryClient,
|
|
7
10
|
type MarketplaceKind,
|
|
8
11
|
WalletKind,
|
|
9
12
|
} from '../../../../_internal';
|
|
@@ -11,6 +14,7 @@ import { buyModal$ } from '../store';
|
|
|
11
14
|
import { useFees } from './useFees';
|
|
12
15
|
import { useConfig } from '../../../../hooks';
|
|
13
16
|
import { useWallet } from '../../../../_internal/transaction-machine/useWallet';
|
|
17
|
+
import { QueryKey } from '@tanstack/react-query';
|
|
14
18
|
|
|
15
19
|
interface UseBuyCollectableProps {
|
|
16
20
|
chainId: string;
|
|
@@ -18,6 +22,8 @@ interface UseBuyCollectableProps {
|
|
|
18
22
|
tokenId: string;
|
|
19
23
|
callbacks?: ModalCallbacks;
|
|
20
24
|
priceCurrencyAddress: string;
|
|
25
|
+
setCheckoutModalIsLoading: (isLoading: boolean) => void;
|
|
26
|
+
setCheckoutModalLoaded: (isLoaded: boolean) => void;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
type BuyCollectableReturn =
|
|
@@ -42,6 +48,8 @@ export const useBuyCollectable = ({
|
|
|
42
48
|
tokenId,
|
|
43
49
|
callbacks,
|
|
44
50
|
priceCurrencyAddress,
|
|
51
|
+
setCheckoutModalIsLoading,
|
|
52
|
+
setCheckoutModalLoaded,
|
|
45
53
|
}: UseBuyCollectableProps): BuyCollectableReturn => {
|
|
46
54
|
const { openSelectPaymentModal } = useSelectPaymentModal();
|
|
47
55
|
const config = useConfig();
|
|
@@ -57,6 +65,13 @@ export const useBuyCollectable = ({
|
|
|
57
65
|
return { status: 'error', buy: null, isLoading, isError: true };
|
|
58
66
|
}
|
|
59
67
|
|
|
68
|
+
const invalidateQueries = async (queriesToInvalidate: QueryKey[]) => {
|
|
69
|
+
const queryClient = getQueryClient();
|
|
70
|
+
for (const queryKey of queriesToInvalidate) {
|
|
71
|
+
await queryClient.invalidateQueries({ queryKey });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
60
75
|
return {
|
|
61
76
|
status: 'ready',
|
|
62
77
|
isLoading,
|
|
@@ -76,6 +91,10 @@ export const useBuyCollectable = ({
|
|
|
76
91
|
walletType: WalletKind.unknown,
|
|
77
92
|
});
|
|
78
93
|
|
|
94
|
+
// these states are necessary to manage appearance of the quantity modal
|
|
95
|
+
setCheckoutModalLoaded(true);
|
|
96
|
+
setCheckoutModalIsLoading(false);
|
|
97
|
+
|
|
79
98
|
const step = steps[0];
|
|
80
99
|
|
|
81
100
|
openSelectPaymentModal({
|
|
@@ -96,10 +115,18 @@ export const useBuyCollectable = ({
|
|
|
96
115
|
enableMainCurrencyPayment: true,
|
|
97
116
|
enableSwapPayments: !!input.checkoutOptions.swap,
|
|
98
117
|
creditCardProviders: input.checkoutOptions.nftCheckout || [],
|
|
99
|
-
onSuccess: (hash: string) =>
|
|
118
|
+
onSuccess: (hash: string) => {
|
|
119
|
+
invalidateQueries([
|
|
120
|
+
collectableKeys.listings,
|
|
121
|
+
collectableKeys.listingsCount,
|
|
122
|
+
collectableKeys.lists,
|
|
123
|
+
collectableKeys.userBalances,
|
|
124
|
+
balanceQueries.all,
|
|
125
|
+
]);
|
|
126
|
+
callbacks?.onSuccess?.({ hash: hash as Hash });
|
|
127
|
+
},
|
|
100
128
|
onError: callbacks?.onError,
|
|
101
129
|
onClose: () => {
|
|
102
|
-
console.log('onClose');
|
|
103
130
|
buyModal$.close();
|
|
104
131
|
},
|
|
105
132
|
});
|
|
@@ -17,9 +17,6 @@ interface ERC1155QuantityModalProps extends CheckoutModalProps {
|
|
|
17
17
|
|
|
18
18
|
export const ERC1155QuantityModal = observer(
|
|
19
19
|
({ buy, collectable, order }: ERC1155QuantityModalProps) => {
|
|
20
|
-
buyModal$.state.quantity.set(
|
|
21
|
-
Math.min(Number(order.quantityRemaining), 1).toString(),
|
|
22
|
-
);
|
|
23
20
|
const currencyOptions = useCurrencyOptions({
|
|
24
21
|
collectionAddress: order.collectionContractAddress as Address,
|
|
25
22
|
});
|
|
@@ -36,6 +33,10 @@ export const ERC1155QuantityModal = observer(
|
|
|
36
33
|
const pricePerToken = order.priceAmount;
|
|
37
34
|
const totalPrice = (BigInt(quantity) * BigInt(pricePerToken)).toString();
|
|
38
35
|
|
|
36
|
+
if (buyModal$.state.checkoutModalLoaded.get()) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
39
40
|
return (
|
|
40
41
|
<ActionModal
|
|
41
42
|
isOpen={buyModal$.isOpen.get()}
|
|
@@ -46,6 +47,8 @@ export const ERC1155QuantityModal = observer(
|
|
|
46
47
|
{
|
|
47
48
|
label: 'Buy now',
|
|
48
49
|
onClick: () => {
|
|
50
|
+
buyModal$.state.checkoutModalIsLoading.set(true);
|
|
51
|
+
|
|
49
52
|
buy({
|
|
50
53
|
quantity: parseUnits(
|
|
51
54
|
buyModal$.state.quantity.get(),
|
|
@@ -56,6 +59,8 @@ export const ERC1155QuantityModal = observer(
|
|
|
56
59
|
marketplace: order.marketplace,
|
|
57
60
|
});
|
|
58
61
|
},
|
|
62
|
+
disabled: buyModal$.state.checkoutModalIsLoading.get(),
|
|
63
|
+
pending: buyModal$.state.checkoutModalIsLoading.get(),
|
|
59
64
|
},
|
|
60
65
|
]}
|
|
61
66
|
>
|
|
@@ -17,7 +17,11 @@ export interface BuyModalState {
|
|
|
17
17
|
quantity: string;
|
|
18
18
|
modalId: number;
|
|
19
19
|
invalidQuantity: boolean;
|
|
20
|
+
checkoutModalIsLoading: boolean;
|
|
21
|
+
checkoutModalLoaded: boolean;
|
|
20
22
|
};
|
|
23
|
+
setCheckoutModalIsLoading: (isLoading: boolean) => void;
|
|
24
|
+
setCheckoutModalLoaded: (isLoaded: boolean) => void;
|
|
21
25
|
callbacks?: ModalCallbacks;
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -36,6 +40,8 @@ export const initialState: BuyModalState = {
|
|
|
36
40
|
order: args.order,
|
|
37
41
|
modalId: buyModal$.state.modalId.get() + 1,
|
|
38
42
|
invalidQuantity: false,
|
|
43
|
+
checkoutModalIsLoading: false,
|
|
44
|
+
checkoutModalLoaded: false,
|
|
39
45
|
});
|
|
40
46
|
buyModal$.callbacks.set(callbacks || defaultCallbacks);
|
|
41
47
|
buyModal$.isOpen.set(true);
|
|
@@ -48,6 +54,14 @@ export const initialState: BuyModalState = {
|
|
|
48
54
|
quantity: '1',
|
|
49
55
|
modalId: 0,
|
|
50
56
|
invalidQuantity: false,
|
|
57
|
+
checkoutModalIsLoading: false,
|
|
58
|
+
checkoutModalLoaded: false,
|
|
59
|
+
},
|
|
60
|
+
setCheckoutModalIsLoading: (isLoading: boolean) => {
|
|
61
|
+
buyModal$.state.checkoutModalIsLoading.set(isLoading);
|
|
62
|
+
},
|
|
63
|
+
setCheckoutModalLoaded: (isLoaded: boolean) => {
|
|
64
|
+
buyModal$.state.checkoutModalLoaded.set(isLoaded);
|
|
51
65
|
},
|
|
52
66
|
callbacks: undefined,
|
|
53
67
|
};
|
|
@@ -159,7 +159,7 @@ const Modal = observer(() => {
|
|
|
159
159
|
<PriceInput
|
|
160
160
|
chainId={chainId}
|
|
161
161
|
collectionAddress={collectionAddress}
|
|
162
|
-
$
|
|
162
|
+
$price={createListingModal$.listingPrice}
|
|
163
163
|
/>
|
|
164
164
|
|
|
165
165
|
{listingPrice.amountRaw !== '0' && (
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { Observable } from '@legendapp/state';
|
|
1
2
|
import { useEffect } from 'react';
|
|
2
|
-
import {
|
|
3
|
+
import { OrderbookKind, type TransactionSteps } from '../../../../_internal';
|
|
4
|
+
import type { ListingInput } from '../../../../_internal/transaction-machine/execute-transaction';
|
|
5
|
+
import { useMarketplaceConfig } from '../../../../hooks';
|
|
6
|
+
import type { ModalCallbacks } from '../../_internal/types';
|
|
3
7
|
import { useGetTokenApprovalData } from './useGetTokenApproval';
|
|
4
|
-
import { ListingInput } from '../../../../_internal/transaction-machine/execute-transaction';
|
|
5
|
-
import { OrderbookKind, TransactionSteps } from '../../../../_internal';
|
|
6
|
-
import { ModalCallbacks } from '../../_internal/types';
|
|
7
8
|
import { useTransactionSteps } from './useTransactionSteps';
|
|
8
9
|
|
|
9
10
|
interface UseCreateListingArgs {
|
|
@@ -20,11 +21,23 @@ export const useCreateListing = ({
|
|
|
20
21
|
listingInput,
|
|
21
22
|
chainId,
|
|
22
23
|
collectionAddress,
|
|
23
|
-
orderbookKind
|
|
24
|
+
orderbookKind,
|
|
24
25
|
steps$,
|
|
25
26
|
callbacks,
|
|
26
27
|
closeMainModal,
|
|
27
28
|
}: UseCreateListingArgs) => {
|
|
29
|
+
const { data: marketplaceConfig, isLoading: marketplaceIsLoading } =
|
|
30
|
+
useMarketplaceConfig();
|
|
31
|
+
|
|
32
|
+
const collectionConfig = marketplaceConfig?.collections.find(
|
|
33
|
+
(c) => c.collectionAddress === collectionAddress,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
orderbookKind =
|
|
37
|
+
orderbookKind ??
|
|
38
|
+
collectionConfig?.destinationMarketplace ??
|
|
39
|
+
OrderbookKind.sequence_marketplace_v2;
|
|
40
|
+
|
|
28
41
|
const { data: tokenApproval, isLoading: tokenApprovalIsLoading } =
|
|
29
42
|
useGetTokenApprovalData({
|
|
30
43
|
chainId,
|
|
@@ -33,6 +46,9 @@ export const useCreateListing = ({
|
|
|
33
46
|
currencyAddress: listingInput.listing.currencyAddress,
|
|
34
47
|
contractType: listingInput.contractType,
|
|
35
48
|
orderbook: orderbookKind,
|
|
49
|
+
query: {
|
|
50
|
+
enabled: !marketplaceIsLoading,
|
|
51
|
+
},
|
|
36
52
|
});
|
|
37
53
|
|
|
38
54
|
useEffect(() => {
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { skipToken, useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { useConfig } from '../../../..';
|
|
3
|
+
import { dateToUnixTime } from '../../../../../utils/date';
|
|
1
4
|
import {
|
|
2
5
|
type ContractType,
|
|
3
6
|
type CreateReq,
|
|
4
7
|
type GenerateListingTransactionArgs,
|
|
5
|
-
getMarketplaceClient,
|
|
6
8
|
type OrderbookKind,
|
|
9
|
+
type QueryArg,
|
|
7
10
|
StepType,
|
|
11
|
+
getMarketplaceClient,
|
|
8
12
|
} from '../../../../_internal';
|
|
9
|
-
import { useConfig } from '../../../..';
|
|
10
|
-
import { dateToUnixTime } from '../../../../../utils/date';
|
|
11
13
|
import { useWallet } from '../../../../_internal/transaction-machine/useWallet';
|
|
12
|
-
import { useQuery } from '@tanstack/react-query';
|
|
13
14
|
|
|
14
15
|
export interface UseGetTokenApprovalDataArgs {
|
|
15
16
|
chainId: string;
|
|
@@ -18,6 +19,7 @@ export interface UseGetTokenApprovalDataArgs {
|
|
|
18
19
|
currencyAddress: string;
|
|
19
20
|
contractType: ContractType;
|
|
20
21
|
orderbook: OrderbookKind;
|
|
22
|
+
query?: QueryArg;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
|
|
@@ -37,34 +39,38 @@ export const useGetTokenApprovalData = (
|
|
|
37
39
|
expiry: String(Number(dateToUnixTime(new Date())) + ONE_DAY_IN_SECONDS),
|
|
38
40
|
} satisfies CreateReq;
|
|
39
41
|
|
|
42
|
+
const isEnabled = wallet && params.query?.enabled !== false;
|
|
43
|
+
|
|
40
44
|
const { data, isLoading, isSuccess } = useQuery({
|
|
41
45
|
queryKey: ['token-approval-data', params.currencyAddress],
|
|
42
|
-
queryFn:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
queryFn: isEnabled
|
|
47
|
+
? async () => {
|
|
48
|
+
const args = {
|
|
49
|
+
collectionAddress: params.collectionAddress,
|
|
50
|
+
owner: await wallet.address(),
|
|
51
|
+
walletType: wallet.walletKind,
|
|
52
|
+
contractType: params.contractType,
|
|
53
|
+
orderbook: params.orderbook,
|
|
54
|
+
listing,
|
|
55
|
+
} satisfies GenerateListingTransactionArgs;
|
|
56
|
+
const steps = await marketplaceClient
|
|
57
|
+
.generateListingTransaction(args)
|
|
58
|
+
.then((resp) => resp.steps);
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
const tokenApprovalStep = steps.find(
|
|
61
|
+
(step) => step.id === StepType.tokenApproval,
|
|
62
|
+
);
|
|
63
|
+
if (!tokenApprovalStep) {
|
|
64
|
+
return {
|
|
65
|
+
step: null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
return {
|
|
70
|
+
step: tokenApprovalStep,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
: skipToken,
|
|
68
74
|
});
|
|
69
75
|
|
|
70
76
|
return {
|
|
@@ -1,29 +1,31 @@
|
|
|
1
|
+
import type { Observable } from '@legendapp/state';
|
|
2
|
+
import type { Address } from 'viem';
|
|
3
|
+
import type { OrderbookKind } from '../../../../../types';
|
|
1
4
|
import {
|
|
2
5
|
ExecuteType,
|
|
3
|
-
|
|
4
|
-
Step,
|
|
6
|
+
type Step,
|
|
5
7
|
StepType,
|
|
6
|
-
TransactionSteps,
|
|
8
|
+
type TransactionSteps,
|
|
9
|
+
balanceQueries,
|
|
10
|
+
collectableKeys,
|
|
11
|
+
getMarketplaceClient,
|
|
7
12
|
} from '../../../../_internal';
|
|
8
|
-
import { OrderbookKind } from '../../../../../types';
|
|
9
|
-
import { ModalCallbacks } from '../../_internal/types';
|
|
10
13
|
import {
|
|
11
|
-
ListingInput,
|
|
14
|
+
type ListingInput,
|
|
12
15
|
TransactionType,
|
|
13
16
|
} from '../../../../_internal/transaction-machine/execute-transaction';
|
|
14
|
-
import { useTransactionStatusModal } from '../../_internal/components/transactionStatusModal';
|
|
15
|
-
import { Address } from 'viem';
|
|
16
|
-
import { Observable } from '@legendapp/state';
|
|
17
17
|
import { useWallet } from '../../../../_internal/transaction-machine/useWallet';
|
|
18
|
-
import { SignatureStep } from '../../../../_internal/transaction-machine/utils';
|
|
18
|
+
import type { SignatureStep } from '../../../../_internal/transaction-machine/utils';
|
|
19
19
|
import { useConfig, useGenerateListingTransaction } from '../../../../hooks';
|
|
20
20
|
import { useGetReceiptFromHash } from '../../../../hooks/useGetReceiptFromHash';
|
|
21
|
+
import { useTransactionStatusModal } from '../../_internal/components/transactionStatusModal';
|
|
22
|
+
import type { ModalCallbacks } from '../../_internal/types';
|
|
21
23
|
|
|
22
24
|
interface UseTransactionStepsArgs {
|
|
23
25
|
listingInput: ListingInput;
|
|
24
26
|
chainId: string;
|
|
25
27
|
collectionAddress: string;
|
|
26
|
-
orderbookKind
|
|
28
|
+
orderbookKind: OrderbookKind;
|
|
27
29
|
callbacks?: ModalCallbacks;
|
|
28
30
|
closeMainModal: () => void;
|
|
29
31
|
steps$: Observable<TransactionSteps>;
|
|
@@ -33,7 +35,7 @@ export const useTransactionSteps = ({
|
|
|
33
35
|
listingInput,
|
|
34
36
|
chainId,
|
|
35
37
|
collectionAddress,
|
|
36
|
-
orderbookKind
|
|
38
|
+
orderbookKind,
|
|
37
39
|
callbacks,
|
|
38
40
|
closeMainModal,
|
|
39
41
|
steps$,
|
|
@@ -77,7 +79,6 @@ export const useTransactionSteps = ({
|
|
|
77
79
|
} else {
|
|
78
80
|
console.debug('onError callback not provided:', error);
|
|
79
81
|
}
|
|
80
|
-
throw error;
|
|
81
82
|
}
|
|
82
83
|
};
|
|
83
84
|
|
|
@@ -103,7 +104,6 @@ export const useTransactionSteps = ({
|
|
|
103
104
|
}
|
|
104
105
|
} catch (error) {
|
|
105
106
|
steps$.approval.isExecuting.set(false);
|
|
106
|
-
throw error;
|
|
107
107
|
}
|
|
108
108
|
};
|
|
109
109
|
|
|
@@ -147,12 +147,39 @@ export const useTransactionSteps = ({
|
|
|
147
147
|
hash,
|
|
148
148
|
orderId,
|
|
149
149
|
callbacks,
|
|
150
|
+
queriesToInvalidate: [
|
|
151
|
+
balanceQueries.all,
|
|
152
|
+
collectableKeys.lowestListings,
|
|
153
|
+
collectableKeys.listings,
|
|
154
|
+
collectableKeys.listingsCount,
|
|
155
|
+
collectableKeys.userBalances,
|
|
156
|
+
],
|
|
150
157
|
});
|
|
151
158
|
|
|
152
|
-
|
|
159
|
+
if (hash) {
|
|
160
|
+
await waitForReceipt(hash);
|
|
161
|
+
|
|
162
|
+
steps$.transaction.isExecuting.set(false);
|
|
163
|
+
steps$.transaction.exist.set(false);
|
|
164
|
+
if (callbacks?.onSuccess && typeof callbacks.onSuccess === 'function') {
|
|
165
|
+
callbacks.onSuccess({ hash });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (orderId) {
|
|
170
|
+
steps$.transaction.isExecuting.set(false);
|
|
171
|
+
steps$.transaction.exist.set(false);
|
|
172
|
+
|
|
173
|
+
if (callbacks?.onSuccess && typeof callbacks.onSuccess === 'function') {
|
|
174
|
+
callbacks.onSuccess({ orderId });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
153
177
|
} catch (error) {
|
|
154
178
|
steps$.transaction.isExecuting.set(false);
|
|
155
|
-
|
|
179
|
+
steps$.transaction.exist.set(false);
|
|
180
|
+
if (callbacks?.onError && typeof callbacks.onError === 'function') {
|
|
181
|
+
callbacks.onError(error as Error);
|
|
182
|
+
}
|
|
156
183
|
}
|
|
157
184
|
};
|
|
158
185
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { Show, observer } from '@legendapp/state/react';
|
|
1
|
+
import { Show, observer, use$ } from '@legendapp/state/react';
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { parseUnits } from 'viem';
|
|
3
|
+
import { parseUnits, zeroAddress } from 'viem';
|
|
4
4
|
import { dateToUnixTime } from '../../../../utils/date';
|
|
5
|
-
import { ContractType } from '../../../_internal';
|
|
6
|
-
import {
|
|
5
|
+
import { ContractType, OrderbookKind } from '../../../_internal';
|
|
6
|
+
import {
|
|
7
|
+
useCollectible,
|
|
8
|
+
useCollection,
|
|
9
|
+
useCurrencies,
|
|
10
|
+
useCurrencyOptions,
|
|
11
|
+
} from '../../../hooks';
|
|
7
12
|
import { useMakeOffer } from './hooks/useMakeOffer';
|
|
8
13
|
import { ActionModal } from '../_internal/components/actionModal/ActionModal';
|
|
9
14
|
import { ErrorModal } from '../_internal/components/actionModal/ErrorModal';
|
|
@@ -14,6 +19,7 @@ import PriceInput from '../_internal/components/priceInput';
|
|
|
14
19
|
import QuantityInput from '../_internal/components/quantityInput';
|
|
15
20
|
import TokenPreview from '../_internal/components/tokenPreview';
|
|
16
21
|
import { makeOfferModal$ } from './store';
|
|
22
|
+
import { Box } from '@0xsequence/design-system';
|
|
17
23
|
|
|
18
24
|
export const MakeOfferModal = () => {
|
|
19
25
|
return <Show if={makeOfferModal$.isOpen}>{() => <Modal />}</Show>;
|
|
@@ -51,6 +57,18 @@ const Modal = observer(() => {
|
|
|
51
57
|
chainId,
|
|
52
58
|
collectionAddress,
|
|
53
59
|
});
|
|
60
|
+
const currencyOptions = useCurrencyOptions({ collectionAddress });
|
|
61
|
+
const {
|
|
62
|
+
data: currencies,
|
|
63
|
+
isLoading: currenciesLoading,
|
|
64
|
+
isError: currenciesIsError,
|
|
65
|
+
} = useCurrencies({
|
|
66
|
+
chainId,
|
|
67
|
+
currencyOptions,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const selectedCurrency = use$(makeOfferModal$.offerPrice.currency);
|
|
71
|
+
|
|
54
72
|
const { isLoading, executeApproval, makeOffer } = useMakeOffer({
|
|
55
73
|
offerInput: {
|
|
56
74
|
contractType: collection?.type as ContractType,
|
|
@@ -73,7 +91,7 @@ const Modal = observer(() => {
|
|
|
73
91
|
steps$: steps$,
|
|
74
92
|
});
|
|
75
93
|
|
|
76
|
-
if (collectableIsLoading || collectionIsLoading) {
|
|
94
|
+
if (collectableIsLoading || collectionIsLoading || currenciesLoading) {
|
|
77
95
|
return (
|
|
78
96
|
<LoadingModal
|
|
79
97
|
isOpen={makeOfferModal$.isOpen.get()}
|
|
@@ -84,7 +102,7 @@ const Modal = observer(() => {
|
|
|
84
102
|
);
|
|
85
103
|
}
|
|
86
104
|
|
|
87
|
-
if (collectableIsError || collectionIsError) {
|
|
105
|
+
if (collectableIsError || collectionIsError || currenciesIsError) {
|
|
88
106
|
return (
|
|
89
107
|
<ErrorModal
|
|
90
108
|
isOpen={makeOfferModal$.isOpen.get()}
|
|
@@ -95,6 +113,10 @@ const Modal = observer(() => {
|
|
|
95
113
|
);
|
|
96
114
|
}
|
|
97
115
|
|
|
116
|
+
const invalidCurrency =
|
|
117
|
+
selectedCurrency?.contractAddress === zeroAddress &&
|
|
118
|
+
orderbookKind !== OrderbookKind.sequence_marketplace_v2;
|
|
119
|
+
|
|
98
120
|
const ctas = [
|
|
99
121
|
{
|
|
100
122
|
label: 'Approve TOKEN',
|
|
@@ -120,10 +142,15 @@ const Modal = observer(() => {
|
|
|
120
142
|
insufficientBalance ||
|
|
121
143
|
isLoading ||
|
|
122
144
|
invalidQuantity ||
|
|
123
|
-
|
|
145
|
+
invalidCurrency,
|
|
124
146
|
},
|
|
125
147
|
];
|
|
126
148
|
|
|
149
|
+
const secondCurrencyAsDefault =
|
|
150
|
+
orderbookKind !== OrderbookKind.sequence_marketplace_v2 &&
|
|
151
|
+
currencies &&
|
|
152
|
+
currencies[0]?.contractAddress === zeroAddress;
|
|
153
|
+
|
|
127
154
|
return (
|
|
128
155
|
<>
|
|
129
156
|
<ActionModal
|
|
@@ -143,8 +170,9 @@ const Modal = observer(() => {
|
|
|
143
170
|
<PriceInput
|
|
144
171
|
chainId={chainId}
|
|
145
172
|
collectionAddress={collectionAddress}
|
|
146
|
-
$
|
|
173
|
+
$price={makeOfferModal$.offerPrice}
|
|
147
174
|
onPriceChange={() => makeOfferModal$.offerPriceChanged.set(true)}
|
|
175
|
+
secondCurrencyAsDefault={secondCurrencyAsDefault}
|
|
148
176
|
checkBalance={{
|
|
149
177
|
enabled: true,
|
|
150
178
|
callback: (state) => setInsufficientBalance(state),
|
|
@@ -170,8 +198,14 @@ const Modal = observer(() => {
|
|
|
170
198
|
price={offerPrice}
|
|
171
199
|
/>
|
|
172
200
|
)}
|
|
173
|
-
|
|
174
201
|
<ExpirationDateSelect $date={makeOfferModal$.expiry} />
|
|
202
|
+
|
|
203
|
+
{invalidCurrency && (
|
|
204
|
+
<Box color="negative" fontSize="small">
|
|
205
|
+
Native currency offers are not supported on this marketplace. Please
|
|
206
|
+
select another currency to continue
|
|
207
|
+
</Box>
|
|
208
|
+
)}
|
|
175
209
|
</ActionModal>
|
|
176
210
|
</>
|
|
177
211
|
);
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { skipToken, useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { dateToUnixTime } from '../../../../../utils/date';
|
|
1
3
|
import {
|
|
2
4
|
type ContractType,
|
|
3
5
|
type CreateReq,
|
|
4
|
-
GenerateOfferTransactionArgs,
|
|
5
|
-
getMarketplaceClient,
|
|
6
|
+
type GenerateOfferTransactionArgs,
|
|
6
7
|
type OrderbookKind,
|
|
8
|
+
type QueryArg,
|
|
7
9
|
StepType,
|
|
10
|
+
getMarketplaceClient,
|
|
8
11
|
} from '../../../../_internal';
|
|
9
|
-
import { useQuery } from '@tanstack/react-query';
|
|
10
12
|
import { useWallet } from '../../../../_internal/transaction-machine/useWallet';
|
|
11
13
|
import { useConfig } from '../../../../hooks/useConfig';
|
|
12
|
-
import { dateToUnixTime } from '../../../../../utils/date';
|
|
13
14
|
|
|
14
15
|
export interface UseGetTokenApprovalDataArgs {
|
|
15
16
|
chainId: string;
|
|
@@ -18,6 +19,7 @@ export interface UseGetTokenApprovalDataArgs {
|
|
|
18
19
|
currencyAddress: string;
|
|
19
20
|
contractType: ContractType;
|
|
20
21
|
orderbook: OrderbookKind;
|
|
22
|
+
query?: QueryArg;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
|
|
@@ -37,34 +39,38 @@ export const useGetTokenApprovalData = (
|
|
|
37
39
|
expiry: String(Number(dateToUnixTime(new Date())) + ONE_DAY_IN_SECONDS),
|
|
38
40
|
} satisfies CreateReq;
|
|
39
41
|
|
|
42
|
+
const isEnabled = wallet && params.query?.enabled !== false;
|
|
43
|
+
|
|
40
44
|
const { data, isLoading, isSuccess } = useQuery({
|
|
41
45
|
queryKey: ['token-approval-data', params.currencyAddress],
|
|
42
|
-
queryFn:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
queryFn: isEnabled
|
|
47
|
+
? async () => {
|
|
48
|
+
const args = {
|
|
49
|
+
collectionAddress: params.collectionAddress,
|
|
50
|
+
maker: await wallet.address(),
|
|
51
|
+
walletType: wallet.walletKind,
|
|
52
|
+
contractType: params.contractType,
|
|
53
|
+
orderbook: params.orderbook,
|
|
54
|
+
offer,
|
|
55
|
+
} satisfies GenerateOfferTransactionArgs;
|
|
56
|
+
const steps = await marketplaceClient
|
|
57
|
+
.generateOfferTransaction(args)
|
|
58
|
+
.then((resp) => resp.steps);
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
const tokenApprovalStep = steps.find(
|
|
61
|
+
(step) => step.id === StepType.tokenApproval,
|
|
62
|
+
);
|
|
63
|
+
if (!tokenApprovalStep) {
|
|
64
|
+
return {
|
|
65
|
+
step: null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
return {
|
|
70
|
+
step: tokenApprovalStep,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
: skipToken,
|
|
68
74
|
enabled: !!wallet && !!params.collectionAddress && !!params.currencyAddress,
|
|
69
75
|
});
|
|
70
76
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Observable } from '@legendapp/state';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import type { Observable } from '@legendapp/state';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import type { OrderbookKind } from '../../../../../types';
|
|
4
|
+
import type { TransactionSteps } from '../../../../_internal';
|
|
5
|
+
import type { OfferInput } from '../../../../_internal/transaction-machine/execute-transaction';
|
|
6
|
+
import type { ModalCallbacks } from '../../_internal/types';
|
|
5
7
|
import { useGetTokenApprovalData } from './useGetTokenApproval';
|
|
6
8
|
import { useTransactionSteps } from './useTransactionSteps';
|
|
7
|
-
import { useEffect } from 'react';
|
|
8
|
-
import { TransactionSteps } from '../../../../_internal';
|
|
9
9
|
|
|
10
10
|
interface UseMakeOfferArgs {
|
|
11
11
|
offerInput: OfferInput;
|
|
12
12
|
chainId: string;
|
|
13
13
|
collectionAddress: string;
|
|
14
|
-
orderbookKind
|
|
14
|
+
orderbookKind: OrderbookKind;
|
|
15
15
|
callbacks?: ModalCallbacks;
|
|
16
16
|
closeMainModal: () => void;
|
|
17
17
|
steps$: Observable<TransactionSteps>;
|
|
@@ -21,7 +21,7 @@ export const useMakeOffer = ({
|
|
|
21
21
|
offerInput,
|
|
22
22
|
chainId,
|
|
23
23
|
collectionAddress,
|
|
24
|
-
orderbookKind
|
|
24
|
+
orderbookKind,
|
|
25
25
|
callbacks,
|
|
26
26
|
closeMainModal,
|
|
27
27
|
steps$,
|