@0xsequence/marketplace-sdk 0.8.9 → 0.8.11
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.
- package/.changeset/fluffy-jokes-lay.md +5 -0
- package/.changeset/wise-bugs-boil.md +8 -0
- package/CHANGELOG.md +43 -0
- package/dist/{chunk-FMEEJFAF.js → chunk-5C6ZZ6WX.js} +1 -1
- package/dist/{chunk-YEGD7PWE.js → chunk-5O44EPXZ.js} +2 -2
- package/dist/chunk-6CTFVBKU.js +1 -0
- package/dist/{chunk-DWTLVJAW.js → chunk-6OPMUCGX.js} +1 -1
- package/dist/chunk-6OPMUCGX.js.map +1 -0
- package/dist/{chunk-O34GCB47.js → chunk-L6KWLCER.js} +4 -4
- package/dist/chunk-L6KWLCER.js.map +1 -0
- package/dist/{chunk-4XLXOEXQ.js → chunk-LAP2CKLN.js} +78 -4
- package/dist/chunk-LAP2CKLN.js.map +1 -0
- package/dist/{chunk-Y63BOO6M.js → chunk-LECCEZAO.js} +1 -1
- package/dist/{chunk-YALXP2PW.js → chunk-N7SQWS2R.js} +3 -3
- package/dist/{chunk-KGM2WLSP.js → chunk-OAOONM4S.js} +695 -440
- package/dist/chunk-OAOONM4S.js.map +1 -0
- package/dist/chunk-Q3ECVC4F.js +811 -0
- package/dist/chunk-Q3ECVC4F.js.map +1 -0
- package/dist/chunk-QY52UADF.js +107 -0
- package/dist/chunk-QY52UADF.js.map +1 -0
- package/dist/{chunk-I2BYHDFE.js → chunk-TNAR3XEF.js} +3898 -844
- package/dist/chunk-TNAR3XEF.js.map +1 -0
- package/dist/chunk-XABYNWXO.js +549 -0
- package/dist/chunk-XABYNWXO.js.map +1 -0
- package/dist/chunk-YB5UUF2G.js +11 -0
- package/dist/chunk-YB5UUF2G.js.map +1 -0
- package/dist/{chunk-35WWD5V6.js → chunk-YWGFI4PN.js} +88 -25
- package/dist/chunk-YWGFI4PN.js.map +1 -0
- package/dist/{create-config-DwrnzwpM.d.ts → create-config-DLMvMTkZ.d.ts} +2 -2
- package/dist/index.css +7 -7
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +19 -14
- package/dist/{lowestListing-BQHIuvNF.d.ts → marketCurrencies-enNVYwBk.d.ts} +95 -3
- package/dist/{marketplace.gen-DQzWciwC.d.ts → marketplace.gen-D24veUQs.d.ts} +3 -2
- package/dist/marketplaceConfig-BwNAbLPw.d.ts +21 -0
- package/dist/new-marketplace-types-BCw19X9S.d.ts +102 -0
- package/dist/react/_internal/api/index.d.ts +4 -3
- package/dist/react/_internal/api/index.js +5 -1
- package/dist/react/_internal/databeat/index.css +2764 -0
- package/dist/react/_internal/databeat/index.css.map +1 -0
- package/dist/react/_internal/databeat/index.d.ts +1 -1
- package/dist/react/_internal/databeat/index.js +15 -14
- package/dist/react/_internal/index.d.ts +62 -9
- package/dist/react/_internal/index.js +7 -3
- package/dist/react/_internal/wagmi/index.d.ts +5 -6
- package/dist/react/_internal/wagmi/index.js +1 -1
- package/dist/react/hooks/index.css +2764 -0
- package/dist/react/hooks/index.css.map +1 -0
- package/dist/react/hooks/index.d.ts +74 -222
- package/dist/react/hooks/index.js +21 -22
- package/dist/react/hooks/options/index.d.ts +5 -4
- package/dist/react/hooks/options/index.js +9 -7
- package/dist/react/index.css +7 -7
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.ts +12 -11
- package/dist/react/index.js +34 -37
- package/dist/react/queries/index.d.ts +4 -3
- package/dist/react/queries/index.js +19 -6
- package/dist/react/ssr/index.d.ts +3 -3
- package/dist/react/ssr/index.js +6 -5
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/collectible-card/index.css +7 -7
- package/dist/react/ui/components/collectible-card/index.css.map +1 -1
- package/dist/react/ui/components/collectible-card/index.d.ts +9 -6
- package/dist/react/ui/components/collectible-card/index.js +19 -23
- package/dist/react/ui/components/marketplace-logos/index.js +1 -1
- package/dist/react/ui/icons/index.js +9 -8
- package/dist/react/ui/index.css +7 -7
- package/dist/react/ui/index.css.map +1 -1
- package/dist/react/ui/index.d.ts +2 -2
- package/dist/react/ui/index.js +17 -21
- package/dist/react/ui/modals/_internal/components/actionModal/index.css +2764 -0
- package/dist/react/ui/modals/_internal/components/actionModal/index.css.map +1 -0
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +15 -14
- package/dist/sdk-config-qorA0TgF.d.ts +165 -0
- package/dist/{services-BI_w8Eq4.d.ts → services-WrshxCqc.d.ts} +6 -3
- package/dist/types/index.d.ts +5 -4
- package/dist/types/index.js +7 -7
- package/dist/{index-DGsVBflk.d.ts → useCollection-YAdXfVO7.d.ts} +1 -2
- package/dist/utils/abi/index.d.ts +1 -0
- package/dist/utils/abi/index.js +7 -1
- package/dist/utils/abi/primary-sale/index.d.ts +1054 -0
- package/dist/utils/abi/primary-sale/index.js +9 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +13 -6
- package/package.json +32 -32
- package/src/react/_internal/api/__mocks__/builder.msw.ts +157 -80
- package/src/react/_internal/api/builder-api.ts +2 -2
- package/src/react/_internal/api/builder.gen.ts +667 -112
- package/src/react/_internal/api/marketplace.gen.ts +1981 -1316
- package/src/react/_internal/api/services.ts +12 -1
- package/src/react/_internal/types.ts +1 -13
- package/src/react/_internal/wagmi/__tests__/create-config.test.ts +99 -84
- package/src/react/_internal/wagmi/create-config.ts +8 -4
- package/src/react/_internal/wagmi/get-connectors.ts +24 -19
- package/src/react/hooks/__tests__/__snapshots__/useListCollections.test.tsx.snap +114 -0
- package/src/react/hooks/__tests__/__snapshots__/useMarketplaceConfig.test.tsx.snap +85 -83
- package/src/react/hooks/__tests__/useFilters.test.tsx +0 -16
- package/src/react/hooks/__tests__/useInventory.test.tsx +16 -16
- package/src/react/hooks/__tests__/useListCollections.test.tsx +23 -56
- package/src/react/hooks/__tests__/{useCurrencies.test.tsx → useMarketCurrencies.test.tsx} +21 -15
- package/src/react/hooks/__tests__/useMarketplaceConfig.test.tsx +2 -59
- package/src/react/hooks/index.ts +3 -1
- package/src/react/hooks/useBalanceOfCollectible.tsx +5 -3
- package/src/react/hooks/useConvertPriceToUSD.tsx +1 -1
- package/src/react/hooks/useFilters.tsx +14 -22
- package/src/react/hooks/useGetTokenSuppliesMap.ts +28 -0
- package/src/react/hooks/useInventory.tsx +4 -3
- package/src/react/hooks/useList1155SaleSupplies.tsx +62 -0
- package/src/react/hooks/useListBalances.tsx +5 -3
- package/src/react/hooks/useListCollectibles.tsx +5 -3
- package/src/react/hooks/useListCollections.tsx +14 -76
- package/src/react/hooks/useListTokenMetadata.ts +19 -0
- package/src/react/hooks/useMarketCurrencies.tsx +8 -0
- package/src/react/hooks/useMarketplaceConfig.tsx +0 -2
- package/src/react/queries/index.ts +2 -0
- package/src/react/queries/inventory.ts +1 -1
- package/src/react/queries/listCollections.ts +118 -0
- package/src/react/queries/listTokenMetadata.ts +38 -0
- package/src/react/queries/marketCurrencies.ts +77 -0
- package/src/react/queries/marketplaceConfig.ts +83 -55
- package/src/react/ssr/__tests__/__snapshots__/create-ssr-client.test.ts.snap +85 -83
- package/src/react/ui/components/collectible-card/CollectibleCard.tsx +2 -2
- package/src/react/ui/components/collectible-card/__tests__/{CollectibleAsset.test.tsx → Media.test.tsx} +48 -14
- package/src/react/ui/components/collectible-card/index.ts +1 -1
- package/src/react/ui/components/collectible-card/media/Media.tsx +211 -0
- package/src/react/ui/components/collectible-card/{collectible-asset/CollectibleAssetSkeleton.tsx → media/MediaSkeleton.tsx} +2 -2
- package/src/react/ui/components/collectible-card/media/types.ts +18 -0
- package/src/react/ui/components/collectible-card/{collectible-asset → media}/utils.ts +8 -3
- package/src/react/ui/index.ts +1 -1
- package/src/react/ui/modals/BuyModal/ERC1155QuantityModal.tsx +9 -3
- package/src/react/ui/modals/BuyModal/hooks/__tests__/useFees.test.tsx +31 -21
- package/src/react/ui/modals/BuyModal/hooks/useFees.ts +3 -2
- package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +28 -3
- package/src/react/ui/modals/CreateListingModal/Modal.tsx +3 -5
- package/src/react/ui/modals/CreateListingModal/hooks/useCreateListing.tsx +5 -3
- package/src/react/ui/modals/CreateListingModal/hooks/useTransactionSteps.tsx +2 -2
- package/src/react/ui/modals/MakeOfferModal/Modal.tsx +2 -3
- package/src/react/ui/modals/MakeOfferModal/hooks/useMakeOffer.tsx +4 -3
- package/src/react/ui/modals/SellModal/Modal.tsx +0 -1
- package/src/react/ui/modals/SellModal/hooks/useTransactionSteps.tsx +2 -2
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/WalletAddressInput.tsx +1 -1
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +0 -1
- package/src/react/ui/modals/TransferModal/index.tsx +0 -1
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +2 -2
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +7 -6
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/__tests__/SelectWaasFeeOptions.test.tsx +13 -7
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/index.tsx +3 -5
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/useWaasFeeOptionManager.tsx +5 -3
- package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
- package/src/react/ui/modals/_internal/hooks/useSelectWaasFeeOptions.ts +2 -12
- package/src/types/index.ts +1 -6
- package/src/types/new-marketplace-types.ts +119 -0
- package/src/types/sdk-config.ts +19 -2
- package/src/types/types.ts +1 -0
- package/src/utils/abi/index.ts +1 -0
- package/src/utils/abi/primary-sale/index.ts +2 -0
- package/src/utils/abi/primary-sale/sequence-1155-sales-contract.ts +450 -0
- package/src/utils/abi/primary-sale/sequence-721-sales-contract.ts +352 -0
- package/src/utils/abi/token/sequence-erc1155-items.ts +454 -0
- package/src/utils/fetchContentType.ts +5 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-35WWD5V6.js.map +0 -1
- package/dist/chunk-4XLXOEXQ.js.map +0 -1
- package/dist/chunk-D7RVSZAQ.js +0 -332
- package/dist/chunk-D7RVSZAQ.js.map +0 -1
- package/dist/chunk-DWTLVJAW.js.map +0 -1
- package/dist/chunk-EODKQL6Y.js +0 -76
- package/dist/chunk-EODKQL6Y.js.map +0 -1
- package/dist/chunk-G3447GIP.js +0 -2880
- package/dist/chunk-G3447GIP.js.map +0 -1
- package/dist/chunk-HHYNOPPI.js +0 -53
- package/dist/chunk-HHYNOPPI.js.map +0 -1
- package/dist/chunk-I2BYHDFE.js.map +0 -1
- package/dist/chunk-JKCF7HEA.js +0 -1
- package/dist/chunk-KGM2WLSP.js.map +0 -1
- package/dist/chunk-MAD64DLJ.js +0 -81
- package/dist/chunk-MAD64DLJ.js.map +0 -1
- package/dist/chunk-N7BPFK46.js +0 -1
- package/dist/chunk-O34GCB47.js.map +0 -1
- package/dist/chunk-UISBTKFF.js +0 -1
- package/dist/chunk-UISBTKFF.js.map +0 -1
- package/dist/chunk-YBOFRP65.js +0 -128
- package/dist/chunk-YBOFRP65.js.map +0 -1
- package/dist/marketplaceConfig-B4Fdsmxu.d.ts +0 -17
- package/dist/sdk-config-txlivEKe.d.ts +0 -133
- package/dist/types-isjvwapz.d.ts +0 -68
- package/src/react/hooks/useCurrencies.tsx +0 -77
- package/src/react/ui/components/collectible-card/collectible-asset/CollectibleAsset.tsx +0 -174
- /package/dist/{chunk-FMEEJFAF.js.map → chunk-5C6ZZ6WX.js.map} +0 -0
- /package/dist/{chunk-YEGD7PWE.js.map → chunk-5O44EPXZ.js.map} +0 -0
- /package/dist/{chunk-JKCF7HEA.js.map → chunk-6CTFVBKU.js.map} +0 -0
- /package/dist/{chunk-Y63BOO6M.js.map → chunk-LECCEZAO.js.map} +0 -0
- /package/dist/{chunk-YALXP2PW.js.map → chunk-N7SQWS2R.js.map} +0 -0
- /package/dist/{chunk-N7BPFK46.js.map → utils/abi/primary-sale/index.js.map} +0 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { cn } from '../../../../../utils';
|
|
5
|
+
import { fetchContentType } from '../../../../../utils/fetchContentType';
|
|
6
|
+
import ChessTileImage from '../../../images/chess-tile.png';
|
|
7
|
+
import ModelViewer from '../../ModelViewer';
|
|
8
|
+
import MediaSkeleton from './MediaSkeleton';
|
|
9
|
+
import type { ContentTypeState, MediaProps } from './types';
|
|
10
|
+
import { getContentType } from './utils';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description This component is used to display a collectible asset.
|
|
14
|
+
* It will display the first valid asset from the assets array.
|
|
15
|
+
* If no valid asset is found, it will display the placeholder image.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <Media
|
|
19
|
+
* name="Collectible"
|
|
20
|
+
* assets={[undefined, "some-image-url", undefined]} // undefined assets will be ignored, "some-image-url" will be rendered
|
|
21
|
+
* assetSrcPrefixUrl="https://example.com/"
|
|
22
|
+
* className="w-full h-full"
|
|
23
|
+
* />
|
|
24
|
+
*/
|
|
25
|
+
export function Media({
|
|
26
|
+
name,
|
|
27
|
+
assets,
|
|
28
|
+
assetSrcPrefixUrl,
|
|
29
|
+
className,
|
|
30
|
+
supply,
|
|
31
|
+
isLoading,
|
|
32
|
+
}: MediaProps) {
|
|
33
|
+
const [assetLoadFailed, setAssetLoadFailed] = useState(false);
|
|
34
|
+
const [assetLoading, setAssetLoading] = useState(true);
|
|
35
|
+
const [contentType, setContentType] = useState<ContentTypeState>({
|
|
36
|
+
type: null,
|
|
37
|
+
loading: true,
|
|
38
|
+
failed: false,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const videoRef = useRef<HTMLVideoElement>(null);
|
|
42
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
43
|
+
|
|
44
|
+
const placeholderImage = ChessTileImage;
|
|
45
|
+
const assetUrl = assets.find((asset): asset is string => !!asset);
|
|
46
|
+
const proxiedAssetUrl = assetUrl
|
|
47
|
+
? assetSrcPrefixUrl
|
|
48
|
+
? `${assetSrcPrefixUrl}${assetUrl}`
|
|
49
|
+
: assetUrl
|
|
50
|
+
: '';
|
|
51
|
+
|
|
52
|
+
const classNames = cn(
|
|
53
|
+
'relative aspect-square overflow-hidden bg-background-secondary',
|
|
54
|
+
supply !== undefined && supply === 0 && 'opacity-50',
|
|
55
|
+
className,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!assetUrl) {
|
|
60
|
+
setContentType({ type: null, loading: false, failed: true });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const determineContentType = async () => {
|
|
65
|
+
try {
|
|
66
|
+
const type = await getContentType(proxiedAssetUrl);
|
|
67
|
+
setContentType({ type, loading: false, failed: false });
|
|
68
|
+
} catch {
|
|
69
|
+
try {
|
|
70
|
+
const type = await fetchContentType(proxiedAssetUrl);
|
|
71
|
+
setContentType({ type, loading: false, failed: false });
|
|
72
|
+
} catch {
|
|
73
|
+
setContentType({ type: null, loading: false, failed: true });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
determineContentType();
|
|
79
|
+
}, [proxiedAssetUrl, assetUrl]);
|
|
80
|
+
|
|
81
|
+
const handleAssetError = () => {
|
|
82
|
+
setAssetLoadFailed(true);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleAssetLoad = () => {
|
|
86
|
+
setAssetLoading(false);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Display placeholder if asset fails to load or doesn't exist
|
|
90
|
+
if ((!isLoading && contentType.failed && !assetLoadFailed) || !assetUrl) {
|
|
91
|
+
return (
|
|
92
|
+
<div className={cn('h-full w-full', classNames)}>
|
|
93
|
+
<img
|
|
94
|
+
src={placeholderImage}
|
|
95
|
+
alt={name || 'Collectible'}
|
|
96
|
+
className="h-full w-full object-cover"
|
|
97
|
+
onError={(e) => {
|
|
98
|
+
console.error('Failed to load placeholder image');
|
|
99
|
+
e.currentTarget.style.display = 'none';
|
|
100
|
+
}}
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Render based on content type
|
|
107
|
+
if (contentType.type === 'html' && !assetLoadFailed) {
|
|
108
|
+
return (
|
|
109
|
+
<div
|
|
110
|
+
className={cn(
|
|
111
|
+
'flex w-full items-center justify-center rounded-lg',
|
|
112
|
+
classNames,
|
|
113
|
+
)}
|
|
114
|
+
>
|
|
115
|
+
{(assetLoading || contentType.loading || isLoading) && (
|
|
116
|
+
<MediaSkeleton />
|
|
117
|
+
)}
|
|
118
|
+
|
|
119
|
+
<iframe
|
|
120
|
+
title={name || 'Collectible'}
|
|
121
|
+
className="aspect-square w-full"
|
|
122
|
+
src={proxiedAssetUrl}
|
|
123
|
+
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
|
124
|
+
sandbox="allow-scripts"
|
|
125
|
+
style={{ border: '0px' }}
|
|
126
|
+
onError={handleAssetError}
|
|
127
|
+
onLoad={handleAssetLoad}
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (contentType.type === '3d-model' && !assetLoadFailed) {
|
|
134
|
+
return (
|
|
135
|
+
<div className={cn('h-full w-full', classNames)}>
|
|
136
|
+
<ModelViewer
|
|
137
|
+
src={proxiedAssetUrl}
|
|
138
|
+
posterSrc={placeholderImage}
|
|
139
|
+
onLoad={handleAssetLoad}
|
|
140
|
+
onError={handleAssetError}
|
|
141
|
+
/>
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (contentType.type === 'video' && !assetLoadFailed) {
|
|
147
|
+
const videoClassNames = cn(
|
|
148
|
+
'absolute inset-0 h-full w-full object-cover transition-transform duration-200 ease-in-out group-hover:scale-hover',
|
|
149
|
+
assetLoading || isLoading ? 'invisible' : 'visible',
|
|
150
|
+
// we can't hide the video controls in safari, when user hovers over the video they show up.
|
|
151
|
+
// `pointer-events-none` is the only way to hide them on hover
|
|
152
|
+
isSafari && 'pointer-events-none',
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<div className={classNames}>
|
|
157
|
+
{(assetLoading || contentType.loading || isLoading) && (
|
|
158
|
+
<MediaSkeleton />
|
|
159
|
+
)}
|
|
160
|
+
|
|
161
|
+
<video
|
|
162
|
+
ref={videoRef}
|
|
163
|
+
className={videoClassNames}
|
|
164
|
+
autoPlay
|
|
165
|
+
loop
|
|
166
|
+
controls
|
|
167
|
+
playsInline
|
|
168
|
+
muted
|
|
169
|
+
controlsList="nodownload noremoteplayback nofullscreen"
|
|
170
|
+
onError={handleAssetError}
|
|
171
|
+
onLoadedMetadata={handleAssetLoad}
|
|
172
|
+
data-testid="collectible-asset-video"
|
|
173
|
+
>
|
|
174
|
+
<source src={proxiedAssetUrl} />
|
|
175
|
+
</video>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Default to image renderer
|
|
181
|
+
const imgSrc =
|
|
182
|
+
assetLoadFailed || contentType.failed ? placeholderImage : proxiedAssetUrl;
|
|
183
|
+
|
|
184
|
+
const imgClassNames = cn(
|
|
185
|
+
'absolute inset-0 h-full w-full object-cover transition-transform duration-200 ease-in-out group-hover:scale-hover',
|
|
186
|
+
assetLoading || contentType.loading || isLoading ? 'invisible' : 'visible',
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<div className={classNames}>
|
|
191
|
+
{(assetLoading || contentType.loading || isLoading) && <MediaSkeleton />}
|
|
192
|
+
|
|
193
|
+
<img
|
|
194
|
+
src={imgSrc}
|
|
195
|
+
alt={name || 'Collectible'}
|
|
196
|
+
className={imgClassNames}
|
|
197
|
+
onError={(e) => {
|
|
198
|
+
if (contentType.type === 'image') {
|
|
199
|
+
setAssetLoadFailed(true);
|
|
200
|
+
}
|
|
201
|
+
// If this is the placeholder image that failed
|
|
202
|
+
if (e.currentTarget.src === placeholderImage) {
|
|
203
|
+
console.error('Failed to load placeholder image');
|
|
204
|
+
e.currentTarget.style.display = 'none';
|
|
205
|
+
}
|
|
206
|
+
}}
|
|
207
|
+
onLoad={handleAssetLoad}
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Skeleton } from '@0xsequence/design-system';
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function MediaSkeleton() {
|
|
4
4
|
return (
|
|
5
5
|
<Skeleton
|
|
6
|
-
data-testid="
|
|
6
|
+
data-testid="media"
|
|
7
7
|
size="lg"
|
|
8
8
|
className="absolute inset-0 h-full w-full animate-shimmer"
|
|
9
9
|
style={{
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type ContentType = 'image' | 'video' | 'html' | '3d-model' | null;
|
|
2
|
+
|
|
3
|
+
type ContentTypeState = {
|
|
4
|
+
type: ContentType;
|
|
5
|
+
loading: boolean;
|
|
6
|
+
failed: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type MediaProps = {
|
|
10
|
+
name?: string;
|
|
11
|
+
assets: (string | undefined)[];
|
|
12
|
+
assetSrcPrefixUrl?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
supply?: number;
|
|
15
|
+
isLoading?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type { ContentType, ContentTypeState, MediaProps };
|
|
@@ -23,9 +23,9 @@ export const is3dModel = (fileName: string | undefined) => {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export const getContentType = (
|
|
26
|
-
url: string,
|
|
26
|
+
url: string | undefined,
|
|
27
27
|
): Promise<'image' | 'video' | 'html' | '3d-model' | null> => {
|
|
28
|
-
return new Promise((resolve) => {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
29
|
const type = isHtml(url)
|
|
30
30
|
? 'html'
|
|
31
31
|
: isVideo(url)
|
|
@@ -35,6 +35,11 @@ export const getContentType = (
|
|
|
35
35
|
: is3dModel(url)
|
|
36
36
|
? '3d-model'
|
|
37
37
|
: null;
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
if (type) {
|
|
40
|
+
resolve(type);
|
|
41
|
+
} else {
|
|
42
|
+
reject(new Error('Unsupported file type'));
|
|
43
|
+
}
|
|
39
44
|
});
|
|
40
45
|
};
|
package/src/react/ui/index.ts
CHANGED
|
@@ -8,4 +8,4 @@ export { useBuyModal } from './modals/BuyModal';
|
|
|
8
8
|
|
|
9
9
|
// components
|
|
10
10
|
export { CollectibleCard } from './components/collectible-card/CollectibleCard';
|
|
11
|
-
export {
|
|
11
|
+
export { Media } from './components/collectible-card/media/Media';
|
|
@@ -58,7 +58,10 @@ export const ERC1155QuantityModal = ({ order }: { order: Order }) => {
|
|
|
58
58
|
const TotalPrice = ({
|
|
59
59
|
order,
|
|
60
60
|
quantityStr,
|
|
61
|
-
}: {
|
|
61
|
+
}: {
|
|
62
|
+
order: Order;
|
|
63
|
+
quantityStr: string;
|
|
64
|
+
}) => {
|
|
62
65
|
const { data: marketplaceConfig } = useMarketplaceConfig();
|
|
63
66
|
const { data: currency, isLoading: isCurrencyLoading } = useCurrency({
|
|
64
67
|
chainId: order.chainId,
|
|
@@ -71,8 +74,11 @@ const TotalPrice = ({
|
|
|
71
74
|
if (currency) {
|
|
72
75
|
try {
|
|
73
76
|
const marketplaceFeePercentage =
|
|
74
|
-
marketplaceConfig?.collections.find((collection) =>
|
|
75
|
-
compareAddress(
|
|
77
|
+
marketplaceConfig?.market.collections.find((collection) =>
|
|
78
|
+
compareAddress(
|
|
79
|
+
collection.itemsAddress,
|
|
80
|
+
order.collectionContractAddress,
|
|
81
|
+
),
|
|
76
82
|
)?.feePercentage || DEFAULT_MARKETPLACE_FEE_PERCENTAGE;
|
|
77
83
|
const quantity = BigInt(quantityStr);
|
|
78
84
|
const totalPriceRaw = BigInt(order.priceAmount) * quantity;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { renderHook } from '@test';
|
|
2
2
|
import { avalanche, optimism } from 'viem/chains';
|
|
3
3
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { MarketplaceType } from '../../../../../../types/new-marketplace-types';
|
|
4
5
|
import { useMarketplaceConfig } from '../../../../../hooks';
|
|
5
6
|
import { useFees } from '../useFees';
|
|
6
7
|
|
|
@@ -30,13 +31,16 @@ describe('useFees', () => {
|
|
|
30
31
|
useMarketplaceConfig as unknown as ReturnType<typeof vi.fn>
|
|
31
32
|
).mockReturnValue({
|
|
32
33
|
data: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
market: {
|
|
35
|
+
collections: [
|
|
36
|
+
{
|
|
37
|
+
itemsAddress: '0x456',
|
|
38
|
+
chainId: 1,
|
|
39
|
+
feePercentage: '5.0',
|
|
40
|
+
marketplaceType: MarketplaceType.MARKET,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
40
44
|
},
|
|
41
45
|
});
|
|
42
46
|
|
|
@@ -59,13 +63,16 @@ describe('useFees', () => {
|
|
|
59
63
|
useMarketplaceConfig as unknown as ReturnType<typeof vi.fn>
|
|
60
64
|
).mockReturnValue({
|
|
61
65
|
data: {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
market: {
|
|
67
|
+
collections: [
|
|
68
|
+
{
|
|
69
|
+
itemsAddress: collectionAddress,
|
|
70
|
+
chainId: chainId.toString(),
|
|
71
|
+
feePercentage: collectionFee,
|
|
72
|
+
marketplaceType: MarketplaceType.MARKET,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
69
76
|
},
|
|
70
77
|
});
|
|
71
78
|
|
|
@@ -110,13 +117,16 @@ describe('useFees', () => {
|
|
|
110
117
|
useMarketplaceConfig as unknown as ReturnType<typeof vi.fn>
|
|
111
118
|
).mockReturnValue({
|
|
112
119
|
data: {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
market: {
|
|
121
|
+
collections: [
|
|
122
|
+
{
|
|
123
|
+
itemsAddress: collectionAddress.toLowerCase(),
|
|
124
|
+
chainId: chainId.toString(),
|
|
125
|
+
feePercentage: collectionFee,
|
|
126
|
+
marketplaceType: MarketplaceType.MARKET,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
120
130
|
},
|
|
121
131
|
});
|
|
122
132
|
|
|
@@ -16,9 +16,10 @@ export const useFees = ({
|
|
|
16
16
|
'0x400cdab4676c17aec07e8ec748a5fc3b674bca41';
|
|
17
17
|
const { data: marketplaceConfig } = useMarketplaceConfig();
|
|
18
18
|
|
|
19
|
-
const collection = marketplaceConfig?.collections.find(
|
|
19
|
+
const collection = marketplaceConfig?.market.collections.find(
|
|
20
20
|
(collection) =>
|
|
21
|
-
collection.
|
|
21
|
+
collection.itemsAddress.toLowerCase() ===
|
|
22
|
+
collectionAddress.toLowerCase() &&
|
|
22
23
|
chainId === Number(collection.chainId),
|
|
23
24
|
);
|
|
24
25
|
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
WalletKind,
|
|
13
13
|
getMarketplaceClient,
|
|
14
14
|
getQueryClient,
|
|
15
|
+
getSequenceApiClient,
|
|
15
16
|
} from '../../../../_internal';
|
|
16
17
|
import type { WalletInstance } from '../../../../_internal/wallet/wallet';
|
|
17
18
|
import { useConfig } from '../../../../hooks';
|
|
@@ -88,6 +89,27 @@ export const getBuyCollectableParams = async ({
|
|
|
88
89
|
throw new Error('Buy step not found');
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
const creditCardProviders = customCreditCardProviderCallback
|
|
93
|
+
? ['custom']
|
|
94
|
+
: checkoutOptions.nftCheckout || [];
|
|
95
|
+
|
|
96
|
+
const isTransakSupported = creditCardProviders.includes('transak');
|
|
97
|
+
|
|
98
|
+
let transakContractId: string | undefined;
|
|
99
|
+
|
|
100
|
+
if (isTransakSupported) {
|
|
101
|
+
const sequenceApiClient = getSequenceApiClient(config);
|
|
102
|
+
const transakContractIdResponse =
|
|
103
|
+
await sequenceApiClient.checkoutOptionsGetTransakContractID({
|
|
104
|
+
chainId,
|
|
105
|
+
contractAddress: buyStep.to,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (transakContractIdResponse.contractId !== '') {
|
|
109
|
+
transakContractId = transakContractIdResponse.contractId;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
91
113
|
return {
|
|
92
114
|
chain: chainId,
|
|
93
115
|
collectibles: [
|
|
@@ -106,9 +128,7 @@ export const getBuyCollectableParams = async ({
|
|
|
106
128
|
recipientAddress: await wallet.address(),
|
|
107
129
|
enableMainCurrencyPayment: true,
|
|
108
130
|
enableSwapPayments: !!checkoutOptions.swap,
|
|
109
|
-
creditCardProviders
|
|
110
|
-
? ['custom']
|
|
111
|
-
: checkoutOptions.nftCheckout || [],
|
|
131
|
+
creditCardProviders,
|
|
112
132
|
onSuccess: (hash: string) => {
|
|
113
133
|
callbacks?.onSuccess?.({ hash: hash as Hash });
|
|
114
134
|
},
|
|
@@ -130,6 +150,11 @@ export const getBuyCollectableParams = async ({
|
|
|
130
150
|
buyModalStore.send({ type: 'close' });
|
|
131
151
|
},
|
|
132
152
|
}),
|
|
153
|
+
...(transakContractId && {
|
|
154
|
+
transakConfig: {
|
|
155
|
+
contractId: transakContractId,
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
133
158
|
} satisfies SelectPaymentSettings;
|
|
134
159
|
};
|
|
135
160
|
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
useBalanceOfCollectible,
|
|
12
12
|
useCollectible,
|
|
13
13
|
useCollection,
|
|
14
|
-
|
|
14
|
+
useMarketCurrencies,
|
|
15
15
|
} from '../../../hooks';
|
|
16
16
|
import {
|
|
17
17
|
ActionModal,
|
|
@@ -52,9 +52,7 @@ const Modal = observer(() => {
|
|
|
52
52
|
shouldHideActionButton: shouldHideListButton,
|
|
53
53
|
waasFeeOptionsShown,
|
|
54
54
|
getActionLabel,
|
|
55
|
-
isTestnet,
|
|
56
55
|
} = useSelectWaasFeeOptions({
|
|
57
|
-
chainId,
|
|
58
56
|
isProcessing: listingIsBeingProcessed,
|
|
59
57
|
feeOptionsVisible: selectWaasFeeOptions$.isVisible.get(),
|
|
60
58
|
selectedFeeOption:
|
|
@@ -74,7 +72,7 @@ const Modal = observer(() => {
|
|
|
74
72
|
data: currencies,
|
|
75
73
|
isLoading: currenciesLoading,
|
|
76
74
|
isError: currenciesIsError,
|
|
77
|
-
} =
|
|
75
|
+
} = useMarketCurrencies({
|
|
78
76
|
chainId,
|
|
79
77
|
collectionAddress,
|
|
80
78
|
includeNativeCurrency: true,
|
|
@@ -154,7 +152,7 @@ const Modal = observer(() => {
|
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
await createListing({
|
|
157
|
-
isTransactionExecuting: wallet?.isWaaS
|
|
155
|
+
isTransactionExecuting: !!wallet?.isWaaS,
|
|
158
156
|
});
|
|
159
157
|
} catch (error) {
|
|
160
158
|
console.error('Create listing failed:', error);
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import type { Observable } from '@legendapp/state';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
|
+
import type { MarketCollection } from '../../../../../types/new-marketplace-types';
|
|
6
|
+
import { compareAddress } from '../../../../../utils';
|
|
5
7
|
import {
|
|
6
8
|
type ContractType,
|
|
7
9
|
type CreateReq,
|
|
@@ -40,9 +42,9 @@ export const useCreateListing = ({
|
|
|
40
42
|
const { data: marketplaceConfig, isLoading: marketplaceIsLoading } =
|
|
41
43
|
useMarketplaceConfig();
|
|
42
44
|
|
|
43
|
-
const collectionConfig = marketplaceConfig?.collections.find(
|
|
44
|
-
(c
|
|
45
|
-
);
|
|
45
|
+
const collectionConfig = marketplaceConfig?.market.collections.find((c) =>
|
|
46
|
+
compareAddress(c.itemsAddress, collectionAddress),
|
|
47
|
+
) as MarketCollection;
|
|
46
48
|
|
|
47
49
|
orderbookKind =
|
|
48
50
|
orderbookKind ??
|
|
@@ -20,8 +20,8 @@ import type {
|
|
|
20
20
|
import { useWallet } from '../../../../_internal/wallet/useWallet';
|
|
21
21
|
import {
|
|
22
22
|
useConfig,
|
|
23
|
-
useCurrencies,
|
|
24
23
|
useGenerateListingTransaction,
|
|
24
|
+
useMarketCurrencies,
|
|
25
25
|
} from '../../../../hooks';
|
|
26
26
|
import { useTransactionStatusModal } from '../../_internal/components/transactionStatusModal';
|
|
27
27
|
import type { ModalCallbacks } from '../../_internal/types';
|
|
@@ -48,7 +48,7 @@ export const useTransactionSteps = ({
|
|
|
48
48
|
const expiry = new Date(Number(listingInput.listing.expiry) * 1000);
|
|
49
49
|
const { show: showTransactionStatusModal } = useTransactionStatusModal();
|
|
50
50
|
const sdkConfig = useConfig();
|
|
51
|
-
const { data: currencies } =
|
|
51
|
+
const { data: currencies } = useMarketCurrencies({
|
|
52
52
|
chainId,
|
|
53
53
|
});
|
|
54
54
|
const currency = currencies?.find(
|
|
@@ -12,8 +12,8 @@ import { useWallet } from '../../../_internal/wallet/useWallet';
|
|
|
12
12
|
import {
|
|
13
13
|
useCollectible,
|
|
14
14
|
useCollection,
|
|
15
|
-
useCurrencies,
|
|
16
15
|
useLowestListing,
|
|
16
|
+
useMarketCurrencies,
|
|
17
17
|
} from '../../../hooks';
|
|
18
18
|
import { useBuyModal } from '../BuyModal';
|
|
19
19
|
import { ActionModal } from '../_internal/components/actionModal/ActionModal';
|
|
@@ -64,7 +64,6 @@ const Modal = observer(() => {
|
|
|
64
64
|
waasFeeOptionsShown,
|
|
65
65
|
getActionLabel,
|
|
66
66
|
} = useSelectWaasFeeOptions({
|
|
67
|
-
chainId,
|
|
68
67
|
isProcessing,
|
|
69
68
|
feeOptionsVisible: selectWaasFeeOptions$.isVisible.get(),
|
|
70
69
|
selectedFeeOption:
|
|
@@ -83,7 +82,7 @@ const Modal = observer(() => {
|
|
|
83
82
|
data: currencies,
|
|
84
83
|
isLoading: currenciesLoading,
|
|
85
84
|
isError: currenciesIsError,
|
|
86
|
-
} =
|
|
85
|
+
} = useMarketCurrencies({
|
|
87
86
|
chainId,
|
|
88
87
|
includeNativeCurrency: false,
|
|
89
88
|
});
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import type { Observable } from '@legendapp/state';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
5
|
import { OrderbookKind } from '../../../../../types';
|
|
6
|
+
import type { MarketCollection } from '../../../../../types/new-marketplace-types';
|
|
6
7
|
import type { TransactionSteps } from '../../../../_internal';
|
|
7
8
|
import type { OfferInput } from '../../../../_internal/types';
|
|
8
9
|
import { useMarketplaceConfig } from '../../../../hooks';
|
|
@@ -32,9 +33,9 @@ export const useMakeOffer = ({
|
|
|
32
33
|
const { data: marketplaceConfig, isLoading: marketplaceIsLoading } =
|
|
33
34
|
useMarketplaceConfig();
|
|
34
35
|
|
|
35
|
-
const collectionConfig = marketplaceConfig?.collections.find(
|
|
36
|
-
(c) => c.
|
|
37
|
-
);
|
|
36
|
+
const collectionConfig = marketplaceConfig?.market.collections.find(
|
|
37
|
+
(c) => c.itemsAddress === collectionAddress,
|
|
38
|
+
) as MarketCollection;
|
|
38
39
|
|
|
39
40
|
orderbookKind =
|
|
40
41
|
orderbookKind ??
|
|
@@ -60,7 +60,6 @@ const Modal = observer(() => {
|
|
|
60
60
|
const isWaaS = wallet?.isWaaS;
|
|
61
61
|
const { shouldHideActionButton: shouldHideSellButton } =
|
|
62
62
|
useSelectWaasFeeOptions({
|
|
63
|
-
chainId,
|
|
64
63
|
isProcessing,
|
|
65
64
|
feeOptionsVisible: selectWaasFeeOptions$.isVisible.get(),
|
|
66
65
|
selectedFeeOption:
|
|
@@ -19,8 +19,8 @@ import type {
|
|
|
19
19
|
import { useWallet } from '../../../../_internal/wallet/useWallet';
|
|
20
20
|
import {
|
|
21
21
|
useConfig,
|
|
22
|
-
useCurrencies,
|
|
23
22
|
useGenerateSellTransaction,
|
|
23
|
+
useMarketCurrencies,
|
|
24
24
|
} from '../../../../hooks';
|
|
25
25
|
import { useFees } from '../../BuyModal/hooks/useFees';
|
|
26
26
|
import { useTransactionStatusModal } from '../../_internal/components/transactionStatusModal';
|
|
@@ -60,7 +60,7 @@ export const useTransactionSteps = ({
|
|
|
60
60
|
collectionAddress: collectionAddress,
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
const { data: currencies } =
|
|
63
|
+
const { data: currencies } = useMarketCurrencies({
|
|
64
64
|
chainId,
|
|
65
65
|
});
|
|
66
66
|
const { generateSellTransactionAsync, isPending: generatingSteps } =
|
|
@@ -26,7 +26,7 @@ const WalletAddressInput = observer(() => {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
|
-
<div className="[&>label>div
|
|
29
|
+
<div className="[&>label>div>span]:text-sm [&>label>div>span]:text-text-80 [&>label]:gap-1">
|
|
30
30
|
<TextInput
|
|
31
31
|
label="Wallet address"
|
|
32
32
|
labelLocation="top"
|
|
@@ -30,7 +30,6 @@ const EnterWalletAddressView = observer(() => {
|
|
|
30
30
|
isProcessingWithWaaS,
|
|
31
31
|
shouldHideActionButton: shouldHideTransferButton,
|
|
32
32
|
} = useSelectWaasFeeOptions({
|
|
33
|
-
chainId,
|
|
34
33
|
isProcessing: transferModal$.state.transferIsBeingProcessed.get(),
|
|
35
34
|
feeOptionsVisible: selectWaasFeeOptions$.isVisible.get(),
|
|
36
35
|
selectedFeeOption:
|
|
@@ -88,7 +88,6 @@ const TransferModal = observer(() => {
|
|
|
88
88
|
const isTransferBeingProcessed =
|
|
89
89
|
transferModal$.state.transferIsBeingProcessed.get();
|
|
90
90
|
const { waasFeeOptionsShown } = useSelectWaasFeeOptions({
|
|
91
|
-
chainId: chainId,
|
|
92
91
|
isProcessing: isTransferBeingProcessed,
|
|
93
92
|
feeOptionsVisible: selectWaasFeeOptions$.isVisible.get(),
|
|
94
93
|
selectedFeeOption:
|
package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx
CHANGED
|
@@ -23,7 +23,7 @@ describe('CurrencyOptionsSelect', () => {
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it('should render loading skeleton when currencies are loading', () => {
|
|
26
|
-
const useCurrenciesSpy = vi.spyOn(hooks, '
|
|
26
|
+
const useCurrenciesSpy = vi.spyOn(hooks, 'useMarketCurrencies');
|
|
27
27
|
useCurrenciesSpy.mockReturnValue({
|
|
28
28
|
isLoading: true,
|
|
29
29
|
data: undefined,
|
|
@@ -38,7 +38,7 @@ describe('CurrencyOptionsSelect', () => {
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
it('should set first currency as default when currencies load', async () => {
|
|
41
|
-
const useCurrenciesSpy = vi.spyOn(hooks, '
|
|
41
|
+
const useCurrenciesSpy = vi.spyOn(hooks, 'useMarketCurrencies');
|
|
42
42
|
useCurrenciesSpy.mockReturnValue({
|
|
43
43
|
isLoading: false,
|
|
44
44
|
data: TEST_CURRENCIES,
|