Skip to content

Commit

Permalink
Merge pull request #90 from lukso-network/feat/up-recovery-list
Browse files Browse the repository at this point in the history
add labels to display main contracts and assets names + symbols
  • Loading branch information
Hugoo authored Feb 9, 2024
2 parents dd55c3c + 39a4152 commit c81e677
Show file tree
Hide file tree
Showing 16 changed files with 11,645 additions and 867 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: ./package-lock.json

- name: Install
run: npm install
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: ./package-lock.json

- name: Install and Build 🔧
run: |
Expand Down
189 changes: 189 additions & 0 deletions components/AddressInfos/AddressInfos.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/**
* @author Jean Cavallera <CJ42>
*/
import React, { useState, useContext, useEffect } from 'react';
import Skeleton from 'react-loading-skeleton';
import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts';

import { NetworkContext } from '../../contexts/NetworksContext';
import useWeb3 from '../../hooks/useWeb3';
import {
EXPLORER_BASE_URL,
LSP1_DELEGATE_ADDRESS,
UP_RECOVERY_ADDRESSES,
} from '../../globals';
import { checkInterface, getData } from '../../utils/web3';

interface Props {
address: string;
}

interface BadgeProps {
text: string;
isLight: boolean;
colorClass?: string;
}

interface AssetProps {
name: string;
symbol: string;
}

const AddressTypeBadge: React.FC<BadgeProps> = ({
text,
isLight,
colorClass,
}) => {
let classText = colorClass;
classText += isLight ? ' is-light' : '';
return <span className={`tag mr-2 ${classText}`}>{text}</span>;
};

const AssetInfosBadge: React.FC<AssetProps> = ({ name, symbol }) => {
return (
<>
<div className="tags has-addons mr-2" style={{ display: 'inline' }}>
<span className="tag is-info">name:</span>
<span className="tag is-light">{name}</span>
</div>
<div className="tags has-addons" style={{ display: 'inline' }}>
<span className="tag is-info">symbol:</span>
<span className="tag is-light">{symbol}</span>
</div>
</>
);
};

const AddressInfos: React.FC<Props> = ({ address }) => {
const web3 = useWeb3();
const { network } = useContext(NetworkContext);

const recoveryAddresses = UP_RECOVERY_ADDRESSES[network.name];

const [isLoading, setIsLoading] = useState(true);
const [isEOA, setIsEOA] = useState(true);
const [isLSP7, setIsLSP7] = useState(false);
const [isLSP8, setIsLSP8] = useState(false);
const [assetName, setAssetName] = useState('');
const [assetSymbol, setAssetSymbol] = useState('');

const checkAddressInterface = async (_address: string) => {
if (!web3 || !_address) {
return;
}

const bytecode = await web3.eth.getCode(_address);

if (!bytecode || bytecode === '0x') {
setIsEOA(true);
return;
}

setIsEOA(false);

const { isLsp7DigitalAsset, isLsp8IdentifiableDigitalAsset } =
await checkInterface(_address, web3);

setIsLSP7(isLsp7DigitalAsset);
setIsLSP8(isLsp8IdentifiableDigitalAsset);

const nameBytesValue = await getData(
address,
ERC725YDataKeys.LSP4.LSP4TokenName,
web3,
);

if (nameBytesValue) {
setAssetName(web3.utils.toUtf8(nameBytesValue));
}

const symbolBytesValue = await getData(
address,
ERC725YDataKeys.LSP4.LSP4TokenSymbol,
web3,
);

if (symbolBytesValue) {
setAssetSymbol(web3.utils.toUtf8(symbolBytesValue));
}
};

useEffect(() => {
if (!address) return;
setIsLoading(true);

checkAddressInterface(address)
.then(() => setIsLoading(false))
.catch(() => setIsLoading(false));
}, [address, web3]);

const isUPRecovery = recoveryAddresses.includes(address);
const isLSP1Delegate = address === LSP1_DELEGATE_ADDRESS;

const addressTypeText = isEOA ? '🔑 EOA' : '📄 Contract';

const explorerLink = `${EXPLORER_BASE_URL[network.name]}/address/${address}`;

const renderTags = () => {
if (isLoading) {
return <Skeleton width="120px" />;
}

return (
<>
{isUPRecovery && (
<AddressTypeBadge
text="🌱 - UP Recovery"
colorClass="is-success"
isLight={false}
/>
)}

{isLSP1Delegate && (
<AddressTypeBadge
text="📢 - LSP1 Delegate"
colorClass="is-link"
isLight={false}
/>
)}

{isLSP7 && (
<>
<AddressTypeBadge
text="🪙 - LSP7 Digital Asset"
colorClass="is-warning"
isLight={true}
/>
<AssetInfosBadge name={assetName} symbol={assetSymbol} />
</>
)}

{isLSP8 && (
<>
<AddressTypeBadge
text="🎨 - LSP8 Identifiable Digital Asset"
colorClass="is-link"
isLight={true}
/>
<AssetInfosBadge name={assetName} symbol={assetSymbol} />
</>
)}
</>
);
};

return (
<div>
<code className="mr-2">
<a target="_blank" rel="noreferrer" href={explorerLink}>
{address}
</a>
</code>
<AddressTypeBadge text={addressTypeText} isLight={true} />

{renderTags()}
</div>
);
};

export default AddressInfos;
1 change: 1 addition & 0 deletions components/AddressInfos/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AddressInfos';
15 changes: 12 additions & 3 deletions components/NavBar/components/NetworksSwitch/NetworksSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ import React, { useContext, useState } from 'react';
import { useRouter } from 'next/router';
import { INetwork, NetworkContext } from '../../../../contexts/NetworksContext';

import { RPC_URL_MAINNET, RPC_URL_TESTNET } from '../../../../globals';
import { RPC_URL } from '../../../../globals';
import { NetworkName } from '../../../../types/network';

const luksoChains: INetwork[] = [
{ name: 'MAINNET', rpc: RPC_URL_MAINNET, imgUrl: '/lukso.png' },
{ name: 'TESTNET', rpc: RPC_URL_TESTNET, imgUrl: '/lukso.png' },
{
name: NetworkName.MAINNET,
rpc: RPC_URL[NetworkName.MAINNET],
imgUrl: '/lukso.png',
},
{
name: NetworkName.TESTNET,
rpc: RPC_URL[NetworkName.TESTNET],
imgUrl: '/lukso.png',
},
];

const NetworkSwitch: React.FC = () => {
Expand Down
55 changes: 29 additions & 26 deletions components/ValueTypeDecoder/ValueTypeDecoder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { LUKSO_IPFS_BASE_URL } from '../../globals';
import useWeb3 from '../../hooks/useWeb3';

import { DecodeDataOutput } from '@erc725/erc725.js/build/main/src/types/decodeData';
import AddressInfos from '../AddressInfos';

interface Props {
address: string;
Expand Down Expand Up @@ -86,11 +87,14 @@ const ValueTypeDecoder: React.FC<Props> = ({
} else {
return (
<ul>
{decodedDataArray.value.map((item, index) => (
<li key={index}>
<code>{item}</code>
</li>
))}
{decodedDataArray.value.map(
(item, index) =>
item && (
<li key={index}>
<AddressInfos address={item.toString()} />
</li>
),
)}
</ul>
);
}
Expand All @@ -103,27 +107,26 @@ const ValueTypeDecoder: React.FC<Props> = ({
return (
<>
<pre>{JSON.stringify(decodedDataOneKey[0].value, null, 4)}</pre>
<li>
<span>
URL:
<code className="ml-2">{decodedDataOneKey[0].value.url}</code>
</span>
{decodedDataOneKey[0].value.url.indexOf('ipfs://') !== -1 && (
<>
<a
className="has-text-link button is-small is-light is-info"
target="_blank"
rel="noreferrer"
href={`${LUKSO_IPFS_BASE_URL}/${decodedDataOneKey[0].value.url.replace(
'ipfs://',
'',
)}`}
>
Retrieve IPFS File ↗️
</a>
</>
)}
</li>

<span>
URL:
<code className="ml-2">{decodedDataOneKey[0].value.url}</code>
</span>
{decodedDataOneKey[0].value.url.indexOf('ipfs://') !== -1 && (
<>
<a
className="has-text-link button is-small is-light is-info"
target="_blank"
rel="noreferrer"
href={`${LUKSO_IPFS_BASE_URL}/${decodedDataOneKey[0].value.url.replace(
'ipfs://',
'',
)}`}
>
Retrieve IPFS File ↗️
</a>
</>
)}
</>
);
}
Expand Down
44 changes: 44 additions & 0 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,50 @@ export const eip165ABI = [
},
];

export const getDataABI = [
{
inputs: [
{
internalType: 'bytes32',
name: 'dataKey',
type: 'bytes32',
},
],
name: 'getData',
outputs: [
{
internalType: 'bytes',
name: 'dataValue',
type: 'bytes',
},
],
stateMutability: 'view',
type: 'function',
},
];

export const getDataBatchABI = [
{
inputs: [
{
internalType: 'bytes32[]',
name: 'dataKeys',
type: 'bytes32[]',
},
],
name: 'getDataBatch',
outputs: [
{
internalType: 'bytes[]',
name: 'dataValues',
type: 'bytes[]',
},
],
stateMutability: 'view',
type: 'function',
},
];

// Sample Address Inputs
export enum SAMPLE_ADDRESS {
MAINNET_UP = '0x0F4180da178ed1C71398a57ca8Cb177F69591f1f',
Expand Down
Loading

0 comments on commit c81e677

Please sign in to comment.