diff --git a/README.md b/README.md index f9d21b0..e50a9f1 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ This repo contains the base Hyperlane ERC20 and ERC721 tokens (HypERC20 and HypERC721). These tokens extend the base standards with an additional `transferRemote` function. Warp Routes make any token or native asset interchain without custom contracts. Read more about Warp Routes and how to deploy your own at [Warp API docs](https://docs.hyperlane.xyz/docs/developers/warp-api). +**NOTE:** ERC721 collateral variants are assumed to [enumerable](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Enumerable) and [metadata](https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Metadata) compliant. + ## Versions | Git Ref | Release Date | Notes | diff --git a/configs/warp-route-token-config.json b/configs/warp-route-token-config.json index 11f55c1..a6569dc 100644 --- a/configs/warp-route-token-config.json +++ b/configs/warp-route-token-config.json @@ -8,27 +8,18 @@ }, "alfajores": { "type": "synthetic", - "name": "Weth", - "symbol": "WETH", - "totalSupply": 0, "owner": "0x5bA371aeA18734Cb7195650aFdfCa4f9251aa513", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "interchainGasPaymaster": "0xF90cB82a76492614D07B82a7658917f3aC811Ac1" }, "fuji": { "type": "synthetic", - "name": "Weth", - "symbol": "WETH", - "totalSupply": 0, "owner": "0x5bA371aeA18734Cb7195650aFdfCa4f9251aa513", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "interchainGasPaymaster": "0xF90cB82a76492614D07B82a7658917f3aC811Ac1" }, "moonbasealpha": { "type": "synthetic", - "name": "Weth", - "symbol": "WETH", - "totalSupply": 0, "owner": "0x5bA371aeA18734Cb7195650aFdfCa4f9251aa513", "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", "interchainGasPaymaster": "0xF90cB82a76492614D07B82a7658917f3aC811Ac1" diff --git a/contracts/HypERC20.sol b/contracts/HypERC20.sol index 6eb5ed5..aaceb03 100644 --- a/contracts/HypERC20.sol +++ b/contracts/HypERC20.sol @@ -11,6 +11,12 @@ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ * @dev Supply on each chain is not constant but the aggregate supply across all chains is. */ contract HypERC20 is ERC20Upgradeable, TokenRouter { + uint8 private immutable _decimals; + + constructor(uint8 decimals) { + _decimals = decimals; + } + /** * @notice Initializes the Hyperlane router, ERC20 metadata, and mints initial supply to deployer. * @param _mailbox The address of the mailbox contract. @@ -37,6 +43,10 @@ contract HypERC20 is ERC20Upgradeable, TokenRouter { _mint(msg.sender, _totalSupply); } + function decimals() public view override returns (uint8) { + return _decimals; + } + /** * @dev Burns `_amount` of token from `msg.sender` balance. * @inheritdoc TokenRouter diff --git a/contracts/test/ERC721Test.sol b/contracts/test/ERC721Test.sol index 1de5544..a8ceb1f 100644 --- a/contracts/test/ERC721Test.sol +++ b/contracts/test/ERC721Test.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -contract ERC721Test is ERC721 { +contract ERC721Test is ERC721Enumerable { constructor( string memory name, string memory symbol, diff --git a/package.json b/package.json index f740afe..3a355e3 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "@hyperlane-xyz/hyperlane-token", "description": "A template for interchain ERC20 and ERC721 tokens using Hyperlane", - "version": "1.3.0", + "version": "1.3.1", "dependencies": { - "@hyperlane-xyz/core": "1.3.0", - "@hyperlane-xyz/sdk": "1.3.0", - "@hyperlane-xyz/utils": "1.3.0", + "@hyperlane-xyz/core": "1.3.1", + "@hyperlane-xyz/sdk": "1.3.1", + "@hyperlane-xyz/utils": "1.3.1", "@openzeppelin/contracts-upgradeable": "^4.8.0", "ethers": "^5.7.2" }, diff --git a/src/config.ts b/src/config.ts index dd17b41..2491f35 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,6 @@ import { ethers } from 'ethers'; -import { GasRouterConfig, RouterConfig } from '@hyperlane-xyz/sdk'; +import { GasRouterConfig } from '@hyperlane-xyz/sdk'; export enum TokenType { synthetic = 'synthetic', @@ -10,12 +10,25 @@ export enum TokenType { native = 'native', } -export type SyntheticConfig = { - type: TokenType.synthetic | TokenType.syntheticUri; +export type TokenMetadata = { name: string; symbol: string; totalSupply: ethers.BigNumberish; }; + +export type ERC20Metadata = TokenMetadata & { + decimals: number; +}; + +export const isTokenMetadata = (metadata: any): metadata is TokenMetadata => + metadata.name && metadata.symbol && metadata.totalSupply !== undefined; // totalSupply can be 0 + +export const isErc20Metadata = (metadata: any): metadata is ERC20Metadata => + metadata.decimals && isTokenMetadata(metadata); + +export type SyntheticConfig = TokenMetadata & { + type: TokenType.synthetic | TokenType.syntheticUri; +}; export type CollateralConfig = { type: TokenType.collateral | TokenType.collateralUri; token: string; @@ -44,19 +57,14 @@ export const isUriConfig = (config: TokenConfig) => config.type === TokenType.syntheticUri || config.type === TokenType.collateralUri; -export type HypERC20Config = Partial & - RouterConfig & - TokenConfig; -export type HypERC20CollateralConfig = Partial & - RouterConfig & - CollateralConfig; -export type HypNativeConfig = Partial & - RouterConfig & - NativeConfig; - -export type HypERC721Config = Partial & - RouterConfig & - TokenConfig; -export type HypERC721CollateralConfig = Partial & - RouterConfig & - CollateralConfig; +export type HypERC20Config = GasRouterConfig & SyntheticConfig & ERC20Metadata; +export type HypERC20CollateralConfig = GasRouterConfig & CollateralConfig; +export type HypNativeConfig = GasRouterConfig & NativeConfig; +export type ERC20RouterConfig = + | HypERC20Config + | HypERC20CollateralConfig + | HypNativeConfig; + +export type HypERC721Config = GasRouterConfig & SyntheticConfig; +export type HypERC721CollateralConfig = GasRouterConfig & CollateralConfig; +export type ERC721RouterConfig = HypERC721Config | HypERC721CollateralConfig; diff --git a/src/deploy.ts b/src/deploy.ts index a43e2e6..6121c22 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -1,89 +1,143 @@ +import { providers } from 'ethers'; + import { ChainMap, ChainName, - GasRouterConfig, GasRouterDeployer, HyperlaneContracts, MultiProvider, objMap, } from '@hyperlane-xyz/sdk'; -import { DeployerOptions } from '@hyperlane-xyz/sdk/dist/deploy/HyperlaneDeployer'; +import { GasConfig, RouterConfig } from '@hyperlane-xyz/sdk/dist/router/types'; import { + CollateralConfig, + ERC20Metadata, + HypERC20CollateralConfig, HypERC20Config, + HypERC721CollateralConfig, HypERC721Config, + HypNativeConfig, TokenConfig, + TokenMetadata, isCollateralConfig, + isErc20Metadata, isNativeConfig, isSyntheticConfig, isUriConfig, } from './config'; +import { isTokenMetadata } from './config'; +import { ERC721RouterConfig } from './config'; +import { ERC20RouterConfig } from './config'; import { HypERC20Factories, HypERC721Factories } from './contracts'; import { + ERC20__factory, + ERC721EnumerableUpgradeable__factory, + HypERC20, + HypERC20Collateral, HypERC20Collateral__factory, HypERC20__factory, + HypERC721, + HypERC721Collateral, HypERC721Collateral__factory, HypERC721URICollateral__factory, HypERC721URIStorage__factory, HypERC721__factory, + HypNative, HypNative__factory, } from './types'; -enum TokenType { - erc20 = 'erc20', - erc721 = 'erc721', -} - -const gasDefaults = (config: TokenConfig, tokenType: TokenType) => { - switch (tokenType) { - case TokenType.erc721: - switch (config.type) { - case 'synthetic': - return 160_000; - case 'syntheticUri': - return 163_000; - case 'collateral': - case 'collateralUri': - default: - return 80_000; - } - default: - case TokenType.erc20: - switch (config.type) { - case 'synthetic': - return 64_000; - case 'native': - return 44_000; - case 'collateral': - default: - return 68_000; - } - } -}; - export class HypERC20Deployer extends GasRouterDeployer< - HypERC20Config & GasRouterConfig, + ERC20RouterConfig, HypERC20Factories > { - constructor( - multiProvider: MultiProvider, - configMap: ChainMap, - factories: any, - options?: DeployerOptions, - ) { - super( - multiProvider, - objMap( - configMap, - (_, config): HypERC20Config & GasRouterConfig => - ({ - ...config, - gas: config.gas ?? gasDefaults(config, TokenType.erc20), - } as HypERC20Config & GasRouterConfig), + constructor(multiProvider: MultiProvider) { + super(multiProvider, {} as HypERC20Factories); // factories not used in deploy + } + + static async fetchMetadata( + provider: providers.Provider, + config: CollateralConfig, + ): Promise { + const erc20 = ERC20__factory.connect(config.token, provider); + + const [name, symbol, totalSupply, decimals] = await Promise.all([ + erc20.name(), + erc20.symbol(), + erc20.totalSupply(), + erc20.decimals(), + ]); + + return { name, symbol, totalSupply, decimals }; + } + + static gasOverheadDefault(config: TokenConfig): number { + switch (config.type) { + case 'synthetic': + return 64_000; + case 'native': + return 44_000; + case 'collateral': + default: + return 68_000; + } + } + + protected async deployCollateral( + chain: ChainName, + config: HypERC20CollateralConfig, + ): Promise { + const router = await this.deployContractFromFactory( + chain, + new HypERC20Collateral__factory(), + 'HypERC20Collateral', + [config.token], + ); + await this.multiProvider.handleTx( + chain, + router.initialize(config.mailbox, config.interchainGasPaymaster), + ); + return router; + } + + protected async deployNative( + chain: ChainName, + config: HypNativeConfig, + ): Promise { + const router = await this.deployContractFromFactory( + chain, + new HypNative__factory(), + 'HypNative', + [], + ); + await this.multiProvider.handleTx( + chain, + router.initialize(config.mailbox, config.interchainGasPaymaster), + ); + return router; + } + + protected async deploySynthetic( + chain: ChainName, + config: HypERC20Config, + ): Promise { + const router = await this.deployContractFromFactory( + chain, + new HypERC20__factory(), + 'HypERC20', + [config.decimals], + ); + await this.multiProvider.handleTx( + chain, + router.initialize( + config.mailbox, + config.interchainGasPaymaster, + config.totalSupply, + config.name, + config.symbol, ), - factories, - options, ); + return router; } router(contracts: HyperlaneContracts) { @@ -91,119 +145,233 @@ export class HypERC20Deployer extends GasRouterDeployer< } async deployContracts(chain: ChainName, config: HypERC20Config) { + let router: HypERC20 | HypERC20Collateral | HypNative; if (isCollateralConfig(config)) { - const router = await this.deployContractFromFactory( - chain, - new HypERC20Collateral__factory(), - 'HypERC20Collateral', - [config.token], - ); - await this.multiProvider.handleTx( - chain, - router.initialize(config.mailbox, config.interchainGasPaymaster), - ); - return { router }; - } else if (isSyntheticConfig(config)) { - const router = await this.deployContractFromFactory( - chain, - new HypERC20__factory(), - 'HypERC20', - [], - ); - await this.multiProvider.handleTx( - chain, - router.initialize( - config.mailbox, - config.interchainGasPaymaster, - config.totalSupply, - config.name, - config.symbol, - ), - ); - return { router }; + router = await this.deployCollateral(chain, config); } else if (isNativeConfig(config)) { - const router = await this.deployContractFromFactory( - chain, - new HypNative__factory(), - 'HypNative', - [], - ); - await this.multiProvider.handleTx( - chain, - router.initialize(config.mailbox, config.interchainGasPaymaster), - ); - return { router }; + router = await this.deployNative(chain, config); + } else if (isSyntheticConfig(config)) { + router = await this.deploySynthetic(chain, config); + } else { + throw new Error('Invalid ERC20 token router config'); + } + return { router }; + } + + async buildTokenMetadata( + configMap: ChainMap, + ): Promise> { + let tokenMetadata: ERC20Metadata | undefined; + + for (const [chain, config] of Object.entries(configMap)) { + if (isCollateralConfig(config)) { + const collateralMetadata = await HypERC20Deployer.fetchMetadata( + this.multiProvider.getProvider(chain), + config, + ); + tokenMetadata = { + ...collateralMetadata, + totalSupply: 0, + }; + } else if (isNativeConfig(config)) { + const chainMetadata = this.multiProvider.getChainMetadata(chain); + if (chainMetadata.nativeToken) { + tokenMetadata = { + ...chainMetadata.nativeToken, + totalSupply: 0, + }; + } + } else if (isErc20Metadata(config)) { + tokenMetadata = config; + } + } + + if (!isErc20Metadata(tokenMetadata)) { + throw new Error('Invalid ERC20 token metadata'); } - throw new Error('Invalid config'); + + return objMap(configMap, () => tokenMetadata!); + } + + buildGasOverhead(configMap: ChainMap): ChainMap { + return objMap(configMap, (_, config) => ({ + gas: HypERC20Deployer.gasOverheadDefault(config), + })); + } + + async deploy(configMap: ChainMap) { + const tokenMetadata = await this.buildTokenMetadata(configMap); + const gasOverhead = this.buildGasOverhead(configMap); + const mergedConfig = objMap(configMap, (chain, config) => { + return { + ...tokenMetadata[chain], + ...gasOverhead[chain], + ...config, + }; + }) as ChainMap; + + return super.deploy(mergedConfig); } } -// TODO: dedupe? export class HypERC721Deployer extends GasRouterDeployer< - HypERC721Config & GasRouterConfig, + ERC721RouterConfig, HypERC721Factories > { - constructor( - multiProvider: MultiProvider, - configMap: ChainMap, - factories: any, - options?: DeployerOptions, - ) { - super( - multiProvider, - objMap( - configMap, - (_, config): HypERC721Config & GasRouterConfig => - ({ - ...config, - gas: config.gas ?? gasDefaults(config, TokenType.erc721), - } as HypERC721Config & GasRouterConfig), - ), - factories, - options, + constructor(multiProvider: MultiProvider) { + super(multiProvider, {} as HypERC721Factories); // factories not used in deploy + } + + static async fetchMetadata( + provider: providers.Provider, + config: CollateralConfig, + ): Promise { + const erc721 = ERC721EnumerableUpgradeable__factory.connect( + config.token, + provider, ); + const [name, symbol, totalSupply] = await Promise.all([ + erc721.name(), + erc721.symbol(), + erc721.totalSupply(), + ]); + + return { name, symbol, totalSupply }; } - router(contracts: HyperlaneContracts) { - return contracts.router; + static gasOverheadDefault(config: TokenConfig): number { + switch (config.type) { + case 'synthetic': + return 160_000; + case 'syntheticUri': + return 163_000; + case 'collateral': + case 'collateralUri': + default: + return 80_000; + } } - async deployContracts(chain: ChainName, config: HypERC721Config) { - if (isCollateralConfig(config)) { - const router = await this.deployContractFromFactory( + protected async deployCollateral( + chain: ChainName, + config: HypERC721CollateralConfig, + ): Promise { + let router: HypERC721Collateral; + if (isUriConfig(config)) { + router = await this.deployContractFromFactory( chain, - isUriConfig(config) - ? new HypERC721URICollateral__factory() - : new HypERC721Collateral__factory(), - `HypERC721${isUriConfig(config) ? 'URI' : ''}Collateral`, + new HypERC721URICollateral__factory(), + 'HypERC721URICollateral', [config.token], ); - await this.multiProvider.handleTx( + } else { + router = await this.deployContractFromFactory( chain, - router.initialize(config.mailbox, config.interchainGasPaymaster), + new HypERC721Collateral__factory(), + 'HypERC721Collateral', + [config.token], ); - return { router }; - } else if (isSyntheticConfig(config)) { - const router = await this.deployContractFromFactory( + } + await this.multiProvider.handleTx( + chain, + router.initialize(config.mailbox, config.interchainGasPaymaster), + ); + return router; + } + + protected async deploySynthetic( + chain: ChainName, + config: HypERC721Config, + ): Promise { + let router: HypERC721; + if (isUriConfig(config)) { + router = await this.deployContractFromFactory( chain, - isUriConfig(config) - ? new HypERC721URIStorage__factory() - : new HypERC721__factory(), - `HypERC721${isUriConfig(config) ? 'URIStorage' : ''}`, + new HypERC721URIStorage__factory(), + 'HypERC721URIStorage', [], ); - await this.multiProvider.handleTx( + } else { + router = await this.deployContractFromFactory( chain, - router.initialize( - config.mailbox, - config.interchainGasPaymaster, - config.totalSupply, - config.name, - config.symbol, - ), + new HypERC721__factory(), + 'HypERC721', + [], ); - return { router }; } - throw new Error('Invalid config'); + await this.multiProvider.handleTx( + chain, + router.initialize( + config.mailbox, + config.interchainGasPaymaster, + config.totalSupply, + config.name, + config.symbol, + ), + ); + return router; + } + + router(contracts: HyperlaneContracts) { + return contracts.router; + } + + async deployContracts(chain: ChainName, config: HypERC721Config) { + let router: HypERC721 | HypERC721Collateral; + if (isCollateralConfig(config)) { + router = await this.deployCollateral(chain, config); + } else if (isSyntheticConfig(config)) { + router = await this.deploySynthetic(chain, config); + } else { + throw new Error('Invalid ERC721 token router config'); + } + return { router }; + } + + async buildTokenMetadata( + configMap: ChainMap, + ): Promise> { + let tokenMetadata: TokenMetadata | undefined; + + for (const [chain, config] of Object.entries(configMap)) { + if (isCollateralConfig(config)) { + const collateralMetadata = await HypERC721Deployer.fetchMetadata( + this.multiProvider.getProvider(chain), + config, + ); + tokenMetadata = { + ...collateralMetadata, + totalSupply: 0, + }; + } else if (isTokenMetadata(config)) { + tokenMetadata = config; + } + } + + if (!isTokenMetadata(tokenMetadata)) { + throw new Error('Invalid ERC721 token metadata'); + } + + return objMap(configMap, () => tokenMetadata!); + } + + buildGasOverhead(configMap: ChainMap): ChainMap { + return objMap(configMap, (_, config) => ({ + gas: HypERC721Deployer.gasOverheadDefault(config), + })); + } + + async deploy(configMap: ChainMap) { + const tokenMetadata = await this.buildTokenMetadata(configMap); + const gasOverhead = this.buildGasOverhead(configMap); + const mergedConfig = objMap(configMap, (chain, config) => { + return { + ...tokenMetadata[chain], + ...gasOverhead[chain], + ...config, + }; + }) as ChainMap; + + return super.deploy(mergedConfig); } } diff --git a/test/erc20.test.ts b/test/erc20.test.ts index afa1857..c347f82 100644 --- a/test/erc20.test.ts +++ b/test/erc20.test.ts @@ -10,6 +10,7 @@ import { Chains, HyperlaneContractsMap, MultiProvider, + RouterConfig, TestCoreApp, TestCoreDeployer, deployTestIgpsAndGetRouterConfig, @@ -17,12 +18,7 @@ import { } from '@hyperlane-xyz/sdk'; import { utils } from '@hyperlane-xyz/utils'; -import { - HypERC20Config, - SyntheticConfig, - TokenConfig, - TokenType, -} from '../src/config'; +import { TokenConfig, TokenType } from '../src/config'; import { HypERC20Factories } from '../src/contracts'; import { HypERC20Deployer } from '../src/deploy'; import { @@ -41,10 +37,10 @@ let remoteDomain: number; const totalSupply = 3000; const amount = 10; -const tokenConfig: SyntheticConfig = { - type: TokenType.synthetic, +const tokenMetadata = { name: 'HypERC20', symbol: 'HYP', + decimals: 18, totalSupply, }; @@ -59,9 +55,9 @@ for (const variant of [ let core: TestCoreApp; let deployer: HypERC20Deployer; let contracts: HyperlaneContractsMap; - let localTokenConfig: TokenConfig = tokenConfig; + let localTokenConfig: TokenConfig; let local: HypERC20 | HypERC20Collateral | HypNative; - let remote: HypERC20 | HypERC20Collateral; + let remote: HypERC20; let interchainGasPayment: BigNumber; beforeEach(async () => { @@ -75,7 +71,7 @@ for (const variant of [ const coreDeployer = new TestCoreDeployer(multiProvider); const coreContractsMaps = await coreDeployer.deploy(); core = new TestCoreApp(coreContractsMaps, multiProvider); - const coreConfig = await deployTestIgpsAndGetRouterConfig( + const routerConfig = await deployTestIgpsAndGetRouterConfig( multiProvider, owner.address, core.contractsMap, @@ -84,9 +80,9 @@ for (const variant of [ let erc20: ERC20 | undefined; if (variant === TokenType.collateral) { erc20 = await new ERC20Test__factory(owner).deploy( - tokenConfig.name, - tokenConfig.symbol, - tokenConfig.totalSupply, + tokenMetadata.name, + tokenMetadata.symbol, + tokenMetadata.totalSupply, ); localTokenConfig = { type: variant, @@ -96,17 +92,21 @@ for (const variant of [ localTokenConfig = { type: variant, }; + } else if (variant === TokenType.synthetic) { + localTokenConfig = { type: variant, ...tokenMetadata }; } - const config: ChainMap = objMap(coreConfig, (key) => ({ - ...coreConfig[key], - ...(key === localChain ? localTokenConfig : tokenConfig), + const config = objMap(routerConfig, (key) => ({ + ...routerConfig[key], + ...(key === localChain + ? localTokenConfig + : { type: TokenType.synthetic }), owner: owner.address, - })); + })) as ChainMap; - deployer = new HypERC20Deployer(multiProvider, config, core); - contracts = await deployer.deploy(); - local = contracts[localChain].router as HypERC20; + deployer = new HypERC20Deployer(multiProvider); + contracts = await deployer.deploy(config); + local = contracts[localChain].router; interchainGasPayment = await local.quoteGasPayment(remoteDomain); diff --git a/test/erc721.test.ts b/test/erc721.test.ts index 33c2c53..acd004e 100644 --- a/test/erc721.test.ts +++ b/test/erc721.test.ts @@ -6,7 +6,6 @@ import { ethers } from 'hardhat'; import { InterchainGasPaymaster__factory } from '@hyperlane-xyz/core'; import { - ChainMap, Chains, HyperlaneContractsMap, MultiProvider, @@ -17,12 +16,7 @@ import { } from '@hyperlane-xyz/sdk'; import { utils } from '@hyperlane-xyz/utils'; -import { - HypERC721CollateralConfig, - HypERC721Config, - SyntheticConfig, - TokenType, -} from '../src/config'; +import { TokenConfig, TokenType } from '../src/config'; import { HypERC721Factories } from '../src/contracts'; import { HypERC721Deployer } from '../src/deploy'; import { @@ -45,20 +39,21 @@ const tokenId2 = 20; const tokenId3 = 30; const tokenId4 = 40; +const tokenMetadata = { + name: 'HypERC721', + symbol: 'HYP', + totalSupply, +}; + for (const withCollateral of [true, false]) { for (const withUri of [true, false]) { - const tokenConfig: SyntheticConfig = { + const tokenConfig: TokenConfig = { type: withUri ? TokenType.syntheticUri : TokenType.synthetic, - name: 'HypERC721', - symbol: 'HYP', - totalSupply, + ...tokenMetadata, }; const configMap = { - test1: { - ...tokenConfig, - totalSupply, - }, + test1: tokenConfig, test2: { ...tokenConfig, totalSupply: 0, @@ -96,9 +91,7 @@ for (const withCollateral of [true, false]) { owner.address, core.contractsMap, ); - const configWithTokenInfo: ChainMap< - HypERC721Config | HypERC721CollateralConfig - > = objMap(coreConfig, (key) => ({ + const configWithTokenInfo = objMap(coreConfig, (key) => ({ ...coreConfig[key], ...configMap[key], owner: owner.address, @@ -112,18 +105,15 @@ for (const withCollateral of [true, false]) { tokenConfig.totalSupply, ); configWithTokenInfo.test1 = { - ...configWithTokenInfo.test1, type: withUri ? TokenType.collateralUri : TokenType.collateral, token: erc721.address, + ...coreConfig.test1, }; } - deployer = new HypERC721Deployer( - multiProvider, - configWithTokenInfo, - core, - ); - contracts = await deployer.deploy(); + deployer = new HypERC721Deployer(multiProvider); + contracts = await deployer.deploy(configWithTokenInfo); + local = contracts[localChain].router; if (withCollateral) { // approve wrapper to transfer tokens diff --git a/yarn.lock b/yarn.lock index dfebe7d..644de22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1220,14 +1220,14 @@ __metadata: languageName: node linkType: hard -"@hyperlane-xyz/core@npm:1.3.0": - version: 1.3.0 - resolution: "@hyperlane-xyz/core@npm:1.3.0" +"@hyperlane-xyz/core@npm:1.3.1": + version: 1.3.1 + resolution: "@hyperlane-xyz/core@npm:1.3.1" dependencies: - "@hyperlane-xyz/utils": 1.3.0 + "@hyperlane-xyz/utils": 1.3.1 "@openzeppelin/contracts": ^4.8.0 "@openzeppelin/contracts-upgradeable": ^4.8.0 - checksum: 8e4c8e72dee2ff2705697f802de06d29fcbdb8789883f051977bbb82748d842647d6274691d918edafa03fa18e9e2fb0359c6af4d8d7f7f99cbe2167a2aef1f4 + checksum: bb341b6ab2f7bbde057082ec277d48df5918b5a4c676887af9b49a54f9dc2d349c34cf74de7b1df20bddbadbdc7467628d3689182c01702cb21e0ac0e4e71981 languageName: node linkType: hard @@ -1235,9 +1235,9 @@ __metadata: version: 0.0.0-use.local resolution: "@hyperlane-xyz/hyperlane-token@workspace:." dependencies: - "@hyperlane-xyz/core": 1.3.0 - "@hyperlane-xyz/sdk": 1.3.0 - "@hyperlane-xyz/utils": 1.3.0 + "@hyperlane-xyz/core": 1.3.1 + "@hyperlane-xyz/sdk": 1.3.1 + "@hyperlane-xyz/utils": 1.3.1 "@nomiclabs/hardhat-ethers": ^2.2.1 "@nomiclabs/hardhat-waffle": ^2.0.3 "@openzeppelin/contracts-upgradeable": ^4.8.0 @@ -1265,28 +1265,30 @@ __metadata: languageName: unknown linkType: soft -"@hyperlane-xyz/sdk@npm:1.3.0": - version: 1.3.0 - resolution: "@hyperlane-xyz/sdk@npm:1.3.0" +"@hyperlane-xyz/sdk@npm:1.3.1": + version: 1.3.1 + resolution: "@hyperlane-xyz/sdk@npm:1.3.1" dependencies: - "@hyperlane-xyz/core": 1.3.0 - "@hyperlane-xyz/utils": 1.3.0 + "@hyperlane-xyz/core": 1.3.1 + "@hyperlane-xyz/utils": 1.3.1 + "@types/coingecko-api": ^1.0.10 + "@types/debug": ^4.1.7 "@wagmi/chains": ^0.2.6 coingecko-api: ^1.0.10 cross-fetch: ^3.1.5 debug: ^4.3.4 ethers: ^5.7.2 zod: ^3.21.2 - checksum: ef8f964b58cf16bd514ed09b8f22c484dcd08385510aa67bbcb896b7a95c103b7f029d66ef676807b07a9be1aaf816d937fce7d5848f9f38529373d2f276be3d + checksum: 3b1339dafb9ea8ba7c91ac3a51fd86638808bc60a06abd36e94fdc86316a7d591b395e5c94f9646d63331bde258f5013ee434e014ddf4d1db3d20a9b6b81f5dc languageName: node linkType: hard -"@hyperlane-xyz/utils@npm:1.3.0": - version: 1.3.0 - resolution: "@hyperlane-xyz/utils@npm:1.3.0" +"@hyperlane-xyz/utils@npm:1.3.1": + version: 1.3.1 + resolution: "@hyperlane-xyz/utils@npm:1.3.1" dependencies: ethers: ^5.7.2 - checksum: 22008ac00bc37f23387b5988fa22c9066796dfa5bcc115a1cd51087b160115279cb3fa57061545fa3053de660750a27bbdb94ef8daa47abbfdf0cef8013dc787 + checksum: 960c972211618ea9b637bf98cdaf052f6175aa535ba6402617b84110731fe2657f8cdb387cc2be24c8250e87d46a99320f7d609067ee8e42b5d98644d0db4f95 languageName: node linkType: hard @@ -1803,6 +1805,13 @@ __metadata: languageName: node linkType: hard +"@types/coingecko-api@npm:^1.0.10": + version: 1.0.10 + resolution: "@types/coingecko-api@npm:1.0.10" + checksum: e9683f9ea9ce2f855f6565089981dd3fceb6c4674365438f3fc3877d089a2fb82cdea011b59d59c7baa1635dc610860cd29a10a4b7a650ff96521ead46f22a50 + languageName: node + linkType: hard + "@types/concat-stream@npm:^1.6.0": version: 1.6.1 resolution: "@types/concat-stream@npm:1.6.1" @@ -1812,6 +1821,15 @@ __metadata: languageName: node linkType: hard +"@types/debug@npm:^4.1.7": + version: 4.1.7 + resolution: "@types/debug@npm:4.1.7" + dependencies: + "@types/ms": "*" + checksum: 0a7b89d8ed72526858f0b61c6fd81f477853e8c4415bb97f48b1b5545248d2ae389931680b94b393b993a7cfe893537a200647d93defe6d87159b96812305adc + languageName: node + linkType: hard + "@types/form-data@npm:0.0.33": version: 0.0.33 resolution: "@types/form-data@npm:0.0.33" @@ -1895,6 +1913,13 @@ __metadata: languageName: node linkType: hard +"@types/ms@npm:*": + version: 0.7.31 + resolution: "@types/ms@npm:0.7.31" + checksum: daadd354aedde024cce6f5aa873fefe7b71b22cd0e28632a69e8b677aeb48ae8caa1c60e5919bb781df040d116b01cb4316335167a3fc0ef6a63fa3614c0f6da + languageName: node + linkType: hard + "@types/node-fetch@npm:^2.5.5": version: 2.6.2 resolution: "@types/node-fetch@npm:2.6.2"