@0xsequence/marketplace-sdk 0.8.8 → 0.8.10
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/CHANGELOG.md +36 -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-KGM2WLSP.js → chunk-7F27CJZW.js} +14 -2
- package/dist/{chunk-KGM2WLSP.js.map → chunk-7F27CJZW.js.map} +1 -1
- package/dist/{chunk-MAD64DLJ.js → chunk-A7BVFBWB.js} +2 -2
- package/dist/{chunk-YBOFRP65.js → chunk-FGM57QUU.js} +2 -2
- package/dist/{chunk-HHYNOPPI.js → chunk-KTST7ORH.js} +2 -2
- package/dist/{chunk-35WWD5V6.js → chunk-M6NJ73Y5.js} +3 -3
- package/dist/chunk-Q3ECVC4F.js +811 -0
- package/dist/chunk-Q3ECVC4F.js.map +1 -0
- package/dist/{chunk-EODKQL6Y.js → chunk-RVIUUJTP.js} +2 -2
- package/dist/{chunk-G3447GIP.js → chunk-SXVUTSMT.js} +24 -9
- package/dist/chunk-SXVUTSMT.js.map +1 -0
- package/dist/{chunk-7IYKUVC3.js → chunk-UJSF7PSC.js} +251 -107
- package/dist/chunk-UJSF7PSC.js.map +1 -0
- package/dist/{chunk-YALXP2PW.js → chunk-WH5BZC7W.js} +2 -2
- package/dist/{chunk-4XLXOEXQ.js → chunk-Y2HJO2VY.js} +25 -4
- package/dist/chunk-Y2HJO2VY.js.map +1 -0
- package/dist/{create-config-DwrnzwpM.d.ts → create-config-CAQcvjl6.d.ts} +2 -2
- package/dist/{index-DGsVBflk.d.ts → index-MlUK9AQE.d.ts} +2 -2
- package/dist/index.css +74 -28
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +10 -4
- package/dist/{lowestListing-BQHIuvNF.d.ts → listTokenMetadata-DO4ChDjn.d.ts} +20 -2
- package/dist/{marketplaceConfig-B4Fdsmxu.d.ts → marketplaceConfig-D0MXemEl.d.ts} +1 -1
- package/dist/react/_internal/api/index.d.ts +3 -2
- package/dist/react/_internal/api/index.js +5 -1
- package/dist/react/_internal/databeat/index.js +11 -10
- package/dist/react/_internal/index.d.ts +6 -5
- package/dist/react/_internal/index.js +5 -1
- package/dist/react/_internal/wagmi/index.d.ts +3 -3
- package/dist/react/hooks/index.d.ts +11 -8
- package/dist/react/hooks/index.js +12 -9
- package/dist/react/hooks/options/index.d.ts +3 -3
- package/dist/react/hooks/options/index.js +3 -3
- package/dist/react/index.css +74 -28
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.ts +11 -10
- package/dist/react/index.js +18 -13
- package/dist/react/queries/index.d.ts +3 -2
- package/dist/react/queries/index.js +6 -4
- package/dist/react/ssr/index.d.ts +2 -2
- package/dist/react/ssr/index.js +2 -2
- package/dist/react/ui/components/collectible-card/index.css +74 -28
- package/dist/react/ui/components/collectible-card/index.css.map +1 -1
- package/dist/react/ui/components/collectible-card/index.d.ts +24 -1
- package/dist/react/ui/components/collectible-card/index.js +18 -15
- package/dist/react/ui/components/marketplace-logos/index.js +1 -1
- package/dist/react/ui/icons/index.js +7 -6
- package/dist/react/ui/index.css +74 -28
- package/dist/react/ui/index.css.map +1 -1
- package/dist/react/ui/index.d.ts +1 -1
- package/dist/react/ui/index.js +16 -13
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +11 -10
- package/dist/{sdk-config-txlivEKe.d.ts → sdk-config-onSPBxJj.d.ts} +1 -0
- package/dist/{services-BI_w8Eq4.d.ts → services-CMSb9ipU.d.ts} +5 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +1 -1
- package/dist/{types-isjvwapz.d.ts → types-B8xzPEKX.d.ts} +2 -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/abi/primary-sale/index.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +10 -4
- package/package.json +32 -31
- package/src/react/_internal/api/services.ts +12 -1
- package/src/react/hooks/index.ts +1 -0
- package/src/react/hooks/useList1155SaleSupplies.tsx +62 -0
- package/src/react/hooks/useListTokenMetadata.ts +19 -0
- package/src/react/queries/index.ts +1 -0
- package/src/react/queries/listTokenMetadata.ts +38 -0
- package/src/react/ui/components/ModelViewer.tsx +54 -0
- package/src/react/ui/components/_internals/custom-select/CustomSelect.tsx +0 -1
- package/src/react/ui/components/collectible-card/CollectibleCard.tsx +7 -3
- package/src/react/ui/components/collectible-card/__tests__/{CollectibleAsset.test.tsx → Media.test.tsx} +9 -15
- package/src/react/ui/components/collectible-card/index.ts +1 -0
- package/src/react/ui/components/collectible-card/media/Media.tsx +206 -0
- package/src/react/ui/components/collectible-card/{collectible-asset/CollectibleAssetSkeleton.tsx → media/MediaSkeleton.tsx} +1 -1
- package/src/react/ui/components/collectible-card/media/types.ts +17 -0
- package/src/react/ui/components/collectible-card/{collectible-asset → media}/utils.ts +16 -7
- package/src/react/ui/index.ts +1 -0
- package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +28 -3
- package/src/react/ui/modals/SuccessfulPurchaseModal/index.tsx +9 -7
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TokenQuantityInput.tsx +1 -1
- package/src/react/ui/modals/_internal/components/actionModal/ActionModal.test.tsx +0 -1
- package/src/react/ui/modals/_internal/components/priceInput/index.tsx +1 -1
- package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +1 -2
- package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +0 -1
- package/src/types/sdk-config.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 +11 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/chunk-4XLXOEXQ.js.map +0 -1
- package/dist/chunk-7IYKUVC3.js.map +0 -1
- package/dist/chunk-G3447GIP.js.map +0 -1
- package/dist/chunk-UISBTKFF.js +0 -1
- package/src/react/ui/components/collectible-card/collectible-asset/CollectibleAsset.tsx +0 -139
- /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-UISBTKFF.js.map → chunk-6CTFVBKU.js.map} +0 -0
- /package/dist/{chunk-MAD64DLJ.js.map → chunk-A7BVFBWB.js.map} +0 -0
- /package/dist/{chunk-YBOFRP65.js.map → chunk-FGM57QUU.js.map} +0 -0
- /package/dist/{chunk-HHYNOPPI.js.map → chunk-KTST7ORH.js.map} +0 -0
- /package/dist/{chunk-35WWD5V6.js.map → chunk-M6NJ73Y5.js.map} +0 -0
- /package/dist/{chunk-EODKQL6Y.js.map → chunk-RVIUUJTP.js.map} +0 -0
- /package/dist/{chunk-YALXP2PW.js.map → chunk-WH5BZC7W.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { EIP2981_ABI, SequenceMarketplaceV1_ABI, SequenceMarketplaceV2_ABI } from './abi/marketplace/index.js';
|
|
2
2
|
export { ERC1155_ABI, ERC20_ABI, ERC721_ABI } from './abi/token/index.js';
|
|
3
|
+
export { ERC1155_SALES_CONTRACT_ABI, ERC721_SALE_ABI } from './abi/primary-sale/index.js';
|
|
3
4
|
import { Image } from '@0xsequence/design-system';
|
|
4
5
|
import { ComponentType } from 'react';
|
|
5
6
|
import { M as MarketplaceKind } from '../marketplace.gen-DQzWciwC.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -10,9 +10,13 @@ import {
|
|
|
10
10
|
networkToWagmiChain,
|
|
11
11
|
truncateEnd,
|
|
12
12
|
truncateMiddle
|
|
13
|
-
} from "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
13
|
+
} from "../chunk-5O44EPXZ.js";
|
|
14
|
+
import "../chunk-5C6ZZ6WX.js";
|
|
15
|
+
import "../chunk-6CTFVBKU.js";
|
|
16
|
+
import {
|
|
17
|
+
ERC1155_SALES_CONTRACT_ABI,
|
|
18
|
+
ERC721_SALE_ABI
|
|
19
|
+
} from "../chunk-Q3ECVC4F.js";
|
|
16
20
|
import {
|
|
17
21
|
ERC1155_ABI,
|
|
18
22
|
ERC20_ABI,
|
|
@@ -25,14 +29,16 @@ import {
|
|
|
25
29
|
} from "../chunk-XX4EVWBF.js";
|
|
26
30
|
import "../chunk-2PSNAIAT.js";
|
|
27
31
|
import "../chunk-DWTLVJAW.js";
|
|
28
|
-
import "../chunk-
|
|
32
|
+
import "../chunk-7F27CJZW.js";
|
|
29
33
|
import "../chunk-D7RVSZAQ.js";
|
|
30
34
|
import "../chunk-NX52D7NX.js";
|
|
31
35
|
export {
|
|
32
36
|
EIP2981_ABI,
|
|
33
37
|
ERC1155_ABI,
|
|
38
|
+
ERC1155_SALES_CONTRACT_ABI,
|
|
34
39
|
ERC20_ABI,
|
|
35
40
|
ERC721_ABI,
|
|
41
|
+
ERC721_SALE_ABI,
|
|
36
42
|
SequenceMarketplaceV1_ABI,
|
|
37
43
|
SequenceMarketplaceV2_ABI,
|
|
38
44
|
calculateEarningsAfterFees,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xsequence/marketplace-sdk",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.10",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
7
7
|
"**/*.css"
|
|
@@ -41,59 +41,60 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@databeat/tracker": "^0.9.3",
|
|
43
43
|
"@legendapp/state": "^3.0.0-beta.30",
|
|
44
|
-
"@tailwindcss/postcss": "^4.
|
|
45
|
-
"@xstate/store": "^3.
|
|
44
|
+
"@tailwindcss/postcss": "^4.1.6",
|
|
45
|
+
"@xstate/store": "^3.6.0",
|
|
46
46
|
"class-variance-authority": "^0.7.1",
|
|
47
47
|
"clsx": "^2.1.1",
|
|
48
48
|
"date-fns": "^4.1.0",
|
|
49
49
|
"dnum": "^2.14.0",
|
|
50
50
|
"nuqs": "^2.4.3",
|
|
51
51
|
"react-day-picker": "^9.6.7",
|
|
52
|
-
"tailwind-merge": "^3.0
|
|
53
|
-
"zod": "^3.24.
|
|
52
|
+
"tailwind-merge": "^3.3.0",
|
|
53
|
+
"zod": "^3.24.4"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"0xsequence": "^2.3.
|
|
57
|
-
"@0xsequence/api": "^2.3.
|
|
58
|
-
"@0xsequence/checkout": "^5.
|
|
59
|
-
"@0xsequence/connect": "^5.
|
|
60
|
-
"@0xsequence/design-system": "^2.1.
|
|
61
|
-
"@0xsequence/indexer": "^2.3.
|
|
62
|
-
"@0xsequence/metadata": "^2.3.
|
|
63
|
-
"@0xsequence/network": "^2.3.
|
|
64
|
-
"@tanstack/react-query": "^5.
|
|
56
|
+
"0xsequence": "^2.3.12",
|
|
57
|
+
"@0xsequence/api": "^2.3.12",
|
|
58
|
+
"@0xsequence/checkout": "^5.3.1",
|
|
59
|
+
"@0xsequence/connect": "^5.3.1",
|
|
60
|
+
"@0xsequence/design-system": "^2.1.12",
|
|
61
|
+
"@0xsequence/indexer": "^2.3.12",
|
|
62
|
+
"@0xsequence/metadata": "^2.3.12",
|
|
63
|
+
"@0xsequence/network": "^2.3.12",
|
|
64
|
+
"@tanstack/react-query": "^5.76.1",
|
|
65
65
|
"react": "^19.1.0",
|
|
66
66
|
"react-dom": "^19.1.0",
|
|
67
|
-
"viem": "^2.
|
|
68
|
-
"wagmi": "^2.
|
|
67
|
+
"viem": "^2.29.2",
|
|
68
|
+
"wagmi": "^2.15.3",
|
|
69
|
+
"@google/model-viewer": "^4.1.0"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
72
|
"@biomejs/biome": "^1.9.4",
|
|
72
|
-
"@changesets/cli": "^2.29.
|
|
73
|
-
"@eslint/js": "^9.
|
|
73
|
+
"@changesets/cli": "^2.29.4",
|
|
74
|
+
"@eslint/js": "^9.26.0",
|
|
74
75
|
"@testing-library/jest-dom": "6.4.7",
|
|
75
|
-
"@testing-library/react": "^16.
|
|
76
|
-
"@types/react": "^19.1.
|
|
77
|
-
"@types/react-dom": "^19.1.
|
|
76
|
+
"@testing-library/react": "^16.3.0",
|
|
77
|
+
"@types/react": "^19.1.4",
|
|
78
|
+
"@types/react-dom": "^19.1.5",
|
|
78
79
|
"@vitest/coverage-v8": "3.0.9",
|
|
79
80
|
"ctix": "^2.7.1",
|
|
80
81
|
"esbuild-plugin-preserve-directives": "^0.0.11",
|
|
81
|
-
"eslint": "^9.
|
|
82
|
+
"eslint": "^9.26.0",
|
|
82
83
|
"eslint-config-biome": "^1.9.4",
|
|
83
|
-
"eslint-plugin-react": "^7.37.
|
|
84
|
+
"eslint-plugin-react": "^7.37.5",
|
|
84
85
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
85
|
-
"globals": "^16.
|
|
86
|
-
"happy-dom": "^17.4.
|
|
87
|
-
"jsdom": "^26.
|
|
88
|
-
"msw": "^2.
|
|
86
|
+
"globals": "^16.1.0",
|
|
87
|
+
"happy-dom": "^17.4.7",
|
|
88
|
+
"jsdom": "^26.1.0",
|
|
89
|
+
"msw": "^2.8.2",
|
|
89
90
|
"postcss": "^8.5.3",
|
|
90
|
-
"prool": "^0.0.
|
|
91
|
-
"tailwindcss": "^4.1.
|
|
91
|
+
"prool": "^0.0.24",
|
|
92
|
+
"tailwindcss": "^4.1.6",
|
|
92
93
|
"tsup": "^8.4.0",
|
|
93
94
|
"typescript": "^5.8.3",
|
|
94
|
-
"typescript-eslint": "^8.
|
|
95
|
+
"typescript-eslint": "^8.32.1",
|
|
95
96
|
"vite-tsconfig-paths": "^5.1.4",
|
|
96
|
-
"vitest": "^3.
|
|
97
|
+
"vitest": "^3.1.3"
|
|
97
98
|
},
|
|
98
99
|
"scripts": {
|
|
99
100
|
"build": "tsc -b && tsup",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SequenceAPIClient } from '@0xsequence/api';
|
|
1
2
|
import { SequenceIndexer } from '@0xsequence/indexer';
|
|
2
3
|
import { SequenceMetadata } from '@0xsequence/metadata';
|
|
3
4
|
import { networks, stringTemplate } from '@0xsequence/network';
|
|
@@ -6,7 +7,7 @@ import { MissingConfigError } from '../../../utils/_internal/error/transaction';
|
|
|
6
7
|
import { SequenceMarketplace } from './marketplace-api';
|
|
7
8
|
|
|
8
9
|
const SERVICES = {
|
|
9
|
-
sequenceApi: 'https
|
|
10
|
+
sequenceApi: 'https://${prefix}api.sequence.app',
|
|
10
11
|
metadata: 'https://${prefix}metadata.sequence.app',
|
|
11
12
|
indexer: 'https://${prefix}${network}-indexer.sequence.app',
|
|
12
13
|
marketplaceApi: 'https://${prefix}marketplace-api.sequence.app/${network}',
|
|
@@ -51,6 +52,11 @@ export const builderRpcApi = (env: Env = 'production') => {
|
|
|
51
52
|
return stringTemplate(SERVICES.builderRpcApi, { prefix });
|
|
52
53
|
};
|
|
53
54
|
|
|
55
|
+
export const sequenceApiUrl = (env: Env = 'production') => {
|
|
56
|
+
const prefix = getPrefix(env);
|
|
57
|
+
return stringTemplate(SERVICES.sequenceApi, { prefix });
|
|
58
|
+
};
|
|
59
|
+
|
|
54
60
|
export const builderMarketplaceApi = (
|
|
55
61
|
projectId: string,
|
|
56
62
|
env: Env = 'production',
|
|
@@ -82,6 +88,11 @@ export const getMarketplaceClient = (
|
|
|
82
88
|
projectAccessKey,
|
|
83
89
|
);
|
|
84
90
|
};
|
|
91
|
+
export const getSequenceApiClient = (config: SdkConfig) => {
|
|
92
|
+
const env = config._internal?.sequenceApiEnv || 'production';
|
|
93
|
+
const projectAccessKey = getAccessKey({ env, config });
|
|
94
|
+
return new SequenceAPIClient(sequenceApiUrl(env), projectAccessKey);
|
|
95
|
+
};
|
|
85
96
|
const getAccessKey = ({ env, config }: { env: Env; config: SdkConfig }) => {
|
|
86
97
|
switch (env) {
|
|
87
98
|
case 'development':
|
package/src/react/hooks/index.ts
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getUnixTime } from 'date-fns';
|
|
2
|
+
import type { Address } from 'viem';
|
|
3
|
+
import { useReadContracts } from 'wagmi';
|
|
4
|
+
import { ERC1155_SALES_CONTRACT_ABI } from '../..';
|
|
5
|
+
|
|
6
|
+
interface UseSaleSupplyDataProps {
|
|
7
|
+
tokenIds: string[];
|
|
8
|
+
salesContractAddress: Address;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function useList1155SaleSupplies({
|
|
12
|
+
tokenIds,
|
|
13
|
+
salesContractAddress,
|
|
14
|
+
}: UseSaleSupplyDataProps) {
|
|
15
|
+
const getReadContractsArgs = (tokenIds: string[]) =>
|
|
16
|
+
tokenIds.map((tokenId) => ({
|
|
17
|
+
address: salesContractAddress,
|
|
18
|
+
abi: ERC1155_SALES_CONTRACT_ABI,
|
|
19
|
+
functionName: 'tokenSaleDetails',
|
|
20
|
+
args: [tokenId],
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
data: supplyData,
|
|
25
|
+
isLoading: supplyDataLoading,
|
|
26
|
+
error: supplyDataError,
|
|
27
|
+
} = useReadContracts({
|
|
28
|
+
batchSize: 500_000, // Node gateway limit has a limit of 512kB, setting it to 500kB to be safe
|
|
29
|
+
contracts: getReadContractsArgs(tokenIds),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const extendedSupplyData = (supplyData || [])
|
|
33
|
+
.map((data, index) => ({
|
|
34
|
+
...data,
|
|
35
|
+
tokenId: tokenIds[index],
|
|
36
|
+
}))
|
|
37
|
+
.filter((data) => data.status === 'success')
|
|
38
|
+
.filter((data) => {
|
|
39
|
+
if (typeof data.result !== 'object') return false;
|
|
40
|
+
const now = BigInt(getUnixTime(new Date()));
|
|
41
|
+
return data.result.endTime > now && data.result.startTime < now;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const getSupply = (tokenId: string): number | undefined => {
|
|
45
|
+
const found = extendedSupplyData.find((data) => data.tokenId === tokenId);
|
|
46
|
+
if (!found || typeof found.result !== 'object' || found.result === null)
|
|
47
|
+
return undefined;
|
|
48
|
+
const supply = found.result.supplyCap;
|
|
49
|
+
if (supply === undefined) return undefined;
|
|
50
|
+
// https://github.com/0xsequence/contracts-library/blob/ead1baf34270c76260d01cfc130bb7cc9d57518e/src/tokens/ERC1155/utility/sale/IERC1155Sale.sol#L8
|
|
51
|
+
// 0 means infinite
|
|
52
|
+
if (supply === 0n) return Number.POSITIVE_INFINITY;
|
|
53
|
+
return Number(supply);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
extendedSupplyData,
|
|
58
|
+
getSupply,
|
|
59
|
+
supplyDataLoading,
|
|
60
|
+
supplyDataError,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { useConfig } from './useConfig';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
type FetchTokenMetadataArgs,
|
|
6
|
+
tokenMetadataOptions,
|
|
7
|
+
} from '../queries/listTokenMetadata';
|
|
8
|
+
|
|
9
|
+
export const useListTokenMetadata = (args: FetchTokenMetadataArgs) => {
|
|
10
|
+
const config = useConfig();
|
|
11
|
+
const { chainId, contractAddress, tokenIds, query } = args;
|
|
12
|
+
|
|
13
|
+
return useQuery({
|
|
14
|
+
...tokenMetadataOptions(
|
|
15
|
+
{ chainId, contractAddress, tokenIds, query },
|
|
16
|
+
config,
|
|
17
|
+
),
|
|
18
|
+
});
|
|
19
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { queryOptions } from '@tanstack/react-query';
|
|
2
|
+
import type { SdkConfig } from '../../types';
|
|
3
|
+
import { getMetadataClient } from '../_internal';
|
|
4
|
+
|
|
5
|
+
export interface FetchTokenMetadataArgs {
|
|
6
|
+
chainId: number;
|
|
7
|
+
contractAddress: string;
|
|
8
|
+
tokenIds: string[];
|
|
9
|
+
query?: {
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const fetchTokenMetadata = async (
|
|
15
|
+
{ chainId, contractAddress, tokenIds }: FetchTokenMetadataArgs,
|
|
16
|
+
config: SdkConfig,
|
|
17
|
+
) => {
|
|
18
|
+
const metadataClient = getMetadataClient(config);
|
|
19
|
+
|
|
20
|
+
const response = await metadataClient.getTokenMetadata({
|
|
21
|
+
chainID: chainId.toString(),
|
|
22
|
+
contractAddress: contractAddress,
|
|
23
|
+
tokenIDs: tokenIds,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return response.tokenMetadata;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const tokenMetadataOptions = (
|
|
30
|
+
args: FetchTokenMetadataArgs,
|
|
31
|
+
config: SdkConfig,
|
|
32
|
+
) => {
|
|
33
|
+
return queryOptions({
|
|
34
|
+
...args.query,
|
|
35
|
+
queryKey: ['listTokenMetadata', args.chainId, args.contractAddress],
|
|
36
|
+
queryFn: () => fetchTokenMetadata(args, config),
|
|
37
|
+
});
|
|
38
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Skeleton } from '@0xsequence/design-system';
|
|
2
|
+
import { Suspense, lazy } from 'react';
|
|
3
|
+
|
|
4
|
+
const ModelViewerComponent = lazy(() =>
|
|
5
|
+
import('@google/model-viewer').then(() => ({
|
|
6
|
+
default: ({
|
|
7
|
+
posterSrc,
|
|
8
|
+
src,
|
|
9
|
+
onLoad,
|
|
10
|
+
onError,
|
|
11
|
+
}: {
|
|
12
|
+
posterSrc: string;
|
|
13
|
+
src?: string;
|
|
14
|
+
onLoad?: () => void;
|
|
15
|
+
onError?: () => void;
|
|
16
|
+
}) => (
|
|
17
|
+
<div className="h-full w-full bg-background-raised">
|
|
18
|
+
{/* @ts-expect-error - This is a web component */}
|
|
19
|
+
<model-viewer
|
|
20
|
+
alt="3d model"
|
|
21
|
+
auto-rotate
|
|
22
|
+
autoplay
|
|
23
|
+
camera-controls
|
|
24
|
+
class="h-full w-full"
|
|
25
|
+
error={onError}
|
|
26
|
+
load={onLoad}
|
|
27
|
+
loading="eager"
|
|
28
|
+
poster={posterSrc}
|
|
29
|
+
reveal="auto"
|
|
30
|
+
shadow-intensity="1"
|
|
31
|
+
src={src}
|
|
32
|
+
touch-action="pan-y"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
),
|
|
36
|
+
})),
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const ModelViewerLoading = () => <Skeleton className="h-full w-full" />;
|
|
40
|
+
|
|
41
|
+
const ModelViewer = (props: {
|
|
42
|
+
posterSrc: string;
|
|
43
|
+
src?: string;
|
|
44
|
+
onLoad?: () => void;
|
|
45
|
+
onError?: () => void;
|
|
46
|
+
}) => {
|
|
47
|
+
return (
|
|
48
|
+
<Suspense fallback={<ModelViewerLoading />}>
|
|
49
|
+
<ModelViewerComponent {...props} />
|
|
50
|
+
</Suspense>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default ModelViewer;
|
|
@@ -12,7 +12,7 @@ import { useCurrency } from '../../../hooks';
|
|
|
12
12
|
import { ActionButton } from '../_internals/action-button/ActionButton';
|
|
13
13
|
import { CollectibleCardAction } from '../_internals/action-button/types';
|
|
14
14
|
import { Footer } from './Footer';
|
|
15
|
-
import {
|
|
15
|
+
import { Media } from './media/Media';
|
|
16
16
|
|
|
17
17
|
function CollectibleSkeleton() {
|
|
18
18
|
return (
|
|
@@ -127,9 +127,13 @@ export function CollectibleCard({
|
|
|
127
127
|
>
|
|
128
128
|
<div className="group relative z-10 flex h-full w-full cursor-pointer flex-col items-start overflow-hidden rounded-xl border-none bg-none p-0 focus:outline-none [&:focus]:rounded-[10px] [&:focus]:outline-[3px] [&:focus]:outline-black [&:focus]:outline-offset-[-3px]">
|
|
129
129
|
<article className="w-full rounded-xl">
|
|
130
|
-
<
|
|
130
|
+
<Media
|
|
131
131
|
name={collectibleMetadata?.name || ''}
|
|
132
|
-
|
|
132
|
+
assets={[
|
|
133
|
+
collectibleMetadata?.image,
|
|
134
|
+
collectibleMetadata?.video,
|
|
135
|
+
collectibleMetadata?.animation_url,
|
|
136
|
+
]}
|
|
133
137
|
assetSrcPrefixUrl={assetSrcPrefixUrl}
|
|
134
138
|
/>
|
|
135
139
|
|
|
@@ -2,10 +2,10 @@ import { render, screen, waitFor } from '@test/test-utils';
|
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
3
|
import * as fetchContentTypeModule from '../../../../../utils/fetchContentType';
|
|
4
4
|
import type { TokenMetadata } from '../../../../_internal';
|
|
5
|
-
import {
|
|
6
|
-
import * as contentTypeUtils from '../
|
|
5
|
+
import { Media } from '../media/Media';
|
|
6
|
+
import * as contentTypeUtils from '../media/utils';
|
|
7
7
|
|
|
8
|
-
describe('
|
|
8
|
+
describe('Media', () => {
|
|
9
9
|
it('renders image content correctly with proper loading states and fallback', async () => {
|
|
10
10
|
const originalImage = window.Image;
|
|
11
11
|
|
|
@@ -30,10 +30,7 @@ describe('CollectibleAsset', () => {
|
|
|
30
30
|
|
|
31
31
|
// Initial render should show the loading skeleton
|
|
32
32
|
const { rerender } = render(
|
|
33
|
-
<
|
|
34
|
-
name="Test Collectible"
|
|
35
|
-
collectibleMetadata={mockMetadata as TokenMetadata}
|
|
36
|
-
/>,
|
|
33
|
+
<Media name="Test Collectible" assets={[mockMetadata.image]} />,
|
|
37
34
|
);
|
|
38
35
|
|
|
39
36
|
// check if skeleton is rendered during loading
|
|
@@ -69,9 +66,9 @@ describe('CollectibleAsset', () => {
|
|
|
69
66
|
};
|
|
70
67
|
|
|
71
68
|
rerender(
|
|
72
|
-
<
|
|
69
|
+
<Media
|
|
73
70
|
name="Test Collectible"
|
|
74
|
-
|
|
71
|
+
assets={[mockMetadataWithBadImage.image]}
|
|
75
72
|
/>,
|
|
76
73
|
);
|
|
77
74
|
|
|
@@ -127,10 +124,7 @@ describe('CollectibleAsset', () => {
|
|
|
127
124
|
};
|
|
128
125
|
|
|
129
126
|
render(
|
|
130
|
-
<
|
|
131
|
-
name="Video Collectible"
|
|
132
|
-
collectibleMetadata={mockVideoMetadata as TokenMetadata}
|
|
133
|
-
/>,
|
|
127
|
+
<Media name="Video Collectible" assets={[mockVideoMetadata.video]} />,
|
|
134
128
|
);
|
|
135
129
|
|
|
136
130
|
await waitFor(() => {
|
|
@@ -192,9 +186,9 @@ describe('CollectibleAsset', () => {
|
|
|
192
186
|
};
|
|
193
187
|
|
|
194
188
|
render(
|
|
195
|
-
<
|
|
189
|
+
<Media
|
|
196
190
|
name="HTML Collectible"
|
|
197
|
-
|
|
191
|
+
assets={[mockHtmlMetadata.animation_url]}
|
|
198
192
|
/>,
|
|
199
193
|
);
|
|
200
194
|
|