mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
import { ImageData, getNounData, getNounSeedFromBlockHash } from '@nouns/assets';
|
|
import { buildSVG } from '@nouns/sdk';
|
|
import CryptoJS from 'crypto-js';
|
|
import React from 'react';
|
|
|
|
import { Image } from 'toolkit/chakra/image';
|
|
|
|
const { palette } = ImageData;
|
|
|
|
interface NounsIdenticonProps {
|
|
hash: string;
|
|
size: number;
|
|
}
|
|
|
|
const MAGIC_HASH = '0xAC1CA184579A254E4F289319E42FF4A67BF5698AD26C6E7C68769D0D21FAFCB1';
|
|
|
|
// analog of getNumberFromString from deleted @cloudnoun package
|
|
export const getNumberFromString = (input: string): number => {
|
|
const str = input.trim();
|
|
if (!str) return 0;
|
|
|
|
const combined = [
|
|
str,
|
|
CryptoJS.MD5(str).toString(CryptoJS.enc.Hex),
|
|
CryptoJS.SHA1(str).toString(CryptoJS.enc.Base64),
|
|
CryptoJS.SHA256(str).toString(CryptoJS.enc.Hex),
|
|
CryptoJS.SHA512(str).toString(CryptoJS.enc.Base64),
|
|
CryptoJS.RIPEMD160(str).toString(CryptoJS.enc.Base64),
|
|
].join('');
|
|
|
|
let sum = 0;
|
|
for (let i = 0; i < combined.length; i++) {
|
|
sum += combined.charCodeAt(i);
|
|
}
|
|
return sum * str.length;
|
|
};
|
|
|
|
const NounsIdenticon: React.FC<NounsIdenticonProps> = ({ hash, size }) => {
|
|
const id = getNumberFromString(hash);
|
|
const seed = getNounSeedFromBlockHash(id, MAGIC_HASH);
|
|
|
|
const { parts, background } = getNounData(seed);
|
|
const svg = buildSVG(parts, palette, background);
|
|
const svgData = btoa(svg);
|
|
if (!svgData) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Image
|
|
src={ `data:image/svg+xml;base64,${ svgData }` }
|
|
alt={ `Nouns identicon for ${ hash }` }
|
|
width={ `${ size }px` }
|
|
height={ `${ size }px` }
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default React.memo(NounsIdenticon);
|