UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

121 lines 4.99 kB
import { ProtocolType, assert, eqAddress, } from '@hyperlane-xyz/utils'; import { TokenAmount } from './TokenAmount.js'; import { PROTOCOL_TO_HYP_NATIVE_STANDARD, PROTOCOL_TO_NATIVE_STANDARD, TOKEN_COLLATERALIZED_STANDARDS, TOKEN_CROSS_COLLATERAL_STANDARDS, TOKEN_HYP_STANDARDS, TOKEN_MULTI_CHAIN_STANDARDS, TOKEN_NFT_STANDARDS, TOKEN_STANDARD_TO_PROTOCOL, TokenStandard, XERC20_STANDARDS, } from './TokenStandard.js'; import { PROTOCOL_TO_DEFAULT_NATIVE_TOKEN } from './nativeTokenMetadata.js'; export function tokenIdentifiersEqual(left, right) { if (left == null || right == null) return left === right; return left === right || eqAddress(left, right); } function matchesUnderlyingAsset(source, target) { if (source.isCollateralized()) { if (source.collateralAddressOrDenom && tokenIdentifiersEqual(source.collateralAddressOrDenom, target.addressOrDenom)) { return true; } // Only HypNative collateral legitimately lacks collateralAddressOrDenom; // any other collateralized token missing it is a config bug, not a native match. if (!source.collateralAddressOrDenom && source.isHypNative() && (target.isNative() || target.isHypNative())) { return true; } } return (source.standard === TokenStandard.CosmosIbc && target.standard === TokenStandard.CosmosNative && tokenIdentifiersEqual(source.addressOrDenom, target.addressOrDenom)); } export class TokenMetadata { protocol; constructor(args) { Object.assign(this, args); this.protocol = TOKEN_STANDARD_TO_PROTOCOL[this.standard]; } static FromChainMetadataNativeToken(chainMetadata) { const { protocol, name: chainName, logoURI, gasCurrencyCoinGeckoId, } = chainMetadata; assert(protocol !== ProtocolType.Unknown, 'Cannot create native token for unknown protocol'); const knownProtocol = protocol; const nativeToken = chainMetadata.nativeToken || PROTOCOL_TO_DEFAULT_NATIVE_TOKEN[knownProtocol]; // CAST: TypeScript cannot infer that `new this(...)` returns InstanceType<T> // for a polymorphic static method bound via `this: T`. return new this({ chainName, standard: PROTOCOL_TO_NATIVE_STANDARD[knownProtocol], addressOrDenom: nativeToken.denom ?? '', decimals: nativeToken.decimals, symbol: nativeToken.symbol, name: nativeToken.name, logoURI, coinGeckoId: gasCurrencyCoinGeckoId, }); } amount(amount) { return new TokenAmount(amount, this); } isNft() { return TOKEN_NFT_STANDARDS.includes(this.standard); } isNative() { return Object.values(PROTOCOL_TO_NATIVE_STANDARD).includes(this.standard); } isHypNative() { return Object.values(PROTOCOL_TO_HYP_NATIVE_STANDARD).includes(this.standard); } isCollateralized() { return TOKEN_COLLATERALIZED_STANDARDS.includes(this.standard); } isHypToken() { return TOKEN_HYP_STANDARDS.includes(this.standard); } isXerc20() { return XERC20_STANDARDS.includes(this.standard); } isIbcToken() { return this.standard === TokenStandard.CosmosIbc; } isMultiChainToken() { return TOKEN_MULTI_CHAIN_STANDARDS.includes(this.standard); } isCrossCollateralToken() { return TOKEN_CROSS_COLLATERAL_STANDARDS.has(this.standard); } getConnections() { return this.connections || []; } getConnectionForChain(chain) { return this.getConnections().filter((t) => t.token.chainName === chain)[0]; } addConnection(connection) { this.connections = [...(this.connections || []), connection]; return this; } removeConnection(token) { const index = this.connections?.findIndex((t) => t.token.equals(token)); if (index !== undefined && index >= 0) this.connections?.splice(index, 1); return this; } equals(token) { if (!token) return false; if ((this.warpRouteId || token.warpRouteId) && this.warpRouteId !== token.warpRouteId) { return false; } return (this.protocol === token.protocol && this.chainName === token.chainName && this.standard === token.standard && this.decimals === token.decimals && tokenIdentifiersEqual(this.addressOrDenom, token.addressOrDenom) && tokenIdentifiersEqual(this.collateralAddressOrDenom, token.collateralAddressOrDenom)); } isFungibleWith(token) { if (!token || token.chainName !== this.chainName) return false; if (this.equals(token)) return true; return (matchesUnderlyingAsset(this, token) || matchesUnderlyingAsset(token, this)); } } //# sourceMappingURL=TokenMetadata.js.map