@0xsequence/marketplace-sdk 0.4.0 → 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-P3EQRM7K.js → chunk-5GDO4ZBC.js} +5 -4
- package/dist/{chunk-P3EQRM7K.js.map → chunk-5GDO4ZBC.js.map} +1 -1
- package/dist/{chunk-QTQH5I2E.js → chunk-EVRILXOH.js} +2 -2
- package/dist/chunk-EVRILXOH.js.map +1 -0
- package/dist/{chunk-GVDLVCR5.js → chunk-GSDUAHL3.js} +1 -1
- package/dist/chunk-GSDUAHL3.js.map +1 -0
- package/dist/{chunk-6HEMV2OR.js → chunk-IOTKCWOB.js} +890 -644
- package/dist/chunk-IOTKCWOB.js.map +1 -0
- package/dist/{chunk-AY2MZHZN.js → chunk-KNX2LER4.js} +5 -6
- package/dist/{chunk-PAHT6PTD.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-PAHT6PTD.js → chunk-LSMQVX77.js} +5 -6
- package/dist/{chunk-AY2MZHZN.js.map → chunk-LSMQVX77.js.map} +1 -1
- package/dist/{chunk-6AYHE7ZA.js → chunk-MIYMMP2K.js} +79 -33
- package/dist/chunk-MIYMMP2K.js.map +1 -0
- package/dist/{chunk-EK5ZSW4M.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 +4 -4
- 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 +663 -74
- package/dist/react/hooks/index.js +7 -7
- 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 +11 -11
- 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 +11 -11
- 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 +11 -11
- 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 +28 -12
- package/src/react/_internal/transaction-machine/useTransactionMachine.ts +43 -8
- package/src/react/hooks/useBuyCollectable.tsx +13 -6
- package/src/react/hooks/useCancelOrder.tsx +14 -7
- package/src/react/hooks/useCreateListing.tsx +74 -10
- package/src/react/hooks/useCurrencies.tsx +1 -1
- package/src/react/hooks/useCurrencyBalance.tsx +1 -1
- package/src/react/hooks/useCurrencyOptions.tsx +1 -1
- package/src/react/hooks/useMakeOffer.tsx +73 -11
- package/src/react/hooks/useSell.tsx +72 -11
- 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 +62 -23
- package/src/react/ui/modals/MakeOfferModal/_store.ts +5 -2
- package/src/react/ui/modals/MakeOfferModal/index.tsx +83 -65
- 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 -10
- 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 +3 -3
- package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +9 -5
- package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +4 -4
- package/src/react/ui/modals/_internal/components/transactionPreview/useTransactionPreviewTitle.tsx +1 -1
- package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +51 -29
- package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +2 -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 +2 -2
- package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getTitle.ts +6 -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 +2 -2
- package/src/utils/price.ts +3 -4
- package/tsconfig.json +1 -21
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-6AYHE7ZA.js.map +0 -1
- package/dist/chunk-6HEMV2OR.js.map +0 -1
- package/dist/chunk-FFCNYF3S.js +0 -153
- package/dist/chunk-FFCNYF3S.js.map +0 -1
- package/dist/chunk-GVDLVCR5.js.map +0 -1
- package/dist/chunk-NMCGA2TB.js +0 -98
- package/dist/chunk-NMCGA2TB.js.map +0 -1
- package/dist/chunk-QTQH5I2E.js.map +0 -1
- package/dist/chunk-Y7YO5TLE.js.map +0 -1
- /package/dist/{chunk-EK5ZSW4M.js.map → chunk-QMO2CUNM.js.map} +0 -0
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { Box, Spinner } 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 LoadingModalProps {
|
|
7
|
-
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
chainId: number;
|
|
8
7
|
onClose: () => void;
|
|
9
8
|
title: string;
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
export const LoadingModal = ({
|
|
13
|
-
|
|
11
|
+
export const LoadingModal = ({
|
|
12
|
+
isOpen,
|
|
13
|
+
chainId,
|
|
14
|
+
onClose,
|
|
15
|
+
title,
|
|
16
|
+
}: LoadingModalProps) => (
|
|
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
|
<Spinner size="lg" />
|
|
16
26
|
</Box>
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { type Observable, observable } from '@legendapp/state';
|
|
2
|
+
import type { ChainId } from '../../../../../_internal';
|
|
3
|
+
import type { Address } from 'viem';
|
|
2
4
|
|
|
3
5
|
export interface ActionModalState {
|
|
4
6
|
isOpen: boolean;
|
|
7
|
+
chainId: ChainId | null;
|
|
8
|
+
collectionAddress: Address | null;
|
|
5
9
|
}
|
|
6
10
|
|
|
7
11
|
export function createActionModalStore() {
|
|
8
12
|
return observable<ActionModalState>({
|
|
9
13
|
isOpen: false,
|
|
14
|
+
chainId: null,
|
|
15
|
+
collectionAddress: null,
|
|
10
16
|
});
|
|
11
17
|
}
|
|
12
18
|
|
|
@@ -32,7 +32,7 @@ function Calendar({ ...props }: CalendarProps) {
|
|
|
32
32
|
margin: 0,
|
|
33
33
|
color: 'hsl(var(--foreground))',
|
|
34
34
|
background: 'hsl(var(--background))',
|
|
35
|
-
border:
|
|
35
|
+
border: '1px solid hsl(var(--border))',
|
|
36
36
|
borderRadius: 'var(--radius)',
|
|
37
37
|
padding: '0.5rem',
|
|
38
38
|
position: 'relative',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Box, TokenImage } from '@0xsequence/design-system';
|
|
2
|
+
import type { Observable } from '@legendapp/state';
|
|
2
3
|
import { useState } from 'react';
|
|
3
|
-
import { Address } from 'viem';
|
|
4
|
-
import { Price } from '../../../../../../types';
|
|
5
|
-
import { Observable } from '@legendapp/state';
|
|
4
|
+
import type { Address } from 'viem';
|
|
5
|
+
import type { Price } from '../../../../../../types';
|
|
6
6
|
|
|
7
7
|
function CurrencyImage({
|
|
8
8
|
$listingPrice,
|
|
@@ -5,14 +5,11 @@ import { useEffect } from 'react';
|
|
|
5
5
|
import type { Hex } from 'viem';
|
|
6
6
|
import type { ChainId, Currency } from '../../../../../_internal';
|
|
7
7
|
import { useCurrencies } from '../../../../../hooks';
|
|
8
|
-
import { CustomSelect } from '../../../../components/_internals/custom-select/CustomSelect';
|
|
9
8
|
import { useCurrencyOptions } from '../../../../../hooks/useCurrencyOptions';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
type
|
|
13
|
-
|
|
14
|
-
value: string;
|
|
15
|
-
};
|
|
9
|
+
import {
|
|
10
|
+
CustomSelect,
|
|
11
|
+
type SelectItem,
|
|
12
|
+
} from '../../../../components/_internals/custom-select/CustomSelect';
|
|
16
13
|
|
|
17
14
|
type CurrencyOptionsSelectProps = {
|
|
18
15
|
collectionAddress: Hex;
|
|
@@ -33,6 +30,7 @@ const CurrencyOptionsSelect = observer(function CurrencyOptionsSelect({
|
|
|
33
30
|
});
|
|
34
31
|
|
|
35
32
|
// set default currency
|
|
33
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
36
34
|
useEffect(() => {
|
|
37
35
|
if (
|
|
38
36
|
currencies &&
|
|
@@ -52,7 +50,8 @@ const CurrencyOptionsSelect = observer(function CurrencyOptionsSelect({
|
|
|
52
50
|
({
|
|
53
51
|
label: currency.symbol,
|
|
54
52
|
value: currency.contractAddress,
|
|
55
|
-
|
|
53
|
+
content: currency.symbol,
|
|
54
|
+
}) as SelectItem,
|
|
56
55
|
);
|
|
57
56
|
|
|
58
57
|
const onChange = (value: string) => {
|
|
@@ -65,9 +64,11 @@ const CurrencyOptionsSelect = observer(function CurrencyOptionsSelect({
|
|
|
65
64
|
return (
|
|
66
65
|
<CustomSelect
|
|
67
66
|
items={options}
|
|
68
|
-
value={currency.symbol}
|
|
69
67
|
onValueChange={onChange}
|
|
70
|
-
defaultValue={
|
|
68
|
+
defaultValue={{
|
|
69
|
+
value: currency.contractAddress,
|
|
70
|
+
content: currency.symbol,
|
|
71
|
+
}}
|
|
71
72
|
/>
|
|
72
73
|
);
|
|
73
74
|
});
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
|
|
3
1
|
import { Box, Skeleton, Text } from '@0xsequence/design-system';
|
|
4
2
|
import type { Observable } from '@legendapp/state';
|
|
5
3
|
import { observer } from '@legendapp/state/react';
|
|
6
|
-
import { addDays
|
|
4
|
+
import { addDays } from 'date-fns';
|
|
7
5
|
import { CustomSelect } from '../../../../components/_internals/custom-select/CustomSelect';
|
|
8
6
|
import CalendarPopover from '../calendarPopover';
|
|
7
|
+
import { useState } from 'react';
|
|
9
8
|
|
|
10
9
|
export const PRESET_RANGES = {
|
|
11
10
|
TODAY: {
|
|
@@ -35,7 +34,7 @@ export const PRESET_RANGES = {
|
|
|
35
34
|
},
|
|
36
35
|
} as const;
|
|
37
36
|
|
|
38
|
-
export type
|
|
37
|
+
export type RangeType =
|
|
39
38
|
(typeof PRESET_RANGES)[keyof typeof PRESET_RANGES]['value'];
|
|
40
39
|
|
|
41
40
|
type ExpirationDateSelectProps = {
|
|
@@ -47,15 +46,16 @@ const ExpirationDateSelect = observer(function ExpirationDateSelect({
|
|
|
47
46
|
className,
|
|
48
47
|
$date,
|
|
49
48
|
}: ExpirationDateSelectProps) {
|
|
50
|
-
const defaultRange = '1_week';
|
|
51
|
-
const [
|
|
52
|
-
function handleSelectPresetRange(range: rangeType) {
|
|
53
|
-
setRange(range);
|
|
49
|
+
const defaultRange = '1_week' as RangeType;
|
|
50
|
+
const [selectedRange, setSelectedRange] = useState<RangeType>(defaultRange);
|
|
54
51
|
|
|
52
|
+
function handleSelectPresetRange(range: RangeType) {
|
|
55
53
|
const presetRange = Object.values(PRESET_RANGES).find(
|
|
56
54
|
(preset) => preset.value === range,
|
|
57
55
|
);
|
|
58
56
|
|
|
57
|
+
setSelectedRange(range);
|
|
58
|
+
|
|
59
59
|
if (!presetRange) {
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
@@ -66,14 +66,6 @@ const ExpirationDateSelect = observer(function ExpirationDateSelect({
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function handleDateValueChange(date: Date) {
|
|
69
|
-
const presetRange = Object.values(PRESET_RANGES).find((preset) =>
|
|
70
|
-
isSameDay(new Date(date), addDays(new Date(), preset.offset)),
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
if (presetRange) {
|
|
74
|
-
setRange(presetRange.value);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
69
|
$date.set(date);
|
|
78
70
|
}
|
|
79
71
|
|
|
@@ -112,12 +104,15 @@ const ExpirationDateSelect = observer(function ExpirationDateSelect({
|
|
|
112
104
|
items={Object.values(PRESET_RANGES).map((preset) => ({
|
|
113
105
|
label: preset.label,
|
|
114
106
|
value: preset.value,
|
|
107
|
+
content: preset.label,
|
|
115
108
|
}))}
|
|
116
|
-
value={range}
|
|
117
109
|
onValueChange={(value) =>
|
|
118
|
-
handleSelectPresetRange(value as
|
|
110
|
+
handleSelectPresetRange(value as RangeType)
|
|
119
111
|
}
|
|
120
|
-
defaultValue={
|
|
112
|
+
defaultValue={{
|
|
113
|
+
value: selectedRange,
|
|
114
|
+
content: selectedRange,
|
|
115
|
+
}}
|
|
121
116
|
/>
|
|
122
117
|
</Box>
|
|
123
118
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { Box, NumericInput } from '@0xsequence/design-system';
|
|
1
|
+
import { Box, NumericInput, Text } from '@0xsequence/design-system';
|
|
2
2
|
import type { Observable } from '@legendapp/state';
|
|
3
3
|
import { observer } from '@legendapp/state/react';
|
|
4
|
-
import { useState } from 'react';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
5
|
import { type Hex, parseUnits } from 'viem';
|
|
6
6
|
import { useAccount } from 'wagmi';
|
|
7
7
|
import type { Price } from '../../../../../../types';
|
|
8
|
-
import CurrencyOptionsSelect from '../currencyOptionsSelect';
|
|
9
|
-
import { priceInputCurrencyImage, priceInputWrapper } from './styles.css';
|
|
10
8
|
import { useCurrencyBalance } from '../../../../../hooks/useCurrencyBalance';
|
|
11
9
|
import CurrencyImage from '../currencyImage';
|
|
10
|
+
import CurrencyOptionsSelect from '../currencyOptionsSelect';
|
|
11
|
+
import { priceInputCurrencyImage, priceInputWrapper } from './styles.css';
|
|
12
12
|
|
|
13
13
|
type PriceInputProps = {
|
|
14
14
|
collectionAddress: Hex;
|
|
15
15
|
chainId: string;
|
|
16
16
|
$listingPrice: Observable<Price | undefined>;
|
|
17
|
+
onPriceChange?: () => void;
|
|
17
18
|
checkBalance?: {
|
|
18
19
|
enabled: boolean;
|
|
19
20
|
callback: (state: boolean) => void;
|
|
@@ -24,6 +25,7 @@ const PriceInput = observer(function PriceInput({
|
|
|
24
25
|
chainId,
|
|
25
26
|
collectionAddress,
|
|
26
27
|
$listingPrice,
|
|
28
|
+
onPriceChange,
|
|
27
29
|
checkBalance,
|
|
28
30
|
}: PriceInputProps) {
|
|
29
31
|
const [balanceError, setBalanceError] = useState('');
|
|
@@ -38,6 +40,17 @@ const PriceInput = observer(function PriceInput({
|
|
|
38
40
|
|
|
39
41
|
const [value, setValue] = useState('');
|
|
40
42
|
|
|
43
|
+
const changeListingPrice = (value: string) => {
|
|
44
|
+
setValue(value);
|
|
45
|
+
try {
|
|
46
|
+
const parsedAmount = parseUnits(value, Number(currencyDecimals));
|
|
47
|
+
$listingPrice.amountRaw.set(parsedAmount.toString());
|
|
48
|
+
onPriceChange?.();
|
|
49
|
+
} catch {
|
|
50
|
+
$listingPrice.amountRaw.set('0');
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
41
54
|
const checkInsufficientBalance = (priceAmountRaw: string) => {
|
|
42
55
|
const hasInsufficientBalance =
|
|
43
56
|
isBalanceSuccess &&
|
|
@@ -56,12 +69,13 @@ const PriceInput = observer(function PriceInput({
|
|
|
56
69
|
}
|
|
57
70
|
};
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
const priceAmountRaw = $listingPrice.amountRaw.get();
|
|
75
|
+
if (priceAmountRaw && priceAmountRaw !== '0') {
|
|
76
|
+
checkInsufficientBalance(priceAmountRaw);
|
|
77
|
+
}
|
|
78
|
+
}, [$listingPrice.currency.get()]);
|
|
65
79
|
|
|
66
80
|
return (
|
|
67
81
|
<Box className={priceInputWrapper} position="relative">
|
|
@@ -91,10 +105,18 @@ const PriceInput = observer(function PriceInput({
|
|
|
91
105
|
onChange={(event) => changeListingPrice(event.target.value)}
|
|
92
106
|
width="full"
|
|
93
107
|
/>
|
|
108
|
+
|
|
94
109
|
{balanceError && (
|
|
95
|
-
<
|
|
110
|
+
<Text
|
|
111
|
+
color="negative"
|
|
112
|
+
fontSize="xsmall"
|
|
113
|
+
fontFamily="body"
|
|
114
|
+
fontWeight="semibold"
|
|
115
|
+
position="absolute"
|
|
116
|
+
style={{ bottom: '-13px' }}
|
|
117
|
+
>
|
|
96
118
|
{balanceError}
|
|
97
|
-
</
|
|
119
|
+
</Text>
|
|
98
120
|
)}
|
|
99
121
|
</Box>
|
|
100
122
|
);
|
|
@@ -23,7 +23,7 @@ export default function QuantityInput({
|
|
|
23
23
|
|
|
24
24
|
let formattedValue = sanitizedValue;
|
|
25
25
|
if (decimalParts.length > 2) {
|
|
26
|
-
formattedValue = decimalParts[0]
|
|
26
|
+
formattedValue = `${decimalParts[0]}.${decimalParts[1]}`;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const finalValue = formatQuantity(formattedValue);
|
|
@@ -32,7 +32,7 @@ export default function QuantityInput({
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function validateQuantity(value: string) {
|
|
35
|
-
if (!value || value.trim() === '' || isNaN(Number(value))) {
|
|
35
|
+
if (!value || value.trim() === '' || Number.isNaN(Number(value))) {
|
|
36
36
|
$invalidQuantity.set(true);
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
@@ -49,7 +49,7 @@ export default function QuantityInput({
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function formatQuantity(value: string) {
|
|
52
|
-
if (!value || isNaN(Number(value))) {
|
|
52
|
+
if (!value || Number.isNaN(Number(value))) {
|
|
53
53
|
return '0';
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -30,7 +30,7 @@ export type ShowSwitchChainModalArgs = {
|
|
|
30
30
|
export const useSwitchChainModal = () => {
|
|
31
31
|
return {
|
|
32
32
|
show: (args: ShowSwitchChainModalArgs) => switchChainModal$.open(args),
|
|
33
|
-
close: () => switchChainModal$.
|
|
33
|
+
close: () => switchChainModal$.delete(),
|
|
34
34
|
isSwitching$: switchChainModal$.state.isSwitching,
|
|
35
35
|
};
|
|
36
36
|
};
|
|
@@ -38,18 +38,21 @@ export const useSwitchChainModal = () => {
|
|
|
38
38
|
const SwitchChainModal = observer(() => {
|
|
39
39
|
const chainIdToSwitchTo = switchChainModal$.state.chainIdToSwitchTo.get();
|
|
40
40
|
const isSwitching$ = switchChainModal$.state.isSwitching;
|
|
41
|
-
const chainName =
|
|
41
|
+
const chainName = chainIdToSwitchTo
|
|
42
|
+
? getPresentableChainName(chainIdToSwitchTo)
|
|
43
|
+
: '';
|
|
42
44
|
const { switchChainAsync } = useSwitchChain();
|
|
43
45
|
|
|
44
46
|
async function handleSwitchChain() {
|
|
45
47
|
isSwitching$.set(true);
|
|
46
48
|
|
|
47
49
|
try {
|
|
48
|
-
|
|
50
|
+
if (!chainIdToSwitchTo) return;
|
|
51
|
+
await switchChainAsync({ chainId: Number(chainIdToSwitchTo) });
|
|
49
52
|
|
|
50
53
|
switchChainModal$.state.onSuccess?.();
|
|
51
54
|
|
|
52
|
-
switchChainModal$.
|
|
55
|
+
switchChainModal$.delete();
|
|
53
56
|
} catch (error) {
|
|
54
57
|
switchChainModal$.state.onError?.(error as SwitchChainErrorType);
|
|
55
58
|
} finally {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ChainId, networks } from '@0xsequence/network';
|
|
1
|
+
import { type ChainId, networks } from '@0xsequence/network';
|
|
2
|
+
import type { Hex } from 'viem';
|
|
3
|
+
import { Box, Text, Spinner } from '@0xsequence/design-system';
|
|
2
4
|
import { truncateMiddle } from '../../../../../../utils';
|
|
3
5
|
import SvgPositiveCircleIcon from '../../../../icons/PositiveCircleIcon';
|
|
4
|
-
import { Box, Spinner, Text } from '@0xsequence/design-system';
|
|
5
|
-
import type { Hex } from 'viem';
|
|
6
6
|
|
|
7
7
|
type TransactionFooterProps = {
|
|
8
8
|
transactionHash: Hex | undefined;
|
|
@@ -12,6 +12,8 @@ type TransactionDetailsProps = {
|
|
|
12
12
|
chainId: string;
|
|
13
13
|
price?: Price;
|
|
14
14
|
currencyImageUrl?: string;
|
|
15
|
+
// We use a placeholder price for create listing modal
|
|
16
|
+
showPlaceholderPrice?: boolean;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
//TODO: Move this
|
|
@@ -22,6 +24,7 @@ export default function TransactionDetails({
|
|
|
22
24
|
collectionAddress,
|
|
23
25
|
chainId,
|
|
24
26
|
price,
|
|
27
|
+
showPlaceholderPrice,
|
|
25
28
|
currencyImageUrl,
|
|
26
29
|
}: TransactionDetailsProps) {
|
|
27
30
|
const { data, isLoading: marketplaceConfigLoading } = useMarketplaceConfig();
|
|
@@ -43,18 +46,18 @@ export default function TransactionDetails({
|
|
|
43
46
|
let formattedAmount =
|
|
44
47
|
price && formatUnits(BigInt(price.amountRaw), price.currency.decimals);
|
|
45
48
|
|
|
46
|
-
if (royaltyPercentage !== undefined && formattedAmount) {
|
|
49
|
+
if (royaltyPercentage !== undefined && formattedAmount && price) {
|
|
47
50
|
formattedAmount = (
|
|
48
51
|
Number.parseFloat(formattedAmount) -
|
|
49
52
|
(Number.parseFloat(formattedAmount) * Number(royaltyPercentage)) / 100
|
|
50
|
-
).
|
|
53
|
+
).toFixed(price.currency.decimals);
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
if (marketplaceFeePercentage !== undefined && formattedAmount) {
|
|
56
|
+
if (marketplaceFeePercentage !== undefined && formattedAmount && price) {
|
|
54
57
|
formattedAmount = (
|
|
55
58
|
Number.parseFloat(formattedAmount) -
|
|
56
59
|
(Number.parseFloat(formattedAmount) * marketplaceFeePercentage) / 100
|
|
57
|
-
).
|
|
60
|
+
).toFixed(price.currency.decimals);
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
return (
|
|
@@ -75,7 +78,8 @@ export default function TransactionDetails({
|
|
|
75
78
|
<Skeleton width="16" height={'4'} />
|
|
76
79
|
) : (
|
|
77
80
|
<Text fontSize={'small'} color={'text100'} fontFamily="body">
|
|
78
|
-
{formattedAmount}
|
|
81
|
+
{showPlaceholderPrice ? '0' : formattedAmount}{' '}
|
|
82
|
+
{price.currency.symbol}
|
|
79
83
|
</Text>
|
|
80
84
|
)}
|
|
81
85
|
</Box>
|
|
@@ -5,15 +5,15 @@ import {
|
|
|
5
5
|
Skeleton,
|
|
6
6
|
Text,
|
|
7
7
|
} from '@0xsequence/design-system';
|
|
8
|
+
import type { TokenMetadata } from '@0xsequence/metadata';
|
|
8
9
|
import { observer } from '@legendapp/state/react';
|
|
9
10
|
import { type Hex, formatUnits } from 'viem';
|
|
10
11
|
import type { Price } from '../../../../../../types';
|
|
11
12
|
import { useCollection } from '../../../../../hooks';
|
|
13
|
+
import ChessTileImage from '../../../../images/chess-tile.png';
|
|
12
14
|
import TimeAgo from '../timeAgo';
|
|
13
15
|
import { transactionStatusModal$ } from '../transactionStatusModal/store';
|
|
14
16
|
import { useTransactionPreviewTitle } from './useTransactionPreviewTitle';
|
|
15
|
-
import type { TokenMetadata } from '@0xsequence/metadata';
|
|
16
|
-
import ChessTileImage from '../../../../images/chess-tile.png';
|
|
17
17
|
|
|
18
18
|
type TransactionPreviewProps = {
|
|
19
19
|
orderId?: string;
|
|
@@ -58,7 +58,7 @@ const TransactionPreview = observer(
|
|
|
58
58
|
const collectibleName = collectible?.name;
|
|
59
59
|
const collectionName = collection?.name;
|
|
60
60
|
const priceFormatted = price
|
|
61
|
-
? formatUnits(BigInt(price
|
|
61
|
+
? formatUnits(BigInt(price?.amountRaw), price?.currency.decimals)
|
|
62
62
|
: undefined;
|
|
63
63
|
|
|
64
64
|
if (collectibleLoading || collectionLoading) {
|
|
@@ -134,7 +134,7 @@ const TransactionPreview = observer(
|
|
|
134
134
|
fontWeight="medium"
|
|
135
135
|
fontFamily="body"
|
|
136
136
|
>
|
|
137
|
-
{priceFormatted} {price
|
|
137
|
+
{priceFormatted} {price?.currency.symbol}
|
|
138
138
|
</Text>
|
|
139
139
|
</Box>
|
|
140
140
|
)}
|
package/src/react/ui/modals/_internal/components/transactionPreview/useTransactionPreviewTitle.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
1
2
|
import type { ConfirmationStatus } from '../transactionStatusModal/store';
|
|
2
3
|
import { TRANSACTION_TITLES } from './consts';
|
|
3
|
-
import { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
4
4
|
|
|
5
5
|
export function useTransactionPreviewTitle(
|
|
6
6
|
orderId: string | undefined,
|
|
@@ -4,29 +4,29 @@ import {
|
|
|
4
4
|
Skeleton,
|
|
5
5
|
Text,
|
|
6
6
|
} from '@0xsequence/design-system';
|
|
7
|
+
import { TRANSACTION_CONFIRMATIONS_DEFAULT } from '@0xsequence/kit';
|
|
8
|
+
import type { ChainId } from '@0xsequence/network';
|
|
7
9
|
import { observer } from '@legendapp/state/react';
|
|
8
10
|
import { Close, Content, Overlay, Portal, Root } from '@radix-ui/react-dialog';
|
|
9
|
-
import {
|
|
11
|
+
import type { QueryKey } from '@tanstack/react-query';
|
|
10
12
|
import { useEffect, useState } from 'react';
|
|
11
|
-
import {
|
|
13
|
+
import { type Hex, WaitForTransactionReceiptTimeoutError } from 'viem';
|
|
12
14
|
import type { Price } from '../../../../../../types';
|
|
15
|
+
import { getPublicRpcClient } from '../../../../../../utils';
|
|
13
16
|
import { getQueryClient } from '../../../../../_internal';
|
|
17
|
+
import type { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
14
18
|
import { useCollectible } from '../../../../../hooks';
|
|
19
|
+
import type { ModalCallbacks } from '../../types';
|
|
15
20
|
import TransactionFooter from '../transaction-footer';
|
|
16
21
|
import TransactionPreview from '../transactionPreview';
|
|
17
|
-
import { TransactionStatus, transactionStatusModal$ } from './store';
|
|
22
|
+
import { type TransactionStatus, transactionStatusModal$ } from './store';
|
|
18
23
|
import {
|
|
19
24
|
closeButton,
|
|
20
25
|
dialogOverlay,
|
|
21
26
|
transactionStatusModalContent,
|
|
22
27
|
} from './styles.css';
|
|
23
|
-
import { ChainId } from '@0xsequence/network';
|
|
24
|
-
import { getPublicRpcClient } from '../../../../../../utils';
|
|
25
|
-
import { TRANSACTION_CONFIRMATIONS_DEFAULT } from '@0xsequence/kit';
|
|
26
|
-
import { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
27
|
-
import { ModalCallbacks } from '../../types';
|
|
28
|
-
import { getTransactionStatusModalTitle } from './util/getTitle';
|
|
29
28
|
import { getTransactionStatusModalMessage } from './util/getMessage';
|
|
29
|
+
import { getTransactionStatusModalTitle } from './util/getTitle';
|
|
30
30
|
|
|
31
31
|
export type ShowTransactionStatusModalArgs = {
|
|
32
32
|
hash?: Hex;
|
|
@@ -74,26 +74,8 @@ const TransactionStatusModal = observer(() => {
|
|
|
74
74
|
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>(
|
|
75
75
|
orderId ? 'SUCCESS' : 'PENDING',
|
|
76
76
|
);
|
|
77
|
-
const title = getTransactionStatusModalTitle({
|
|
78
|
-
transactionStatus,
|
|
79
|
-
transactionType: type!,
|
|
80
|
-
orderId,
|
|
81
|
-
});
|
|
82
|
-
const message = getTransactionStatusModalMessage({
|
|
83
|
-
transactionStatus,
|
|
84
|
-
transactionType: type!,
|
|
85
|
-
collectibleName: collectible?.name || '',
|
|
86
|
-
orderId,
|
|
87
|
-
});
|
|
88
|
-
const { onError, onSuccess }: ModalCallbacks = callbacks || {};
|
|
89
|
-
const queryClient = getQueryClient();
|
|
90
|
-
const publicClient = chainId ? getPublicRpcClient(chainId) : null;
|
|
91
|
-
const waitForTransactionReceiptPromise =
|
|
92
|
-
publicClient?.waitForTransactionReceipt({
|
|
93
|
-
confirmations: confirmations || TRANSACTION_CONFIRMATIONS_DEFAULT,
|
|
94
|
-
hash: hash!,
|
|
95
|
-
});
|
|
96
77
|
|
|
78
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
97
79
|
useEffect(() => {
|
|
98
80
|
if (!transactionStatusModal$.isOpen.get()) return;
|
|
99
81
|
|
|
@@ -103,9 +85,20 @@ const TransactionStatusModal = observer(() => {
|
|
|
103
85
|
if (receipt.status === 'success') {
|
|
104
86
|
console.log('receipt', receipt);
|
|
105
87
|
setTransactionStatus('SUCCESS');
|
|
88
|
+
if (callbacks?.onSuccess) {
|
|
89
|
+
callbacks.onSuccess(hash || '0x');
|
|
90
|
+
} else {
|
|
91
|
+
console.debug('onSuccess callback not provided:', hash);
|
|
92
|
+
}
|
|
106
93
|
}
|
|
107
94
|
})
|
|
108
95
|
.catch((error) => {
|
|
96
|
+
if (callbacks?.onError) {
|
|
97
|
+
callbacks.onError(error);
|
|
98
|
+
} else {
|
|
99
|
+
console.debug('onError callback not provided:', error);
|
|
100
|
+
}
|
|
101
|
+
|
|
109
102
|
if (error instanceof WaitForTransactionReceiptTimeoutError) {
|
|
110
103
|
setTransactionStatus('TIMEOUT');
|
|
111
104
|
return;
|
|
@@ -121,7 +114,36 @@ const TransactionStatusModal = observer(() => {
|
|
|
121
114
|
return () => {
|
|
122
115
|
setTransactionStatus('PENDING');
|
|
123
116
|
};
|
|
124
|
-
}, [
|
|
117
|
+
}, [
|
|
118
|
+
callbacks?.onSuccess,
|
|
119
|
+
callbacks?.onError,
|
|
120
|
+
transactionStatusModal$.isOpen.get(),
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
if (!type) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const title = getTransactionStatusModalTitle({
|
|
128
|
+
transactionStatus,
|
|
129
|
+
transactionType: type,
|
|
130
|
+
orderId,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const message = getTransactionStatusModalMessage({
|
|
134
|
+
transactionStatus,
|
|
135
|
+
transactionType: type,
|
|
136
|
+
collectibleName: collectible?.name || '',
|
|
137
|
+
orderId,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const queryClient = getQueryClient();
|
|
141
|
+
const publicClient = chainId ? getPublicRpcClient(chainId) : null;
|
|
142
|
+
const waitForTransactionReceiptPromise =
|
|
143
|
+
publicClient?.waitForTransactionReceipt({
|
|
144
|
+
confirmations: confirmations || TRANSACTION_CONFIRMATIONS_DEFAULT,
|
|
145
|
+
hash: hash || '0x',
|
|
146
|
+
});
|
|
125
147
|
|
|
126
148
|
return (
|
|
127
149
|
<Root open={transactionStatusModal$.isOpen.get()}>
|
|
@@ -3,8 +3,8 @@ import type { QueryKey } from '@tanstack/react-query';
|
|
|
3
3
|
import type { Hex } from 'viem';
|
|
4
4
|
import type { ShowTransactionStatusModalArgs } from '.';
|
|
5
5
|
import type { Price } from '../../../../../../types';
|
|
6
|
-
import { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
7
|
-
import { ModalCallbacks } from '../../types';
|
|
6
|
+
import type { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
|
|
7
|
+
import type { ModalCallbacks } from '../../types';
|
|
8
8
|
|
|
9
9
|
export type ConfirmationStatus = {
|
|
10
10
|
isConfirming: boolean;
|
package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getFormattedType.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { TransactionType } from '../../../../../../_internal/transaction-machine
|
|
|
2
2
|
|
|
3
3
|
export function getFormattedType(
|
|
4
4
|
transactionType: TransactionType,
|
|
5
|
-
verb
|
|
5
|
+
verb = false,
|
|
6
6
|
): string {
|
|
7
7
|
switch (transactionType) {
|
|
8
8
|
case TransactionType.TRANSFER:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TransactionType } from '../../../../../../_internal/transaction-machine/execute-transaction';
|
|
2
|
-
import { TransactionStatus } from '../store';
|
|
1
|
+
import type { TransactionType } from '../../../../../../_internal/transaction-machine/execute-transaction';
|
|
2
|
+
import type { TransactionStatus } from '../store';
|
|
3
3
|
import { getFormattedType } from './getFormattedType';
|
|
4
4
|
|
|
5
5
|
export function getTransactionStatusModalMessage({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TransactionType } from '../../../../../../_internal/transaction-machine/execute-transaction';
|
|
2
|
-
import { TransactionStatus } from '../store';
|
|
1
|
+
import type { TransactionType } from '../../../../../../_internal/transaction-machine/execute-transaction';
|
|
2
|
+
import type { TransactionStatus } from '../store';
|
|
3
3
|
import { getFormattedType } from './getFormattedType';
|
|
4
4
|
|
|
5
5
|
export function getTransactionStatusModalTitle({
|
|
@@ -8,9 +8,12 @@ export function getTransactionStatusModalTitle({
|
|
|
8
8
|
orderId,
|
|
9
9
|
}: {
|
|
10
10
|
transactionStatus: TransactionStatus;
|
|
11
|
-
transactionType: TransactionType;
|
|
11
|
+
transactionType: TransactionType | undefined;
|
|
12
12
|
orderId?: string;
|
|
13
13
|
}): string {
|
|
14
|
+
if (transactionType === undefined) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
14
17
|
if (orderId) {
|
|
15
18
|
return `Your ${getFormattedType(transactionType)} has processed`;
|
|
16
19
|
}
|