Skip to content

Commit f8cc428

Browse files
committed
Add basic docs WIP
1 parent 4b2164c commit f8cc428

19 files changed

+336
-161
lines changed

.prettierignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Add files here to ignore them from prettier formatting
2+
3+
/dist
4+
/coverage
5+
6+
/.nx/cache

.prettierrc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"trailingComma": "all",
3+
"singleQuote": true,
4+
"bracketSpacing": true,
5+
"bracketSameLine": false,
6+
"parser": "typescript",
7+
"printWidth": 100,
8+
"tabWidth": 2,
9+
"useTabs": false,
10+
"semi": true
11+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"glob": "^10.3.10",
4141
"happy-dom": "^13.1.4",
4242
"jsdom": "^23.2.0",
43-
"prettier": "^2.8.5",
43+
"prettier": "^2.8.8",
4444
"simple-git-hooks": "^2.9.0",
4545
"ts-node": "10.9.1",
4646
"typescript": "5.4.0-dev.20240116",

packages/nft-renderer/README.md

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,60 @@ pnpm install @rmrk-team/nft-renderer
1313
## Usage
1414

1515
```tsx
16-
import { Address } from "viem";
16+
import React from "react";
17+
import type {Address} from "viem";
18+
import {
19+
NETWORK_CONTRACTS_PROPS,
20+
RMRKUtilityContracts,
21+
} from "@rmrk-team/rmrk-evm-utils";
22+
import {RMRKContextProvider} from "@rmrk-team/rmrk-hooks";
23+
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
24+
import {WagmiProvider} from "wagmi";
25+
import {hardhat} from "wagmi/chains";
1726

18-
export const NftRendererWrapper
19-
({
20-
chainId, contractAddress, tokenId
27+
const queryClient = new QueryClient();
28+
29+
// You can pass custom utility contracts to the RMRKContextProvider
30+
const customUtilityContracts = {
31+
[hardhat.id]: {
32+
[NETWORK_CONTRACTS_PROPS.RMRKEquipRenderUtils]: "0x00",
33+
[NETWORK_CONTRACTS_PROPS.RMRKBulkWriter]: "0x00",
34+
[NETWORK_CONTRACTS_PROPS.RMRKCollectionUtils]: "0x00",
35+
[NETWORK_CONTRACTS_PROPS.RMRKCatalogUtils]: "0x00",
36+
},
37+
} satisfies RMRKUtilityContracts;
38+
39+
const rmrkConfig = {
40+
utilityContracts: customUtilityContracts,
41+
};
42+
43+
export const NftRendererWrapper = ({
44+
contractAddress,
45+
tokenId,
2146
}: {
22-
chainId: number, contractAddress: Address, tokenId: bigint
47+
chainId: number;
48+
contractAddress: Address;
49+
tokenId: bigint;
2350
}) => {
24-
return (
25-
<Flex height="100vh" width="100vw">
26-
<Flex height="100vh" aspectRatio={'1/1'} margin="0 auto">
27-
<NFTRenderer
28-
chainId={chainId}
29-
contractAddress={collection}
30-
tokenId={tokenId}
31-
loader={<Loader/>}
32-
/>
51+
return (
52+
<WagmiProvider config={wagmiConfig}>
53+
<QueryClientProvider client={queryClient}>
54+
<RMRKContextProvider config={rmrkConfig}>
55+
<Flex height="100vh" width="100vw">
56+
<Flex height="100vh" aspectRatio={"1/1"} margin="0 auto">
57+
<NFTRenderer
58+
chainId={chainId}
59+
contractAddress={contractAddress}
60+
tokenId={tokenId}
61+
loader={<Loader/>}
62+
/>
3363
</Flex>
34-
</Flex>
35-
);
36-
}
64+
</Flex>
65+
</RMRKContextProvider>
66+
</QueryClientProvider>
67+
</WagmiProvider>
68+
);
69+
};
3770
```
3871

3972
## Building

packages/nft-renderer/src/components/nft-renderer.tsx

Lines changed: 76 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
import { MultiLayer2DRenderer } from '@rmrk-team/rmrk-2d-renderer';
2-
import {
3-
RMRKCatalogImpl,
4-
RMRKEquippableImpl,
5-
mapChainIdToNetwork,
6-
} from '@rmrk-team/rmrk-evm-utils';
2+
import { RMRKCatalogImpl, RMRKEquippableImpl } from '@rmrk-team/rmrk-evm-utils';
73
import {
84
useFetchIpfsMetadata,
95
useGetAssetData,
106
useGetComposedState,
117
useGetInterfaceSupport,
12-
useRMRKConfig,
138
} from '@rmrk-team/rmrk-hooks';
149
import React, { useEffect, useRef, useState } from 'react';
1510
import { css } from 'styled-system/css';
@@ -20,6 +15,57 @@ import type { Chain } from 'wagmi/chains';
2015
import '../styles/index.css';
2116
import type { RenderPart } from '../types/types.js';
2217

18+
const useIsAddressAContract = ({
19+
address,
20+
chainId,
21+
onError,
22+
}: {
23+
address: Address;
24+
chainId: Chain['id'];
25+
onError?: (error: Error) => void;
26+
}) => {
27+
const publicClient = usePublicClient({
28+
chainId,
29+
});
30+
31+
const [isContract, setIsContract] = useState<boolean>();
32+
const [isLoading, setIsLoading] = useState<boolean>(false);
33+
const [error, setError] = useState<Error>();
34+
35+
useEffect(() => {
36+
const isValidAddress = isAddress(address);
37+
38+
if (isValidAddress) {
39+
(async () => {
40+
setIsLoading(true);
41+
const isContract = await publicClient.getBytecode({
42+
address,
43+
});
44+
setIsContract(!!isContract);
45+
setIsLoading(false);
46+
if (!isContract) {
47+
setError(new Error(`Address ${address} is not a contract`));
48+
}
49+
})();
50+
} else {
51+
setError(new Error(`Address ${address} is not a valid address`));
52+
}
53+
}, [address, publicClient]);
54+
55+
useEffect(() => {
56+
if (error && onError) {
57+
onError(error);
58+
}
59+
}, [error, onError]);
60+
61+
return {
62+
isContract,
63+
isLoading,
64+
error,
65+
isError: !!error,
66+
};
67+
};
68+
2369
type NFTRenderer = {
2470
chainId: Chain['id'];
2571
contractAddress: Address;
@@ -30,42 +76,31 @@ type NFTRenderer = {
3076
};
3177

3278
/**
33-
* @description To use this component, make sure you have a WagmiProvider wrapped it
79+
* Renders a multi layered RMRK NFT based on the provided parameters.
80+
*
81+
* @param {Object} options - The options for rendering the NFT.
82+
* @param {string} options.chainId - The chain ID of the blockchain network.
83+
* @param {string} options.contractAddress - The address of the contract containing the NFT.
84+
* @param {string} options.tokenId - The ID of the token to render.
85+
* @param {ReactNode} options.loader - The loader component to display while the NFT is loading.
86+
* @param {Function} options.onError - The callback function to handle errors.
3487
*/
3588
export function NFTRenderer({
3689
chainId,
3790
contractAddress,
3891
tokenId,
39-
advancedMode,
4092
loader,
4193
onError,
4294
}: NFTRenderer) {
4395
const rendererContainerRef = useRef<null | HTMLDivElement>(null);
4496
const tokenIdBigint = BigInt(tokenId);
45-
const network = mapChainIdToNetwork(chainId);
46-
47-
const config = useRMRKConfig();
48-
49-
const publicClient = usePublicClient({
50-
chainId,
51-
});
5297

53-
const isValidAddress = isAddress(contractAddress);
54-
const [isContract, setIsContract] = useState<boolean>();
55-
const [isGettingIsContract, setIsGettingIsContract] = useState<boolean>(true);
56-
57-
useEffect(() => {
58-
(async () => {
59-
if (isValidAddress) {
60-
setIsGettingIsContract(true);
61-
const isContract = await publicClient.getBytecode({
62-
address: contractAddress,
63-
});
64-
setIsContract(!!isContract);
65-
setIsGettingIsContract(false);
66-
}
67-
})();
68-
}, [contractAddress, isValidAddress, publicClient]);
98+
const {
99+
isContract,
100+
isLoading: isLoadingIsContract,
101+
isError: isErrorIsContract,
102+
error: errorIsContract,
103+
} = useIsAddressAContract({ address: contractAddress, chainId });
69104

70105
const {
71106
isLoading: isLoadingGetInterfaceSupport,
@@ -129,6 +164,7 @@ export function NFTRenderer({
129164
data: catalogType,
130165
isLoading: loadingCatalogType,
131166
error: errorCatalogType,
167+
isError: isErrorCatalogType,
132168
} = useReadContract({
133169
address: catalogAddress,
134170
abi: RMRKCatalogImpl,
@@ -179,9 +215,15 @@ export function NFTRenderer({
179215
isErrorTokenUri ||
180216
isErrorTokenMetadata ||
181217
isErrorPrimaryAsset ||
182-
isErrorComposableState;
218+
isErrorComposableState ||
219+
isErrorIsContract ||
220+
isErrorCatalogType;
183221

184-
const error = errorComposableState || errorPrimaryAsset;
222+
const error =
223+
errorComposableState ||
224+
errorPrimaryAsset ||
225+
errorIsContract ||
226+
errorCatalogType;
185227

186228
useEffect(() => {
187229
if (error && onError) {
@@ -204,7 +246,7 @@ export function NFTRenderer({
204246
}
205247

206248
const isLoading =
207-
isGettingIsContract ||
249+
isLoadingIsContract ||
208250
isLoadingTokenUri ||
209251
isLoadingPrimaryAsset ||
210252
isLoadingTokenMetadata ||
@@ -241,32 +283,6 @@ export function NFTRenderer({
241283
</div>
242284
) : (
243285
<>
244-
{isValidAddress === false ? <p>Invalid address</p> : null}
245-
{isValidAddress && !isContract ? <p>Not a contract</p> : null}
246-
{isContract && isErrorTokenUri ? <p>Failed to get NFT data</p> : null}
247-
248-
{advancedMode ? (
249-
<>
250-
<h1>
251-
Token {tokenId.toString()} on {network} in {contractAddress}
252-
</h1>
253-
{composableState ? (
254-
<div>
255-
<>
256-
<p>Is Equippable</p>
257-
<p>metadataURI: {assetMetadataUri}</p>
258-
<p>groupId: {equippableGroupId?.toString()}</p>
259-
<p>catalog: {catalogAddress}</p>
260-
</>
261-
</div>
262-
) : primaryAsset ? (
263-
<p>metadataURI: {primaryAsset.metadataUri}</p>
264-
) : tokenUri ? (
265-
<p>metadataURI: {tokenUri}</p>
266-
) : null}
267-
</>
268-
) : null}
269-
270286
{renderParts && renderParts.length > 0 ? (
271287
<MultiLayer2DRenderer
272288
resources={renderParts}

packages/nft-renderer/src/components/providers.tsx

Lines changed: 0 additions & 16 deletions
This file was deleted.

packages/nft-renderer/src/components/wagmi-provider.tsx

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/nft-renderer/src/lib/web3/wagmi-config.ts

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)