@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.
Files changed (133) hide show
  1. package/dist/{chunk-3LOJQCTV.js → chunk-5GDO4ZBC.js} +5 -4
  2. package/dist/{chunk-3LOJQCTV.js.map → chunk-5GDO4ZBC.js.map} +1 -1
  3. package/dist/{chunk-E3ZFT6WR.js → chunk-EVRILXOH.js} +12 -2
  4. package/dist/chunk-EVRILXOH.js.map +1 -0
  5. package/dist/{chunk-N5F6IEAK.js → chunk-GSDUAHL3.js} +1 -1
  6. package/dist/chunk-GSDUAHL3.js.map +1 -0
  7. package/dist/{chunk-IRN77TJW.js → chunk-IOTKCWOB.js} +925 -667
  8. package/dist/chunk-IOTKCWOB.js.map +1 -0
  9. package/dist/{chunk-KRMV6FJE.js → chunk-KNX2LER4.js} +5 -6
  10. package/dist/{chunk-4FC3IG7C.js.map → chunk-KNX2LER4.js.map} +1 -1
  11. package/dist/{chunk-SBVLWSRZ.js → chunk-LF44FCG5.js} +2 -2
  12. package/dist/{chunk-SBVLWSRZ.js.map → chunk-LF44FCG5.js.map} +1 -1
  13. package/dist/{chunk-4FC3IG7C.js → chunk-LSMQVX77.js} +5 -6
  14. package/dist/{chunk-KRMV6FJE.js.map → chunk-LSMQVX77.js.map} +1 -1
  15. package/dist/{chunk-B3LFJJVS.js → chunk-MIYMMP2K.js} +90 -40
  16. package/dist/chunk-MIYMMP2K.js.map +1 -0
  17. package/dist/{chunk-Z7NLKEXF.js → chunk-QMO2CUNM.js} +2 -2
  18. package/dist/{chunk-L6GSYPCR.js → chunk-RZSZNVEH.js} +5 -5
  19. package/dist/{chunk-L6GSYPCR.js.map → chunk-RZSZNVEH.js.map} +1 -1
  20. package/dist/chunk-T5T6JNB2.js +171 -0
  21. package/dist/chunk-T5T6JNB2.js.map +1 -0
  22. package/dist/chunk-UPLTM63S.js +435 -0
  23. package/dist/chunk-UPLTM63S.js.map +1 -0
  24. package/dist/{chunk-Y7YO5TLE.js → chunk-XXML5K3X.js} +5 -2
  25. package/dist/chunk-XXML5K3X.js.map +1 -0
  26. package/dist/{create-config-CgtmCzvb.d.ts → create-config-8sffBvlt.d.ts} +1 -1
  27. package/dist/index.js +5 -5
  28. package/dist/react/_internal/api/index.js +2 -2
  29. package/dist/react/_internal/index.d.ts +1 -1
  30. package/dist/react/_internal/index.js +3 -3
  31. package/dist/react/_internal/wagmi/index.d.ts +1 -1
  32. package/dist/react/_internal/wagmi/index.js +2 -2
  33. package/dist/react/hooks/index.d.ts +666 -77
  34. package/dist/react/hooks/index.js +8 -8
  35. package/dist/react/index.css +17 -0
  36. package/dist/react/index.css.map +1 -1
  37. package/dist/react/index.d.ts +1 -1
  38. package/dist/react/index.js +12 -12
  39. package/dist/react/ssr/index.js +1 -1
  40. package/dist/react/ssr/index.js.map +1 -1
  41. package/dist/react/ui/components/index.css +17 -0
  42. package/dist/react/ui/components/index.css.map +1 -1
  43. package/dist/react/ui/components/index.js +12 -12
  44. package/dist/react/ui/icons/index.js +4 -4
  45. package/dist/react/ui/icons/index.js.map +1 -1
  46. package/dist/react/ui/index.css +17 -0
  47. package/dist/react/ui/index.css.map +1 -1
  48. package/dist/react/ui/index.js +12 -12
  49. package/dist/react/ui/modals/_internal/components/actionModal/index.css +22 -0
  50. package/dist/react/ui/modals/_internal/components/actionModal/index.css.map +1 -1
  51. package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +17 -9
  52. package/dist/react/ui/modals/_internal/components/actionModal/index.js +8 -4
  53. package/dist/react/ui/styles/index.d.ts +1 -1
  54. package/dist/styles/index.d.ts +1 -1
  55. package/dist/styles/index.js +2 -2
  56. package/dist/types/index.js +3 -3
  57. package/dist/utils/index.js +2 -2
  58. package/package.json +25 -25
  59. package/src/react/_internal/api/marketplace-api.ts +3 -2
  60. package/src/react/_internal/transaction-machine/execute-transaction.ts +41 -19
  61. package/src/react/_internal/transaction-machine/useTransactionMachine.ts +43 -8
  62. package/src/react/hooks/useBuyCollectable.tsx +15 -8
  63. package/src/react/hooks/useCancelOrder.tsx +15 -7
  64. package/src/react/hooks/useCreateListing.tsx +75 -11
  65. package/src/react/hooks/useCurrencies.tsx +1 -2
  66. package/src/react/hooks/useCurrencyBalance.tsx +1 -1
  67. package/src/react/hooks/useCurrencyOptions.tsx +1 -1
  68. package/src/react/hooks/useMakeOffer.tsx +74 -12
  69. package/src/react/hooks/useSell.tsx +73 -12
  70. package/src/react/ui/components/_internals/action-button/ActionButton.tsx +1 -7
  71. package/src/react/ui/components/_internals/action-button/types.ts +7 -0
  72. package/src/react/ui/components/_internals/custom-select/CustomSelect.tsx +18 -15
  73. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +5 -7
  74. package/src/react/ui/components/collectible-card/Footer.tsx +5 -7
  75. package/src/react/ui/components/collectible-card/styles.css.ts +1 -1
  76. package/src/react/ui/icons/ArrowUp.tsx +3 -0
  77. package/src/react/ui/icons/Bell.tsx +3 -0
  78. package/src/react/ui/icons/CalendarIcon.tsx +3 -0
  79. package/src/react/ui/icons/DiamondEye.tsx +3 -0
  80. package/src/react/ui/icons/InfoIcon.tsx +3 -0
  81. package/src/react/ui/icons/InventoryIcon.tsx +3 -0
  82. package/src/react/ui/icons/MinusIcon.tsx +3 -0
  83. package/src/react/ui/icons/PlusIcon.tsx +3 -0
  84. package/src/react/ui/icons/PositiveCircleIcon.tsx +3 -0
  85. package/src/react/ui/modals/BuyModal/index.tsx +25 -8
  86. package/src/react/ui/modals/CreateListingModal/_store.ts +5 -2
  87. package/src/react/ui/modals/CreateListingModal/index.tsx +66 -25
  88. package/src/react/ui/modals/MakeOfferModal/_store.ts +5 -2
  89. package/src/react/ui/modals/MakeOfferModal/index.tsx +87 -67
  90. package/src/react/ui/modals/SellModal/index.tsx +107 -57
  91. package/src/react/ui/modals/TransferModal/_store.ts +1 -1
  92. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +4 -2
  93. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +5 -5
  94. package/src/react/ui/modals/TransferModal/index.tsx +1 -1
  95. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +29 -8
  96. package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +15 -5
  97. package/src/react/ui/modals/_internal/components/actionModal/LoadingModal.tsx +15 -5
  98. package/src/react/ui/modals/_internal/components/actionModal/store.ts +6 -0
  99. package/src/react/ui/modals/_internal/components/calendar/index.tsx +1 -1
  100. package/src/react/ui/modals/_internal/components/currencyImage/index.tsx +3 -3
  101. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +11 -16
  102. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +14 -19
  103. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +34 -12
  104. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +3 -3
  105. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +7 -4
  106. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +1 -0
  107. package/src/react/ui/modals/_internal/components/transaction-footer/index.tsx +10 -8
  108. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +9 -5
  109. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +7 -4
  110. package/src/react/ui/modals/_internal/components/transactionPreview/useTransactionPreviewTitle.tsx +9 -11
  111. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +60 -31
  112. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +6 -2
  113. package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getFormattedType.ts +1 -1
  114. package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getMessage.ts +8 -2
  115. package/src/react/ui/modals/_internal/components/transactionStatusModal/util/getTitle.ts +12 -3
  116. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/index.tsx +146 -0
  117. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/store.ts +12 -0
  118. package/src/react/ui/modals/_internal/components/waasFeeOptionsBox/styles.css.ts +53 -0
  119. package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +117 -0
  120. package/src/utils/_internal/error/transaction.ts +12 -2
  121. package/src/utils/price.ts +3 -4
  122. package/tsconfig.json +1 -21
  123. package/tsconfig.tsbuildinfo +1 -1
  124. package/dist/chunk-B3LFJJVS.js.map +0 -1
  125. package/dist/chunk-E3ZFT6WR.js.map +0 -1
  126. package/dist/chunk-FFCNYF3S.js +0 -153
  127. package/dist/chunk-FFCNYF3S.js.map +0 -1
  128. package/dist/chunk-IRN77TJW.js.map +0 -1
  129. package/dist/chunk-N5F6IEAK.js.map +0 -1
  130. package/dist/chunk-NMCGA2TB.js +0 -98
  131. package/dist/chunk-NMCGA2TB.js.map +0 -1
  132. package/dist/chunk-Y7YO5TLE.js.map +0 -1
  133. /package/dist/{chunk-Z7NLKEXF.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
- store: Observable<ActionModalState>;
5
+ isOpen: boolean;
6
+ chainId: number;
8
7
  onClose: () => void;
9
8
  title: string;
10
9
  }
11
10
 
12
- export const LoadingModal = ({ store, onClose, title }: LoadingModalProps) => (
13
- <ActionModal store={store} onClose={onClose} title={title} ctas={[]}>
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: `1px solid hsl(var(--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
- // TODO: this should be exported from design system
12
- type SelectOption = {
13
- label: string;
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,22 +30,17 @@ 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 &&
39
37
  currencies.length > 0 &&
40
38
  !selectedCurrency$.get()?.contractAddress
41
39
  ) {
42
- console.debug('Setting default currency', currencies[0]);
43
40
  selectedCurrency$.set(currencies[0]);
44
41
  }
45
42
  }, [currencies]);
46
43
 
47
- console.debug('CurrencyOptionsSelect', {
48
- currencies,
49
- currenciesLoading,
50
- currency,
51
- });
52
44
  if (!currencies || currenciesLoading || !currency.symbol) {
53
45
  return <Skeleton borderRadius="lg" width="20" height="7" marginRight="3" />;
54
46
  }
@@ -58,7 +50,8 @@ const CurrencyOptionsSelect = observer(function CurrencyOptionsSelect({
58
50
  ({
59
51
  label: currency.symbol,
60
52
  value: currency.contractAddress,
61
- }) satisfies SelectOption,
53
+ content: currency.symbol,
54
+ }) as SelectItem,
62
55
  );
63
56
 
64
57
  const onChange = (value: string) => {
@@ -71,9 +64,11 @@ const CurrencyOptionsSelect = observer(function CurrencyOptionsSelect({
71
64
  return (
72
65
  <CustomSelect
73
66
  items={options}
74
- value={currency.symbol}
75
67
  onValueChange={onChange}
76
- defaultValue={currency.contractAddress}
68
+ defaultValue={{
69
+ value: currency.contractAddress,
70
+ content: currency.symbol,
71
+ }}
77
72
  />
78
73
  );
79
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, isSameDay } from 'date-fns';
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 rangeType =
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 [range, setRange] = useState<rangeType>(defaultRange);
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 rangeType)
110
+ handleSelectPresetRange(value as RangeType)
119
111
  }
120
- defaultValue={defaultRange}
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
- const changeListingPrice = (value: string) => {
60
- setValue(value);
61
- const parsedAmount = parseUnits(value, Number(currencyDecimals));
62
- $listingPrice.amountRaw.set(parsedAmount.toString());
63
- checkBalance && checkInsufficientBalance(parsedAmount.toString());
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
- <Box color="negative" fontSize="small">
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
- </Box>
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] + '.' + decimalParts[1];
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$.close(),
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 = getPresentableChainName(chainIdToSwitchTo!);
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
- await switchChainAsync({ chainId: Number(chainIdToSwitchTo!) });
50
+ if (!chainIdToSwitchTo) return;
51
+ await switchChainAsync({ chainId: Number(chainIdToSwitchTo) });
49
52
 
50
53
  switchChainModal$.state.onSuccess?.();
51
54
 
52
- switchChainModal$.close();
55
+ switchChainModal$.delete();
53
56
  } catch (error) {
54
57
  switchChainModal$.state.onError?.(error as SwitchChainErrorType);
55
58
  } finally {
@@ -44,6 +44,7 @@ export default function TokenPreview({
44
44
  width={'9'}
45
45
  height={'9'}
46
46
  borderRadius={'xs'}
47
+ style={{ objectFit: 'cover' }}
47
48
  />
48
49
 
49
50
  <Box display={'flex'} flexDirection={'column'} marginLeft={'3'}>
@@ -1,11 +1,12 @@
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
- transactionHash: Hex;
8
+ transactionHash: Hex | undefined;
9
+ orderId?: string;
9
10
  isConfirming: boolean;
10
11
  isConfirmed: boolean;
11
12
  isFailed: boolean;
@@ -15,6 +16,7 @@ type TransactionFooterProps = {
15
16
 
16
17
  export default function TransactionFooter({
17
18
  transactionHash,
19
+ orderId,
18
20
  isConfirming,
19
21
  isConfirmed,
20
22
  isFailed,
@@ -22,12 +24,12 @@ export default function TransactionFooter({
22
24
  chainId,
23
25
  }: TransactionFooterProps) {
24
26
  const icon =
25
- (isConfirming && <Spinner size="md" />) ||
26
- (isConfirmed && <SvgPositiveCircleIcon size="md" />);
27
+ ((isConfirmed || orderId) && <SvgPositiveCircleIcon size="md" />) ||
28
+ (isConfirming && <Spinner size="md" />);
27
29
 
28
30
  const title =
31
+ ((isConfirmed || orderId) && 'Transaction complete') ||
29
32
  (isConfirming && 'Processing transaction') ||
30
- (isConfirmed && 'Transaction complete') ||
31
33
  (isFailed && 'Transaction failed') ||
32
34
  (isTimeout && 'Transaction took longer than expected');
33
35
 
@@ -64,7 +66,7 @@ export default function TransactionFooter({
64
66
  fontWeight="medium"
65
67
  fontFamily="body"
66
68
  >
67
- {truncateMiddle(transactionHash, 4, 4)}
69
+ {transactionHash && truncateMiddle(transactionHash, 4, 4)}
68
70
  </Text>
69
71
  </Box>
70
72
  </Box>
@@ -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
- ).toString();
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
- ).toString();
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} {price.currency.symbol}
81
+ {showPlaceholderPrice ? '0' : formattedAmount}{' '}
82
+ {price.currency.symbol}
79
83
  </Text>
80
84
  )}
81
85
  </Box>
@@ -5,17 +5,18 @@ 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
+ orderId?: string;
19
20
  price?: Price;
20
21
  collectionAddress: Hex;
21
22
  chainId: string;
@@ -30,6 +31,7 @@ type TransactionPreviewProps = {
30
31
 
31
32
  const TransactionPreview = observer(
32
33
  ({
34
+ orderId,
33
35
  price,
34
36
  collectionAddress,
35
37
  chainId,
@@ -43,6 +45,7 @@ const TransactionPreview = observer(
43
45
  }: TransactionPreviewProps) => {
44
46
  const { type } = transactionStatusModal$.state.get();
45
47
  const title = useTransactionPreviewTitle(
48
+ orderId,
46
49
  { isConfirmed, isConfirming, isFailed, isTimeout },
47
50
  type,
48
51
  );
@@ -55,7 +58,7 @@ const TransactionPreview = observer(
55
58
  const collectibleName = collectible?.name;
56
59
  const collectionName = collection?.name;
57
60
  const priceFormatted = price
58
- ? formatUnits(BigInt(price!.amountRaw), price!.currency.decimals)
61
+ ? formatUnits(BigInt(price?.amountRaw), price?.currency.decimals)
59
62
  : undefined;
60
63
 
61
64
  if (collectibleLoading || collectionLoading) {
@@ -131,7 +134,7 @@ const TransactionPreview = observer(
131
134
  fontWeight="medium"
132
135
  fontFamily="body"
133
136
  >
134
- {priceFormatted} {price!.currency.symbol}
137
+ {priceFormatted} {price?.currency.symbol}
135
138
  </Text>
136
139
  </Box>
137
140
  )}
@@ -1,22 +1,20 @@
1
- import { useMemo } from 'react';
1
+ import type { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
2
2
  import type { ConfirmationStatus } from '../transactionStatusModal/store';
3
3
  import { TRANSACTION_TITLES } from './consts';
4
- import { TransactionType } from '../../../../../_internal/transaction-machine/execute-transaction';
5
4
 
6
5
  export function useTransactionPreviewTitle(
6
+ orderId: string | undefined,
7
7
  status: ConfirmationStatus,
8
8
  type?: TransactionType | undefined,
9
9
  ): string {
10
- return useMemo(() => {
11
- if (!type) return '';
10
+ if (!type) return '';
12
11
 
13
- const { isConfirming, isConfirmed, isFailed } = status;
14
- const titles = TRANSACTION_TITLES[type];
12
+ const { isConfirming, isConfirmed, isFailed } = status;
13
+ const titles = TRANSACTION_TITLES[type];
15
14
 
16
- if (isConfirming) return titles.confirming;
17
- if (isConfirmed) return titles.confirmed;
18
- if (isFailed) return titles.failed;
15
+ if (isConfirmed || orderId) return titles.confirmed;
16
+ if (isConfirming) return titles.confirming;
17
+ if (isFailed) return titles.failed;
19
18
 
20
- return '';
21
- }, [status, type]);
19
+ return '';
22
20
  }