@davatar/react
Advanced tools
Comparing version 1.9.0 to 1.10.0
import { BaseProvider } from '@ethersproject/providers'; | ||
import { CSSProperties, ReactChild } from 'react'; | ||
export interface Props { | ||
export declare type ImageProps = { | ||
/** | ||
* The size of the avatar in pixels. | ||
*/ | ||
size: number; | ||
/** | ||
* The URI of the image to be resolved | ||
*/ | ||
uri?: string | null; | ||
/** | ||
* An Ethereum address | ||
*/ | ||
address?: string | null; | ||
/** | ||
* Custom CSS styles to apply to the <img /> tag | ||
*/ | ||
style?: CSSProperties; | ||
className?: string; | ||
/** | ||
* An API key for The Graph | ||
* | ||
* @deprecated | ||
*/ | ||
graphApiKey?: string; | ||
/** | ||
* An ethers provider | ||
*/ | ||
provider?: BaseProvider | null; | ||
/** | ||
* The kind of generated avatar to display if image isn't loaded | ||
*/ | ||
generatedAvatarType?: 'jazzicon' | 'blockies'; | ||
/** | ||
* A default component to render if image isn't loaded | ||
*/ | ||
defaultComponent?: ReactChild | ReactChild[]; | ||
} | ||
export declare const getCachedUrl: (key: string) => string | null; | ||
export declare const getGatewayUrl: (uri: string, tokenId?: string | undefined) => string; | ||
export default function Avatar({ uri, style, className, size, address, provider, generatedAvatarType, defaultComponent, }: Props): JSX.Element; | ||
/** | ||
* How long to cache resolved images for, in milliseconds | ||
* | ||
* @default 24 hours | ||
*/ | ||
cacheTTL?: number; | ||
}; | ||
export default function Image({ uri, style, className, size, address, provider, generatedAvatarType, defaultComponent, cacheTTL, }: ImageProps): JSX.Element; |
@@ -34,10 +34,10 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getGatewayUrl = exports.getCachedUrl = void 0; | ||
const contracts_1 = require("@ethersproject/contracts"); | ||
const bn_js_1 = __importDefault(require("bn.js")); | ||
const react_1 = __importStar(require("react")); | ||
const AvatarProvider_1 = require("./AvatarProvider"); | ||
const Blockies_1 = __importDefault(require("./Blockies")); | ||
const Jazzicon_1 = __importDefault(require("./Jazzicon")); | ||
// 24 hour TTL | ||
const CACHE_TTL = 60 * 60 * 24 * 1000; | ||
const cache_1 = require("./cache"); | ||
const resolve_1 = require("./resolve"); | ||
const erc721Abi = [ | ||
@@ -51,55 +51,10 @@ 'function ownerOf(uint256 tokenId) view returns (address)', | ||
]; | ||
const getCachedUrl = (key) => { | ||
const normalizedKey = key.toLowerCase(); | ||
const cachedItem = window.localStorage.getItem(`davatar/${normalizedKey}`); | ||
if (cachedItem) { | ||
const item = JSON.parse(cachedItem); | ||
if (new Date(item.expiresAt) > new Date()) { | ||
return (0, exports.getGatewayUrl)(item.url); | ||
} | ||
} | ||
return null; | ||
}; | ||
exports.getCachedUrl = getCachedUrl; | ||
const getGatewayUrl = (uri, tokenId) => { | ||
const match = new RegExp(/([a-z]+)(?::\/\/|\/)(.*)/).exec(uri); | ||
if (!match || match.length < 3) { | ||
return uri; | ||
} | ||
const id = match[2]; | ||
let url = uri; | ||
switch (match[1]) { | ||
case 'ar': { | ||
url = `https://arweave.net/${id}`; | ||
break; | ||
} | ||
case 'ipfs': | ||
if (id.includes('ipfs') || id.includes('ipns')) { | ||
url = `https://gateway.ipfs.io/${id}`; | ||
} | ||
else { | ||
url = `https://gateway.ipfs.io/ipfs/${id}`; | ||
} | ||
break; | ||
case 'ipns': | ||
if (id.includes('ipfs') || id.includes('ipns')) { | ||
url = `https://gateway.ipfs.io/${id}`; | ||
} | ||
else { | ||
url = `https://gateway.ipfs.io/ipns/${id}`; | ||
} | ||
break; | ||
case 'http': | ||
case 'https': | ||
break; | ||
} | ||
return tokenId ? url.replaceAll('{id}', tokenId) : url; | ||
}; | ||
exports.getGatewayUrl = getGatewayUrl; | ||
function Avatar({ uri, style, className, size, address, provider, generatedAvatarType, defaultComponent, }) { | ||
function Image({ uri, style, className, size, address, provider, generatedAvatarType, defaultComponent, cacheTTL, }) { | ||
const [url, setUrl] = (0, react_1.useState)(null); | ||
const [loaded, setLoaded] = (0, react_1.useState)(false); | ||
const avatarEthersProvider = (0, AvatarProvider_1.useAvatarEthersProvider)(); | ||
const ethersProvider = (0, react_1.useMemo)(() => provider || avatarEthersProvider, [provider, avatarEthersProvider]); | ||
(0, react_1.useEffect)(() => { | ||
if (!uri && address) { | ||
const cachedUrl = (0, exports.getCachedUrl)(address.toLowerCase()); | ||
const cachedUrl = (0, cache_1.getCachedUrl)(address.toLowerCase()); | ||
if (cachedUrl) { | ||
@@ -113,11 +68,13 @@ setUrl(cachedUrl); | ||
if (uri) { | ||
const cachedUrl = (0, exports.getCachedUrl)(uri); | ||
const cachedUrl = (0, cache_1.getCachedUrl)(uri); | ||
if (cachedUrl) { | ||
setUrl(cachedUrl); | ||
return; | ||
} | ||
} | ||
if (uri && address) { | ||
const cachedUrl = (0, exports.getCachedUrl)(`${address.toLowerCase()}/${uri}`); | ||
const cachedUrl = (0, cache_1.getCachedUrl)(`${address.toLowerCase()}/${uri}`); | ||
if (cachedUrl) { | ||
setUrl(cachedUrl); | ||
return; | ||
} | ||
@@ -208,17 +165,15 @@ } | ||
const normalizedAddress = address === null || address === void 0 ? void 0 : address.toLowerCase(); | ||
if (provider) { | ||
const erc721Contract = new contracts_1.Contract(contractId, erc721Abi, provider); | ||
(() => __awaiter(this, void 0, void 0, function* () { | ||
if (normalizedAddress) { | ||
const owner = yield erc721Contract.ownerOf(tokenId); | ||
if (!owner || owner.toLowerCase() !== normalizedAddress) { | ||
throw new Error('ERC721 token not owned by address'); | ||
} | ||
const erc721Contract = new contracts_1.Contract(contractId, erc721Abi, ethersProvider); | ||
(() => __awaiter(this, void 0, void 0, function* () { | ||
if (normalizedAddress) { | ||
const owner = yield erc721Contract.ownerOf(tokenId); | ||
if (!owner || owner.toLowerCase() !== normalizedAddress) { | ||
throw new Error('ERC721 token not owned by address'); | ||
} | ||
const tokenURI = yield erc721Contract.tokenURI(tokenId); | ||
const res = yield fetch((0, exports.getGatewayUrl)(tokenURI, new bn_js_1.default(tokenId).toString(16))); | ||
const data = (yield res.json()); | ||
setUrl((0, exports.getGatewayUrl)(data.image)); | ||
}))(); | ||
} | ||
} | ||
const tokenURI = yield erc721Contract.tokenURI(tokenId); | ||
const res = yield fetch((0, resolve_1.getGatewayUrl)(tokenURI, new bn_js_1.default(tokenId).toString(16))); | ||
const data = (yield res.json()); | ||
setUrl((0, resolve_1.getGatewayUrl)(data.image)); | ||
}))(); | ||
} | ||
@@ -228,35 +183,26 @@ else if (match1155 && match1155.length === 3) { | ||
const tokenId = match1155[2]; | ||
if (provider) { | ||
const erc1155Contract = new contracts_1.Contract(contractId, erc1155Abi, provider); | ||
(() => __awaiter(this, void 0, void 0, function* () { | ||
if (address) { | ||
const balance = yield erc1155Contract.balanceOf(address, tokenId); | ||
if (balance.isZero()) { | ||
throw new Error('ERC1155 token not owned by address'); | ||
} | ||
const erc1155Contract = new contracts_1.Contract(contractId, erc1155Abi, ethersProvider); | ||
(() => __awaiter(this, void 0, void 0, function* () { | ||
if (address) { | ||
const balance = yield erc1155Contract.balanceOf(address, tokenId); | ||
if (balance.isZero()) { | ||
throw new Error('ERC1155 token not owned by address'); | ||
} | ||
const tokenURI = yield erc1155Contract.uri(tokenId); | ||
const res = yield fetch((0, exports.getGatewayUrl)(tokenURI, new bn_js_1.default(tokenId).toString(16))); | ||
const data = (yield res.json()); | ||
setUrl((0, exports.getGatewayUrl)(data.image)); | ||
}))(); | ||
} | ||
} | ||
const tokenURI = yield erc1155Contract.uri(tokenId); | ||
const res = yield fetch((0, resolve_1.getGatewayUrl)(tokenURI, new bn_js_1.default(tokenId).toString(16))); | ||
const data = (yield res.json()); | ||
setUrl((0, resolve_1.getGatewayUrl)(data.image)); | ||
}))(); | ||
} | ||
else { | ||
setUrl((0, exports.getGatewayUrl)(uri)); | ||
setUrl((0, resolve_1.getGatewayUrl)(uri)); | ||
} | ||
}, [uri, address, provider]); | ||
}, [uri, address, ethersProvider]); | ||
const onLoad = (0, react_1.useCallback)(() => { | ||
setLoaded(true); | ||
if (address) { | ||
const normalizedAddress = address.toLowerCase(); | ||
const cachedItem = window.localStorage.getItem(normalizedAddress); | ||
const item = cachedItem && JSON.parse(cachedItem); | ||
if (!item || new Date(item.expiresAt) > new Date()) { | ||
const expireDate = new Date(new Date().getTime() + CACHE_TTL); | ||
window.localStorage.setItem(`davatar/${normalizedAddress}`, JSON.stringify({ url, expiresAt: expireDate })); | ||
window.localStorage.setItem(`davatar/${normalizedAddress}/${uri}`, JSON.stringify({ url, expiresAt: expireDate })); | ||
} | ||
if (address && url) { | ||
(0, cache_1.storeCachedURI)(address, url, cacheTTL); | ||
} | ||
}, [address, url, uri]); | ||
}, [address, url, cacheTTL]); | ||
let avatarImg = null; | ||
@@ -275,3 +221,3 @@ const cssStyle = Object.assign({ display: loaded ? undefined : 'none', width: `${size}px`, height: `${size}px`, borderRadius: `${size}px` }, (style || {})); | ||
} | ||
exports.default = Avatar; | ||
exports.default = Image; | ||
//# sourceMappingURL=Image.js.map |
@@ -1,12 +0,6 @@ | ||
import { ReactChild, CSSProperties } from 'react'; | ||
export { default as Image } from './Image'; | ||
export interface DavatarProps { | ||
size: number; | ||
address: string; | ||
provider?: any; | ||
graphApiKey?: string; | ||
generatedAvatarType?: 'jazzicon' | 'blockies'; | ||
defaultComponent?: ReactChild | ReactChild[]; | ||
style?: CSSProperties; | ||
} | ||
export default function Davatar({ size, address, provider, graphApiKey, generatedAvatarType, defaultComponent, style, }: DavatarProps): JSX.Element; | ||
export type { ImageProps } from './Image'; | ||
export { default } from './Avatar'; | ||
export type { AvatarProps } from './Avatar'; | ||
export { AvatarProvider } from './AvatarProvider'; | ||
export type { AvatarProviderProps } from './AvatarProvider'; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -25,48 +6,9 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Image = void 0; | ||
const providers_1 = require("@ethersproject/providers"); | ||
const react_1 = __importStar(require("react")); | ||
const Image_1 = __importDefault(require("./Image")); | ||
var Image_2 = require("./Image"); | ||
Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return __importDefault(Image_2).default; } }); | ||
function Davatar({ size, address, provider, graphApiKey, generatedAvatarType, defaultComponent, style, }) { | ||
const [avatarUri, setAvatarUri] = (0, react_1.useState)(null); | ||
const [ethersProvider, setEthersProvider] = (0, react_1.useState)(null); | ||
(0, react_1.useEffect)(() => { | ||
var _a, _b; | ||
let eth = (0, providers_1.getDefaultProvider)(); | ||
let chainId = null; | ||
let isEthers = false; | ||
// carlos: Only use the provided provider if ENS is actually on that chain | ||
if (provider) { | ||
if ((_a = provider.currentProvider) === null || _a === void 0 ? void 0 : _a.chainId) { | ||
chainId = parseInt(provider.currentProvider.chainId); | ||
} | ||
else if ((_b = provider.network) === null || _b === void 0 ? void 0 : _b.chainId) { | ||
isEthers = true; | ||
chainId = provider.network.chainId; | ||
} | ||
if ([1, 3, 4, 5].includes(chainId)) { | ||
eth = isEthers ? provider : new providers_1.Web3Provider(provider.currentProvider); | ||
} | ||
else { | ||
chainId = 1; | ||
} | ||
} | ||
setEthersProvider(eth); | ||
eth.lookupAddress(address).then(ensName => { | ||
if (ensName) { | ||
eth.getResolver(ensName).then(resolver => { | ||
resolver.getText('avatar').then(avatar => { | ||
if (avatar && avatar.length > 0) { | ||
setAvatarUri(avatar); | ||
} | ||
}); | ||
}); | ||
} | ||
}); | ||
}, [address, provider]); | ||
return (react_1.default.createElement(Image_1.default, { size: size, address: address, uri: avatarUri, graphApiKey: graphApiKey, provider: ethersProvider, generatedAvatarType: generatedAvatarType, defaultComponent: defaultComponent, style: style })); | ||
} | ||
exports.default = Davatar; | ||
exports.AvatarProvider = exports.default = exports.Image = void 0; | ||
var Image_1 = require("./Image"); | ||
Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return __importDefault(Image_1).default; } }); | ||
var Avatar_1 = require("./Avatar"); | ||
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(Avatar_1).default; } }); | ||
var AvatarProvider_1 = require("./AvatarProvider"); | ||
Object.defineProperty(exports, "AvatarProvider", { enumerable: true, get: function () { return AvatarProvider_1.AvatarProvider; } }); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@davatar/react", | ||
"version": "1.9.0", | ||
"description": "A Web3 ENS-based avatar implementation for React", | ||
"homepage": "https://github.com/TBDAO/davatar-helpers", | ||
"version": "1.10.0", | ||
"description": "An ENS avatar implementation for React", | ||
"homepage": "https://github.com/metaphor-xyz/davatar-helpers", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/TBDAO/davatar-helpers.git", | ||
"url": "https://github.com/metaphor-xyz/davatar-helpers.git", | ||
"directory": "packages/react" | ||
@@ -14,7 +14,18 @@ }, | ||
"build": "tsc", | ||
"prepublish": "npm run build" | ||
"prepublish": "npm run build", | ||
"storybook": "start-storybook -p 6006", | ||
"build-storybook": "build-storybook" | ||
}, | ||
"author": "TBDAO", | ||
"author": "Metaphor", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@babel/core": "^7.18.0", | ||
"@storybook/addon-actions": "^6.5.3", | ||
"@storybook/addon-essentials": "^6.5.3", | ||
"@storybook/addon-interactions": "^6.5.3", | ||
"@storybook/addon-links": "^6.5.3", | ||
"@storybook/builder-webpack4": "^6.5.3", | ||
"@storybook/manager-webpack4": "^6.5.3", | ||
"@storybook/react": "^6.5.3", | ||
"@storybook/testing-library": "^0.0.11", | ||
"@types/bn.js": "^5.1.0", | ||
@@ -24,3 +35,5 @@ "@types/color": "^3.0.2", | ||
"@types/react": "^17.0.20", | ||
"typescript": "^4.4.2" | ||
"babel-loader": "^8.2.5", | ||
"typescript": "^4.4.2", | ||
"webpack": "^4" | ||
}, | ||
@@ -31,4 +44,7 @@ "peerDependencies": { | ||
"dependencies": { | ||
"@ethersproject/contracts": "^5.4.1", | ||
"@ethersproject/providers": "^5.4.5", | ||
"@ethersproject/abstract-signer": "^5", | ||
"@ethersproject/contracts": "^5", | ||
"@ethersproject/logger": "^5", | ||
"@ethersproject/properties": "^5", | ||
"@ethersproject/providers": "^5", | ||
"@types/react-blockies": "^1.4.1", | ||
@@ -35,0 +51,0 @@ "bn.js": "^5.2.0", |
@@ -59,5 +59,4 @@ # @davatar/react | ||
``` | ||
key: davatar/{wallet address} and davatar/{wallet address}/{uri} | ||
value: {avatar image URI} | ||
expiredAt: expiry datetime | ||
key: davatar/cache | ||
value: [address]{ avatar url, expiredAt: expiry datetime } | ||
``` | ||
@@ -64,0 +63,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
579142
34
8454
3
11
16
75
+ Added@ethersproject/logger@^5
+ Added@ethersproject/properties@^5
Updated@ethersproject/contracts@^5
Updated@ethersproject/providers@^5