@0xsequence/marketplace-sdk 0.3.11 → 0.4.1
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-3LOJQCTV.js → chunk-5GDO4ZBC.js} +5 -4
- package/dist/{chunk-3LOJQCTV.js.map → chunk-5GDO4ZBC.js.map} +1 -1
- package/dist/{chunk-E3ZFT6WR.js → chunk-EVRILXOH.js} +12 -2
- package/dist/chunk-EVRILXOH.js.map +1 -0
- package/dist/{chunk-N5F6IEAK.js → chunk-GSDUAHL3.js} +1 -1
- package/dist/chunk-GSDUAHL3.js.map +1 -0
- package/dist/{chunk-IRN77TJW.js → chunk-IOTKCWOB.js} +925 -667
- package/dist/chunk-IOTKCWOB.js.map +1 -0
- package/dist/{chunk-KRMV6FJE.js → chunk-KNX2LER4.js} +5 -6
- package/dist/{chunk-4FC3IG7C.js.map → chunk-KNX2LER4.js.map} +1 -1
- package/dist/{chunk-SBVLWSRZ.js → chunk-LF44FCG5.js} +2 -2
- package/dist/{chunk-SBVLWSRZ.js.map → chunk-LF44FCG5.js.map} +1 -1
- package/dist/{chunk-4FC3IG7C.js → chunk-LSMQVX77.js} +5 -6
- package/dist/{chunk-KRMV6FJE.js.map → chunk-LSMQVX77.js.map} +1 -1
- package/dist/{chunk-B3LFJJVS.js → chunk-MIYMMP2K.js} +90 -40
- package/dist/chunk-MIYMMP2K.js.map +1 -0
- package/dist/{chunk-Z7NLKEXF.js → chunk-QMO2CUNM.js} +2 -2
- package/dist/{chunk-L6GSYPCR.js → chunk-RZSZNVEH.js} +5 -5
- package/dist/{chunk-L6GSYPCR.js.map → chunk-RZSZNVEH.js.map} +1 -1
- package/dist/chunk-T5T6JNB2.js +171 -0
- package/dist/chunk-T5T6JNB2.js.map +1 -0
- package/dist/chunk-UPLTM63S.js +435 -0
- package/dist/chunk-UPLTM63S.js.map +1 -0
- package/dist/{chunk-Y7YO5TLE.js → chunk-XXML5K3X.js} +5 -2
- package/dist/chunk-XXML5K3X.js.map +1 -0
- package/dist/{create-config-CgtmCzvb.d.ts → create-config-8sffBvlt.d.ts} +1 -1
- package/dist/index.js +5 -5
- package/dist/react/_internal/api/index.js +2 -2
- package/dist/react/_internal/index.d.ts +1 -1
- package/dist/react/_internal/index.js +3 -3
- package/dist/react/_internal/wagmi/index.d.ts +1 -1
- package/dist/react/_internal/wagmi/index.js +2 -2
- package/dist/react/hooks/index.d.ts +666 -77
- package/dist/react/hooks/index.js +8 -8
- package/dist/react/index.css +17 -0
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +12 -12
- package/dist/react/ssr/index.js +1 -1
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/index.css +17 -0
- package/dist/react/ui/components/index.css.map +1 -1
- package/dist/react/ui/components/index.js +12 -12
- package/dist/react/ui/icons/index.js +4 -4
- package/dist/react/ui/icons/index.js.map +1 -1
- package/dist/react/ui/index.css +17 -0
- package/dist/react/ui/index.css.map +1 -1
- package/dist/react/ui/index.js +12 -12
- package/dist/react/ui/modals/_internal/components/actionModal/index.css +22 -0
- package/dist/react/ui/modals/_internal/components/actionModal/index.css.map +1 -1
- package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +17 -9
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +8 -4
- package/dist/react/ui/styles/index.d.ts +1 -1
- package/dist/styles/index.d.ts +1 -1
- package/dist/styles/index.js +2 -2
- package/dist/types/index.js +3 -3
- package/dist/utils/index.js +2 -2
- package/package.json +25 -25
- package/src/react/_internal/api/marketplace-api.ts +3 -2
- package/src/react/_internal/transaction-machine/execute-transaction.ts +41 -19
- package/src/react/_internal/transaction-machine/useTransactionMachine.ts +43 -8
- package/src/react/hooks/useBuyCollectable.tsx +15 -8
- package/src/react/hooks/useCancelOrder.tsx +15 -7
- package/src/react/hooks/useCreateListing.tsx +75 -11
- package/src/react/hooks/useCurrencies.tsx +1 -2
- package/src/react/hooks/useCurrencyBalance.tsx +1 -1
- package/src/react/hooks/useCurrencyOptions.tsx +1 -1
- package/src/react/hooks/useMakeOffer.tsx +74 -12
- package/src/react/hooks/useSell.tsx +73 -12
- package/src/react/ui/components/_internals/action-button/ActionButton.tsx +1 -7
- package/src/react/ui/components/_internals/action-button/types.ts +7 -0
- package/src/react/ui/components/_internals/custom-select/CustomSelect.tsx +18 -15
- package/src/react/ui/components/collectible-card/CollectibleCard.tsx +5 -7
- package/src/react/ui/components/collectible-card/Footer.tsx +5 -7
- package/src/react/ui/components/collectible-card/styles.css.ts +1 -1
- package/src/react/ui/icons/ArrowUp.tsx +3 -0
- package/src/react/ui/icons/Bell.tsx +3 -0
- package/src/react/ui/icons/CalendarIcon.tsx +3 -0
- package/src/react/ui/icons/DiamondEye.tsx +3 -0
- package/src/react/ui/icons/InfoIcon.tsx +3 -0
- package/src/react/ui/icons/InventoryIcon.tsx +3 -0
- package/src/react/ui/icons/MinusIcon.tsx +3 -0
- package/src/react/ui/icons/PlusIcon.tsx +3 -0
- package/src/react/ui/icons/PositiveCircleIcon.tsx +3 -0
- package/src/react/ui/modals/BuyModal/index.tsx +25 -8
- package/src/react/ui/modals/CreateListingModal/_store.ts +5 -2
- package/src/react/ui/modals/CreateListingModal/index.tsx +66 -25
- package/src/react/ui/modals/MakeOfferModal/_store.ts +5 -2
- package/src/react/ui/modals/MakeOfferModal/index.tsx +87 -67
- package/src/react/ui/modals/SellModal/index.tsx +107 -57
- package/src/react/ui/modals/TransferModal/_store.ts +1 -1
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +4 -2
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +5 -5
- package/src/react/ui/modals/TransferModal/index.tsx +1 -1
- package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +29 -8
- package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +15 -5
- package/src/react/ui/modals/_internal/components/actionModal/LoadingModal.tsx +15 -5
- package/src/react/ui/modals/_internal/components/actionModal/store.ts +6 -0
- package/src/react/ui/modals/_internal/components/calendar/index.tsx +1 -1
- package/src/react/ui/modals/_internal/components/currencyImage/index.tsx +3 -3
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +11 -16
- package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +14 -19
- package/src/react/ui/modals/_internal/components/priceInput/index.tsx +34 -12
- package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +3 -3
- package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +7 -4
- package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +1 -0
- package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +10 -8
- package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +9 -5
- package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +7 -4
- package/src/react/ui/modals/_internal/components/transactionPreview/useTransactionPreviewTitle.tsx +9 -11
- package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +60 -31
- package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +6 -2
- package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getFormattedType.ts +1 -1
- package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getMessage.ts +8 -2
- package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getTitle.ts +12 -3
- package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/index.tsx +146 -0
- package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/store.ts +12 -0
- package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/styles.css.ts +53 -0
- package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +117 -0
- package/src/utils/_internal/error/transaction.ts +12 -2
- package/src/utils/price.ts +3 -4
- package/tsconfig.json +1 -21
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-B3LFJJVS.js.map +0 -1
- package/dist/chunk-E3ZFT6WR.js.map +0 -1
- package/dist/chunk-FFCNYF3S.js +0 -153
- package/dist/chunk-FFCNYF3S.js.map +0 -1
- package/dist/chunk-IRN77TJW.js.map +0 -1
- package/dist/chunk-N5F6IEAK.js.map +0 -1
- package/dist/chunk-NMCGA2TB.js +0 -98
- package/dist/chunk-NMCGA2TB.js.map +0 -1
- package/dist/chunk-Y7YO5TLE.js.map +0 -1
- /package/dist/{chunk-Z7NLKEXF.js.map → chunk-QMO2CUNM.js.map} +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Show, observer } from '@legendapp/state/react';
|
|
2
2
|
import type { QueryKey } from '@tanstack/react-query';
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { type Hex, parseUnits } from 'viem';
|
|
5
5
|
import {
|
|
6
6
|
ContractType,
|
|
7
|
-
OrderbookKind,
|
|
7
|
+
type OrderbookKind,
|
|
8
8
|
collectableKeys,
|
|
9
9
|
} from '../../../_internal';
|
|
10
|
+
import { TransactionType } from '../../../_internal/transaction-machine/execute-transaction';
|
|
10
11
|
import { useCollectible, useCollection, useCurrencies } from '../../../hooks';
|
|
12
|
+
import { useCurrencyOptions } from '../../../hooks/useCurrencyOptions';
|
|
11
13
|
import { useMakeOffer } from '../../../hooks/useMakeOffer';
|
|
12
14
|
import { ActionModal } from '../_internal/components/actionModal/ActionModal';
|
|
13
15
|
import { ErrorModal } from '../_internal/components/actionModal/ErrorModal';
|
|
@@ -20,8 +22,6 @@ import TokenPreview from '../_internal/components/tokenPreview';
|
|
|
20
22
|
import { useTransactionStatusModal } from '../_internal/components/transactionStatusModal';
|
|
21
23
|
import type { ModalCallbacks } from '../_internal/types';
|
|
22
24
|
import { makeOfferModal$ } from './_store';
|
|
23
|
-
import { TransactionType } from '../../../_internal/transaction-machine/execute-transaction';
|
|
24
|
-
import { useCurrencyOptions } from '../../../hooks/useCurrencyOptions';
|
|
25
25
|
|
|
26
26
|
export type ShowMakeOfferModalArgs = {
|
|
27
27
|
collectionAddress: Hex;
|
|
@@ -60,11 +60,15 @@ const ModalContent = observer(
|
|
|
60
60
|
collectionAddress,
|
|
61
61
|
chainId,
|
|
62
62
|
offerPrice,
|
|
63
|
+
offerPriceChanged,
|
|
64
|
+
invalidQuantity,
|
|
63
65
|
collectibleId,
|
|
64
66
|
orderbookKind,
|
|
67
|
+
callbacks,
|
|
65
68
|
} = state;
|
|
66
69
|
const [insufficientBalance, setInsufficientBalance] = useState(false);
|
|
67
|
-
|
|
70
|
+
const [approvalExecutedSuccess, setApprovalExecutedSuccess] =
|
|
71
|
+
useState(false);
|
|
68
72
|
const {
|
|
69
73
|
data: collectible,
|
|
70
74
|
isLoading: collectableIsLoading,
|
|
@@ -93,33 +97,25 @@ const ModalContent = observer(
|
|
|
93
97
|
chainId,
|
|
94
98
|
collectionAddress,
|
|
95
99
|
orderbookKind,
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
enabled: makeOfferModal$.isOpen.get(),
|
|
101
|
+
onSwitchChainRefused: () => makeOfferModal$.close(),
|
|
102
|
+
onApprovalSuccess: () => setApprovalExecutedSuccess(true),
|
|
103
|
+
onTransactionSent: (hash, orderId) => {
|
|
104
|
+
if (!hash && !orderId) return;
|
|
105
|
+
|
|
98
106
|
showTransactionStatusModal({
|
|
99
107
|
hash,
|
|
108
|
+
orderId,
|
|
100
109
|
price: makeOfferModal$.offerPrice.get(),
|
|
101
110
|
collectionAddress,
|
|
102
111
|
chainId,
|
|
103
112
|
collectibleId,
|
|
104
113
|
type: TransactionType.OFFER,
|
|
105
114
|
queriesToInvalidate: collectableKeys.all as unknown as QueryKey[],
|
|
115
|
+
callbacks,
|
|
106
116
|
});
|
|
107
117
|
makeOfferModal$.close();
|
|
108
118
|
},
|
|
109
|
-
onSuccess: (hash) => {
|
|
110
|
-
if (typeof makeOfferModal$.callbacks?.onSuccess === 'function') {
|
|
111
|
-
makeOfferModal$.callbacks.onSuccess(hash);
|
|
112
|
-
} else {
|
|
113
|
-
console.debug('onSuccess callback not provided:', hash);
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
onError: (error) => {
|
|
117
|
-
if (typeof makeOfferModal$.callbacks?.onError === 'function') {
|
|
118
|
-
makeOfferModal$.callbacks.onError(error);
|
|
119
|
-
} else {
|
|
120
|
-
console.debug('onError callback not provided:', error);
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
119
|
});
|
|
124
120
|
|
|
125
121
|
const dateToUnixTime = (date: Date) =>
|
|
@@ -128,7 +124,7 @@ const ModalContent = observer(
|
|
|
128
124
|
const currencyAddress = offerPrice.currency.contractAddress;
|
|
129
125
|
|
|
130
126
|
const { isLoading, steps, refreshSteps } = getMakeOfferSteps({
|
|
131
|
-
contractType: collection
|
|
127
|
+
contractType: collection?.type as ContractType,
|
|
132
128
|
offer: {
|
|
133
129
|
tokenId: collectibleId,
|
|
134
130
|
quantity: parseUnits(
|
|
@@ -140,16 +136,20 @@ const ModalContent = observer(
|
|
|
140
136
|
pricePerToken: offerPrice.amountRaw,
|
|
141
137
|
},
|
|
142
138
|
});
|
|
139
|
+
const approvalNeeded = steps?.approval.isPending;
|
|
143
140
|
|
|
141
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
144
142
|
useEffect(() => {
|
|
145
143
|
if (!currencyAddress) return;
|
|
144
|
+
|
|
146
145
|
refreshSteps();
|
|
147
146
|
}, [currencyAddress]);
|
|
148
147
|
|
|
149
148
|
if (collectableIsLoading || collectionIsLoading || currenciesIsLoading) {
|
|
150
149
|
return (
|
|
151
150
|
<LoadingModal
|
|
152
|
-
|
|
151
|
+
isOpen={makeOfferModal$.isOpen.get()}
|
|
152
|
+
chainId={Number(chainId)}
|
|
153
153
|
onClose={makeOfferModal$.close}
|
|
154
154
|
title="Make an offer"
|
|
155
155
|
/>
|
|
@@ -159,20 +159,26 @@ const ModalContent = observer(
|
|
|
159
159
|
if (collectableIsError || collectionIsError) {
|
|
160
160
|
return (
|
|
161
161
|
<ErrorModal
|
|
162
|
-
|
|
162
|
+
isOpen={makeOfferModal$.isOpen.get()}
|
|
163
|
+
chainId={Number(chainId)}
|
|
163
164
|
onClose={makeOfferModal$.close}
|
|
164
165
|
title="Make an offer"
|
|
165
166
|
/>
|
|
166
167
|
);
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
169
171
|
const handleStepExecution = async (execute?: any) => {
|
|
170
172
|
if (!execute) return;
|
|
171
173
|
try {
|
|
172
174
|
await refreshSteps();
|
|
173
175
|
await execute();
|
|
174
176
|
} catch (error) {
|
|
175
|
-
|
|
177
|
+
if (callbacks?.onError) {
|
|
178
|
+
callbacks.onError(error as Error);
|
|
179
|
+
} else {
|
|
180
|
+
console.debug('onError callback not provided:', error);
|
|
181
|
+
}
|
|
176
182
|
}
|
|
177
183
|
};
|
|
178
184
|
|
|
@@ -180,68 +186,82 @@ const ModalContent = observer(
|
|
|
180
186
|
{
|
|
181
187
|
label: 'Approve TOKEN',
|
|
182
188
|
onClick: () => handleStepExecution(() => steps?.approval.execute()),
|
|
183
|
-
hidden: !
|
|
184
|
-
pending: steps?.approval.isExecuting,
|
|
189
|
+
hidden: !approvalNeeded || approvalExecutedSuccess,
|
|
190
|
+
pending: steps?.approval.isExecuting || isLoading,
|
|
185
191
|
variant: 'glass' as const,
|
|
186
|
-
disabled:
|
|
192
|
+
disabled:
|
|
193
|
+
invalidQuantity ||
|
|
194
|
+
isLoading ||
|
|
195
|
+
steps?.transaction.isExecuting ||
|
|
196
|
+
insufficientBalance ||
|
|
197
|
+
offerPrice.amountRaw === '0' ||
|
|
198
|
+
!offerPriceChanged,
|
|
187
199
|
},
|
|
188
200
|
{
|
|
189
201
|
label: 'Make offer',
|
|
190
202
|
onClick: () => handleStepExecution(() => steps?.transaction.execute()),
|
|
203
|
+
|
|
191
204
|
pending: steps?.transaction.isExecuting || isLoading,
|
|
192
205
|
disabled:
|
|
193
|
-
|
|
206
|
+
(!approvalExecutedSuccess && approvalNeeded) ||
|
|
194
207
|
offerPrice.amountRaw === '0' ||
|
|
195
208
|
insufficientBalance ||
|
|
196
209
|
isLoading ||
|
|
197
|
-
|
|
210
|
+
invalidQuantity ||
|
|
211
|
+
offerPrice.amountRaw === '0',
|
|
198
212
|
},
|
|
199
213
|
];
|
|
200
214
|
|
|
201
215
|
return (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
<PriceInput
|
|
216
|
-
chainId={chainId}
|
|
217
|
-
collectionAddress={collectionAddress}
|
|
218
|
-
$listingPrice={makeOfferModal$.offerPrice}
|
|
219
|
-
checkBalance={{
|
|
220
|
-
enabled: true,
|
|
221
|
-
callback: (state) => setInsufficientBalance(state),
|
|
222
|
-
}}
|
|
223
|
-
/>
|
|
224
|
-
|
|
225
|
-
{collection?.type === ContractType.ERC1155 && (
|
|
226
|
-
<QuantityInput
|
|
227
|
-
$quantity={makeOfferModal$.quantity}
|
|
228
|
-
$invalidQuantity={makeOfferModal$.invalidQuantity}
|
|
229
|
-
decimals={collectible?.decimals || 0}
|
|
230
|
-
maxQuantity={String(Number.MAX_SAFE_INTEGER)}
|
|
216
|
+
<>
|
|
217
|
+
<ActionModal
|
|
218
|
+
isOpen={makeOfferModal$.isOpen.get()}
|
|
219
|
+
chainId={Number(chainId)}
|
|
220
|
+
onClose={() => makeOfferModal$.close()}
|
|
221
|
+
title="Make an offer"
|
|
222
|
+
ctas={ctas}
|
|
223
|
+
>
|
|
224
|
+
<TokenPreview
|
|
225
|
+
collectionName={collection?.name}
|
|
226
|
+
collectionAddress={collectionAddress}
|
|
227
|
+
collectibleId={collectibleId}
|
|
228
|
+
chainId={chainId}
|
|
231
229
|
/>
|
|
232
|
-
)}
|
|
233
230
|
|
|
234
|
-
|
|
235
|
-
<FloorPriceText
|
|
236
|
-
tokenId={collectibleId}
|
|
231
|
+
<PriceInput
|
|
237
232
|
chainId={chainId}
|
|
238
233
|
collectionAddress={collectionAddress}
|
|
239
|
-
|
|
234
|
+
$listingPrice={makeOfferModal$.offerPrice}
|
|
235
|
+
onPriceChange={() => makeOfferModal$.offerPriceChanged.set(true)}
|
|
236
|
+
checkBalance={{
|
|
237
|
+
enabled: true,
|
|
238
|
+
callback: (state) => setInsufficientBalance(state),
|
|
239
|
+
}}
|
|
240
240
|
/>
|
|
241
|
-
)}
|
|
242
241
|
|
|
243
|
-
|
|
244
|
-
|
|
242
|
+
{collection?.type === ContractType.ERC1155 && (
|
|
243
|
+
<QuantityInput
|
|
244
|
+
$quantity={makeOfferModal$.quantity}
|
|
245
|
+
$invalidQuantity={makeOfferModal$.invalidQuantity}
|
|
246
|
+
decimals={collectible?.decimals || 0}
|
|
247
|
+
maxQuantity={String(Number.MAX_SAFE_INTEGER)}
|
|
248
|
+
/>
|
|
249
|
+
)}
|
|
250
|
+
|
|
251
|
+
{offerPrice.amountRaw !== '0' &&
|
|
252
|
+
offerPriceChanged &&
|
|
253
|
+
!insufficientBalance && (
|
|
254
|
+
<FloorPriceText
|
|
255
|
+
tokenId={collectibleId}
|
|
256
|
+
chainId={chainId}
|
|
257
|
+
collectionAddress={collectionAddress}
|
|
258
|
+
price={offerPrice}
|
|
259
|
+
/>
|
|
260
|
+
)}
|
|
261
|
+
|
|
262
|
+
<ExpirationDateSelect $date={makeOfferModal$.expiry} />
|
|
263
|
+
</ActionModal>
|
|
264
|
+
</>
|
|
245
265
|
);
|
|
246
266
|
},
|
|
247
267
|
);
|
|
@@ -11,7 +11,10 @@ import { useCollection, useCurrencies } from '../../../hooks';
|
|
|
11
11
|
import { useSell } from '../../../hooks/useSell';
|
|
12
12
|
import { ErrorModal } from '..//_internal/components/actionModal/ErrorModal';
|
|
13
13
|
import type { ModalCallbacks } from '..//_internal/types';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
ActionModal,
|
|
16
|
+
ActionModalProps,
|
|
17
|
+
} from '../_internal/components/actionModal/ActionModal';
|
|
15
18
|
import { LoadingModal } from '../_internal/components/actionModal/LoadingModal';
|
|
16
19
|
import TokenPreview from '../_internal/components/tokenPreview';
|
|
17
20
|
import TransactionDetails from '../_internal/components/transactionDetails';
|
|
@@ -20,6 +23,8 @@ import { useTransactionStatusModal } from '../_internal/components/transactionSt
|
|
|
20
23
|
import { sellModal$ } from './_store';
|
|
21
24
|
import { TransactionType } from '../../../_internal/transaction-machine/execute-transaction';
|
|
22
25
|
import { useCurrencyOptions } from '../../../hooks/useCurrencyOptions';
|
|
26
|
+
import { useEffect, useState } from 'react';
|
|
27
|
+
import { MarketplaceKind } from '../../../_internal/api/marketplace.gen';
|
|
23
28
|
|
|
24
29
|
export type ShowSellModalArgs = {
|
|
25
30
|
chainId: string;
|
|
@@ -53,26 +58,60 @@ const ModalContent = observer(
|
|
|
53
58
|
}: {
|
|
54
59
|
showTransactionStatusModal: TransactionStatusModalReturn['show'];
|
|
55
60
|
}) => {
|
|
56
|
-
const { tokenId, collectionAddress, chainId, order } =
|
|
61
|
+
const { tokenId, collectionAddress, chainId, order, callbacks } =
|
|
62
|
+
sellModal$.get();
|
|
57
63
|
const { data: collectible } = useCollection({
|
|
58
64
|
chainId,
|
|
59
65
|
collectionAddress,
|
|
60
66
|
});
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
const [approvalExecutedSuccess, setApprovalExecutedSuccess] =
|
|
68
|
+
useState(false);
|
|
69
|
+
const {
|
|
70
|
+
data: collection,
|
|
71
|
+
isLoading: collectionLoading,
|
|
72
|
+
isError: collectionError,
|
|
73
|
+
} = useCollection({
|
|
74
|
+
chainId,
|
|
63
75
|
collectionAddress,
|
|
76
|
+
});
|
|
77
|
+
const currencyOptions = useCurrencyOptions({ collectionAddress });
|
|
78
|
+
const { data: currencies, isLoading: currenciesLoading } = useCurrencies({
|
|
64
79
|
chainId,
|
|
80
|
+
currencyOptions,
|
|
81
|
+
});
|
|
82
|
+
const { getSellSteps, isLoading: machineLoading } = useSell({
|
|
83
|
+
collectionAddress,
|
|
84
|
+
chainId,
|
|
85
|
+
enabled: sellModal$.isOpen.get(),
|
|
86
|
+
onSwitchChainRefused: () => {
|
|
87
|
+
sellModal$.close();
|
|
88
|
+
},
|
|
89
|
+
onApprovalSuccess: () => setApprovalExecutedSuccess(true),
|
|
65
90
|
onTransactionSent: (hash) => {
|
|
66
91
|
if (!hash) return;
|
|
67
92
|
showTransactionStatusModal({
|
|
68
93
|
hash: hash,
|
|
69
|
-
price:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
94
|
+
price: order
|
|
95
|
+
? {
|
|
96
|
+
amountRaw: order.priceAmount,
|
|
97
|
+
currency: currencies?.find(
|
|
98
|
+
(currency) =>
|
|
99
|
+
currency.contractAddress === order.priceCurrencyAddress,
|
|
100
|
+
) ?? {
|
|
101
|
+
chainId: Number(chainId),
|
|
102
|
+
contractAddress: order.priceCurrencyAddress,
|
|
103
|
+
name: 'Unknown',
|
|
104
|
+
symbol: 'UNK',
|
|
105
|
+
decimals: 18,
|
|
106
|
+
imageUrl: '',
|
|
107
|
+
exchangeRate: 0,
|
|
108
|
+
defaultChainCurrency: false,
|
|
109
|
+
nativeCurrency: false,
|
|
110
|
+
createdAt: new Date().toISOString(),
|
|
111
|
+
updatedAt: new Date().toISOString(),
|
|
112
|
+
},
|
|
113
|
+
}
|
|
114
|
+
: undefined,
|
|
76
115
|
collectionAddress,
|
|
77
116
|
chainId,
|
|
78
117
|
collectibleId: tokenId,
|
|
@@ -81,43 +120,48 @@ const ModalContent = observer(
|
|
|
81
120
|
...collectableKeys.all,
|
|
82
121
|
balanceQueries.all,
|
|
83
122
|
] as unknown as QueryKey[],
|
|
123
|
+
callbacks,
|
|
84
124
|
});
|
|
85
125
|
sellModal$.close();
|
|
86
126
|
},
|
|
87
|
-
onSuccess: (hash) => {
|
|
88
|
-
if (typeof sellModal$.callbacks?.onSuccess === 'function') {
|
|
89
|
-
sellModal$.callbacks.onSuccess(hash);
|
|
90
|
-
} else {
|
|
91
|
-
console.debug('onSuccess callback not provided:', hash);
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
onError: (error) => {
|
|
95
|
-
if (typeof sellModal$.callbacks?.onError === 'function') {
|
|
96
|
-
sellModal$.callbacks.onError(error);
|
|
97
|
-
} else {
|
|
98
|
-
console.debug('onError callback not provided:', error);
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
127
|
});
|
|
102
128
|
|
|
103
|
-
const {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const { data: currencies, isLoading: currenciesLoading } = useCurrencies({
|
|
113
|
-
chainId,
|
|
114
|
-
currencyOptions,
|
|
129
|
+
const { isLoading, steps, refreshSteps } = getSellSteps({
|
|
130
|
+
orderId: order?.orderId ?? '',
|
|
131
|
+
marketplace: order?.marketplace as MarketplaceKind,
|
|
132
|
+
quantity: order?.quantityRemaining
|
|
133
|
+
? parseUnits(
|
|
134
|
+
order.quantityRemaining,
|
|
135
|
+
collectible?.decimals || 0,
|
|
136
|
+
).toString()
|
|
137
|
+
: '1',
|
|
115
138
|
});
|
|
116
139
|
|
|
117
|
-
|
|
140
|
+
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
refreshSteps();
|
|
143
|
+
}, [order, machineLoading]);
|
|
144
|
+
|
|
145
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
146
|
+
const handleStepExecution = async (execute?: any) => {
|
|
147
|
+
if (!execute) return;
|
|
148
|
+
try {
|
|
149
|
+
await refreshSteps();
|
|
150
|
+
await execute();
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (callbacks?.onError) {
|
|
153
|
+
callbacks.onError(error as Error);
|
|
154
|
+
} else {
|
|
155
|
+
console.debug('onError callback not provided:', error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (collectionLoading || currenciesLoading || machineLoading) {
|
|
118
161
|
return (
|
|
119
162
|
<LoadingModal
|
|
120
|
-
|
|
163
|
+
isOpen={sellModal$.isOpen.get()}
|
|
164
|
+
chainId={Number(chainId)}
|
|
121
165
|
onClose={sellModal$.close}
|
|
122
166
|
title="You have an offer"
|
|
123
167
|
/>
|
|
@@ -127,38 +171,44 @@ const ModalContent = observer(
|
|
|
127
171
|
if (collectionError || order === undefined) {
|
|
128
172
|
return (
|
|
129
173
|
<ErrorModal
|
|
130
|
-
|
|
174
|
+
isOpen={sellModal$.isOpen.get()}
|
|
175
|
+
chainId={Number(chainId)}
|
|
131
176
|
onClose={sellModal$.close}
|
|
132
177
|
title="You have an offer"
|
|
133
178
|
/>
|
|
134
179
|
);
|
|
135
180
|
}
|
|
136
181
|
|
|
182
|
+
const approvalNeeded = steps?.approval.isPending;
|
|
183
|
+
|
|
137
184
|
const currency = currencies?.find(
|
|
138
185
|
(c) => c.contractAddress === order?.priceCurrencyAddress,
|
|
139
186
|
);
|
|
140
187
|
|
|
188
|
+
const ctas = [
|
|
189
|
+
{
|
|
190
|
+
label: 'Approve TOKEN',
|
|
191
|
+
onClick: () => handleStepExecution(() => steps?.approval.execute()),
|
|
192
|
+
hidden: !approvalNeeded || approvalExecutedSuccess,
|
|
193
|
+
pending: steps?.approval.isExecuting || isLoading,
|
|
194
|
+
variant: 'glass' as const,
|
|
195
|
+
disabled: isLoading || steps?.transaction.isExecuting,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
label: 'Accept',
|
|
199
|
+
onClick: () => handleStepExecution(() => steps?.transaction.execute()),
|
|
200
|
+
pending: steps?.transaction.isExecuting || isLoading,
|
|
201
|
+
disabled: (!approvalExecutedSuccess && approvalNeeded) || isLoading,
|
|
202
|
+
},
|
|
203
|
+
] satisfies ActionModalProps['ctas'];
|
|
204
|
+
|
|
141
205
|
return (
|
|
142
206
|
<ActionModal
|
|
143
|
-
|
|
207
|
+
isOpen={sellModal$.isOpen.get()}
|
|
208
|
+
chainId={Number(chainId)}
|
|
144
209
|
onClose={sellModal$.close}
|
|
145
210
|
title="You have an offer"
|
|
146
|
-
ctas={
|
|
147
|
-
{
|
|
148
|
-
label: 'Accept',
|
|
149
|
-
onClick: () =>
|
|
150
|
-
sell({
|
|
151
|
-
orderId: order?.orderId,
|
|
152
|
-
marketplace: order?.marketplace,
|
|
153
|
-
quantity: order?.quantityRemaining
|
|
154
|
-
? parseUnits(
|
|
155
|
-
order.quantityRemaining,
|
|
156
|
-
collectible?.decimals || 0,
|
|
157
|
-
).toString()
|
|
158
|
-
: '1',
|
|
159
|
-
}),
|
|
160
|
-
},
|
|
161
|
-
]}
|
|
211
|
+
ctas={ctas}
|
|
162
212
|
>
|
|
163
213
|
<TransactionHeader
|
|
164
214
|
title="Offer received"
|
|
@@ -2,7 +2,7 @@ import { observable } from '@legendapp/state';
|
|
|
2
2
|
import type { Hex } from 'viem';
|
|
3
3
|
import type { ShowTransferModalArgs } from '.';
|
|
4
4
|
import type { CollectionType } from '../../../_internal';
|
|
5
|
-
import { ModalCallbacks } from '../_internal/types';
|
|
5
|
+
import type { ModalCallbacks } from '../_internal/types';
|
|
6
6
|
|
|
7
7
|
export interface TransferModalState {
|
|
8
8
|
isOpen: boolean;
|
|
@@ -23,11 +23,13 @@ const EnterWalletAddressView = () => {
|
|
|
23
23
|
chainId,
|
|
24
24
|
contractAddress: collectionAddress,
|
|
25
25
|
tokenId: collectibleId,
|
|
26
|
-
accountAddress: address
|
|
26
|
+
accountAddress: address ?? '',
|
|
27
27
|
query: { enabled: !!address },
|
|
28
28
|
});
|
|
29
29
|
const balanceAmount = tokenBalance?.pages[0].balances[0].balance;
|
|
30
|
-
const insufficientBalance: boolean =
|
|
30
|
+
const insufficientBalance: boolean = balanceAmount
|
|
31
|
+
? $quantity.get() > balanceAmount
|
|
32
|
+
: true;
|
|
31
33
|
const { data: collection } = useCollection({
|
|
32
34
|
collectionAddress,
|
|
33
35
|
chainId,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import type { QueryKey } from '@tanstack/react-query';
|
|
1
2
|
import type { Hex } from 'viem';
|
|
2
3
|
import { ContractType } from '../../../../../../types';
|
|
3
|
-
import { useTransferTokens } from '../../../../../hooks';
|
|
4
|
-
import { transferModal$ } from '../../_store';
|
|
5
4
|
import { InvalidContractTypeError } from '../../../../../../utils/_internal/error/transaction';
|
|
6
|
-
import { useTransactionStatusModal } from '../../../_internal/components/transactionStatusModal';
|
|
7
|
-
import { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
8
5
|
import { balanceQueries } from '../../../../../_internal';
|
|
9
|
-
import {
|
|
6
|
+
import { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
7
|
+
import { useTransferTokens } from '../../../../../hooks';
|
|
8
|
+
import { useTransactionStatusModal } from '../../../_internal/components/transactionStatusModal';
|
|
9
|
+
import { transferModal$ } from '../../_store';
|
|
10
10
|
|
|
11
11
|
const useHandleTransfer = () => {
|
|
12
12
|
const {
|
|
@@ -4,11 +4,11 @@ import { Close, Content, Overlay, Portal, Root } from '@radix-ui/react-dialog';
|
|
|
4
4
|
import type { Hex } from 'viem';
|
|
5
5
|
import { useAccount } from 'wagmi';
|
|
6
6
|
import { useSwitchChainModal } from '../_internal/components/switchChainModal';
|
|
7
|
+
import type { ModalCallbacks } from '../_internal/types';
|
|
7
8
|
import { transferModal$ } from './_store';
|
|
8
9
|
import EnterWalletAddressView from './_views/enterWalletAddress';
|
|
9
10
|
import FollowWalletInstructionsView from './_views/followWalletInstructions';
|
|
10
11
|
import { closeButton, dialogOverlay, transferModalContent } from './styles.css';
|
|
11
|
-
import { ModalCallbacks } from '../_internal/types';
|
|
12
12
|
|
|
13
13
|
export type ShowTransferModalArgs = {
|
|
14
14
|
collectionAddress: Hex;
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import type React from 'react';
|
|
4
|
-
import type
|
|
4
|
+
import { useState, type ComponentProps } from 'react';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
Box,
|
|
8
8
|
Button,
|
|
9
9
|
CloseIcon,
|
|
10
10
|
IconButton,
|
|
11
|
+
Spinner,
|
|
11
12
|
Text,
|
|
12
13
|
} from '@0xsequence/design-system';
|
|
13
|
-
import type { Observable } from '@legendapp/state';
|
|
14
14
|
import { observer } from '@legendapp/state/react';
|
|
15
15
|
import { Close, Content, Overlay, Portal, Root } from '@radix-ui/react-dialog';
|
|
16
16
|
import { getProviderEl } from '../../../../../_internal';
|
|
17
|
-
import type { ActionModalState } from './store';
|
|
18
17
|
import {
|
|
19
18
|
closeButton,
|
|
20
19
|
cta as ctaStyle,
|
|
21
20
|
dialogContent,
|
|
22
21
|
dialogOverlay,
|
|
23
22
|
} from './styles.css';
|
|
23
|
+
import WaasFeeOptionsBox from '../waasFeeOptionsBox';
|
|
24
24
|
|
|
25
25
|
export interface ActionModalProps {
|
|
26
|
-
|
|
26
|
+
isOpen: boolean;
|
|
27
27
|
onClose: () => void;
|
|
28
28
|
title: string;
|
|
29
29
|
children: React.ReactNode;
|
|
@@ -35,12 +35,15 @@ export interface ActionModalProps {
|
|
|
35
35
|
hidden?: boolean;
|
|
36
36
|
variant?: ComponentProps<typeof Button>['variant'];
|
|
37
37
|
}[];
|
|
38
|
+
chainId: number;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
export const ActionModal = observer(
|
|
41
|
-
({
|
|
42
|
+
({ isOpen, onClose, title, children, ctas, chainId }: ActionModalProps) => {
|
|
43
|
+
const [isSelectingFees, setIsSelectingFees] = useState(false);
|
|
44
|
+
|
|
42
45
|
return (
|
|
43
|
-
<Root open={
|
|
46
|
+
<Root open={isOpen && !!chainId}>
|
|
44
47
|
<Portal container={getProviderEl()}>
|
|
45
48
|
<Overlay className={dialogOverlay} />
|
|
46
49
|
<Content className={dialogContent.narrow}>
|
|
@@ -77,15 +80,33 @@ export const ActionModal = observer(
|
|
|
77
80
|
}}
|
|
78
81
|
variant={cta.variant || 'primary'}
|
|
79
82
|
pending={cta.pending}
|
|
80
|
-
disabled={cta.disabled}
|
|
83
|
+
disabled={cta.disabled || isSelectingFees}
|
|
81
84
|
size="lg"
|
|
82
85
|
width="full"
|
|
83
|
-
label={
|
|
86
|
+
label={
|
|
87
|
+
<Box
|
|
88
|
+
display="flex"
|
|
89
|
+
alignItems="center"
|
|
90
|
+
gap="2"
|
|
91
|
+
justifyContent="center"
|
|
92
|
+
>
|
|
93
|
+
{cta.pending && <Spinner size="sm" />}
|
|
94
|
+
|
|
95
|
+
{cta.label}
|
|
96
|
+
</Box>
|
|
97
|
+
}
|
|
84
98
|
/>
|
|
85
99
|
),
|
|
86
100
|
)}
|
|
87
101
|
</Box>
|
|
88
102
|
</Box>
|
|
103
|
+
|
|
104
|
+
<WaasFeeOptionsBox
|
|
105
|
+
chainId={chainId}
|
|
106
|
+
onFeeOptionsLoaded={() => setIsSelectingFees(true)}
|
|
107
|
+
onFeeOptionConfirmed={() => setIsSelectingFees(false)}
|
|
108
|
+
/>
|
|
109
|
+
|
|
89
110
|
<Close className={closeButton} asChild onClick={onClose}>
|
|
90
111
|
<IconButton size="xs" aria-label="Close modal" icon={CloseIcon} />
|
|
91
112
|
</Close>
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { Box } from '@0xsequence/design-system';
|
|
2
|
-
import type { Observable } from '@legendapp/state';
|
|
3
2
|
import { ActionModal } from './ActionModal';
|
|
4
|
-
import type { ActionModalState } from './store';
|
|
5
3
|
|
|
6
4
|
interface ErrorModalProps {
|
|
7
|
-
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
chainId: number;
|
|
8
7
|
onClose: () => void;
|
|
9
8
|
title: string;
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
export const ErrorModal = ({
|
|
13
|
-
|
|
11
|
+
export const ErrorModal = ({
|
|
12
|
+
isOpen,
|
|
13
|
+
chainId,
|
|
14
|
+
onClose,
|
|
15
|
+
title,
|
|
16
|
+
}: ErrorModalProps) => (
|
|
17
|
+
<ActionModal
|
|
18
|
+
isOpen={isOpen}
|
|
19
|
+
chainId={chainId}
|
|
20
|
+
onClose={onClose}
|
|
21
|
+
title={title}
|
|
22
|
+
ctas={[]}
|
|
23
|
+
>
|
|
14
24
|
<Box display="flex" justifyContent="center" alignItems="center" padding="4">
|
|
15
25
|
Error loading item details
|
|
16
26
|
</Box>
|