@0xsequence/marketplace-sdk 0.8.1 → 0.8.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 (75) hide show
  1. package/.changeset/flat-parks-clean.md +8 -0
  2. package/CHANGELOG.md +9 -0
  3. package/dist/{builder-types-QlHwc9bI.d.ts → builder-types-Wrqq6YoW.d.ts} +1 -1
  4. package/dist/{chunk-3JU7SQVE.js → chunk-4DFOSZTE.js} +60 -23
  5. package/dist/chunk-4DFOSZTE.js.map +1 -0
  6. package/dist/{chunk-Q5RKAMYF.js → chunk-BGY4WXER.js} +43 -1
  7. package/dist/chunk-BGY4WXER.js.map +1 -0
  8. package/dist/{chunk-X3QNSQER.js → chunk-F6CUGMI4.js} +44 -67
  9. package/dist/chunk-F6CUGMI4.js.map +1 -0
  10. package/dist/{chunk-A5ACY5YV.js → chunk-LDHGFXPJ.js} +2 -2
  11. package/dist/{chunk-BN36GABQ.js → chunk-S2UFNIYX.js} +82 -61
  12. package/dist/chunk-S2UFNIYX.js.map +1 -0
  13. package/dist/{chunk-BCO4CYE4.js → chunk-SJU6QZHM.js} +2 -2
  14. package/dist/{chunk-2VHHJNXY.js → chunk-WXKV5N4T.js} +3 -3
  15. package/dist/{chunk-ABSYNRT5.js → chunk-XOHAZXBZ.js} +3 -11
  16. package/dist/chunk-XOHAZXBZ.js.map +1 -0
  17. package/dist/{create-config-ClkUr27C.d.ts → create-config-B58hoCDv.d.ts} +1 -1
  18. package/dist/{index-CnaFSNE9.d.ts → index-PhhCRKUH.d.ts} +1 -1
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +10 -6
  21. package/dist/{listCollectibles-B0tbqnRd.d.ts → lowestListing-CuLxIWxy.d.ts} +49 -42
  22. package/dist/{marketplace.gen-BTHxxhG2.d.ts → marketplace.gen-De2-sxiG.d.ts} +1 -1
  23. package/dist/react/_internal/api/index.d.ts +2 -2
  24. package/dist/react/_internal/databeat/index.d.ts +1 -1
  25. package/dist/react/_internal/databeat/index.js +7 -7
  26. package/dist/react/_internal/index.d.ts +5 -5
  27. package/dist/react/_internal/wagmi/index.d.ts +3 -3
  28. package/dist/react/hooks/index.d.ts +8 -143
  29. package/dist/react/hooks/index.js +8 -10
  30. package/dist/react/hooks/options/index.d.ts +3 -3
  31. package/dist/react/index.d.ts +8 -8
  32. package/dist/react/index.js +12 -14
  33. package/dist/react/queries/index.d.ts +2 -2
  34. package/dist/react/queries/index.js +10 -27
  35. package/dist/react/queries/index.js.map +1 -1
  36. package/dist/react/ssr/index.d.ts +2 -2
  37. package/dist/react/ui/components/collectible-card/index.d.ts +1 -1
  38. package/dist/react/ui/components/collectible-card/index.js +10 -10
  39. package/dist/react/ui/icons/index.js +4 -4
  40. package/dist/react/ui/index.d.ts +1 -1
  41. package/dist/react/ui/index.js +10 -10
  42. package/dist/react/ui/modals/_internal/components/actionModal/index.js +7 -7
  43. package/dist/{services-ybGoDJd9.d.ts → services-BdzIAR9w.d.ts} +1 -1
  44. package/dist/types/index.d.ts +3 -3
  45. package/dist/{types-o_pKUpQG.d.ts → types-CmHOStH3.d.ts} +2 -2
  46. package/dist/utils/abi/index.js +5 -5
  47. package/dist/utils/index.d.ts +54 -2
  48. package/dist/utils/index.js +10 -6
  49. package/package.json +4 -2
  50. package/src/react/hooks/__tests__/useHighestOffer.test.tsx +7 -8
  51. package/src/react/hooks/__tests__/useLowestListing.test.tsx +4 -5
  52. package/src/react/hooks/useHighestOffer.tsx +1 -39
  53. package/src/react/hooks/useLowestListing.tsx +4 -51
  54. package/src/react/queries/highestOffer.ts +25 -30
  55. package/src/react/queries/index.ts +1 -0
  56. package/src/react/queries/lowestListing.ts +52 -0
  57. package/src/react/ui/modals/BuyModal/ERC1155QuantityModal.tsx +6 -9
  58. package/src/react/ui/modals/BuyModal/Modal.tsx +26 -8
  59. package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +6 -2
  60. package/src/react/ui/modals/MakeOfferModal/Modal.tsx +4 -4
  61. package/src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx +1 -5
  62. package/src/react/ui/modals/_internal/components/floorPriceText/index.tsx +4 -4
  63. package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/index.tsx +1 -1
  64. package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +18 -14
  65. package/src/types/api-types.ts +1 -1
  66. package/src/types/types.ts +5 -0
  67. package/src/utils/price.ts +103 -0
  68. package/dist/chunk-3JU7SQVE.js.map +0 -1
  69. package/dist/chunk-ABSYNRT5.js.map +0 -1
  70. package/dist/chunk-BN36GABQ.js.map +0 -1
  71. package/dist/chunk-Q5RKAMYF.js.map +0 -1
  72. package/dist/chunk-X3QNSQER.js.map +0 -1
  73. /package/dist/{chunk-A5ACY5YV.js.map → chunk-LDHGFXPJ.js.map} +0 -0
  74. /package/dist/{chunk-BCO4CYE4.js.map → chunk-SJU6QZHM.js.map} +0 -0
  75. /package/dist/{chunk-2VHHJNXY.js.map → chunk-WXKV5N4T.js.map} +0 -0
@@ -64,7 +64,7 @@ const SelectWaasFeeOptions = observer(
64
64
  >
65
65
  <Divider className="mt-0 mb-4" />
66
66
 
67
- <Text className="mb-2 font-body text-large" fontWeight="bold">
67
+ <Text className="mb-2 font-body font-bold text-large text-text-100">
68
68
  {feeOptionsConfirmed ? titleOnConfirm : 'Select a fee option'}
69
69
  </Text>
70
70
 
@@ -1,9 +1,10 @@
1
1
  'use client';
2
2
 
3
3
  import { Image, Skeleton, Text } from '@0xsequence/design-system';
4
- import { type Hex, formatUnits } from 'viem';
4
+ import type { Hex } from 'viem';
5
5
  import { DEFAULT_MARKETPLACE_FEE_PERCENTAGE } from '../../../../../../consts';
6
6
  import type { Price } from '../../../../../../types';
7
+ import { calculateEarningsAfterFees } from '../../../../../../utils/price';
7
8
  import { useMarketplaceConfig, useRoyalty } from '../../../../../hooks';
8
9
 
9
10
  type TransactionDetailsProps = {
@@ -42,21 +43,24 @@ export default function TransactionDetails({
42
43
 
43
44
  const priceLoading = !price || marketplaceConfigLoading || royaltyLoading;
44
45
 
45
- let formattedAmount =
46
- price && formatUnits(BigInt(price.amountRaw), price.currency.decimals);
46
+ let formattedAmount = '0';
47
47
 
48
- if (royalty !== null && formattedAmount && price) {
49
- formattedAmount = (
50
- Number.parseFloat(formattedAmount) -
51
- (Number.parseFloat(formattedAmount) * Number(royalty.percentage)) / 100
52
- ).toFixed(price.currency.decimals);
53
- }
48
+ if (price) {
49
+ const fees: number[] = [];
50
+
51
+ if (royalty !== null) {
52
+ fees.push(Number(royalty.percentage));
53
+ }
54
+
55
+ if (marketplaceFeePercentage > 0) {
56
+ fees.push(marketplaceFeePercentage);
57
+ }
54
58
 
55
- if (marketplaceFeePercentage !== undefined && formattedAmount && price) {
56
- formattedAmount = (
57
- Number.parseFloat(formattedAmount) -
58
- (Number.parseFloat(formattedAmount) * marketplaceFeePercentage) / 100
59
- ).toFixed(price.currency.decimals);
59
+ formattedAmount = calculateEarningsAfterFees(
60
+ BigInt(price.amountRaw),
61
+ price.currency.decimals,
62
+ fees,
63
+ );
60
64
  }
61
65
 
62
66
  return (
@@ -21,9 +21,9 @@ export type {
21
21
  Page,
22
22
  SortBy,
23
23
  Filter,
24
+ Order,
24
25
  PropertyFilter,
25
26
  CollectiblesFilter,
26
- Order,
27
27
  FeeBreakdown,
28
28
  CollectibleOrder,
29
29
  OrderFilter,
@@ -4,3 +4,8 @@ export type Price = {
4
4
  amountRaw: string;
5
5
  currency: Currency;
6
6
  };
7
+
8
+ // export type Order = Omit<APIOrder, 'priceAmount' | 'priceAmountNet'> & {
9
+ // priceAmount: bigint;
10
+ // priceAmountNet: bigint;
11
+ // };
@@ -1,3 +1,4 @@
1
+ import * as dn from 'dnum';
1
2
  import { formatUnits } from 'viem';
2
3
 
3
4
  type CalculatePriceDifferencePercentageArgs = {
@@ -6,6 +7,19 @@ type CalculatePriceDifferencePercentageArgs = {
6
7
  decimals: number;
7
8
  };
8
9
 
10
+ /**
11
+ * Calculates the percentage difference between two prices
12
+ * @param args - Object containing input price, base price, and decimals
13
+ * @returns The percentage difference as a string with 2 decimal places
14
+ * @example
15
+ * ```ts
16
+ * const diff = calculatePriceDifferencePercentage({
17
+ * inputPriceRaw: 1000000n,
18
+ * basePriceRaw: 900000n,
19
+ * decimals: 6
20
+ * }); // Returns "11.11"
21
+ * ```
22
+ */
9
23
  export const calculatePriceDifferencePercentage = ({
10
24
  inputPriceRaw,
11
25
  basePriceRaw,
@@ -19,6 +33,16 @@ export const calculatePriceDifferencePercentage = ({
19
33
  return percentageDifference.toFixed(2);
20
34
  };
21
35
 
36
+ /**
37
+ * Formats a raw price amount with the specified number of decimal places
38
+ * @param amount - The raw price amount as a bigint
39
+ * @param decimals - Number of decimal places to format to
40
+ * @returns Formatted price string with proper decimal and thousands separators
41
+ * @example
42
+ * ```ts
43
+ * const formatted = formatPrice(1000000n, 6); // Returns "1.000000"
44
+ * ```
45
+ */
22
46
  export const formatPrice = (amount: bigint, decimals: number): string => {
23
47
  const formattedUnits = Number(formatUnits(amount, decimals));
24
48
  return formattedUnits.toLocaleString('en-US', {
@@ -26,3 +50,82 @@ export const formatPrice = (amount: bigint, decimals: number): string => {
26
50
  maximumFractionDigits: decimals,
27
51
  });
28
52
  };
53
+
54
+ /**
55
+ * Calculates the final earnings amount after applying multiple fee percentages
56
+ * @param amount - The raw amount as a bigint (e.g., from a blockchain transaction)
57
+ * @param decimals - The number of decimal places for the currency (e.g., 18 for ETH, 6 for USDC)
58
+ * @param fees - Array of fee percentages to apply (e.g., [2.5, 1.0] for 2.5% and 1% fees)
59
+ * @returns Formatted string representing the final earnings after all fees are applied
60
+ * @throws Will return '0' if there's an error in calculation
61
+ * @example
62
+ * ```ts
63
+ * const earnings = calculateEarningsAfterFees(
64
+ * 1000000000000000000n, // 1 ETH
65
+ * 18, // ETH decimals
66
+ * [2.5, 1.0] // 2.5% and 1% fees
67
+ * ); // Returns "0.96525" (1 ETH after 2.5% and 1% fees)
68
+ * ```
69
+ */
70
+ export const calculateEarningsAfterFees = (
71
+ amount: bigint,
72
+ decimals: number,
73
+ fees: number[],
74
+ ): string => {
75
+ try {
76
+ const decimalAmount = Number(formatUnits(amount, decimals));
77
+ let earnings = dn.from(decimalAmount.toString(), decimals);
78
+
79
+ for (const fee of fees) {
80
+ if (fee > 0) {
81
+ const feeMultiplier = dn.from((1 - fee / 100).toString(), decimals);
82
+ earnings = dn.multiply(earnings, feeMultiplier);
83
+ }
84
+ }
85
+
86
+ return dn.format(earnings, {
87
+ digits: decimals,
88
+ trailingZeros: false,
89
+ locale: 'en-US',
90
+ });
91
+ } catch (error) {
92
+ console.error('Error calculating earnings after fees:', error);
93
+ return '0';
94
+ }
95
+ };
96
+
97
+ /**
98
+ * Formats a price amount with fee applied
99
+ * @param amount - The raw price amount as a bigint
100
+ * @param decimals - Number of decimal places for the currency
101
+ * @param feePercentage - Fee percentage to apply (e.g., 3.5 for 3.5%)
102
+ * @returns Formatted price string with fee applied and proper decimal/thousands separators
103
+ * @example
104
+ * ```ts
105
+ * const priceWithFee = formatPriceWithFee(1000000n, 6, 3.5); // Returns "1.035"
106
+ * ```
107
+ */
108
+ export const formatPriceWithFee = (
109
+ amount: bigint,
110
+ decimals: number,
111
+ feePercentage: number,
112
+ ): string => {
113
+ try {
114
+ const decimalAmount = Number(formatUnits(amount, decimals));
115
+ const price = dn.from(decimalAmount.toString(), decimals);
116
+ const feeMultiplier = dn.from(
117
+ (1 + feePercentage / 100).toString(),
118
+ decimals,
119
+ );
120
+ const totalPrice = dn.multiply(price, feeMultiplier);
121
+
122
+ return dn.format(totalPrice, {
123
+ digits: decimals,
124
+ trailingZeros: false,
125
+ locale: 'en-US',
126
+ });
127
+ } catch (error) {
128
+ console.error('Error formatting price with fee:', error);
129
+ return '0';
130
+ }
131
+ };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/queries/balanceOfCollectible.ts","../src/react/queries/highestOffer.ts","../src/react/queries/listBalances.ts","../src/react/queries/listCollectibles.ts"],"sourcesContent":["import { queryOptions, skipToken } from '@tanstack/react-query';\nimport type { Hex } from 'viem';\nimport type { UseQueryParameters } from 'wagmi/query';\nimport type { SdkConfig } from '../../types';\nimport { LaosAPI, collectableKeys, getIndexerClient } from '../_internal';\n\nexport type UseBalanceOfCollectibleArgs = {\n\tcollectionAddress: Hex;\n\tcollectableId: string;\n\tuserAddress: Hex | undefined;\n\tchainId: number;\n\tisLaos721?: boolean;\n\tquery?: UseQueryParameters;\n};\n\n/**\n * Fetches the balance of a specific collectible for a user\n *\n * @param args - Arguments for the API call\n * @param config - SDK configuration\n * @returns The balance data\n */\nexport async function fetchBalanceOfCollectible(\n\targs: Omit<UseBalanceOfCollectibleArgs, 'userAddress'> & { userAddress: Hex },\n\tconfig: SdkConfig,\n) {\n\tif (args.isLaos721) {\n\t\tconst laosApi = new LaosAPI();\n\t\tconst response = await laosApi.getTokenBalances({\n\t\t\tchainId: args.chainId.toString(),\n\t\t\taccountAddress: args.userAddress,\n\t\t\tincludeMetadata: true,\n\t\t});\n\n\t\treturn response.balances[0] || null;\n\t}\n\n\tconst indexerClient = getIndexerClient(args.chainId, config);\n\treturn indexerClient\n\t\t.getTokenBalances({\n\t\t\taccountAddress: args.userAddress,\n\t\t\tcontractAddress: args.collectionAddress,\n\t\t\ttokenID: args.collectableId,\n\t\t\tincludeMetadata: false,\n\t\t\tmetadataOptions: {\n\t\t\t\tverifiedOnly: true,\n\t\t\t\tincludeContracts: [args.collectionAddress],\n\t\t\t},\n\t\t})\n\t\t.then((res) => res.balances[0] || null);\n}\n\n/**\n * Creates a tanstack query options object for the balance query\n *\n * @param args - The query arguments\n * @param config - SDK configuration\n * @returns Query options configuration\n */\nexport function balanceOfCollectibleOptions(\n\targs: UseBalanceOfCollectibleArgs,\n\tconfig: SdkConfig,\n) {\n\tconst enabled = !!args.userAddress && (args.query?.enabled ?? true);\n\treturn queryOptions({\n\t\tqueryKey: [...collectableKeys.userBalances, args],\n\t\tqueryFn: enabled\n\t\t\t? () =>\n\t\t\t\t\tfetchBalanceOfCollectible(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...args,\n\t\t\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: this is guaranteed by the userAddress check above\n\t\t\t\t\t\t\tuserAddress: args.userAddress!,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t)\n\t\t\t: skipToken,\n\t});\n}\n","import { queryOptions } from '@tanstack/react-query';\nimport type { UseQueryParameters } from 'wagmi/query';\nimport type { Order as APIOrder, SdkConfig } from '../../types';\nimport { collectableKeys, getMarketplaceClient } from '../_internal';\n\nexport type UseHighestOfferArgs = {\n\tcollectionAddress: string;\n\ttokenId: string;\n\tchainId: number;\n\tquery?: UseQueryParameters;\n};\n\nexport type Order = Omit<APIOrder, 'priceAmount' | 'priceAmountNet'> & {\n\tpriceAmount: bigint;\n\tpriceAmountNet: bigint;\n};\n\n/**\n * Fetches the highest offer for a specific collectible\n *\n * @param args - Arguments for the API call\n * @param config - SDK configuration\n * @returns The highest offer data\n */\nexport async function fetchHighestOffer(\n\targs: UseHighestOfferArgs,\n\tconfig: SdkConfig,\n) {\n\tconst marketplaceClient = getMarketplaceClient(args.chainId, config);\n\n\tconst data = await marketplaceClient.getCollectibleHighestOffer({\n\t\tcontractAddress: args.collectionAddress,\n\t\ttokenId: args.tokenId,\n\t});\n\n\tlet order: Order | undefined;\n\tif (data.order) {\n\t\torder = {\n\t\t\t...data.order,\n\t\t\tpriceAmount: BigInt(data.order.priceAmount),\n\t\t\tpriceAmountNet: BigInt(data.order.priceAmountNet),\n\t\t};\n\t}\n\n\treturn order ?? null;\n}\n\n/**\n * Creates a tanstack query options object for the highest offer query\n *\n * @param args - The query arguments\n * @param config - SDK configuration\n * @returns Query options configuration\n */\nexport function highestOfferOptions(\n\targs: UseHighestOfferArgs,\n\tconfig: SdkConfig,\n) {\n\treturn queryOptions({\n\t\tqueryKey: [...collectableKeys.highestOffers, args],\n\t\tqueryFn: () => fetchHighestOffer(args, config),\n\t});\n}\n","import type { GetTokenBalancesReturn, Page } from '@0xsequence/indexer';\nimport { infiniteQueryOptions } from '@tanstack/react-query';\nimport type { Hex } from 'viem';\nimport type { SdkConfig } from '../../types';\nimport { balanceQueries, getIndexerClient } from '../_internal';\n\nexport type UseListBalancesArgs = {\n\tchainId: number;\n\taccountAddress?: Hex;\n\tcontractAddress?: Hex;\n\ttokenId?: string;\n\tincludeMetadata?: boolean;\n\tmetadataOptions?: {\n\t\tverifiedOnly?: boolean;\n\t\tunverifiedOnly?: boolean;\n\t\tincludeContracts?: Hex[];\n\t};\n\tincludeCollectionTokens?: boolean;\n\tpage?: Page;\n\tisLaos721?: boolean;\n\t//TODO: More options\n\tquery?: {\n\t\tenabled?: boolean;\n\t};\n};\n\n/**\n * Fetches a list of token balances with pagination support\n *\n * @param args - Arguments for the API call\n * @param config - SDK configuration\n * @param page - Page parameters for pagination\n * @returns The token balances data\n */\nexport async function fetchBalances(\n\targs: UseListBalancesArgs,\n\tconfig: SdkConfig,\n\tpage: Page,\n): Promise<GetTokenBalancesReturn> {\n\tif (args.isLaos721) {\n\t\tconst response = await fetch(\n\t\t\t'https://extensions.api.laosnetwork.io/token/GetTokenBalances',\n\t\t\t{\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tchainId: args.chainId.toString(),\n\t\t\t\t\taccountAddress: args.accountAddress,\n\t\t\t\t\tincludeMetadata: args.includeMetadata ?? true,\n\t\t\t\t\tpage: {\n\t\t\t\t\t\tsort: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcolumn: 'CREATED_AT',\n\t\t\t\t\t\t\t\torder: 'DESC',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Laos API request failed with status ${response.status}`);\n\t\t}\n\n\t\t// TODO: This is pretty unsafe, we should validate the response\n\t\treturn response.json() as Promise<GetTokenBalancesReturn>;\n\t}\n\n\tconst indexerClient = getIndexerClient(args.chainId, config);\n\treturn indexerClient.getTokenBalances({\n\t\t...args,\n\t\ttokenID: args.tokenId,\n\t\tpage: page,\n\t});\n}\n\n/**\n * Creates a tanstack infinite query options object for the balances query\n *\n * @param args - The query arguments\n * @param config - SDK configuration\n * @returns Query options configuration\n */\nexport function listBalancesOptions(\n\targs: UseListBalancesArgs,\n\tconfig: SdkConfig,\n) {\n\treturn infiniteQueryOptions({\n\t\t...args.query,\n\t\tqueryKey: [...balanceQueries.lists, args, config],\n\t\tqueryFn: ({ pageParam }) => fetchBalances(args, config, pageParam),\n\t\tinitialPageParam: { page: 1, pageSize: 30 } as Page,\n\t\tgetNextPageParam: (lastPage) => lastPage.page.after,\n\t});\n}\n","import { infiniteQueryOptions } from '@tanstack/react-query';\nimport type { Hex } from 'viem';\nimport type { Page, SdkConfig } from '../../types';\nimport type {\n\tCollectibleOrder,\n\tCollectiblesFilter,\n\tListCollectiblesArgs,\n\tListCollectiblesReturn,\n} from '../_internal';\nimport { OrderSide, collectableKeys, getMarketplaceClient } from '../_internal';\nimport { fetchBalances } from './listBalances';\nexport type UseListCollectiblesArgs = {\n\tcollectionAddress: Hex;\n\tchainId: number;\n\tside: OrderSide;\n\tfilter?: CollectiblesFilter;\n\tisLaos721?: boolean;\n\tquery?: {\n\t\tenabled?: boolean;\n\t};\n};\n\n/**\n * Fetches a list of collectibles with pagination support\n *\n * @param args - Arguments for the API call\n * @param config - SDK configuration\n * @param page - Page parameters for pagination\n * @returns The collectibles data\n */\nexport async function fetchCollectibles(\n\targs: UseListCollectiblesArgs,\n\tconfig: SdkConfig,\n\tpage: Page,\n): Promise<ListCollectiblesReturn> {\n\tconst marketplaceClient = getMarketplaceClient(args.chainId, config);\n\tconst parsedArgs = {\n\t\t...args,\n\t\tcontractAddress: args.collectionAddress,\n\t\tpage: page,\n\t\tside: args.side,\n\t} satisfies ListCollectiblesArgs;\n\n\tif (args.isLaos721 && args.side === OrderSide.listing) {\n\t\ttry {\n\t\t\tconst balances = await fetchBalances(args, config, page);\n\t\t\tconst collectibles: CollectibleOrder[] = balances.balances.map(\n\t\t\t\t(balance) => {\n\t\t\t\t\tif (!balance.tokenMetadata)\n\t\t\t\t\t\tthrow new Error('Token metadata not found');\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\ttokenId: balance.tokenID ?? '',\n\t\t\t\t\t\t\tattributes: balance.tokenMetadata.attributes,\n\t\t\t\t\t\t\timage: balance.tokenMetadata.image,\n\t\t\t\t\t\t\tname: balance.tokenMetadata.name,\n\t\t\t\t\t\t\tdescription: balance.tokenMetadata.description,\n\t\t\t\t\t\t\tvideo: balance.tokenMetadata.video,\n\t\t\t\t\t\t\taudio: balance.tokenMetadata.audio,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tcollectibles: collectibles,\n\t\t\t\t//@ts-expect-error\n\t\t\t\tpage: balances.page,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\t// If the request fails, ignore the error and return the collectibles from our indexer\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\treturn await marketplaceClient.listCollectibles(parsedArgs);\n}\n\n/**\n * Creates a tanstack infinite query options object for the collectibles query\n *\n * @param args - The query arguments\n * @param config - SDK configuration\n * @returns Query options configuration\n */\nexport function listCollectiblesOptions(\n\targs: UseListCollectiblesArgs,\n\tconfig: SdkConfig,\n) {\n\treturn infiniteQueryOptions({\n\t\t...args.query,\n\t\tqueryKey: [...collectableKeys.lists, args, config],\n\t\tqueryFn: ({ pageParam }) => fetchCollectibles(args, config, pageParam),\n\t\tinitialPageParam: { page: 1, pageSize: 30 } as Page,\n\t\tgetNextPageParam: (lastPage) =>\n\t\t\tlastPage.page?.more ? lastPage.page : undefined,\n\t});\n}\n"],"mappings":"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","names":["queryOptions","queryOptions","infiniteQueryOptions","infiniteQueryOptions"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/ui/modals/_internal/components/actionModal/ActionModal.tsx","../src/react/ui/modals/_internal/components/actionModal/store.ts"],"sourcesContent":["'use client';\n\nimport type React from 'react';\nimport type { ComponentProps } from 'react';\n\nimport { Button, Modal, Spinner, Text } from '@0xsequence/design-system';\nimport { observer } from '@legendapp/state/react';\nimport { useWallet } from '../../../../../_internal/wallet/useWallet';\nimport { MODAL_OVERLAY_PROPS } from '../consts';\nimport { MODAL_CONTENT_PROPS } from '../consts';\nimport { useSwitchChainModal } from '../switchChainModal';\n\nexport interface ActionModalProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\ttitle: string;\n\tchildren: React.ReactNode;\n\tctas: {\n\t\tlabel: React.ReactNode;\n\t\tonClick: (() => Promise<void>) | (() => void);\n\t\tpending?: boolean;\n\t\tdisabled?: boolean;\n\t\thidden?: boolean;\n\t\tvariant?: ComponentProps<typeof Button>['variant'];\n\t\ttestid?: string;\n\t}[];\n\tchainId: number;\n\tmodalLoading?: boolean;\n\tspinnerContainerClassname?: string;\n\tdisableAnimation?: boolean;\n\thideCtas?: boolean;\n}\n\nexport const ActionModal = observer(\n\t({\n\t\tisOpen,\n\t\tonClose,\n\t\ttitle,\n\t\tchildren,\n\t\tctas,\n\t\tchainId,\n\t\tdisableAnimation,\n\t\tmodalLoading,\n\t\tspinnerContainerClassname,\n\t\thideCtas,\n\t}: ActionModalProps) => {\n\t\tconst { show: showSwitchChainModal } = useSwitchChainModal();\n\t\tconst { wallet, isLoading, isError } = useWallet();\n\n\t\tconst checkChain = async ({ onSuccess }: { onSuccess: () => void }) => {\n\t\t\tconst walletChainId = await wallet?.getChainId();\n\t\t\tconst chainMismatch = walletChainId !== Number(chainId);\n\t\t\tif (chainMismatch) {\n\t\t\t\tshowSwitchChainModal({\n\t\t\t\t\tchainIdToSwitchTo: Number(chainId),\n\t\t\t\t\tonSuccess,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tonSuccess();\n\t\t\t}\n\t\t};\n\n\t\tif (wallet?.isWaaS) {\n\t\t\twallet.switchChain(Number(chainId));\n\t\t}\n\n\t\tif (!isOpen || !chainId) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<Modal\n\t\t\t\tisDismissible={true}\n\t\t\t\tonClose={onClose}\n\t\t\t\toverlayProps={MODAL_OVERLAY_PROPS}\n\t\t\t\tcontentProps={MODAL_CONTENT_PROPS}\n\t\t\t\tdisableAnimation={disableAnimation}\n\t\t\t>\n\t\t\t\t<div className=\"relative flex grow flex-col items-center gap-4 p-6\">\n\t\t\t\t\t<Text\n\t\t\t\t\t\tclassName=\"w-full text-center font-body text-large\"\n\t\t\t\t\t\tfontWeight=\"bold\"\n\t\t\t\t\t\tcolor=\"text100\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</Text>\n\n\t\t\t\t\t{modalLoading || isLoading || isError ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`flex ${spinnerContainerClassname} w-full items-center justify-center`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{isError && (\n\t\t\t\t\t\t\t\t<Text className=\"text-center font-body text-error100 text-small\">\n\t\t\t\t\t\t\t\t\tError loading modal\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{isLoading && <Spinner size=\"lg\" />}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\tchildren\n\t\t\t\t\t)}\n\n\t\t\t\t\t{!hideCtas && !isLoading && !isError && (\n\t\t\t\t\t\t<div className=\"flex w-full flex-col gap-2\">\n\t\t\t\t\t\t\t{ctas.map(\n\t\t\t\t\t\t\t\t(cta) =>\n\t\t\t\t\t\t\t\t\t!cta.hidden && (\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-full rounded-[12px] [&>div]:justify-center\"\n\t\t\t\t\t\t\t\t\t\t\tkey={cta.onClick.toString()}\n\t\t\t\t\t\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\t\t\t\t\t\tawait checkChain({\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcta.onClick();\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tvariant={cta.variant || 'primary'}\n\t\t\t\t\t\t\t\t\t\t\tpending={cta.pending}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={cta.disabled}\n\t\t\t\t\t\t\t\t\t\t\tsize=\"lg\"\n\t\t\t\t\t\t\t\t\t\t\tdata-testid={cta.testid}\n\t\t\t\t\t\t\t\t\t\t\tlabel={\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{cta.pending && <Spinner size=\"sm\" />}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t{cta.label}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</Modal>\n\t\t);\n\t},\n);\n","import { type Observable, observable } from '@legendapp/state';\nimport type { Address } from 'viem';\n\nexport interface ActionModalState {\n\tisOpen: boolean;\n\tchainId: number | null;\n\tcollectionAddress: Address | null;\n}\n\nexport function createActionModalStore() {\n\treturn observable<ActionModalState>({\n\t\tisOpen: false,\n\t\tchainId: null,\n\t\tcollectionAddress: null,\n\t});\n}\n\nexport function openModal(store: Observable<ActionModalState>) {\n\tstore.isOpen.set(true);\n}\n\nexport function closeModal(store: Observable<ActionModalState>) {\n\tstore.isOpen.set(false);\n}\n"],"mappings":";;;;;;;;AAKA,SAAS,QAAQ,OAAO,SAAS,YAAY;AAC7C,SAAS,gBAAgB;AAyEpB,cASC,YATD;AA9CE,IAAM,cAAc;AAAA,EAC1B,CAAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,MAAwB;AACvB,UAAM,EAAE,MAAM,qBAAqB,IAAI,oBAAoB;AAC3D,UAAM,EAAE,QAAQ,WAAW,QAAQ,IAAI,UAAU;AAEjD,UAAM,aAAa,OAAO,EAAE,UAAU,MAAiC;AACtE,YAAM,gBAAgB,MAAM,QAAQ,WAAW;AAC/C,YAAM,gBAAgB,kBAAkB,OAAO,OAAO;AACtD,UAAI,eAAe;AAClB,6BAAqB;AAAA,UACpB,mBAAmB,OAAO,OAAO;AAAA,UACjC;AAAA,QACD,CAAC;AAAA,MACF,OAAO;AACN,kBAAU;AAAA,MACX;AAAA,IACD;AAEA,QAAI,QAAQ,QAAQ;AACnB,aAAO,YAAY,OAAO,OAAO,CAAC;AAAA,IACnC;AAEA,QAAI,CAAC,UAAU,CAAC,SAAS;AACxB,aAAO;AAAA,IACR;AAEA,WACC;AAAA,MAAC;AAAA;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA,cAAc;AAAA,QACd,cAAc;AAAA,QACd;AAAA,QAEA,+BAAC,SAAI,WAAU,sDACd;AAAA;AAAA,YAAC;AAAA;AAAA,cACA,WAAU;AAAA,cACV,YAAW;AAAA,cACX,OAAM;AAAA,cAEL;AAAA;AAAA,UACF;AAAA,UAEC,gBAAgB,aAAa,UAC7B;AAAA,YAAC;AAAA;AAAA,cACA,WAAW,QAAQ,yBAAyB;AAAA,cAE3C;AAAA,2BACA,oBAAC,QAAK,WAAU,kDAAiD,iCAEjE;AAAA,gBAEA,aAAa,oBAAC,WAAQ,MAAK,MAAK;AAAA;AAAA;AAAA,UAClC,IAEA;AAAA,UAGA,CAAC,YAAY,CAAC,aAAa,CAAC,WAC5B,oBAAC,SAAI,WAAU,8BACb,eAAK;AAAA,YACL,CAAC,QACA,CAAC,IAAI,UACJ;AAAA,cAAC;AAAA;AAAA,gBACA,WAAU;AAAA,gBAEV,SAAS,YAAY;AACpB,wBAAM,WAAW;AAAA,oBAChB,WAAW,MAAM;AAChB,0BAAI,QAAQ;AAAA,oBACb;AAAA,kBACD,CAAC;AAAA,gBACF;AAAA,gBACA,SAAS,IAAI,WAAW;AAAA,gBACxB,SAAS,IAAI;AAAA,gBACb,UAAU,IAAI;AAAA,gBACd,MAAK;AAAA,gBACL,eAAa,IAAI;AAAA,gBACjB,OACC,qBAAC,SAAI,WAAU,0CACb;AAAA,sBAAI,WAAW,oBAAC,WAAQ,MAAK,MAAK;AAAA,kBAElC,IAAI;AAAA,mBACN;AAAA;AAAA,cAlBI,IAAI,QAAQ,SAAS;AAAA,YAoB3B;AAAA,UAEH,GACD;AAAA,WAEF;AAAA;AAAA,IACD;AAAA,EAEF;AACD;;;AC1IA,SAA0B,kBAAkB;AASrC,SAAS,yBAAyB;AACxC,SAAO,WAA6B;AAAA,IACnC,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,mBAAmB;AAAA,EACpB,CAAC;AACF;AAEO,SAAS,UAAU,OAAqC;AAC9D,QAAM,OAAO,IAAI,IAAI;AACtB;AAEO,SAAS,WAAW,OAAqC;AAC/D,QAAM,OAAO,IAAI,KAAK;AACvB;","names":[]}