@0xsequence/marketplace-sdk 0.3.0 → 0.3.2

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 (165) hide show
  1. package/dist/chunk-22NLQ3AS.js +3078 -0
  2. package/dist/chunk-22NLQ3AS.js.map +1 -0
  3. package/dist/chunk-3OHM45R3.js +1294 -0
  4. package/dist/chunk-3OHM45R3.js.map +1 -0
  5. package/dist/{chunk-MQR6SHXZ.js → chunk-4YU2UPYH.js} +58 -103
  6. package/dist/chunk-4YU2UPYH.js.map +1 -0
  7. package/dist/chunk-7NJETFMF.js +21 -0
  8. package/dist/chunk-7NJETFMF.js.map +1 -0
  9. package/dist/{chunk-UYRQ5MJQ.js → chunk-FUM4OGOQ.js} +4 -4
  10. package/dist/chunk-FUM4OGOQ.js.map +1 -0
  11. package/dist/{chunk-7OO74L2K.js → chunk-GJAKQ5Q3.js} +40 -1
  12. package/dist/chunk-GJAKQ5Q3.js.map +1 -0
  13. package/dist/chunk-MCI3KOSQ.js +2 -0
  14. package/dist/{chunk-BJE7AG6V.js → chunk-O7UQGT43.js} +698 -23
  15. package/dist/chunk-O7UQGT43.js.map +1 -0
  16. package/dist/{chunk-CSN7YD5Q.js → chunk-Q57TEA3Z.js} +20 -2
  17. package/dist/chunk-Q57TEA3Z.js.map +1 -0
  18. package/dist/{chunk-VEX7FDL6.js → chunk-SBVLWSRZ.js} +2 -2
  19. package/dist/{chunk-VEX7FDL6.js.map → chunk-SBVLWSRZ.js.map} +1 -1
  20. package/dist/{chunk-6S4FYXP6.js → chunk-SPW24Y7I.js} +40 -1
  21. package/dist/chunk-SPW24Y7I.js.map +1 -0
  22. package/dist/chunk-UISBTKFF.js +1 -0
  23. package/dist/{chunk-OUWB3FHZ.js → chunk-WA433WAJ.js} +9 -33
  24. package/dist/chunk-WA433WAJ.js.map +1 -0
  25. package/dist/{chunk-O5JXKTWP.js → chunk-WFE6OCYF.js} +4 -4
  26. package/dist/chunk-WFE6OCYF.js.map +1 -0
  27. package/dist/chunk-XX4EVWBF.js +1292 -0
  28. package/dist/chunk-XX4EVWBF.js.map +1 -0
  29. package/dist/chunk-Y7YO5TLE.js +53 -0
  30. package/dist/chunk-Y7YO5TLE.js.map +1 -0
  31. package/dist/index.css +1 -50
  32. package/dist/index.d.ts +3 -5
  33. package/dist/index.js +12 -14
  34. package/dist/index.js.map +1 -1
  35. package/dist/react/hooks/index.css +82 -0
  36. package/dist/react/hooks/index.css.map +1 -0
  37. package/dist/react/hooks/index.d.ts +401 -462
  38. package/dist/react/hooks/index.js +26 -6
  39. package/dist/react/index.css +56 -91
  40. package/dist/react/index.css.map +1 -1
  41. package/dist/react/index.d.ts +2 -2
  42. package/dist/react/index.js +32 -13
  43. package/dist/react/ui/components/index.css +86 -121
  44. package/dist/react/ui/components/index.css.map +1 -1
  45. package/dist/react/ui/components/index.d.ts +10 -4
  46. package/dist/react/ui/components/index.js +12 -11
  47. package/dist/react/ui/icons/index.js +3 -2
  48. package/dist/react/ui/icons/index.js.map +1 -1
  49. package/dist/react/ui/index.css +56 -91
  50. package/dist/react/ui/index.css.map +1 -1
  51. package/dist/react/ui/index.d.ts +29 -31
  52. package/dist/react/ui/index.js +14 -11
  53. package/dist/react/ui/modals/_internal/components/actionModal/index.js +5 -16
  54. package/dist/react/ui/modals/_internal/components/actionModal/index.js.map +1 -1
  55. package/dist/styles/index.css +1 -50
  56. package/dist/styles/index.css.map +1 -1
  57. package/dist/styles/index.d.ts +2 -6
  58. package/dist/styles/index.js +9 -11
  59. package/dist/utils/abi/index.d.ts +2 -0
  60. package/dist/utils/abi/index.js +21 -0
  61. package/dist/utils/abi/marketplace/index.d.ts +805 -0
  62. package/dist/utils/abi/marketplace/index.js +12 -0
  63. package/dist/utils/abi/{abi/token → token}/index.js +1 -2
  64. package/dist/utils/index.d.ts +5 -5
  65. package/dist/utils/index.js +12 -14
  66. package/package.json +17 -15
  67. package/src/react/_internal/transaction-machine/execute-transaction.ts +592 -0
  68. package/src/react/_internal/transaction-machine/useTransactionMachine.ts +66 -0
  69. package/src/react/hooks/index.ts +4 -0
  70. package/src/react/hooks/useBuyCollectable.tsx +38 -0
  71. package/src/react/hooks/useCancelOrder.tsx +38 -0
  72. package/src/react/hooks/useCheckoutOptions.tsx +9 -6
  73. package/src/react/hooks/useCreateListing.tsx +65 -0
  74. package/src/react/hooks/useGenerateBuyTransaction.tsx +71 -0
  75. package/src/react/hooks/useListListingsForCollectible.tsx +1 -1
  76. package/src/react/hooks/useMakeOffer.tsx +62 -0
  77. package/src/react/hooks/useRoyaltyPercentage.tsx +1 -1
  78. package/src/react/hooks/useSell.tsx +62 -0
  79. package/src/react/ui/components/_internals/action-button/ActionButton.tsx +107 -115
  80. package/src/react/ui/components/_internals/custom-select/CustomSelect.tsx +63 -0
  81. package/src/react/ui/components/_internals/custom-select/styles.css.ts +64 -0
  82. package/src/react/ui/components/collectible-card/CollectibleCard.tsx +127 -130
  83. package/src/react/ui/components/collectible-card/Footer.tsx +65 -58
  84. package/src/react/ui/icons/Bell.tsx +2 -2
  85. package/src/react/ui/index.ts +1 -0
  86. package/src/react/ui/modals/BuyModal/_store.ts +53 -0
  87. package/src/react/ui/modals/BuyModal/index.tsx +119 -0
  88. package/src/react/ui/modals/CreateListingModal/_store.ts +35 -312
  89. package/src/react/ui/modals/CreateListingModal/index.tsx +185 -126
  90. package/src/react/ui/modals/MakeOfferModal/_store.ts +34 -276
  91. package/src/react/ui/modals/MakeOfferModal/index.tsx +195 -136
  92. package/src/react/ui/modals/SellModal/_store.ts +29 -262
  93. package/src/react/ui/modals/SellModal/index.tsx +156 -121
  94. package/src/react/ui/modals/SuccessfulPurchaseModal/_store.ts +17 -3
  95. package/src/react/ui/modals/SuccessfulPurchaseModal/index.tsx +3 -2
  96. package/src/react/ui/modals/TransferModal/index.tsx +9 -16
  97. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +1 -0
  98. package/src/react/ui/modals/_internal/components/actionModal/ErrorModal.tsx +18 -0
  99. package/src/react/ui/modals/_internal/components/actionModal/LoadingModal.tsx +18 -0
  100. package/src/react/ui/modals/_internal/components/calendarPopover/index.tsx +1 -0
  101. package/src/react/ui/modals/_internal/components/calendarPopover/overrides.css +8 -0
  102. package/src/react/ui/modals/_internal/components/calendarPopover/styles.css.ts +10 -4
  103. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +10 -13
  104. package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +23 -9
  105. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +7 -18
  106. package/src/react/ui/modals/_internal/components/switchChainModal/index.tsx +17 -44
  107. package/src/react/ui/modals/_internal/components/switchChainModal/store.ts +10 -8
  108. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +14 -3
  109. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +4 -2
  110. package/src/react/ui/modals/_internal/components/transactionHeader/index.tsx +4 -4
  111. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +4 -2
  112. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +13 -10
  113. package/src/react/ui/modals/_internal/types.ts +13 -0
  114. package/src/react/ui/modals/modal-provider.tsx +4 -2
  115. package/src/styles/index.ts +0 -2
  116. package/src/utils/abi/index.ts +2 -0
  117. package/src/utils/abi/marketplace/index.ts +3 -0
  118. package/src/utils/abi/marketplace/sequence-marketplace-v1.ts +463 -0
  119. package/src/utils/abi/marketplace/sequence-marketplace-v2.ts +802 -0
  120. package/src/utils/index.ts +2 -3
  121. package/src/utils/network.ts +4 -2
  122. package/tsconfig.tsbuildinfo +1 -1
  123. package/dist/chunk-6JWGELXL.js +0 -214
  124. package/dist/chunk-6JWGELXL.js.map +0 -1
  125. package/dist/chunk-6S4FYXP6.js.map +0 -1
  126. package/dist/chunk-7OO74L2K.js.map +0 -1
  127. package/dist/chunk-BCNFYVAL.js +0 -1
  128. package/dist/chunk-BJE7AG6V.js.map +0 -1
  129. package/dist/chunk-CSN7YD5Q.js.map +0 -1
  130. package/dist/chunk-D7QQP6MS.js +0 -2
  131. package/dist/chunk-DBFOPEV6.js +0 -23
  132. package/dist/chunk-DBFOPEV6.js.map +0 -1
  133. package/dist/chunk-MQR6SHXZ.js.map +0 -1
  134. package/dist/chunk-O5JXKTWP.js.map +0 -1
  135. package/dist/chunk-OUWB3FHZ.js.map +0 -1
  136. package/dist/chunk-PE2LLUTJ.js +0 -213
  137. package/dist/chunk-PE2LLUTJ.js.map +0 -1
  138. package/dist/chunk-QVFMD6S2.js +0 -21
  139. package/dist/chunk-QVFMD6S2.js.map +0 -1
  140. package/dist/chunk-QXLZPSSR.js +0 -3316
  141. package/dist/chunk-QXLZPSSR.js.map +0 -1
  142. package/dist/chunk-UYRQ5MJQ.js.map +0 -1
  143. package/dist/utils/abi/abi/standard/index.d.ts +0 -25
  144. package/dist/utils/abi/abi/standard/index.js +0 -8
  145. package/dist/utils/abi/clients/index.d.ts +0 -27
  146. package/dist/utils/abi/clients/index.js +0 -13
  147. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/styles.css.ts +0 -33
  148. package/src/react/ui/modals/_internal/components/expirationDateSelect/styles.css.ts +0 -25
  149. package/src/utils/abi/abi/standard/index.ts +0 -1
  150. package/src/utils/abi/clients/ERC1155.ts +0 -82
  151. package/src/utils/abi/clients/ERC20.ts +0 -101
  152. package/src/utils/abi/clients/ERC721.ts +0 -97
  153. package/src/utils/abi/clients/index.ts +0 -3
  154. /package/dist/{chunk-BCNFYVAL.js.map → chunk-MCI3KOSQ.js.map} +0 -0
  155. /package/dist/{chunk-D7QQP6MS.js.map → chunk-UISBTKFF.js.map} +0 -0
  156. /package/dist/utils/abi/{abi/standard/index.js.map → index.js.map} +0 -0
  157. /package/dist/utils/abi/{abi/token → marketplace}/index.js.map +0 -0
  158. /package/dist/utils/abi/{abi/token → token}/index.d.ts +0 -0
  159. /package/dist/utils/abi/{clients → token}/index.js.map +0 -0
  160. /package/src/react/hooks/{useGenerateCancleTransaction.tsx → useGenerateCancelTransaction.tsx} +0 -0
  161. /package/src/utils/abi/{abi/standard → marketplace}/EIP2981.ts +0 -0
  162. /package/src/utils/abi/{abi/token → token}/ERC1155.ts +0 -0
  163. /package/src/utils/abi/{abi/token → token}/ERC20.ts +0 -0
  164. /package/src/utils/abi/{abi/token → token}/ERC721.ts +0 -0
  165. /package/src/utils/abi/{abi/token → token}/index.ts +0 -0
@@ -1,23 +1,25 @@
1
1
  import { Show, observer } from '@legendapp/state/react';
2
- import { useState } from 'react';
2
+ import { useEffect, useState } from 'react';
3
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';
10
- import {
11
- ActionModal,
12
- type ActionModalProps,
13
- } from '../_internal/components/actionModal/ActionModal';
4
+ import { collectableKeys, ContractType, StepType } from '../../../_internal';
5
+ import { useCollectible, useCollection, useCurrencies } from '../../../hooks';
6
+ import { useMakeOffer } from '../../../hooks/useMakeOffer';
7
+ import { ActionModal } from '../_internal/components/actionModal/ActionModal';
14
8
  import ExpirationDateSelect from '../_internal/components/expirationDateSelect';
15
9
  import FloorPriceText from '../_internal/components/floorPriceText';
16
10
  import PriceInput from '../_internal/components/priceInput';
17
11
  import QuantityInput from '../_internal/components/quantityInput';
18
- import { useSwitchChainModal } from '../_internal/components/switchChainModal';
19
12
  import TokenPreview from '../_internal/components/tokenPreview';
20
- import { makeOfferModal$, useHydrate } from './_store';
13
+ import { useTransactionStatusModal } from '../_internal/components/transactionStatusModal';
14
+ import { makeOfferModal$ } from './_store';
15
+ import {
16
+ getMakeOfferTransactionMessage,
17
+ getMakeOfferTransactionTitle,
18
+ } from './_utils/getMakeOfferTransactionTitleMessage';
19
+ import { LoadingModal } from '../_internal/components/actionModal/LoadingModal';
20
+ import { ErrorModal } from '../_internal/components/actionModal/ErrorModal';
21
+ import type { ModalCallbacks } from '../_internal/types';
22
+ import type { QueryKey } from '@tanstack/react-query';
21
23
 
22
24
  export type ShowMakeOfferModalArgs = {
23
25
  collectionAddress: Hex;
@@ -25,144 +27,201 @@ export type ShowMakeOfferModalArgs = {
25
27
  collectibleId: string;
26
28
  };
27
29
 
28
- export const useMakeOfferModal = () => {
29
- const { chainId: accountChainId } = useAccount();
30
- const { show: showSwitchNetworkModal } = useSwitchChainModal();
31
- const { errorCallbacks, successCallbacks } = makeOfferModal$.state.get();
32
-
33
- const openModal = (args: ShowMakeOfferModalArgs) => {
34
- makeOfferModal$.open(args);
35
- };
36
-
37
- const handleShowModal = (args: ShowMakeOfferModalArgs) => {
38
- const isSameChain = accountChainId === Number(args.chainId);
39
-
40
- if (!isSameChain) {
41
- showSwitchNetworkModal({
42
- chainIdToSwitchTo: Number(args.chainId),
43
- onSwitchChain: () => openModal(args),
44
- callbacks: {
45
- onSuccess: successCallbacks?.onSwitchChainSuccess,
46
- onUnknownError: errorCallbacks?.onSwitchChainError,
47
- onSwitchingNotSupported: errorCallbacks?.onSwitchingNotSupportedError,
48
- onUserRejectedRequest:
49
- errorCallbacks?.onUserRejectedSwitchingChainRequestError,
50
- },
51
- });
52
- return;
53
- }
54
-
55
- openModal(args);
56
- };
57
-
58
- return {
59
- show: handleShowModal,
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
- },
73
- };
74
- };
30
+ export const useMakeOfferModal = (defaultCallbacks?: ModalCallbacks) => ({
31
+ show: (args: ShowMakeOfferModalArgs) =>
32
+ makeOfferModal$.open({ ...args, callbacks: defaultCallbacks }),
33
+ close: makeOfferModal$.close,
34
+ });
75
35
 
76
36
  export const MakeOfferModal = () => {
37
+ const { show: showTransactionStatusModal } = useTransactionStatusModal();
77
38
  return (
78
39
  <Show if={makeOfferModal$.isOpen}>
79
- <Modal />
40
+ <ModalContent showTransactionStatusModal={showTransactionStatusModal} />
80
41
  </Show>
81
42
  );
82
43
  };
83
44
 
84
- const Modal = () => {
85
- useHydrate();
86
- return <ModalContent />;
87
- };
45
+ type TransactionStatusModalReturn = ReturnType<
46
+ typeof useTransactionStatusModal
47
+ >;
48
+
49
+ const ModalContent = observer(
50
+ ({
51
+ showTransactionStatusModal,
52
+ }: {
53
+ showTransactionStatusModal: TransactionStatusModalReturn['show'];
54
+ }) => {
55
+ const state = makeOfferModal$.get();
56
+ const { collectionAddress, chainId, offerPrice, collectibleId } = state;
57
+ const [insufficientBalance, setInsufficientBalance] = useState(false);
58
+
59
+ const {
60
+ data: collectible,
61
+ isLoading: collectableIsLoading,
62
+ isError: collectableIsError,
63
+ } = useCollectible({
64
+ chainId,
65
+ collectionAddress,
66
+ collectibleId,
67
+ });
68
+
69
+ const {
70
+ data: collection,
71
+ isLoading: collectionIsLoading,
72
+ isError: collectionIsError,
73
+ } = useCollection({
74
+ chainId,
75
+ collectionAddress,
76
+ });
77
+
78
+ const { isLoading: currenciesIsLoading } = useCurrencies({
79
+ chainId,
80
+ collectionAddress,
81
+ });
82
+
83
+ const { getMakeOfferSteps } = useMakeOffer({
84
+ chainId,
85
+ collectionAddress,
86
+ onTransactionSent: (hash) => {
87
+ if (!hash) return;
88
+ showTransactionStatusModal({
89
+ hash,
90
+ price: makeOfferModal$.offerPrice.get(),
91
+ collectionAddress,
92
+ chainId,
93
+ tokenId: collectibleId,
94
+ getTitle: getMakeOfferTransactionTitle,
95
+ getMessage: (params) =>
96
+ getMakeOfferTransactionMessage(params, collectible?.name || ''),
97
+ type: StepType.createOffer,
98
+ queriesToInvalidate: collectableKeys.all as unknown as QueryKey[],
99
+ });
100
+ makeOfferModal$.close();
101
+ },
102
+ onSuccess: (hash) => {
103
+ makeOfferModal$.callbacks?.onSuccess?.(hash);
104
+ },
105
+ onError: (error) => {
106
+ makeOfferModal$.callbacks?.onError?.(error);
107
+ },
108
+ });
109
+
110
+ const dateToUnixTime = (date: Date) =>
111
+ Math.floor(date.getTime() / 1000).toString();
112
+
113
+ const currencyAddress = offerPrice.currency.contractAddress;
114
+
115
+ const { isLoading, steps, refreshSteps } = getMakeOfferSteps({
116
+ contractType: collection!.type as ContractType,
117
+ offer: {
118
+ tokenId: collectibleId,
119
+ quantity: makeOfferModal$.quantity.get(),
120
+ expiry: dateToUnixTime(makeOfferModal$.expiry.get()),
121
+ currencyAddress,
122
+ pricePerToken: offerPrice.amountRaw,
123
+ },
124
+ });
125
+
126
+ useEffect(() => {
127
+ if (!currencyAddress) return;
128
+ refreshSteps();
129
+ }, [currencyAddress]);
130
+
131
+ if (collectableIsLoading || collectionIsLoading || currenciesIsLoading) {
132
+ return (
133
+ <LoadingModal
134
+ store={makeOfferModal$}
135
+ onClose={makeOfferModal$.close}
136
+ title="Make an offer"
137
+ />
138
+ );
139
+ }
88
140
 
89
- const ModalContent = observer(() => {
90
- const [insufficientBalance, setInsufficientBalance] = useState(false);
91
- const {
92
- chainId,
93
- collectionAddress,
94
- collectibleId,
95
- collectionName,
96
- collectionType,
97
- offerPrice,
98
- } = makeOfferModal$.state.get();
99
-
100
- const { steps } = makeOfferModal$.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: 'Make offer',
112
- onClick: steps.createOffer.execute,
113
- pending: steps.createOffer.pending,
114
- disabled:
115
- steps.tokenApproval.isNeeded() ||
116
- offerPrice.amountRaw === '0' ||
117
- insufficientBalance,
118
- },
119
- ] satisfies ActionModalProps['ctas'];
141
+ if (collectableIsError || collectionIsError) {
142
+ return (
143
+ <ErrorModal
144
+ store={makeOfferModal$}
145
+ onClose={makeOfferModal$.close}
146
+ title="Make an offer"
147
+ />
148
+ );
149
+ }
120
150
 
121
- return (
122
- <ActionModal
123
- store={makeOfferModal$}
124
- onClose={() => {
125
- makeOfferModal$.close();
126
- }}
127
- title="Make an offer"
128
- ctas={ctas}
129
- >
130
- <TokenPreview
131
- collectionName={collectionName}
132
- collectionAddress={collectionAddress}
133
- collectibleId={collectibleId}
134
- chainId={chainId}
135
- />
136
-
137
- <PriceInput
138
- chainId={chainId}
139
- collectionAddress={collectionAddress}
140
- $listingPrice={makeOfferModal$.state.offerPrice}
141
- checkBalance={{
142
- enabled: true,
143
- callback: (state) => setInsufficientBalance(state),
144
- }}
145
- />
146
-
147
- {collectionType === ContractType.ERC1155 && (
148
- <QuantityInput
149
- chainId={chainId}
150
- $quantity={makeOfferModal$.state.quantity}
151
+ const handleStepExecution = async (execute?: any) => {
152
+ if (!execute) return;
153
+ try {
154
+ await refreshSteps();
155
+ await execute();
156
+ } catch (error) {
157
+ makeOfferModal$.callbacks?.onError?.(error as Error);
158
+ }
159
+ };
160
+
161
+ const ctas = [
162
+ {
163
+ label: 'Approve TOKEN',
164
+ onClick: () => handleStepExecution(() => steps?.approval.execute()),
165
+ hidden: !steps?.approval.isPending,
166
+ pending: steps?.approval.isExecuting,
167
+ variant: 'glass' as const,
168
+ },
169
+ {
170
+ label: 'Make offer',
171
+ onClick: () => handleStepExecution(() => steps?.transaction.execute()),
172
+ pending: steps?.transaction.isExecuting || isLoading,
173
+ disabled:
174
+ steps?.approval.isPending ||
175
+ offerPrice.amountRaw === '0' ||
176
+ insufficientBalance ||
177
+ isLoading,
178
+ },
179
+ ];
180
+
181
+ return (
182
+ <ActionModal
183
+ store={makeOfferModal$}
184
+ onClose={() => makeOfferModal$.close()}
185
+ title="Make an offer"
186
+ ctas={ctas}
187
+ >
188
+ <TokenPreview
189
+ collectionName={collection?.name}
151
190
  collectionAddress={collectionAddress}
152
191
  collectibleId={collectibleId}
192
+ chainId={chainId}
153
193
  />
154
- )}
155
194
 
156
- {!!offerPrice && (
157
- <FloorPriceText
158
- tokenId={collectibleId}
195
+ <PriceInput
159
196
  chainId={chainId}
160
197
  collectionAddress={collectionAddress}
161
- price={offerPrice}
198
+ $listingPrice={makeOfferModal$.offerPrice}
199
+ checkBalance={{
200
+ enabled: true,
201
+ callback: (state) => setInsufficientBalance(state),
202
+ }}
162
203
  />
163
- )}
164
204
 
165
- <ExpirationDateSelect $date={makeOfferModal$.state.expiry} />
166
- </ActionModal>
167
- );
168
- });
205
+ {collection?.type === ContractType.ERC1155 && (
206
+ <QuantityInput
207
+ chainId={chainId}
208
+ $quantity={makeOfferModal$.quantity}
209
+ collectionAddress={collectionAddress}
210
+ collectibleId={collectibleId}
211
+ />
212
+ )}
213
+
214
+ {!!offerPrice && (
215
+ <FloorPriceText
216
+ tokenId={collectibleId}
217
+ chainId={chainId}
218
+ collectionAddress={collectionAddress}
219
+ price={offerPrice}
220
+ />
221
+ )}
222
+
223
+ <ExpirationDateSelect $date={makeOfferModal$.expiry} />
224
+ </ActionModal>
225
+ );
226
+ },
227
+ );
@@ -1,276 +1,43 @@
1
- import { observable, when } from '@legendapp/state';
2
- import { useMount, useSelector } from '@legendapp/state/react';
3
- import type { QueryKey } from '@tanstack/react-query';
1
+ import { observable } from '@legendapp/state';
4
2
  import type { Hex } from 'viem';
5
- import { useAccount, useSendTransaction } from 'wagmi';
6
- import type { ShowSellModalArgs } from '.';
7
- import type {
8
- SellErrorCallbacks,
9
- SellSuccessCallbacks,
10
- } from '../../../../types/callbacks';
11
- import {
12
- MarketplaceKind,
13
- type Order,
14
- type Step,
15
- StepType,
16
- type WalletKind,
17
- balanceQueries,
18
- collectableKeys,
19
- } from '../../../_internal';
20
- import {
21
- useCollectible,
22
- useCurrencies,
23
- useGenerateSellTransaction,
24
- } from '../../../hooks';
25
- import { useTransactionStatusModal } from '../_internal/components/transactionStatusModal';
26
- import {
27
- getSellTransactionMessage,
28
- getSellTransactionTitle,
29
- } from './_utils/getSellTransactionTitleMessage';
3
+ import type { Order } from '../../../_internal';
4
+ import type { BaseModalState, ModalCallbacks } from '../_internal/types';
30
5
 
31
- export interface SellModalState {
32
- isOpen: boolean;
33
- open: (args: ShowSellModalArgs) => void;
34
- close: () => void;
35
- state: {
6
+ type SellModalState = BaseModalState & {
7
+ tokenId: string;
8
+ order?: Order;
9
+ };
10
+
11
+ const initialState: SellModalState & {
12
+ open: (args: {
36
13
  collectionAddress: Hex;
37
14
  chainId: string;
38
15
  tokenId: string;
39
- order: Order | undefined;
40
- errorCallbacks?: SellErrorCallbacks;
41
- successCallbacks?: SellSuccessCallbacks;
42
- };
43
- steps: {
44
- isLoading: () => boolean;
45
- stepsData: Step[] | undefined;
46
- _currentStep: null | 'tokenApproval' | 'sell';
47
- tokenApproval: {
48
- isNeeded: () => boolean;
49
- pending: boolean;
50
- getStep: () => Step | undefined;
51
- execute: () => void;
52
- };
53
- sell: {
54
- pending: boolean;
55
- execute: () => void;
56
- };
57
- };
58
- hash: Hex | undefined;
59
- }
60
-
61
- export const initialState: SellModalState = {
16
+ order: Order;
17
+ callbacks?: ModalCallbacks;
18
+ }) => void;
19
+ close: () => void;
20
+ } = {
62
21
  isOpen: false,
63
- open: ({ collectionAddress, chainId, tokenId, order }: ShowSellModalArgs) => {
64
- sellModal$.state.set({
65
- ...sellModal$.state.get(),
66
- collectionAddress,
67
- chainId,
68
- tokenId,
69
- order,
70
- });
22
+ collectionAddress: '' as Hex,
23
+ chainId: '',
24
+ tokenId: '',
25
+ order: undefined,
26
+ callbacks: undefined,
27
+
28
+ open: (args) => {
29
+ sellModal$.collectionAddress.set(args.collectionAddress);
30
+ sellModal$.chainId.set(args.chainId);
31
+ sellModal$.tokenId.set(args.tokenId);
32
+ sellModal$.order.set(args.order);
33
+ sellModal$.callbacks.set(args.callbacks);
71
34
  sellModal$.isOpen.set(true);
72
35
  },
36
+
73
37
  close: () => {
74
38
  sellModal$.isOpen.set(false);
75
- sellModal$.state.set({
76
- ...initialState.state,
77
- });
78
- },
79
- state: {
80
- collectionAddress: '' as Hex,
81
- chainId: '',
82
- tokenId: '',
83
- order: undefined,
39
+ sellModal$.callbacks.set(undefined);
84
40
  },
85
- steps: {
86
- isLoading: () => !!sellModal$.steps.stepsData.get(),
87
- stepsData: undefined,
88
- _currentStep: null,
89
- tokenApproval: {} as SellModalState['steps']['tokenApproval'],
90
- sell: {} as SellModalState['steps']['sell'],
91
- },
92
- hash: undefined,
93
41
  };
94
42
 
95
43
  export const sellModal$ = observable(initialState);
96
-
97
- export const useHydrate = () => {
98
- const chainId = useSelector(sellModal$.state.chainId);
99
-
100
- const collectionAddress = useSelector(sellModal$.state.collectionAddress);
101
-
102
- const order = useSelector(sellModal$.state.order);
103
-
104
- useTokenApprovalHandler(chainId);
105
- useSellHandler(chainId);
106
-
107
- const { generateSellTransactionAsync } = useGenerateSellTransaction({
108
- chainId,
109
- });
110
-
111
- const { connector, address } = useAccount();
112
-
113
- useMount(() => {
114
- const setSteps = async () => {
115
- const sellTransactionData = await generateSellTransactionAsync({
116
- walletType: connector?.walletType as WalletKind,
117
- collectionAddress: collectionAddress,
118
- seller: address as string,
119
- marketplace: MarketplaceKind.sequence_marketplace_v1,
120
- ordersData: [
121
- {
122
- ...order!,
123
- orderId: order!.orderId,
124
- quantity: '1',
125
- },
126
- ],
127
- additionalFees: [],
128
- });
129
- sellModal$.steps.stepsData.set(sellTransactionData);
130
- };
131
-
132
- when(() => !!order && !!connector, setSteps);
133
- });
134
- };
135
-
136
- const useTokenApprovalHandler = (chainId: string) => {
137
- const { sendTransactionAsync, isPending } = useSendTransaction();
138
- const onError = sellModal$.state.get().errorCallbacks?.onApproveTokenError;
139
- const onSuccess: (() => void) | undefined =
140
- sellModal$.state.get().successCallbacks?.onApproveTokenSuccess;
141
-
142
- sellModal$.steps.tokenApproval.set({
143
- isNeeded: () => !!sellModal$.steps.tokenApproval.getStep(),
144
- getStep: () =>
145
- sellModal$.steps.stepsData
146
- ?.get()
147
- ?.find((s) => s.id === StepType.tokenApproval),
148
- pending:
149
- sellModal$.steps._currentStep.get() === 'tokenApproval' && isPending,
150
- execute: async () => {
151
- const step = sellModal$.steps.tokenApproval.getStep();
152
- if (!step) return;
153
- sellModal$.steps._currentStep.set('tokenApproval');
154
-
155
- try {
156
- await sendTransactionAsync({
157
- to: step.to as Hex,
158
- chainId: Number(chainId),
159
- data: step.data as Hex,
160
- value: BigInt(step.value || '0'),
161
- });
162
-
163
- sellModal$.steps._currentStep.set(null);
164
-
165
- onSuccess && onSuccess();
166
- } catch (error) {
167
- onError && onError(error);
168
- }
169
- },
170
- });
171
- };
172
-
173
- const useSellHandler = (chainId: string) => {
174
- const { tokenId, collectionAddress, errorCallbacks, successCallbacks } =
175
- sellModal$.state.get();
176
- const { address } = useAccount();
177
- const {
178
- generateSellTransactionAsync,
179
- isPending: generateSellTransactionPending,
180
- } = useGenerateSellTransaction({
181
- chainId,
182
- });
183
- const { data: collectible } = useCollectible({
184
- chainId,
185
- collectibleId: tokenId,
186
- collectionAddress,
187
- });
188
- const { data: currencies } = useCurrencies({ chainId });
189
-
190
- const { sendTransactionAsync, isPending: sendTransactionPending } =
191
- useSendTransaction();
192
- const { show: showTransactionStatusModal } = useTransactionStatusModal();
193
-
194
- function setSellStep() {
195
- sellModal$.steps.sell.set({
196
- pending:
197
- sellModal$.steps._currentStep.get() === 'sell' &&
198
- (generateSellTransactionPending || sendTransactionPending),
199
- execute: () => {
200
- sellModal$.steps._currentStep.set('sell');
201
- const { collectionAddress, order } = sellModal$.state.get();
202
-
203
- generateSellTransactionAsync({
204
- collectionAddress: collectionAddress,
205
- seller: address as string,
206
- marketplace: order!.marketplace,
207
- ordersData: [
208
- {
209
- ...order!,
210
- quantity: '1',
211
- },
212
- ],
213
- additionalFees: order?.feeBreakdown
214
- ? [
215
- {
216
- amount: String(order!.feeBps),
217
- receiver: order!.feeBreakdown?.[0]?.recipientAddress,
218
- },
219
- ]
220
- : [],
221
- })
222
- .then(async (response) => {
223
- const step = response.find((s) => s.id === StepType.sell);
224
- if (!step) throw new Error('No steps found');
225
- try {
226
- const hash = await sendTransactionAsync({
227
- to: step.to as Hex,
228
- chainId: Number(chainId),
229
- data: step.data as Hex,
230
- value: BigInt(step.value || '0'),
231
- });
232
-
233
- sellModal$.hash.set(hash);
234
-
235
- sellModal$.steps._currentStep.set(null);
236
-
237
- sellModal$.close();
238
-
239
- showTransactionStatusModal({
240
- hash: hash!,
241
- price: {
242
- amountRaw: order!.priceAmount,
243
- currency: currencies!.find(
244
- (currency) =>
245
- currency.contractAddress === order!.priceCurrencyAddress,
246
- )!,
247
- },
248
- collectionAddress,
249
- chainId,
250
- tokenId,
251
- getTitle: getSellTransactionTitle,
252
- getMessage: (params) =>
253
- getSellTransactionMessage(params, collectible?.name || ''),
254
- type: StepType.sell,
255
- callbacks: {
256
- onSuccess: successCallbacks?.onSellSuccess,
257
- onUnknownError: errorCallbacks?.onSellError,
258
- },
259
- queriesToInvalidate: [
260
- ...collectableKeys.all,
261
- balanceQueries.all,
262
- ] as unknown as QueryKey[],
263
- });
264
- } catch (error) {
265
- errorCallbacks?.onSellError?.(error);
266
- }
267
- })
268
- .catch((error) => {
269
- errorCallbacks?.onSellError?.(error);
270
- });
271
- },
272
- });
273
- }
274
-
275
- when(currencies && collectible, setSellStep);
276
- };