@0xsequence/marketplace-sdk 0.0.1 → 0.2.0

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 (144) hide show
  1. package/.ctirc +32 -0
  2. package/dist/{chunk-TZGLKJRF.js → chunk-4E34HVSA.js} +2 -2
  3. package/dist/chunk-5EOVZAKT.js +1325 -0
  4. package/dist/chunk-5EOVZAKT.js.map +1 -0
  5. package/dist/{chunk-RNUHUVLC.js → chunk-6JWGELXL.js} +1 -1
  6. package/dist/chunk-6JWGELXL.js.map +1 -0
  7. package/dist/{chunk-4PFMUVE4.js → chunk-CSN7YD5Q.js} +2 -2
  8. package/dist/chunk-CSN7YD5Q.js.map +1 -0
  9. package/dist/{chunk-G3D572BT.js → chunk-FCQCNLFZ.js} +24 -1
  10. package/dist/chunk-FCQCNLFZ.js.map +1 -0
  11. package/dist/{chunk-HGBEC3WX.js → chunk-GZIA25G4.js} +1 -1
  12. package/dist/chunk-GZIA25G4.js.map +1 -0
  13. package/dist/{chunk-QOJXWHRZ.js → chunk-LFQB477Y.js} +3 -1
  14. package/dist/chunk-LFQB477Y.js.map +1 -0
  15. package/dist/{chunk-SM7V6ZWI.js → chunk-MD4JHPMH.js} +493 -418
  16. package/dist/chunk-MD4JHPMH.js.map +1 -0
  17. package/dist/{chunk-EDTC7UES.js → chunk-NII6JJGH.js} +9 -4
  18. package/dist/chunk-NII6JJGH.js.map +1 -0
  19. package/dist/{chunk-BBB3XUB4.js → chunk-PE2LLUTJ.js} +1 -1
  20. package/dist/chunk-PE2LLUTJ.js.map +1 -0
  21. package/dist/chunk-Q2BVDQ3G.js +41 -0
  22. package/dist/chunk-Q2BVDQ3G.js.map +1 -0
  23. package/dist/{chunk-3TYUQEFM.js → chunk-VEX7FDL6.js} +2 -2
  24. package/dist/chunk-VEX7FDL6.js.map +1 -0
  25. package/dist/{create-config-Dz0gCiQ0.d.ts → create-config-CgtmCzvb.d.ts} +2 -2
  26. package/dist/index.css +4 -1
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.js +4 -4
  29. package/dist/{marketplace-config-DZbtyrma.d.ts → marketplace-config-Bbxl-uKX.d.ts} +2 -1
  30. package/dist/react/_internal/api/index.d.ts +1 -1
  31. package/dist/react/_internal/api/index.js +1 -1
  32. package/dist/react/_internal/index.d.ts +5 -4
  33. package/dist/react/_internal/index.js +16 -8
  34. package/dist/react/_internal/wagmi/index.d.ts +3 -3
  35. package/dist/react/_internal/wagmi/index.js +1 -1
  36. package/dist/react/hooks/index.d.ts +1691 -103
  37. package/dist/react/hooks/index.js +34 -22
  38. package/dist/react/index.css +4 -1
  39. package/dist/react/index.css.map +1 -1
  40. package/dist/react/index.d.ts +7 -6
  41. package/dist/react/index.js +43 -31
  42. package/dist/react/ssr/index.d.ts +26 -25
  43. package/dist/react/ssr/index.js +34 -4
  44. package/dist/react/ssr/index.js.map +1 -1
  45. package/dist/react/ui/icons/index.js +2 -2
  46. package/dist/react/ui/index.css +4 -1
  47. package/dist/react/ui/index.css.map +1 -1
  48. package/dist/react/ui/index.d.ts +47 -42
  49. package/dist/react/ui/index.js +10 -10
  50. package/dist/react/ui/modals/_internal/components/actionModal/index.js +4 -4
  51. package/dist/{services-BIwQ1C1c.d.ts → services-Dei25J6_.d.ts} +1 -1
  52. package/dist/styles/index.css +4 -1
  53. package/dist/styles/index.css.map +1 -1
  54. package/dist/styles/index.d.ts +2 -1
  55. package/dist/styles/index.js +4 -4973
  56. package/dist/styles/index.js.map +1 -1
  57. package/dist/types/index.d.ts +2 -1
  58. package/dist/types/index.js +3 -3
  59. package/dist/types-BzZVURNL.d.ts +19 -0
  60. package/dist/utils/abi/clients/index.js +1 -1
  61. package/dist/utils/index.d.ts +2 -1
  62. package/dist/utils/index.js +2 -2
  63. package/package.json +19 -25
  64. package/src/react/_internal/api/marketplace.gen.ts +4 -1
  65. package/src/react/_internal/api/zod-schema.ts +636 -0
  66. package/src/react/_internal/types.ts +33 -9
  67. package/src/react/_internal/wagmi/create-config.ts +9 -3
  68. package/src/react/_internal/wagmi/embedded.ts +1 -1
  69. package/src/react/_internal/wagmi/universal.ts +1 -1
  70. package/src/react/hooks/index.ts +3 -0
  71. package/src/react/hooks/options/marketplaceConfigOptions.ts +2 -2
  72. package/src/react/hooks/useBalanceOfCollectible.tsx +47 -21
  73. package/src/react/hooks/useCheckoutOptions.tsx +63 -0
  74. package/src/react/hooks/useCollectible.tsx +20 -14
  75. package/src/react/hooks/useCollection.tsx +18 -12
  76. package/src/react/hooks/useCountOfCollectables.tsx +77 -0
  77. package/src/react/hooks/useCurrencies.tsx +67 -56
  78. package/src/react/hooks/useFilters.tsx +18 -12
  79. package/src/react/hooks/useFloorOrder.tsx +24 -9
  80. package/src/react/hooks/useGenerateListingTransaction.tsx +8 -7
  81. package/src/react/hooks/useGenerateOfferTransaction.tsx +5 -5
  82. package/src/react/hooks/useGenerateSellTransaction.tsx +19 -12
  83. package/src/react/hooks/useHighestOffer.tsx +26 -16
  84. package/src/react/hooks/useListBalances.tsx +60 -29
  85. package/src/react/hooks/useListCollectibles.tsx +28 -15
  86. package/src/react/hooks/useListOffersForCollectible.tsx +17 -8
  87. package/src/react/hooks/useLowestListing.tsx +26 -17
  88. package/src/react/hooks/useRoyaltyPercentage.tsx +18 -8
  89. package/src/react/hooks/useTransferTokens.tsx +3 -3
  90. package/src/react/provider.tsx +1 -1
  91. package/src/react/ssr/create-ssr-client.ts +1 -1
  92. package/src/react/ui/modals/CreateListingModal/_store.ts +39 -40
  93. package/src/react/ui/modals/CreateListingModal/index.tsx +152 -130
  94. package/src/react/ui/modals/MakeOfferModal/_store.ts +38 -43
  95. package/src/react/ui/modals/MakeOfferModal/index.tsx +39 -28
  96. package/src/react/ui/modals/SellModal/_store.ts +59 -57
  97. package/src/react/ui/modals/SellModal/index.tsx +34 -12
  98. package/src/react/ui/modals/SuccessfulPurchaseModal/_store.ts +1 -1
  99. package/src/react/ui/modals/SuccessfulPurchaseModal/index.tsx +14 -14
  100. package/src/react/ui/modals/TransferModal/_store.ts +11 -11
  101. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +92 -89
  102. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +114 -0
  103. package/src/react/ui/modals/TransferModal/_views/followWalletInstructions/index.tsx +0 -96
  104. package/src/react/ui/modals/TransferModal/index.tsx +24 -3
  105. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +1 -1
  106. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +4 -4
  107. package/src/react/ui/modals/_internal/components/floorPriceText/index.tsx +4 -3
  108. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +55 -12
  109. package/src/react/ui/modals/_internal/components/priceInput/styles.css.ts +4 -0
  110. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +3 -2
  111. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +4 -4
  112. package/src/react/ui/modals/_internal/components/switchChainModal/store.ts +4 -4
  113. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +3 -2
  114. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +7 -5
  115. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +6 -6
  116. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +47 -14
  117. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +14 -6
  118. package/src/types/api-types.ts +2 -2
  119. package/src/types/callbacks.ts +51 -0
  120. package/src/types/marketplace-config.ts +2 -1
  121. package/src/types/types.ts +1 -1
  122. package/src/utils/get-public-rpc-client.ts +1 -1
  123. package/tsconfig.json +24 -0
  124. package/tsconfig.tsbuildinfo +1 -0
  125. package/tsup.config.ts +35 -0
  126. package/README.md +0 -8
  127. package/dist/chunk-3TYUQEFM.js.map +0 -1
  128. package/dist/chunk-4PFMUVE4.js.map +0 -1
  129. package/dist/chunk-BBB3XUB4.js.map +0 -1
  130. package/dist/chunk-EDTC7UES.js.map +0 -1
  131. package/dist/chunk-G3D572BT.js.map +0 -1
  132. package/dist/chunk-HGBEC3WX.js.map +0 -1
  133. package/dist/chunk-QOJXWHRZ.js.map +0 -1
  134. package/dist/chunk-RNUHUVLC.js.map +0 -1
  135. package/dist/chunk-SM7V6ZWI.js.map +0 -1
  136. package/dist/chunk-STO74F2I.js +0 -14
  137. package/dist/chunk-STO74F2I.js.map +0 -1
  138. package/dist/chunk-VPGWEMWL.js +0 -162
  139. package/dist/chunk-VPGWEMWL.js.map +0 -1
  140. package/dist/chunk-ZE2LNX65.js +0 -394
  141. package/dist/chunk-ZE2LNX65.js.map +0 -1
  142. package/dist/types-BrAQ8-w4.d.ts +0 -12
  143. package/src/react/hooks/useCollectionCounts.tsx +0 -61
  144. /package/dist/{chunk-TZGLKJRF.js.map → chunk-4E34HVSA.js.map} +0 -0
@@ -1,146 +1,168 @@
1
- import { Box } from '@0xsequence/design-system';
2
- import { ContractType } from '@internal';
3
- import { Show, observer } from '@legendapp/state/react';
1
+ import { Box } from "@0xsequence/design-system";
2
+ import { Show, observer } from "@legendapp/state/react";
3
+ import type { Hex } from "viem";
4
+ import { useAccount } from "wagmi";
4
5
  import {
5
- ActionModal,
6
- type ActionModalProps,
7
- } from '../_internal/components/actionModal/ActionModal';
8
- import ExpirationDateSelect from '../_internal/components/expirationDateSelect';
9
- import FloorPriceText from '../_internal/components/floorPriceText';
10
- import PriceInput from '../_internal/components/priceInput';
11
- import QuantityInput from '../_internal/components/quantityInput';
12
- import TokenPreview from '../_internal/components/tokenPreview';
13
- import TransactionDetails from '../_internal/components/transactionDetails';
14
- import { createListingModal$, useHydrate } from './_store';
15
- import { useAccount } from 'wagmi';
16
- import { useSwitchChainModal } from '../_internal/components/switchChainModal';
17
- import type { Messages } from '../../../../types/messages';
6
+ ActionModal,
7
+ type ActionModalProps,
8
+ } from "../_internal/components/actionModal/ActionModal";
9
+ import ExpirationDateSelect from "../_internal/components/expirationDateSelect";
10
+ import FloorPriceText from "../_internal/components/floorPriceText";
11
+ import PriceInput from "../_internal/components/priceInput";
12
+ import QuantityInput from "../_internal/components/quantityInput";
13
+ import { useSwitchChainModal } from "../_internal/components/switchChainModal";
14
+ import TokenPreview from "../_internal/components/tokenPreview";
15
+ import TransactionDetails from "../_internal/components/transactionDetails";
16
+ import { createListingModal$, useHydrate } from "./_store";
17
+ import {
18
+ CreateListingErrorCallbacks,
19
+ CreateListingSuccessCallbacks,
20
+ } from "../../../../types/callbacks";
21
+ import { ContractType } from "../../../_internal";
18
22
 
19
23
  export type ShowCreateListingModalArgs = {
20
- collectionAddress: string;
21
- chainId: string;
22
- collectibleId: string;
23
- messages?: Messages;
24
+ collectionAddress: Hex;
25
+ chainId: string;
26
+ collectibleId: string;
24
27
  };
25
28
 
26
29
  export const useCreateListingModal = () => {
27
- const { chainId: accountChainId } = useAccount();
28
- const { show: showSwitchNetworkModal } = useSwitchChainModal();
29
-
30
- const openModal = (args: ShowCreateListingModalArgs) => {
31
- createListingModal$.open(args);
32
- };
33
-
34
- const handleShowModal = (args: ShowCreateListingModalArgs) => {
35
- const isSameChain = accountChainId === Number(args.chainId);
36
-
37
- if (!isSameChain) {
38
- showSwitchNetworkModal({
39
- chainIdToSwitchTo: Number(args.chainId),
40
- onSwitchChain: () => openModal(args),
41
- messages: args.messages?.switchChain,
42
- });
43
- return;
44
- }
45
-
46
- openModal(args);
47
- };
48
-
49
- return {
50
- show: handleShowModal,
51
- close: () => createListingModal$.close(),
52
- };
30
+ const { chainId: accountChainId } = useAccount();
31
+ const { show: showSwitchNetworkModal } = useSwitchChainModal();
32
+ const { errorCallbacks, successCallbacks } = createListingModal$.state.get();
33
+
34
+ const openModal = (args: ShowCreateListingModalArgs) => {
35
+ createListingModal$.open(args);
36
+ };
37
+
38
+ const handleShowModal = (args: ShowCreateListingModalArgs) => {
39
+ const isSameChain = accountChainId === Number(args.chainId);
40
+
41
+ if (!isSameChain) {
42
+ showSwitchNetworkModal({
43
+ chainIdToSwitchTo: Number(args.chainId),
44
+ onSwitchChain: () => openModal(args),
45
+ callbacks: {
46
+ onSuccess: successCallbacks?.onSwitchChainSuccess,
47
+ onUnknownError: errorCallbacks?.onSwitchChainError,
48
+ onSwitchingNotSupported: errorCallbacks?.onSwitchingNotSupportedError,
49
+ onUserRejectedRequest:
50
+ errorCallbacks?.onUserRejectedSwitchingChainRequestError,
51
+ },
52
+ });
53
+ return;
54
+ }
55
+
56
+ openModal(args);
57
+ };
58
+
59
+ return {
60
+ show: handleShowModal,
61
+ close: () => createListingModal$.close(),
62
+ onError: (callbacks: CreateListingErrorCallbacks) => {
63
+ createListingModal$.state.set({
64
+ ...createListingModal$.state.get(),
65
+ errorCallbacks: callbacks,
66
+ });
67
+ },
68
+ onSuccess: (callbacks: CreateListingSuccessCallbacks) => {
69
+ createListingModal$.state.set({
70
+ ...createListingModal$.state.get(),
71
+ successCallbacks: callbacks,
72
+ });
73
+ },
74
+ };
53
75
  };
54
76
 
55
77
  export const CreateListingModal = () => {
56
- return (
57
- <Show if={createListingModal$.isOpen}>
58
- <Modal />
59
- </Show>
60
- );
78
+ return (
79
+ <Show if={createListingModal$.isOpen}>
80
+ <Modal />
81
+ </Show>
82
+ );
61
83
  };
62
84
 
63
85
  const Modal = () => {
64
- useHydrate();
65
- return <ModalContent />;
86
+ useHydrate();
87
+ return <ModalContent />;
66
88
  };
67
89
 
68
90
  const ModalContent = observer(() => {
69
- const {
70
- chainId,
71
- collectionAddress,
72
- collectibleId,
73
- collectionName,
74
- collectionType,
75
- listingPrice,
76
- } = createListingModal$.state.get();
77
-
78
- const { steps } = createListingModal$.get();
79
-
80
- const ctas = [
81
- {
82
- label: 'Approve TOKEN',
83
- onClick: steps.tokenApproval.execute,
84
- hidden: !steps.tokenApproval.isNeeded(),
85
- pending: steps.tokenApproval.pending,
86
- variant: 'glass' as const,
87
- },
88
- {
89
- label: 'List item for sale',
90
- onClick: steps.createListing.execute,
91
- pending: steps.createListing.pending,
92
- disabled:
93
- steps.tokenApproval.isNeeded() || listingPrice.amountRaw === '0',
94
- },
95
- ] satisfies ActionModalProps['ctas'];
96
-
97
- return (
98
- <ActionModal
99
- store={createListingModal$}
100
- onClose={() => createListingModal$.close()}
101
- title="List item for sale"
102
- ctas={ctas}
103
- >
104
- <TokenPreview
105
- collectionName={collectionName}
106
- collectionAddress={collectionAddress}
107
- collectibleId={collectibleId}
108
- chainId={chainId}
109
- />
110
-
111
- <Box display="flex" flexDirection="column" width="full" gap="1">
112
- <PriceInput
113
- chainId={chainId}
114
- collectionAddress={collectionAddress}
115
- $listingPrice={createListingModal$.state.listingPrice}
116
- />
117
- {!!listingPrice && (
118
- <FloorPriceText
119
- tokenId={collectibleId}
120
- chainId={chainId}
121
- collectionAddress={collectionAddress}
122
- price={listingPrice}
123
- />
124
- )}
125
- </Box>
126
-
127
- {collectionType === ContractType.ERC1155 && (
128
- <QuantityInput
129
- chainId={chainId}
130
- collectionAddress={collectionAddress}
131
- collectibleId={collectibleId}
132
- $quantity={createListingModal$.state.quantity}
133
- />
134
- )}
135
-
136
- <ExpirationDateSelect $date={createListingModal$.state.expiry} />
137
-
138
- <TransactionDetails
139
- collectibleId={collectibleId}
140
- collectionAddress={collectionAddress}
141
- chainId={chainId}
142
- price={createListingModal$.state.listingPrice.get()}
143
- />
144
- </ActionModal>
145
- );
91
+ const {
92
+ chainId,
93
+ collectionAddress,
94
+ collectibleId,
95
+ collectionName,
96
+ collectionType,
97
+ listingPrice,
98
+ } = createListingModal$.state.get();
99
+
100
+ const { steps } = createListingModal$.get();
101
+
102
+ const ctas = [
103
+ {
104
+ label: "Approve TOKEN",
105
+ onClick: steps.tokenApproval.execute,
106
+ hidden: !steps.tokenApproval.isNeeded(),
107
+ pending: steps.tokenApproval.pending,
108
+ variant: "glass" as const,
109
+ },
110
+ {
111
+ label: "List item for sale",
112
+ onClick: steps.createListing.execute,
113
+ pending: steps.createListing.pending,
114
+ disabled:
115
+ steps.tokenApproval.isNeeded() || listingPrice.amountRaw === "0",
116
+ },
117
+ ] satisfies ActionModalProps["ctas"];
118
+
119
+ return (
120
+ <ActionModal
121
+ store={createListingModal$}
122
+ onClose={() => createListingModal$.close()}
123
+ title="List item for sale"
124
+ ctas={ctas}
125
+ >
126
+ <TokenPreview
127
+ collectionName={collectionName}
128
+ collectionAddress={collectionAddress}
129
+ collectibleId={collectibleId}
130
+ chainId={chainId}
131
+ />
132
+
133
+ <Box display="flex" flexDirection="column" width="full" gap="1">
134
+ <PriceInput
135
+ chainId={chainId}
136
+ collectionAddress={collectionAddress}
137
+ $listingPrice={createListingModal$.state.listingPrice}
138
+ />
139
+ {!!listingPrice && (
140
+ <FloorPriceText
141
+ tokenId={collectibleId}
142
+ chainId={chainId}
143
+ collectionAddress={collectionAddress}
144
+ price={listingPrice}
145
+ />
146
+ )}
147
+ </Box>
148
+
149
+ {collectionType === ContractType.ERC1155 && (
150
+ <QuantityInput
151
+ chainId={chainId}
152
+ collectionAddress={collectionAddress}
153
+ collectibleId={collectibleId}
154
+ $quantity={createListingModal$.state.quantity}
155
+ />
156
+ )}
157
+
158
+ <ExpirationDateSelect $date={createListingModal$.state.expiry} />
159
+
160
+ <TransactionDetails
161
+ collectibleId={collectibleId}
162
+ collectionAddress={collectionAddress}
163
+ chainId={chainId}
164
+ price={createListingModal$.state.listingPrice.get()}
165
+ />
166
+ </ActionModal>
167
+ );
146
168
  });
@@ -1,27 +1,34 @@
1
1
  import { observable, when } from '@legendapp/state';
2
2
  import { useMount, useSelector } from '@legendapp/state/react';
3
- import { useCollection } from '@react-hooks/useCollection';
4
- import { useGenerateOfferTransaction } from '@react-hooks/useGenerateOfferTransaction';
3
+ import type { QueryKey } from '@tanstack/react-query';
4
+ import { addDays } from 'date-fns/addDays';
5
+ import type { Hex } from 'viem';
6
+ import { useAccount, useSendTransaction } from 'wagmi';
7
+ import type { ShowMakeOfferModalArgs } from '.';
8
+ import type { Price } from '../../../../types';
9
+ import type {
10
+ MakeOfferErrorCallbacks,
11
+ MakeOfferSuccessCallbacks,
12
+ } from '../../../../types/callbacks';
5
13
  import {
14
+ type CollectionType,
6
15
  type Currency,
7
16
  OrderbookKind,
8
- type Price,
9
17
  type Step,
10
18
  StepType,
11
19
  type WalletKind,
12
- } from '@types';
13
- import { addDays } from 'date-fns/addDays';
14
- import { parseUnits, type Hex } from 'viem';
15
- import { useAccount, useSendTransaction } from 'wagmi';
16
- import type { ShowMakeOfferModalArgs } from '.';
17
- import type { Messages } from '../../../../types/messages';
20
+ collectableKeys,
21
+ } from '../../../_internal';
22
+ import {
23
+ useCollectible,
24
+ useCollection,
25
+ useGenerateOfferTransaction,
26
+ } from '../../../hooks';
18
27
  import { useTransactionStatusModal } from '../_internal/components/transactionStatusModal';
19
28
  import {
20
29
  getMakeOfferTransactionMessage,
21
30
  getMakeOfferTransactionTitle,
22
31
  } from './_utils/getMakeOfferTransactionTitleMessage';
23
- import { useCollectible } from '@react-hooks/useCollectible';
24
- import type { CollectionType } from '@internal';
25
32
 
26
33
  export interface MakeOfferModalState {
27
34
  isOpen: boolean;
@@ -32,11 +39,12 @@ export interface MakeOfferModalState {
32
39
  collectionType: CollectionType | undefined;
33
40
  offerPrice: Price;
34
41
  quantity: string;
35
- collectionAddress: string;
42
+ collectionAddress: Hex;
36
43
  chainId: string;
37
44
  collectibleId: string;
38
45
  expiry: Date;
39
- messages?: Messages;
46
+ errorCallbacks?: MakeOfferErrorCallbacks;
47
+ successCallbacks?: MakeOfferSuccessCallbacks;
40
48
  };
41
49
  steps: {
42
50
  isLoading: () => boolean;
@@ -62,14 +70,12 @@ export const initialState: MakeOfferModalState = {
62
70
  collectionAddress,
63
71
  chainId,
64
72
  collectibleId,
65
- messages,
66
73
  }: ShowMakeOfferModalArgs) => {
67
74
  makeOfferModal$.state.set({
68
75
  ...makeOfferModal$.state.get(),
69
76
  collectionAddress,
70
77
  chainId,
71
78
  collectibleId,
72
- messages,
73
79
  });
74
80
  makeOfferModal$.isOpen.set(true);
75
81
  },
@@ -85,7 +91,7 @@ export const initialState: MakeOfferModalState = {
85
91
  quantity: '1',
86
92
  expiry: new Date(addDays(new Date(), 7).toJSON()),
87
93
  collectionType: undefined,
88
- collectionAddress: '',
94
+ collectionAddress: '' as Hex,
89
95
  chainId: '',
90
96
  collectibleId: '',
91
97
  },
@@ -164,11 +170,10 @@ export const useHydrate = () => {
164
170
 
165
171
  const useTokenApprovalHandler = (chainId: string) => {
166
172
  const { sendTransactionAsync, isPending, isSuccess } = useSendTransaction();
167
- const {
168
- onUnknownError,
169
- onSuccess,
170
- }: { onUnknownError?: Function; onSuccess?: Function } =
171
- makeOfferModal$.state.get().messages?.approveToken || {};
173
+ const onError =
174
+ makeOfferModal$.state.get().errorCallbacks?.onApproveTokenError;
175
+ const onSuccess: (() => void) | undefined =
176
+ makeOfferModal$.state.get().successCallbacks?.onApproveTokenSuccess;
172
177
 
173
178
  makeOfferModal$.steps.tokenApproval.set({
174
179
  isNeeded: () => !!makeOfferModal$.steps.tokenApproval.getStep(),
@@ -192,7 +197,7 @@ const useTokenApprovalHandler = (chainId: string) => {
192
197
 
193
198
  onSuccess && onSuccess();
194
199
  } catch (error) {
195
- onUnknownError && onUnknownError(error);
200
+ onError && onError(error);
196
201
  }
197
202
  },
198
203
  });
@@ -206,12 +211,12 @@ const useTokenApprovalHandler = (chainId: string) => {
206
211
  };
207
212
 
208
213
  const useCreateOfferHandler = (chainId: string) => {
209
- const { collectibleId, collectionAddress } = makeOfferModal$.state.get();
214
+ const { collectibleId, collectionAddress, errorCallbacks, successCallbacks } =
215
+ makeOfferModal$.state.get();
210
216
  const { connector, address } = useAccount();
211
217
  const {
212
218
  generateOfferTransactionAsync,
213
219
  isPending: generateOfferTransactionPending,
214
- error: generateOfferTransactionError,
215
220
  } = useGenerateOfferTransaction({ chainId });
216
221
  const { data: collectible } = useCollectible({
217
222
  chainId,
@@ -219,12 +224,6 @@ const useCreateOfferHandler = (chainId: string) => {
219
224
  collectibleId,
220
225
  });
221
226
 
222
- const {
223
- onUnknownError,
224
- onSuccess,
225
- }: { onUnknownError?: Function; onSuccess?: Function } =
226
- makeOfferModal$.state.get().messages?.sellCollectible || {};
227
-
228
227
  const { sendTransactionAsync, isPending: sendTransactionPending } =
229
228
  useSendTransaction();
230
229
 
@@ -248,10 +247,7 @@ const useCreateOfferHandler = (chainId: string) => {
248
247
  expiry: makeOfferModal$.state.expiry.get(),
249
248
  currencyAddress:
250
249
  makeOfferModal$.state.offerPrice.currency.contractAddress.get(),
251
- pricePerToken: parseUnits(
252
- makeOfferModal$.state.offerPrice.amountRaw.get(),
253
- makeOfferModal$.state.offerPrice.currency.decimals.get(),
254
- ).toString(),
250
+ pricePerToken: makeOfferModal$.state.offerPrice.amountRaw.get(),
255
251
  },
256
252
  })
257
253
  .then(async (steps) => {
@@ -268,6 +264,8 @@ const useCreateOfferHandler = (chainId: string) => {
268
264
 
269
265
  makeOfferModal$.steps._currentStep.set(null);
270
266
 
267
+ makeOfferModal$.close();
268
+
271
269
  showTransactionStatusModal({
272
270
  hash: hash!,
273
271
  price: makeOfferModal$.state.offerPrice.get(),
@@ -278,19 +276,16 @@ const useCreateOfferHandler = (chainId: string) => {
278
276
  getMessage: (params) =>
279
277
  getMakeOfferTransactionMessage(params, collectible?.name || ''),
280
278
  type: StepType.createOffer,
279
+ callbacks: {
280
+ onSuccess: successCallbacks?.onMakeOfferSuccess,
281
+ onUnknownError: errorCallbacks?.onMakeOfferError,
282
+ },
283
+ queriesToInvalidate: collectableKeys.all as unknown as QueryKey[],
281
284
  });
282
-
283
- makeOfferModal$.close();
284
-
285
- onSuccess && onSuccess();
286
285
  })
287
286
  .catch((error) => {
288
- onUnknownError && onUnknownError(error);
287
+ errorCallbacks?.onMakeOfferError?.(error);
289
288
  });
290
289
  },
291
290
  });
292
-
293
- if (generateOfferTransactionError) {
294
- onUnknownError && onUnknownError(generateOfferTransactionError);
295
- }
296
291
  };
@@ -1,7 +1,12 @@
1
- import { ContractType } from '@internal';
2
1
  import { Show, observer } from '@legendapp/state/react';
3
- import { type Hex, erc20Abi, parseUnits } from 'viem';
4
- import { useAccount, useReadContract } from 'wagmi';
2
+ import { useState } from 'react';
3
+ import type { Hex } from 'viem';
4
+ import { useAccount } from 'wagmi';
5
+ import type {
6
+ MakeOfferErrorCallbacks,
7
+ MakeOfferSuccessCallbacks,
8
+ } from '../../../../types/callbacks';
9
+ import { ContractType } from '../../../_internal';
5
10
  import {
6
11
  ActionModal,
7
12
  type ActionModalProps,
@@ -10,21 +15,20 @@ import ExpirationDateSelect from '../_internal/components/expirationDateSelect';
10
15
  import FloorPriceText from '../_internal/components/floorPriceText';
11
16
  import PriceInput from '../_internal/components/priceInput';
12
17
  import QuantityInput from '../_internal/components/quantityInput';
18
+ import { useSwitchChainModal } from '../_internal/components/switchChainModal';
13
19
  import TokenPreview from '../_internal/components/tokenPreview';
14
20
  import { makeOfferModal$, useHydrate } from './_store';
15
- import { useSwitchChainModal } from '../_internal/components/switchChainModal';
16
- import type { Messages } from '../../../../types/messages';
17
21
 
18
22
  export type ShowMakeOfferModalArgs = {
19
- collectionAddress: string;
23
+ collectionAddress: Hex;
20
24
  chainId: string;
21
25
  collectibleId: string;
22
- messages?: Messages;
23
26
  };
24
27
 
25
28
  export const useMakeOfferModal = () => {
26
29
  const { chainId: accountChainId } = useAccount();
27
30
  const { show: showSwitchNetworkModal } = useSwitchChainModal();
31
+ const { errorCallbacks, successCallbacks } = makeOfferModal$.state.get();
28
32
 
29
33
  const openModal = (args: ShowMakeOfferModalArgs) => {
30
34
  makeOfferModal$.open(args);
@@ -37,7 +41,13 @@ export const useMakeOfferModal = () => {
37
41
  showSwitchNetworkModal({
38
42
  chainIdToSwitchTo: Number(args.chainId),
39
43
  onSwitchChain: () => openModal(args),
40
- messages: args.messages?.switchChain,
44
+ callbacks: {
45
+ onSuccess: successCallbacks?.onSwitchChainSuccess,
46
+ onUnknownError: errorCallbacks?.onSwitchChainError,
47
+ onSwitchingNotSupported: errorCallbacks?.onSwitchingNotSupportedError,
48
+ onUserRejectedRequest:
49
+ errorCallbacks?.onUserRejectedSwitchingChainRequestError,
50
+ },
41
51
  });
42
52
  return;
43
53
  }
@@ -48,6 +58,18 @@ export const useMakeOfferModal = () => {
48
58
  return {
49
59
  show: handleShowModal,
50
60
  close: () => makeOfferModal$.close(),
61
+ onError: (callbacks: MakeOfferErrorCallbacks) => {
62
+ makeOfferModal$.state.set({
63
+ ...makeOfferModal$.state.get(),
64
+ errorCallbacks: callbacks,
65
+ });
66
+ },
67
+ onSuccess: (callbacks: MakeOfferSuccessCallbacks) => {
68
+ makeOfferModal$.state.set({
69
+ ...makeOfferModal$.state.get(),
70
+ successCallbacks: callbacks,
71
+ });
72
+ },
51
73
  };
52
74
  };
53
75
 
@@ -65,6 +87,7 @@ const Modal = () => {
65
87
  };
66
88
 
67
89
  const ModalContent = observer(() => {
90
+ const [insufficientBalance, setInsufficientBalance] = useState(false);
68
91
  const {
69
92
  chainId,
70
93
  collectionAddress,
@@ -76,24 +99,6 @@ const ModalContent = observer(() => {
76
99
 
77
100
  const { steps } = makeOfferModal$.get();
78
101
 
79
- const { address: accountAddress } = useAccount();
80
- const { data: balance, isSuccess: isBalanceSuccess } = useReadContract({
81
- address:
82
- makeOfferModal$.state.offerPrice.currency.contractAddress.get() as Hex,
83
- abi: erc20Abi,
84
- functionName: 'balanceOf',
85
- args: [accountAddress as Hex],
86
- });
87
-
88
- let balanceError = '';
89
- if (
90
- isBalanceSuccess &&
91
- parseUnits(offerPrice.amountRaw, offerPrice.currency.decimals) >
92
- (balance || 0)
93
- ) {
94
- balanceError = 'Insufficient balance';
95
- }
96
-
97
102
  const ctas = [
98
103
  {
99
104
  label: 'Approve TOKEN',
@@ -106,7 +111,10 @@ const ModalContent = observer(() => {
106
111
  label: 'Make offer',
107
112
  onClick: steps.createOffer.execute,
108
113
  pending: steps.createOffer.pending,
109
- disabled: steps.tokenApproval.isNeeded() || offerPrice.amountRaw === '0',
114
+ disabled:
115
+ steps.tokenApproval.isNeeded() ||
116
+ offerPrice.amountRaw === '0' ||
117
+ insufficientBalance,
110
118
  },
111
119
  ] satisfies ActionModalProps['ctas'];
112
120
 
@@ -130,7 +138,10 @@ const ModalContent = observer(() => {
130
138
  chainId={chainId}
131
139
  collectionAddress={collectionAddress}
132
140
  $listingPrice={makeOfferModal$.state.offerPrice}
133
- error={balanceError}
141
+ checkBalance={{
142
+ enabled: true,
143
+ callback: (state) => setInsufficientBalance(state),
144
+ }}
134
145
  />
135
146
 
136
147
  {collectionType === ContractType.ERC1155 && (