@0xsequence/marketplace-sdk 0.0.1 → 0.1.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 (93) hide show
  1. package/dist/chunk-7CL54NCX.js +41 -0
  2. package/dist/chunk-7CL54NCX.js.map +1 -0
  3. package/dist/{chunk-G3D572BT.js → chunk-G3YU4NQ2.js} +24 -1
  4. package/dist/chunk-G3YU4NQ2.js.map +1 -0
  5. package/dist/{chunk-SM7V6ZWI.js → chunk-GNB736ZE.js} +226 -208
  6. package/dist/chunk-GNB736ZE.js.map +1 -0
  7. package/dist/chunk-ITJEOCDV.js +1006 -0
  8. package/dist/chunk-ITJEOCDV.js.map +1 -0
  9. package/dist/{chunk-QOJXWHRZ.js → chunk-LFQB477Y.js} +3 -1
  10. package/dist/chunk-LFQB477Y.js.map +1 -0
  11. package/dist/{chunk-VPGWEMWL.js → chunk-M4MXVMAM.js} +134 -25
  12. package/dist/chunk-M4MXVMAM.js.map +1 -0
  13. package/dist/{chunk-4PFMUVE4.js → chunk-SNOEEUPZ.js} +2 -2
  14. package/dist/{create-config-Dz0gCiQ0.d.ts → create-config-Cto2ehcz.d.ts} +1 -1
  15. package/dist/index.css +4 -1
  16. package/dist/index.d.ts +3 -2
  17. package/dist/index.js +1 -1
  18. package/dist/{marketplace-config-DZbtyrma.d.ts → marketplace-config-Bbxl-uKX.d.ts} +2 -1
  19. package/dist/react/_internal/index.d.ts +4 -3
  20. package/dist/react/_internal/index.js +9 -1
  21. package/dist/react/_internal/wagmi/index.d.ts +2 -2
  22. package/dist/react/hooks/index.d.ts +1363 -101
  23. package/dist/react/hooks/index.js +13 -7
  24. package/dist/react/index.css +4 -1
  25. package/dist/react/index.css.map +1 -1
  26. package/dist/react/index.d.ts +6 -5
  27. package/dist/react/index.js +28 -22
  28. package/dist/react/ssr/index.d.ts +2 -1
  29. package/dist/react/ssr/index.js +23 -0
  30. package/dist/react/ssr/index.js.map +1 -1
  31. package/dist/react/ui/index.css +4 -1
  32. package/dist/react/ui/index.css.map +1 -1
  33. package/dist/react/ui/index.d.ts +4 -4
  34. package/dist/react/ui/index.js +5 -5
  35. package/dist/react/ui/modals/_internal/components/actionModal/index.js +2 -2
  36. package/dist/styles/index.css +4 -1
  37. package/dist/styles/index.css.map +1 -1
  38. package/dist/styles/index.d.ts +2 -1
  39. package/dist/styles/index.js +3 -4972
  40. package/dist/styles/index.js.map +1 -1
  41. package/dist/types/index.d.ts +2 -1
  42. package/dist/types/index.js +1 -1
  43. package/dist/types-BzZVURNL.d.ts +19 -0
  44. package/dist/utils/index.d.ts +2 -1
  45. package/dist/utils/index.js +1 -1
  46. package/package.json +3 -2
  47. package/src/react/_internal/api/zod-schema.ts +636 -0
  48. package/src/react/_internal/types.ts +32 -8
  49. package/src/react/hooks/index.ts +1 -0
  50. package/src/react/hooks/useBalanceOfCollectible.tsx +43 -18
  51. package/src/react/hooks/useCollectible.tsx +17 -11
  52. package/src/react/hooks/useCollection.tsx +35 -29
  53. package/src/react/hooks/useCountOfCollectables.tsx +77 -0
  54. package/src/react/hooks/useCurrencies.tsx +23 -12
  55. package/src/react/hooks/useFilters.tsx +15 -9
  56. package/src/react/hooks/useFloorOrder.tsx +23 -8
  57. package/src/react/hooks/useGenerateSellTransaction.tsx +16 -9
  58. package/src/react/hooks/useHighestOffer.tsx +23 -13
  59. package/src/react/hooks/useListBalances.tsx +57 -26
  60. package/src/react/hooks/useListCollectibles.tsx +25 -12
  61. package/src/react/hooks/useListOffersForCollectible.tsx +13 -5
  62. package/src/react/hooks/useLowestListing.tsx +23 -14
  63. package/src/react/hooks/useRoyaltyPercentage.tsx +18 -8
  64. package/src/react/hooks/useTransferTokens.tsx +3 -3
  65. package/src/react/ui/modals/CreateListingModal/_store.ts +5 -5
  66. package/src/react/ui/modals/CreateListingModal/index.tsx +5 -4
  67. package/src/react/ui/modals/MakeOfferModal/_store.ts +6 -9
  68. package/src/react/ui/modals/MakeOfferModal/index.tsx +15 -25
  69. package/src/react/ui/modals/SellModal/_store.ts +28 -23
  70. package/src/react/ui/modals/SellModal/index.tsx +11 -10
  71. package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +8 -7
  72. package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +2 -1
  73. package/src/react/ui/modals/_internal/components/floorPriceText/index.tsx +3 -2
  74. package/src/react/ui/modals/_internal/components/priceInput/index.tsx +55 -12
  75. package/src/react/ui/modals/_internal/components/priceInput/styles.css.ts +4 -0
  76. package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +2 -1
  77. package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +2 -1
  78. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
  79. package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +4 -4
  80. package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +14 -14
  81. package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +5 -5
  82. package/src/types/marketplace-config.ts +2 -1
  83. package/dist/chunk-G3D572BT.js.map +0 -1
  84. package/dist/chunk-QOJXWHRZ.js.map +0 -1
  85. package/dist/chunk-SM7V6ZWI.js.map +0 -1
  86. package/dist/chunk-STO74F2I.js +0 -14
  87. package/dist/chunk-STO74F2I.js.map +0 -1
  88. package/dist/chunk-VPGWEMWL.js.map +0 -1
  89. package/dist/chunk-ZE2LNX65.js +0 -394
  90. package/dist/chunk-ZE2LNX65.js.map +0 -1
  91. package/dist/types-BrAQ8-w4.d.ts +0 -12
  92. package/src/react/hooks/useCollectionCounts.tsx +0 -61
  93. /package/dist/{chunk-4PFMUVE4.js.map → chunk-SNOEEUPZ.js.map} +0 -0
@@ -1,56 +1,87 @@
1
- import type { MetadataOptions, Page } from '@0xsequence/indexer';
1
+ import { type Page, SortOrder } from '@0xsequence/indexer';
2
2
  import {
3
- type ChainId,
4
- type QueryArg,
3
+ AddressSchema,
4
+ ChainIdSchema,
5
+ QueryArgSchema,
5
6
  balanceQueries,
6
7
  getIndexerClient,
7
8
  } from '@internal';
8
9
  import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/react-query';
9
10
  import type { SdkConfig } from '@types';
11
+ import { z } from 'zod';
10
12
  import { useConfig } from './useConfig';
11
13
 
12
- export type UseTokenBalancesArgs = {
13
- chainId: ChainId;
14
- accountAddress?: string;
15
- contractAddress?: string;
16
- tokenId?: string;
17
- includeMetadata?: boolean;
18
- metadataOptions?: MetadataOptions;
19
- includeCollectionTokens?: boolean;
20
- page?: Page;
21
- } & QueryArg;
22
-
23
- export type UseFetchTokenBalancesReturn = ReturnType<typeof fetchTokenBalances>;
24
-
25
- const fetchTokenBalances = async (
26
- args: UseTokenBalancesArgs,
14
+ export const metadataOptionsSchema = z.object({
15
+ verifiedOnly: z.boolean().optional(),
16
+ unverifiedOnly: z.boolean().optional(),
17
+ includeContracts: z.array(z.string()).optional(),
18
+ });
19
+
20
+ const sortOrderSchema = z.nativeEnum(SortOrder);
21
+
22
+ const sortBySchema = z.object({
23
+ column: z.string(),
24
+ order: sortOrderSchema,
25
+ });
26
+
27
+ const pageSchema = z.object({
28
+ page: z.number().optional(),
29
+ column: z.string().optional(),
30
+ before: z.any().optional(),
31
+ after: z.any().optional(),
32
+ sort: z.array(sortBySchema).optional(),
33
+ pageSize: z.number().optional(),
34
+ more: z.boolean().optional(),
35
+ });
36
+
37
+ const useListBalancesArgsSchema = z.object({
38
+ chainId: ChainIdSchema.pipe(z.coerce.number()),
39
+ accountAddress: AddressSchema.optional(),
40
+ contractAddress: AddressSchema.optional(),
41
+ tokenId: z.string().optional(),
42
+ includeMetadata: z.boolean().optional(),
43
+ metadataOptions: metadataOptionsSchema.optional(),
44
+ includeCollectionTokens: z.boolean().optional(),
45
+ page: pageSchema.optional(),
46
+ query: QueryArgSchema,
47
+ });
48
+
49
+ export type UseFetchTokenBalancesReturn = Awaited<
50
+ ReturnType<typeof fetchBalances>
51
+ >;
52
+
53
+ export type UseListBalancesArgs = z.input<typeof useListBalancesArgsSchema>;
54
+
55
+ const fetchBalances = async (
56
+ args: UseListBalancesArgs,
27
57
  page: Page,
28
58
  config: SdkConfig,
29
59
  ) => {
30
- const indexerClient = getIndexerClient(args.chainId, config);
60
+ const parsedArgs = useListBalancesArgsSchema.parse(args);
61
+ const indexerClient = getIndexerClient(parsedArgs.chainId, config);
31
62
 
32
63
  return indexerClient.getTokenBalances({
33
- ...args,
34
- tokenID: args.tokenId,
64
+ ...parsedArgs,
65
+ tokenID: parsedArgs.tokenId,
35
66
  page: page,
36
67
  });
37
68
  };
38
69
 
39
- export const tokenBalancesOptions = (
40
- args: UseTokenBalancesArgs,
70
+ export const listBalancesOptions = (
71
+ args: UseListBalancesArgs,
41
72
  config: SdkConfig,
42
73
  ) => {
43
74
  return infiniteQueryOptions({
44
75
  ...args.query,
45
76
  queryKey: [...balanceQueries.lists, args, config],
46
77
  queryFn: ({ pageParam }: { pageParam: Page }) =>
47
- fetchTokenBalances(args, pageParam, config),
78
+ fetchBalances(args, pageParam, config),
48
79
  initialPageParam: { page: 1, pageSize: 30 } as Page,
49
80
  getNextPageParam: (lastPage) => lastPage.page.after,
50
81
  });
51
82
  };
52
83
 
53
- export const useTokenBalances = (args: UseTokenBalancesArgs) => {
84
+ export const useListBalances = (args: UseListBalancesArgs) => {
54
85
  const config = useConfig();
55
- return useInfiniteQuery(tokenBalancesOptions(args, config));
86
+ return useInfiniteQuery(listBalancesOptions(args, config));
56
87
  };
@@ -1,32 +1,45 @@
1
1
  import {
2
- type ChainId,
2
+ AddressSchema,
3
+ ChainIdSchema,
3
4
  type ListCollectiblesArgs,
4
5
  type Page,
6
+ QueryArgSchema,
5
7
  collectableKeys,
6
8
  getMarketplaceClient,
7
9
  } from '@internal';
8
10
  import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/react-query';
9
11
  import type { SdkConfig } from '@types';
12
+ import { z } from 'zod';
13
+ import { listCollectiblesArgsSchema } from '../_internal/api/zod-schema';
10
14
  import { useConfig } from './useConfig';
11
15
 
12
- export type UseListCollectiblesArgs = Omit<
13
- ListCollectiblesArgs,
14
- 'contractAddress'
15
- > & {
16
- collectionAddress: string;
17
- chainId: ChainId;
18
- };
16
+ const UseListCollectiblesArgsSchema = listCollectiblesArgsSchema
17
+ .omit({
18
+ contractAddress: true,
19
+ })
20
+ .extend({
21
+ collectionAddress: AddressSchema,
22
+ chainId: ChainIdSchema.pipe(z.coerce.string()),
23
+ query: QueryArgSchema,
24
+ });
25
+
26
+ export type UseListCollectiblesArgs = z.infer<
27
+ typeof UseListCollectiblesArgsSchema
28
+ >;
19
29
 
20
- export type UseListCollectiblesReturn = ReturnType<typeof fetchCollectibles>;
30
+ export type UseListCollectiblesReturn = Awaited<
31
+ ReturnType<typeof fetchCollectibles>
32
+ >;
21
33
 
22
34
  const fetchCollectibles = async (
23
35
  args: UseListCollectiblesArgs,
24
36
  page: Page,
25
- marketplaceClient: ReturnType<typeof getMarketplaceClient>,
37
+ marketplaceClient: Awaited<ReturnType<typeof getMarketplaceClient>>,
26
38
  ) => {
39
+ const parsedArgs = UseListCollectiblesArgsSchema.parse(args);
27
40
  const arg = {
28
- ...args,
29
- contractAddress: args.collectionAddress,
41
+ ...parsedArgs,
42
+ contractAddress: parsedArgs.collectionAddress,
30
43
  page,
31
44
  } satisfies ListCollectiblesArgs;
32
45
 
@@ -1,18 +1,26 @@
1
1
  import {
2
+ ChainIdSchema,
2
3
  type ListOffersForCollectibleArgs,
3
4
  collectableKeys,
4
5
  getMarketplaceClient,
5
6
  } from '@internal';
6
7
  import { infiniteQueryOptions, useInfiniteQuery } from '@tanstack/react-query';
7
8
  import type { Page, SdkConfig } from '@types';
9
+ import { z } from 'zod';
10
+ import { listOffersForCollectibleArgsSchema } from '../_internal/api/zod-schema';
8
11
  import { useConfig } from './useConfig';
9
12
 
10
- export type UseListOffersForCollectibleArgs = ListOffersForCollectibleArgs & {
11
- chainId: string;
12
- };
13
+ const UseListOffersForCollectibleArgsSchema =
14
+ listOffersForCollectibleArgsSchema.extend({
15
+ chainId: ChainIdSchema.pipe(z.coerce.string()),
16
+ });
17
+
18
+ type UseListOffersForCollectibleArgs = z.infer<
19
+ typeof UseListOffersForCollectibleArgsSchema
20
+ >;
13
21
 
14
- export type UseListOffersForCollectible = ReturnType<
15
- typeof fetchListOffersForCollectible
22
+ export type UseListOffersForCollectibleReturn = Awaited<
23
+ ReturnType<typeof fetchListOffersForCollectible>
16
24
  >;
17
25
 
18
26
  const fetchListOffersForCollectible = async (
@@ -1,32 +1,41 @@
1
1
  import {
2
- type ChainId,
3
- type GetCollectibleLowestListingArgs,
4
- type QueryArg,
2
+ AddressSchema,
3
+ ChainIdSchema,
4
+ QueryArgSchema,
5
5
  collectableKeys,
6
6
  getMarketplaceClient,
7
7
  } from '@internal';
8
8
  import { queryOptions, useQuery } from '@tanstack/react-query';
9
9
  import type { SdkConfig } from '@types';
10
+ import { z } from 'zod';
11
+ import { getCollectibleLowestListingArgsSchema } from '../_internal/api/zod-schema';
10
12
  import { useConfig } from './useConfig';
11
13
 
12
- export type UseLowestListingArgs = Omit<
13
- GetCollectibleLowestListingArgs,
14
- 'contractAddress'
15
- > & {
16
- collectionAddress: string;
17
- chainId: ChainId;
18
- } & QueryArg;
14
+ const UseLowestListingSchema = getCollectibleLowestListingArgsSchema
15
+ .omit({
16
+ contractAddress: true,
17
+ })
18
+ .extend({
19
+ collectionAddress: AddressSchema,
20
+ chainId: ChainIdSchema.pipe(z.coerce.string()),
21
+ query: QueryArgSchema,
22
+ });
23
+
24
+ export type UseLowestListingArgs = z.infer<typeof UseLowestListingSchema>;
19
25
 
20
- export type UseLowestListingReturn = ReturnType<typeof fetchLowestListing>;
26
+ export type UseLowestListingReturn = Awaited<
27
+ ReturnType<typeof fetchLowestListing>
28
+ >;
21
29
 
22
30
  const fetchLowestListing = async (
23
31
  args: UseLowestListingArgs,
24
32
  config: SdkConfig,
25
33
  ) => {
26
- const marketplaceClient = getMarketplaceClient(args.chainId, config);
34
+ const parsedArgs = UseLowestListingSchema.parse(args);
35
+ const marketplaceClient = getMarketplaceClient(parsedArgs.chainId, config);
27
36
  return marketplaceClient.getCollectibleLowestListing({
28
- ...args,
29
- contractAddress: args.collectionAddress,
37
+ ...parsedArgs,
38
+ contractAddress: parsedArgs.collectionAddress,
30
39
  });
31
40
  };
32
41
 
@@ -1,21 +1,31 @@
1
- import { type ChainId, type QueryArg, collectableKeys } from '@internal';
1
+ import {
2
+ AddressSchema,
3
+ ChainIdSchema,
4
+ QueryArgSchema,
5
+ collectableKeys,
6
+ } from '@internal';
2
7
  import { queryOptions, useQuery } from '@tanstack/react-query';
3
8
  import type { Hex } from 'viem';
4
9
  import { getContract } from 'viem';
10
+ import { z } from 'zod';
5
11
  import { EIP2981_ABI } from '../../utils/abi/abi/standard/EIP2981';
6
12
  import { getPublicRpcClient } from '../../utils/get-public-rpc-client';
7
13
 
8
- type UseRoyaletyPercentageArgs = {
9
- chainId: ChainId;
10
- collectionAddress: string;
11
- collectibleId: string;
12
- } & QueryArg;
14
+ const UseRoyaletyPercentageSchema = z.object({
15
+ chainId: ChainIdSchema.pipe(z.coerce.string()),
16
+ collectionAddress: AddressSchema,
17
+ collectibleId: z.string(),
18
+ query: QueryArgSchema,
19
+ });
20
+
21
+ type UseRoyaletyPercentageArgs = z.infer<typeof UseRoyaletyPercentageSchema>;
13
22
 
14
23
  const fetchRoyaletyPercentage = async (args: UseRoyaletyPercentageArgs) => {
15
- const publicClient = getPublicRpcClient(args.chainId);
24
+ const parsedArgs = UseRoyaletyPercentageSchema.parse(args);
25
+ const publicClient = getPublicRpcClient(parsedArgs.chainId);
16
26
 
17
27
  const contract = getContract({
18
- address: args.collectionAddress as Hex,
28
+ address: parsedArgs.collectionAddress as Hex,
19
29
  abi: EIP2981_ABI,
20
30
  client: publicClient,
21
31
  });
@@ -1,7 +1,7 @@
1
- import type { ContractType, ChainId } from '@internal';
2
- import { ERC1155_ABI } from '../../utils';
3
- import { type Abi, erc721Abi, type Address, type Hex } from 'viem';
1
+ import type { ChainId, ContractType } from '@internal';
2
+ import { type Abi, type Address, type Hex, erc721Abi } from 'viem';
4
3
  import { useAccount, useWriteContract } from 'wagmi';
4
+ import { ERC1155_ABI } from '../../utils';
5
5
 
6
6
  interface BaseTransferParams {
7
7
  chainId: ChainId;
@@ -1,5 +1,7 @@
1
+ import type { CollectionType } from '@internal';
1
2
  import { observable, when } from '@legendapp/state';
2
3
  import { useMount, useSelector } from '@legendapp/state/react';
4
+ import { useCollectible } from '@react-hooks/useCollectible';
3
5
  import { useCollection } from '@react-hooks/useCollection';
4
6
  import { useGenerateListingTransaction } from '@react-hooks/useGenerateListingTransaction';
5
7
  import {
@@ -20,8 +22,6 @@ import {
20
22
  getCreateListingTransactionMessage,
21
23
  getCreateListingTransactionTitle,
22
24
  } from './_utils/getCreateListingTransactionTitleMessage';
23
- import { useCollectible } from '@react-hooks/useCollectible';
24
- import type { CollectionType } from '@internal';
25
25
 
26
26
  export interface CreateListingModalState {
27
27
  isOpen: boolean;
@@ -32,7 +32,7 @@ export interface CreateListingModalState {
32
32
  collectionType: CollectionType | undefined;
33
33
  listingPrice: Price;
34
34
  quantity: string;
35
- collectionAddress: string;
35
+ collectionAddress: Hex;
36
36
  chainId: string;
37
37
  collectibleId: string;
38
38
  expiry: Date;
@@ -85,7 +85,7 @@ export const initialState: CreateListingModalState = {
85
85
  quantity: '1',
86
86
  expiry: new Date(addDays(new Date(), 7).toJSON()),
87
87
  collectionType: undefined,
88
- collectionAddress: '',
88
+ collectionAddress: '' as Hex,
89
89
  chainId: '',
90
90
  collectibleId: '',
91
91
  },
@@ -225,7 +225,7 @@ const useCreateListingHandler = (chainId: string) => {
225
225
  onUnknownError,
226
226
  onSuccess,
227
227
  }: { onUnknownError?: Function; onSuccess?: Function } =
228
- createListingModal$.state.get().messages?.sellCollectible || {};
228
+ createListingModal$.state.get().messages?.createListing || {};
229
229
 
230
230
  const { sendTransactionAsync, isPending: sendTransactionPending } =
231
231
  useSendTransaction();
@@ -1,6 +1,9 @@
1
1
  import { Box } from '@0xsequence/design-system';
2
2
  import { ContractType } from '@internal';
3
3
  import { Show, observer } from '@legendapp/state/react';
4
+ import type { Hex } from 'viem';
5
+ import { useAccount } from 'wagmi';
6
+ import type { Messages } from '../../../../types/messages';
4
7
  import {
5
8
  ActionModal,
6
9
  type ActionModalProps,
@@ -9,15 +12,13 @@ import ExpirationDateSelect from '../_internal/components/expirationDateSelect';
9
12
  import FloorPriceText from '../_internal/components/floorPriceText';
10
13
  import PriceInput from '../_internal/components/priceInput';
11
14
  import QuantityInput from '../_internal/components/quantityInput';
15
+ import { useSwitchChainModal } from '../_internal/components/switchChainModal';
12
16
  import TokenPreview from '../_internal/components/tokenPreview';
13
17
  import TransactionDetails from '../_internal/components/transactionDetails';
14
18
  import { createListingModal$, useHydrate } from './_store';
15
- import { useAccount } from 'wagmi';
16
- import { useSwitchChainModal } from '../_internal/components/switchChainModal';
17
- import type { Messages } from '../../../../types/messages';
18
19
 
19
20
  export type ShowCreateListingModalArgs = {
20
- collectionAddress: string;
21
+ collectionAddress: Hex;
21
22
  chainId: string;
22
23
  collectibleId: string;
23
24
  messages?: Messages;
@@ -1,5 +1,7 @@
1
+ import type { CollectionType } from '@internal';
1
2
  import { observable, when } from '@legendapp/state';
2
3
  import { useMount, useSelector } from '@legendapp/state/react';
4
+ import { useCollectible } from '@react-hooks/useCollectible';
3
5
  import { useCollection } from '@react-hooks/useCollection';
4
6
  import { useGenerateOfferTransaction } from '@react-hooks/useGenerateOfferTransaction';
5
7
  import {
@@ -11,7 +13,7 @@ import {
11
13
  type WalletKind,
12
14
  } from '@types';
13
15
  import { addDays } from 'date-fns/addDays';
14
- import { parseUnits, type Hex } from 'viem';
16
+ import { type Hex } from 'viem';
15
17
  import { useAccount, useSendTransaction } from 'wagmi';
16
18
  import type { ShowMakeOfferModalArgs } from '.';
17
19
  import type { Messages } from '../../../../types/messages';
@@ -20,8 +22,6 @@ import {
20
22
  getMakeOfferTransactionMessage,
21
23
  getMakeOfferTransactionTitle,
22
24
  } from './_utils/getMakeOfferTransactionTitleMessage';
23
- import { useCollectible } from '@react-hooks/useCollectible';
24
- import type { CollectionType } from '@internal';
25
25
 
26
26
  export interface MakeOfferModalState {
27
27
  isOpen: boolean;
@@ -32,7 +32,7 @@ export interface MakeOfferModalState {
32
32
  collectionType: CollectionType | undefined;
33
33
  offerPrice: Price;
34
34
  quantity: string;
35
- collectionAddress: string;
35
+ collectionAddress: Hex;
36
36
  chainId: string;
37
37
  collectibleId: string;
38
38
  expiry: Date;
@@ -85,7 +85,7 @@ export const initialState: MakeOfferModalState = {
85
85
  quantity: '1',
86
86
  expiry: new Date(addDays(new Date(), 7).toJSON()),
87
87
  collectionType: undefined,
88
- collectionAddress: '',
88
+ collectionAddress: '' as Hex,
89
89
  chainId: '',
90
90
  collectibleId: '',
91
91
  },
@@ -248,10 +248,7 @@ const useCreateOfferHandler = (chainId: string) => {
248
248
  expiry: makeOfferModal$.state.expiry.get(),
249
249
  currencyAddress:
250
250
  makeOfferModal$.state.offerPrice.currency.contractAddress.get(),
251
- pricePerToken: parseUnits(
252
- makeOfferModal$.state.offerPrice.amountRaw.get(),
253
- makeOfferModal$.state.offerPrice.currency.decimals.get(),
254
- ).toString(),
251
+ pricePerToken: makeOfferModal$.state.offerPrice.amountRaw.get(),
255
252
  },
256
253
  })
257
254
  .then(async (steps) => {
@@ -1,7 +1,9 @@
1
1
  import { ContractType } from '@internal';
2
2
  import { Show, observer } from '@legendapp/state/react';
3
- import { type Hex, erc20Abi, parseUnits } from 'viem';
4
- import { useAccount, useReadContract } from 'wagmi';
3
+ import { useState } from 'react';
4
+ import type { Hex } from 'viem';
5
+ import { useAccount } from 'wagmi';
6
+ import type { Messages } from '../../../../types/messages';
5
7
  import {
6
8
  ActionModal,
7
9
  type ActionModalProps,
@@ -10,13 +12,12 @@ import ExpirationDateSelect from '../_internal/components/expirationDateSelect';
10
12
  import FloorPriceText from '../_internal/components/floorPriceText';
11
13
  import PriceInput from '../_internal/components/priceInput';
12
14
  import QuantityInput from '../_internal/components/quantityInput';
15
+ import { useSwitchChainModal } from '../_internal/components/switchChainModal';
13
16
  import TokenPreview from '../_internal/components/tokenPreview';
14
17
  import { makeOfferModal$, useHydrate } from './_store';
15
- import { useSwitchChainModal } from '../_internal/components/switchChainModal';
16
- import type { Messages } from '../../../../types/messages';
17
18
 
18
19
  export type ShowMakeOfferModalArgs = {
19
- collectionAddress: string;
20
+ collectionAddress: Hex;
20
21
  chainId: string;
21
22
  collectibleId: string;
22
23
  messages?: Messages;
@@ -65,6 +66,7 @@ const Modal = () => {
65
66
  };
66
67
 
67
68
  const ModalContent = observer(() => {
69
+ const [insufficientBalance, setInsufficientBalance] = useState(false);
68
70
  const {
69
71
  chainId,
70
72
  collectionAddress,
@@ -76,24 +78,6 @@ const ModalContent = observer(() => {
76
78
 
77
79
  const { steps } = makeOfferModal$.get();
78
80
 
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
81
  const ctas = [
98
82
  {
99
83
  label: 'Approve TOKEN',
@@ -106,7 +90,10 @@ const ModalContent = observer(() => {
106
90
  label: 'Make offer',
107
91
  onClick: steps.createOffer.execute,
108
92
  pending: steps.createOffer.pending,
109
- disabled: steps.tokenApproval.isNeeded() || offerPrice.amountRaw === '0',
93
+ disabled:
94
+ steps.tokenApproval.isNeeded() ||
95
+ offerPrice.amountRaw === '0' ||
96
+ insufficientBalance,
110
97
  },
111
98
  ] satisfies ActionModalProps['ctas'];
112
99
 
@@ -130,7 +117,10 @@ const ModalContent = observer(() => {
130
117
  chainId={chainId}
131
118
  collectionAddress={collectionAddress}
132
119
  $listingPrice={makeOfferModal$.state.offerPrice}
133
- error={balanceError}
120
+ checkBalance={{
121
+ enabled: true,
122
+ callback: (state) => setInsufficientBalance(state),
123
+ }}
134
124
  />
135
125
 
136
126
  {collectionType === ContractType.ERC1155 && (
@@ -1,15 +1,3 @@
1
- import { observable, when } from '@legendapp/state';
2
- import {
3
- MarketplaceKind,
4
- StepType,
5
- type Order,
6
- type Step,
7
- type WalletKind,
8
- } from '@types';
9
- import { useMount, useSelector } from '@legendapp/state/react';
10
- import { useGenerateSellTransaction } from '@react-hooks/useGenerateSellTransaction';
11
- import { useAccount, useSendTransaction } from 'wagmi';
12
- import type { Hex } from 'viem';
13
1
  import type { ShowSellModalArgs } from '.';
14
2
  import type { Messages } from '../../../../types/messages';
15
3
  import { useTransactionStatusModal } from '../_internal/components/transactionStatusModal';
@@ -17,15 +5,27 @@ import {
17
5
  getSellTransactionMessage,
18
6
  getSellTransactionTitle,
19
7
  } from './_utils/getSellTransactionTitleMessage';
8
+ import { observable, when } from '@legendapp/state';
9
+ import { useMount, useSelector } from '@legendapp/state/react';
20
10
  import { useCollectible } from '@react-hooks/useCollectible';
21
11
  import { useCurrencies } from '@react-hooks/useCurrencies';
12
+ import { useGenerateSellTransaction } from '@react-hooks/useGenerateSellTransaction';
13
+ import {
14
+ MarketplaceKind,
15
+ StepType,
16
+ type Order,
17
+ type Step,
18
+ type WalletKind,
19
+ } from '@types';
20
+ import type { Hex } from 'viem';
21
+ import { useAccount, useSendTransaction } from 'wagmi';
22
22
 
23
23
  export interface SellModalState {
24
24
  isOpen: boolean;
25
25
  open: (args: ShowSellModalArgs) => void;
26
26
  close: () => void;
27
27
  state: {
28
- collectionAddress: string;
28
+ collectionAddress: Hex;
29
29
  chainId: string;
30
30
  tokenId: string;
31
31
  order: Order | undefined;
@@ -75,7 +75,7 @@ export const initialState: SellModalState = {
75
75
  });
76
76
  },
77
77
  state: {
78
- collectionAddress: '',
78
+ collectionAddress: '' as Hex,
79
79
  chainId: '',
80
80
  tokenId: '',
81
81
  order: undefined,
@@ -124,7 +124,7 @@ export const useHydrate = () => {
124
124
  ],
125
125
  additionalFees: [],
126
126
  });
127
- sellModal$.steps.stepsData.set(sellTransactionData.steps);
127
+ sellModal$.steps.stepsData.set(sellTransactionData);
128
128
  };
129
129
 
130
130
  when(() => !!order && !!connector, setSteps);
@@ -204,6 +204,7 @@ const useSellHandler = (chainId: string) => {
204
204
  execute: () => {
205
205
  sellModal$.steps._currentStep.set('sell');
206
206
  const { collectionAddress, order } = sellModal$.state.get();
207
+
207
208
  generateSellTransactionAsync({
208
209
  collectionAddress: collectionAddress,
209
210
  seller: address as string,
@@ -214,15 +215,17 @@ const useSellHandler = (chainId: string) => {
214
215
  quantity: '1',
215
216
  },
216
217
  ],
217
- additionalFees: [
218
- {
219
- amount: String(order!.feeBps),
220
- receiver: order!.feeBreakdown[0].recipientAddress,
221
- },
222
- ],
218
+ additionalFees: order?.feeBreakdown
219
+ ? [
220
+ {
221
+ amount: String(order!.feeBps),
222
+ receiver: order!.feeBreakdown?.[0]?.recipientAddress,
223
+ },
224
+ ]
225
+ : [],
223
226
  })
224
227
  .then(async (response) => {
225
- const step = response.steps.find((s) => s.id === StepType.sell);
228
+ const step = response.find((s) => s.id === StepType.sell);
226
229
  if (!step) throw new Error('No steps found');
227
230
  try {
228
231
  const hash = await sendTransactionAsync({
@@ -257,7 +260,9 @@ const useSellHandler = (chainId: string) => {
257
260
  sellModal$.close();
258
261
 
259
262
  onSuccess && onSuccess();
260
- } catch (error) {}
263
+ } catch (error) {
264
+ onUnknownError && onUnknownError(error);
265
+ }
261
266
  })
262
267
  .catch((error) => {
263
268
  onUnknownError && onUnknownError(error);
@@ -1,22 +1,23 @@
1
+ import { Show, observer } from '@legendapp/state/react';
2
+ import { useCollection } from '@react-hooks/useCollection';
3
+ import { useCurrencies } from '@react-hooks/useCurrencies';
4
+ import type { Order, Price } from '@types';
5
+ import type { Hex } from 'viem';
6
+ import { useAccount } from 'wagmi';
7
+ import type { Messages } from '../../../../types/messages';
1
8
  import {
2
9
  ActionModal,
3
10
  type ActionModalProps,
4
11
  } from '../_internal/components/actionModal/ActionModal';
5
- import { sellModal$, useHydrate } from './_store';
6
- import { observer, Show } from '@legendapp/state/react';
7
- import { useCollection } from '@react-hooks/useCollection';
8
- import type { Order, Price } from '@types';
9
- import TransactionHeader from '../_internal/components/transactionHeader';
12
+ import { useSwitchChainModal } from '../_internal/components/switchChainModal';
10
13
  import TokenPreview from '../_internal/components/tokenPreview';
11
14
  import TransactionDetails from '../_internal/components/transactionDetails';
12
- import { useCurrencies } from '@react-hooks/useCurrencies';
13
- import { useAccount } from 'wagmi';
14
- import { useSwitchChainModal } from '../_internal/components/switchChainModal';
15
- import type { Messages } from '../../../../types/messages';
15
+ import TransactionHeader from '../_internal/components/transactionHeader';
16
+ import { sellModal$, useHydrate } from './_store';
16
17
 
17
18
  export type ShowSellModalArgs = {
18
19
  chainId: string;
19
- collectionAddress: string;
20
+ collectionAddress: Hex;
20
21
  tokenId: string;
21
22
  order: Order;
22
23
  collectibleName: string | undefined;