Unify deploy and app abstractions (#507)

* Simplify SDK app abstraction

* Simplify SDK deploy abstraction

Co-authored-by: nambrot <nambrot@googlemail.com>
pull/525/head
Yorke Rhodes 3 years ago committed by GitHub
parent 041f9f3e8f
commit d3e788ac3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      typescript/deploy/src/check.ts
  2. 255
      typescript/deploy/src/core/deploy.ts
  3. 144
      typescript/deploy/src/deploy.ts
  4. 15
      typescript/deploy/src/index.ts
  5. 25
      typescript/deploy/src/proxy.ts
  6. 36
      typescript/deploy/src/router/check.ts
  7. 37
      typescript/deploy/src/router/deploy.ts
  8. 2
      typescript/deploy/src/router/index.ts
  9. 11
      typescript/deploy/src/router/types.ts
  10. 18
      typescript/deploy/src/utils.ts
  11. 2
      typescript/deploy/src/verify/index.ts
  12. 2
      typescript/deploy/src/verify/utils.ts
  13. 61
      typescript/hardhat/src/TestCoreApp.ts
  14. 94
      typescript/hardhat/src/TestCoreDeploy.ts
  15. 4
      typescript/hardhat/test/testAbacusDeploy.test.ts
  16. 12
      typescript/infra/hardhat.config.ts
  17. 3
      typescript/infra/scripts/check-deploy.ts
  18. 17
      typescript/infra/scripts/core.ts
  19. 2
      typescript/infra/scripts/utils.ts
  20. 32
      typescript/infra/src/core/check.ts
  21. 24
      typescript/infra/src/core/deploy.ts
  22. 3
      typescript/infra/src/utils/utils.ts
  23. 16
      typescript/infra/test/core.test.ts
  24. 45
      typescript/sdk/src/app.ts
  25. 129
      typescript/sdk/src/contracts.ts
  26. 69
      typescript/sdk/src/core/app.ts
  27. 127
      typescript/sdk/src/core/contracts.ts
  28. 52
      typescript/sdk/src/core/environments/dev.json
  29. 40
      typescript/sdk/src/core/environments/dev.ts
  30. 6
      typescript/sdk/src/core/environments/index.ts
  31. 104
      typescript/sdk/src/core/environments/test.json
  32. 77
      typescript/sdk/src/core/environments/test.ts
  33. 493
      typescript/sdk/src/core/environments/testnet.json
  34. 346
      typescript/sdk/src/core/environments/testnet.ts
  35. 5
      typescript/sdk/src/core/index.ts
  36. 4
      typescript/sdk/src/core/message.ts
  37. 13
      typescript/sdk/src/gas/calculator.ts
  38. 16
      typescript/sdk/src/index.ts
  39. 49
      typescript/sdk/src/proxy.ts
  40. 20
      typescript/sdk/src/router.ts
  41. 8
      typescript/sdk/src/types.ts
  42. 8
      typescript/sdk/src/utils.ts
  43. 16
      typescript/sdk/test/gas/calculator.test.ts
  44. 3
      typescript/sdk/tsconfig.json

@ -2,10 +2,10 @@ import { expect } from 'chai';
import { import {
AbacusApp, AbacusApp,
BeaconProxyAddresses,
ChainMap, ChainMap,
ChainName, ChainName,
MultiProvider, MultiProvider,
ProxiedAddress,
} from '@abacus-network/sdk'; } from '@abacus-network/sdk';
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
@ -54,7 +54,7 @@ export abstract class AbacusAppChecker<
async checkUpgradeBeacon( async checkUpgradeBeacon(
chain: Chain, chain: Chain,
name: string, name: string,
proxiedAddress: ProxiedAddress, proxiedAddress: BeaconProxyAddresses,
) { ) {
const dc = this.multiProvider.getChainConnection(chain); const dc = this.multiProvider.getChainConnection(chain);
const implementation = await upgradeBeaconImplementation( const implementation = await upgradeBeaconImplementation(

@ -1,35 +1,28 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { import { Inbox } from '@abacus-network/core';
AbacusConnectionManager__factory,
InboxValidatorManager,
InboxValidatorManager__factory,
Inbox__factory,
InterchainGasPaymaster__factory,
OutboxValidatorManager__factory,
Outbox__factory,
UpgradeBeaconController__factory,
} from '@abacus-network/core';
import { import {
AbacusCore, AbacusCore,
BeaconProxyAddresses,
ChainConnection, ChainConnection,
ChainMap, ChainMap,
ChainName, ChainName,
CoreContractAddresses,
CoreContracts, CoreContracts,
CoreContractsMap,
InboxContracts, InboxContracts,
MailboxAddresses,
MultiProvider, MultiProvider,
OutboxContracts,
ProxiedContract,
RemoteChainMap, RemoteChainMap,
Remotes, Remotes,
chainMetadata, chainMetadata,
coreFactories,
objMap, objMap,
promiseObjAll, promiseObjAll,
} from '@abacus-network/sdk'; } from '@abacus-network/sdk';
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
import { AbacusAppDeployer } from '../deploy'; import { AbacusDeployer } from '../deploy';
import { ProxiedContract } from '../proxy';
export type ValidatorManagerConfig = { export type ValidatorManagerConfig = {
validators: Array<types.Address>; validators: Array<types.Address>;
@ -40,173 +33,148 @@ export type CoreConfig = {
validatorManager: ValidatorManagerConfig; validatorManager: ValidatorManagerConfig;
}; };
type FactoryBuilder = (signer: ethers.Signer) => ethers.ContractFactory; export class AbacusCoreDeployer<Chain extends ChainName> extends AbacusDeployer<
export class AbacusCoreDeployer<
Chain extends ChainName,
> extends AbacusAppDeployer<
Chain, Chain,
CoreConfig, CoreConfig,
CoreContractAddresses<Chain, any> typeof coreFactories,
CoreContracts<Chain, Chain>
> { > {
inboxFactoryBuilder: FactoryBuilder = (signer: ethers.Signer) =>
new Inbox__factory(signer);
outboxFactoryBuilder: FactoryBuilder = (signer: ethers.Signer) =>
new Outbox__factory(signer);
startingBlockNumbers: ChainMap<Chain, number | undefined>; startingBlockNumbers: ChainMap<Chain, number | undefined>;
constructor( constructor(
multiProvider: MultiProvider<Chain>, multiProvider: MultiProvider<Chain>,
configMap: ChainMap<Chain, CoreConfig>, configMap: ChainMap<Chain, CoreConfig>,
factoriesOverride = coreFactories,
) { ) {
super(multiProvider, configMap); super(multiProvider, configMap, factoriesOverride);
this.startingBlockNumbers = objMap(configMap, () => undefined); this.startingBlockNumbers = objMap(configMap, () => undefined);
} }
async deploy(): Promise<CoreContractsMap<Chain>> {
return super.deploy() as Promise<CoreContractsMap<Chain>>;
}
async deployOutbox<LocalChain extends Chain>(
chain: LocalChain,
config: ValidatorManagerConfig,
ubcAddress: types.Address,
): Promise<OutboxContracts> {
const domain = chainMetadata[chain].id;
const outboxValidatorManager = await this.deployContract(
chain,
'outboxValidatorManager',
[domain, config.validators, config.threshold],
);
const outbox = await this.deployProxiedContract(
chain,
'outbox',
[domain],
ubcAddress,
[outboxValidatorManager.address],
);
return { outbox, outboxValidatorManager };
}
async deployInbox<Local extends Chain>(
localChain: Local,
remoteChain: Remotes<Chain, Local>,
config: ValidatorManagerConfig,
ubcAddress: types.Address,
duplicate?: ProxiedContract<Inbox, BeaconProxyAddresses>,
): Promise<InboxContracts> {
const localDomain = chainMetadata[localChain].id;
const remoteDomain = chainMetadata[remoteChain].id;
const inboxValidatorManager = await this.deployContract(
localChain,
'inboxValidatorManager',
[localDomain, config.validators, config.threshold],
);
const initArgs: Parameters<Inbox['initialize']> = [
remoteDomain,
inboxValidatorManager.address,
];
let inbox: ProxiedContract<Inbox, BeaconProxyAddresses>;
if (duplicate) {
inbox = await this.duplicateProxiedContract(
localChain,
duplicate,
initArgs,
);
} else {
inbox = await this.deployProxiedContract(
localChain,
'inbox',
[localDomain],
ubcAddress,
initArgs,
);
}
return { inbox, inboxValidatorManager };
}
async deployContracts<LocalChain extends Chain>( async deployContracts<LocalChain extends Chain>(
chain: LocalChain, chain: LocalChain,
config: CoreConfig, config: CoreConfig,
): Promise<CoreContractAddresses<Chain, LocalChain>> { ): Promise<CoreContracts<Chain, LocalChain>> {
const dc = this.multiProvider.getChainConnection(chain); const dc = this.multiProvider.getChainConnection(chain);
const signer = dc.signer!;
const provider = dc.provider!; const provider = dc.provider!;
const startingBlockNumber = await provider.getBlockNumber(); const startingBlockNumber = await provider.getBlockNumber();
this.startingBlockNumbers[chain] = startingBlockNumber; this.startingBlockNumbers[chain] = startingBlockNumber;
const upgradeBeaconController = await this.deployContract( const upgradeBeaconController = await this.deployContract(
chain, chain,
'UpgradeBeaconController', 'upgradeBeaconController',
new UpgradeBeaconController__factory(signer),
[], [],
); );
const outboxValidatorManagerConfig = config.validatorManager;
const domain = chainMetadata[chain].id;
const outboxValidatorManager = await this.deployContract(
chain,
'OutboxValidatorManager',
new OutboxValidatorManager__factory(signer),
[
domain,
outboxValidatorManagerConfig.validators,
outboxValidatorManagerConfig.threshold,
],
);
const outbox = await this.deployProxiedContract(
chain,
'Outbox',
this.outboxFactoryBuilder(signer),
[domain],
upgradeBeaconController.address,
[outboxValidatorManager.address],
);
const interchainGasPaymaster = await this.deployContract( const interchainGasPaymaster = await this.deployContract(
chain, chain,
'InterchainGasPaymaster', 'interchainGasPaymaster',
new InterchainGasPaymaster__factory(signer),
[], [],
); );
const abacusConnectionManager = await this.deployContract( const abacusConnectionManager = await this.deployContract(
chain, chain,
'AbacusConnectionManager', 'abacusConnectionManager',
new AbacusConnectionManager__factory(signer),
[], [],
); );
await abacusConnectionManager.setOutbox(
outbox.contract.address,
dc.overrides,
);
await abacusConnectionManager.setInterchainGasPaymaster( await abacusConnectionManager.setInterchainGasPaymaster(
interchainGasPaymaster.address, interchainGasPaymaster.address,
dc.overrides,
);
const remotes = Object.keys(this.configMap).filter(
(k) => k !== chain,
) as Remotes<Chain, LocalChain>[];
const deployValidatorManager = async (
remote: Remotes<Chain, LocalChain>,
): Promise<InboxValidatorManager> => {
const remoteConfig = this.configMap[remote].validatorManager;
return this.deployContract(
chain,
'InboxValidatorManager',
new InboxValidatorManager__factory(signer),
[
chainMetadata[remote].id,
remoteConfig.validators,
remoteConfig.threshold,
],
); );
};
const [firstRemote, ...trailingRemotes] = remotes; const outbox = await this.deployOutbox(
const firstValidatorManager = await deployValidatorManager(firstRemote);
const firstInbox = await this.deployProxiedContract(
chain, chain,
'Inbox', config.validatorManager,
this.inboxFactoryBuilder(signer),
[domain],
upgradeBeaconController.address, upgradeBeaconController.address,
[chainMetadata[firstRemote].id, firstValidatorManager.address],
); );
await abacusConnectionManager.setOutbox(outbox.outbox.address);
const getMailbox = ( const remotes = this.multiProvider.remoteChains(chain);
validatorManager: ethers.Contract, const inboxes: Partial<Record<Chain, InboxContracts>> = {};
box: ProxiedContract<ethers.Contract>, let prev: Chain | undefined;
): MailboxAddresses => ({ for (const remote of remotes) {
...box.addresses, const inbox = await this.deployInbox(
validatorManager: validatorManager.address,
});
type RemoteMailboxEntry = [Remotes<Chain, LocalChain>, MailboxAddresses];
const firstInboxAddresses: RemoteMailboxEntry = [
firstRemote,
getMailbox(firstValidatorManager, firstInbox),
];
const trailingInboxAddresses = await Promise.all(
trailingRemotes.map(async (remote): Promise<RemoteMailboxEntry> => {
const validatorManager = await deployValidatorManager(remote);
const inbox = await this.duplicateProxiedContract(
chain, chain,
'Inbox', remote,
firstInbox, this.configMap[remote].validatorManager,
[chainMetadata[remote].id, validatorManager.address], upgradeBeaconController.address,
); inboxes[prev]?.inbox,
return [remote, getMailbox(validatorManager, inbox)];
}),
); );
await abacusConnectionManager.enrollInbox(
const inboxAddresses = [firstInboxAddresses, ...trailingInboxAddresses];
await Promise.all(
inboxAddresses.map(([remote, mailbox]) =>
abacusConnectionManager.enrollInbox(
chainMetadata[remote].id, chainMetadata[remote].id,
mailbox.proxy, inbox.inbox.address,
),
),
); );
inboxes[remote] = inbox;
prev = remote;
}
return { return {
upgradeBeaconController: upgradeBeaconController.address, upgradeBeaconController,
abacusConnectionManager: abacusConnectionManager.address, abacusConnectionManager,
interchainGasPaymaster: interchainGasPaymaster.address, interchainGasPaymaster,
outbox: getMailbox(outboxValidatorManager, outbox), inboxes: inboxes as RemoteChainMap<Chain, LocalChain, InboxContracts>,
inboxes: Object.fromEntries(inboxAddresses) as RemoteChainMap< ...outbox,
Chain,
LocalChain,
MailboxAddresses
>,
}; };
} }
@ -232,36 +200,37 @@ export class AbacusCoreDeployer<
Chain extends ChainName, Chain extends ChainName,
Local extends Chain, Local extends Chain,
>( >(
core: CoreContracts<Chain, Local>, coreContracts: CoreContracts<Chain, Local>,
owner: types.Address, owner: types.Address,
chainConnection: ChainConnection, chainConnection: ChainConnection,
): Promise<ethers.ContractReceipt> { ): Promise<ethers.ContractReceipt> {
await core.contracts.outbox.validatorManager.transferOwnership( await coreContracts.outboxValidatorManager.transferOwnership(
owner, owner,
chainConnection.overrides, chainConnection.overrides,
); );
await core.contracts.abacusConnectionManager.transferOwnership( await coreContracts.abacusConnectionManager.transferOwnership(
owner, owner,
chainConnection.overrides, chainConnection.overrides,
); );
await core.contracts.upgradeBeaconController.transferOwnership( await coreContracts.upgradeBeaconController.transferOwnership(
owner, owner,
chainConnection.overrides, chainConnection.overrides,
); );
const inboxContracts: InboxContracts[] = Object.values( const inboxContracts = Object.values<InboxContracts>(coreContracts.inboxes);
core.contracts.inboxes,
);
await Promise.all( await Promise.all(
inboxContracts.map(async (inbox) => { inboxContracts.map(async (inbox) => {
await inbox.validatorManager.transferOwnership( await inbox.inboxValidatorManager.transferOwnership(
owner,
chainConnection.overrides,
);
await inbox.inbox.contract.transferOwnership(
owner, owner,
chainConnection.overrides, chainConnection.overrides,
); );
await inbox.inbox.transferOwnership(owner, chainConnection.overrides);
}), }),
); );
const tx = await core.contracts.outbox.outbox.transferOwnership( const tx = await coreContracts.outbox.contract.transferOwnership(
owner, owner,
chainConnection.overrides, chainConnection.overrides,
); );

@ -1,21 +1,23 @@
import { Debugger, debug } from 'debug'; import { Debugger, debug } from 'debug';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import fs from 'fs';
import path from 'path';
import { import {
UpgradeBeaconProxy__factory, UpgradeBeaconProxy__factory,
UpgradeBeacon__factory, UpgradeBeacon__factory,
} from '@abacus-network/core'; } from '@abacus-network/core';
import { import {
AbacusContracts,
AbacusFactories,
BeaconProxyAddresses,
ChainMap, ChainMap,
ChainName, ChainName,
MultiProvider, MultiProvider,
ProxiedContract,
objMap, objMap,
} from '@abacus-network/sdk'; } from '@abacus-network/sdk';
import { ProxyKind } from '@abacus-network/sdk/dist/proxy';
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
import { ProxiedContract } from './proxy';
import { import {
ContractVerificationInput, ContractVerificationInput,
getContractVerificationInput, getContractVerificationInput,
@ -25,47 +27,54 @@ export interface DeployerOptions {
logger?: Debugger; logger?: Debugger;
} }
// TODO: Make AppDeployer generic on AbacusApp and return instance from deploy() export abstract class AbacusDeployer<
export abstract class AbacusAppDeployer<Chain extends ChainName, C, A> { Chain extends ChainName,
Config,
Factories extends AbacusFactories,
Contracts extends AbacusContracts,
> {
verificationInputs: ChainMap<Chain, ContractVerificationInput[]>; verificationInputs: ChainMap<Chain, ContractVerificationInput[]>;
protected logger: Debugger; protected logger: Debugger;
constructor( constructor(
protected readonly multiProvider: MultiProvider<Chain>, protected readonly multiProvider: MultiProvider<Chain>,
protected readonly configMap: ChainMap<Chain, C>, protected readonly configMap: ChainMap<Chain, Config>,
protected readonly factories: Factories,
protected readonly options?: DeployerOptions, protected readonly options?: DeployerOptions,
) { ) {
this.verificationInputs = objMap(configMap, () => []); this.verificationInputs = objMap(configMap, () => []);
this.logger = options?.logger || debug('abacus:AppDeployer'); this.logger = options?.logger || debug('abacus:AppDeployer');
} }
abstract deployContracts(chain: Chain, config: C): Promise<A>; abstract deployContracts(chain: Chain, config: Config): Promise<Contracts>;
async deploy() { async deploy() {
this.logger('Start Deploy'); this.logger('Start Deploy');
this.verificationInputs = objMap(this.configMap, () => []); this.verificationInputs = objMap(this.configMap, () => []);
const chains = this.multiProvider.chains(); const chains = this.multiProvider.chains();
const entries: [Chain, A][] = []; const entries: [Chain, Contracts][] = [];
for (const chain of chains) { for (const chain of chains) {
this.logger(`Deploying to ${chain}...`); this.logger(`Deploying to ${chain}...`);
const result = await this.deployContracts(chain, this.configMap[chain]); const result = await this.deployContracts(chain, this.configMap[chain]);
entries.push([chain, result]); entries.push([chain, result]);
} }
return Object.fromEntries(entries) as Record<Chain, A>; return Object.fromEntries(entries) as Record<Chain, Contracts>;
} }
async deployContract<F extends ethers.ContractFactory>( async deployContract<K extends keyof Factories>(
chain: Chain, chain: Chain,
contractName: string, contractName: K,
factory: F, args: Parameters<Factories[K]['deploy']>,
args: Parameters<F['deploy']>, ): Promise<ReturnType<Factories[K]['deploy']>> {
): Promise<ReturnType<F['deploy']>> { this.logger(`Deploy ${contractName.toString()} on ${chain}`);
this.logger(`Deploy ${contractName} on ${chain}`);
const chainConnection = this.multiProvider.getChainConnection(chain); const chainConnection = this.multiProvider.getChainConnection(chain);
const contract = await factory.deploy(...args, chainConnection.overrides); const factory = this.factories[contractName].connect(
chainConnection.signer!,
);
const contract = await factory.deploy(...args);
await contract.deployTransaction.wait(chainConnection.confirmations); await contract.deployTransaction.wait(chainConnection.confirmations);
const verificationInput = getContractVerificationInput( const verificationInput = getContractVerificationInput(
contractName, contractName.toString(),
contract, contract,
factory.bytecode, factory.bytecode,
); );
@ -78,48 +87,43 @@ export abstract class AbacusAppDeployer<Chain extends ChainName, C, A> {
* *
*/ */
async deployProxiedContract< async deployProxiedContract<
F extends ethers.ContractFactory, K extends keyof Factories,
C extends ethers.Contract = Awaited<ReturnType<F['deploy']>>, C extends Awaited<ReturnType<Factories[K]['deploy']>>,
>( >(
chain: Chain, chain: Chain,
contractName: string, contractName: K,
factory: F, deployArgs: Parameters<Factories[K]['deploy']>,
deployArgs: Parameters<F['deploy']>,
ubcAddress: types.Address, ubcAddress: types.Address,
initArgs: Parameters<C['initialize']>, initArgs: Parameters<C['initialize']>,
) { ): Promise<ProxiedContract<C, BeaconProxyAddresses>> {
const chainConnection = this.multiProvider.getChainConnection(chain); const chainConnection = this.multiProvider.getChainConnection(chain);
const signer = chainConnection.signer; const signer = chainConnection.signer;
const implementation = await this.deployContract( const implementation = await this.deployContract<K>(
chain, chain,
`${contractName} Implementation`, contractName,
factory,
deployArgs, deployArgs,
); );
const beacon = await this.deployContract( const beacon = await new UpgradeBeacon__factory(signer).deploy(
chain, implementation.address,
`${contractName} UpgradeBeacon`, ubcAddress,
new UpgradeBeacon__factory(signer),
[implementation.address, ubcAddress],
); );
const initData = implementation.interface.encodeFunctionData( const initData = implementation.interface.encodeFunctionData(
'initialize', 'initialize',
initArgs, initArgs,
); );
const proxy = await this.deployContract( const beaconProxy = await new UpgradeBeaconProxy__factory(signer).deploy(
chain, beacon.address,
`${contractName} Proxy`, initData,
new UpgradeBeaconProxy__factory(signer),
[beacon.address, initData],
); );
return new ProxiedContract<C, BeaconProxyAddresses>(
const proxiedContract = new ProxiedContract(factory.attach(proxy.address), { implementation.attach(beaconProxy.address) as any,
proxy: proxy.address, {
kind: ProxyKind.UpgradeBeacon,
proxy: beaconProxy.address,
implementation: implementation.address, implementation: implementation.address,
beacon: beacon.address, beacon: beacon.address,
}); },
return proxiedContract; );
} }
/** /**
@ -128,61 +132,25 @@ export abstract class AbacusAppDeployer<Chain extends ChainName, C, A> {
*/ */
async duplicateProxiedContract<C extends ethers.Contract>( async duplicateProxiedContract<C extends ethers.Contract>(
chain: Chain, chain: Chain,
contractName: string, proxy: ProxiedContract<C, BeaconProxyAddresses>,
proxy: ProxiedContract<C>,
initArgs: Parameters<C['initialize']>, initArgs: Parameters<C['initialize']>,
) { ): Promise<ProxiedContract<C, BeaconProxyAddresses>> {
const chainConnection = this.multiProvider.getChainConnection(chain); const signer = this.multiProvider.getChainConnection(chain).signer!;
const initData = proxy.contract.interface.encodeFunctionData( const initData = proxy.contract.interface.encodeFunctionData(
'initialize', 'initialize',
initArgs, initArgs,
); );
const newProxy = await this.deployContract( const proxyAddresses = proxy.addresses as BeaconProxyAddresses;
chain, const newProxy = await new UpgradeBeaconProxy__factory(signer).deploy(
`${contractName} Proxy`, proxyAddresses.beacon,
new UpgradeBeaconProxy__factory(chainConnection.signer!), initData,
[proxy.addresses.beacon, initData],
); );
return new ProxiedContract<C, BeaconProxyAddresses>(
const newProxiedContract = new ProxiedContract( proxy.contract.attach(newProxy.address) as C,
proxy.contract.attach(newProxy.address),
{ {
...proxy.addresses, ...proxyAddresses,
proxy: newProxy.address, proxy: newProxy.address,
}, },
); );
return newProxiedContract;
}
writeOutput(directory: string, addresses: ChainMap<Chain, A>) {
this.writeContracts(addresses, path.join(directory, 'addresses.ts'));
this.writeVerification(path.join(directory, 'verification'));
}
writeContracts(addresses: ChainMap<Chain, A>, filepath: string) {
const contents = `export const addresses = ${AbacusAppDeployer.stringify(
addresses,
)}`;
AbacusAppDeployer.write(filepath, contents);
}
writeVerification(directory: string) {
objMap(this.verificationInputs, (chain, input) => {
AbacusAppDeployer.writeJson(path.join(directory, `${chain}.json`), input);
});
}
static stringify(obj: any) {
return JSON.stringify(obj, null, 2);
}
static write(filepath: string, contents: string) {
const dir = path.dirname(filepath);
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(filepath, contents);
}
static writeJson(filepath: string, obj: any) {
AbacusAppDeployer.write(filepath, AbacusAppDeployer.stringify(obj));
} }
} }

@ -5,17 +5,16 @@ export {
CoreConfig, CoreConfig,
ValidatorManagerConfig, ValidatorManagerConfig,
} from './core/deploy'; } from './core/deploy';
export { AbacusAppDeployer } from './deploy'; export { AbacusDeployer } from './deploy';
export { export { UpgradeBeaconViolation } from './proxy';
ProxiedContract,
ProxyViolationType,
UpgradeBeaconViolation,
} from './proxy';
export { export {
AbacusRouterChecker, AbacusRouterChecker,
AbacusRouterDeployer, AbacusRouterDeployer,
Router,
RouterConfig, RouterConfig,
} from './router'; } from './router';
export * as utils from './utils'; export * as utils from './utils';
export { ContractVerifier, VerificationInput } from './verify'; export {
ContractVerifier,
getConstructorArguments,
VerificationInput,
} from './verify';

@ -1,29 +1,14 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { ChainName, ProxiedAddress } from '@abacus-network/sdk'; import { BeaconProxyAddresses, ChainName } from '@abacus-network/sdk';
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
import { CheckerViolation } from './config'; import { CheckerViolation } from './config';
export class ProxiedContract<T extends ethers.Contract> {
constructor(
public readonly contract: T,
public readonly addresses: ProxiedAddress,
) {}
get address() {
return this.contract.address;
}
}
export enum ProxyViolationType {
UpgradeBeacon = 'UpgradeBeacon',
}
export interface UpgradeBeaconViolation extends CheckerViolation { export interface UpgradeBeaconViolation extends CheckerViolation {
type: ProxyViolationType.UpgradeBeacon; type: BeaconProxyAddresses['kind'];
data: { data: {
proxiedAddress: ProxiedAddress; proxiedAddress: BeaconProxyAddresses;
name: string; name: string;
}; };
actual: string; actual: string;
@ -42,12 +27,12 @@ export async function upgradeBeaconImplementation(
export function upgradeBeaconViolation<Chain extends ChainName>( export function upgradeBeaconViolation<Chain extends ChainName>(
chain: Chain, chain: Chain,
name: string, name: string,
proxiedAddress: ProxiedAddress, proxiedAddress: BeaconProxyAddresses,
actual: types.Address, actual: types.Address,
): UpgradeBeaconViolation { ): UpgradeBeaconViolation {
return { return {
chain, chain,
type: ProxyViolationType.UpgradeBeacon, type: proxiedAddress.kind,
actual, actual,
expected: proxiedAddress.implementation, expected: proxiedAddress.implementation,
data: { data: {

@ -1,21 +1,22 @@
import { expect } from 'chai'; import { expect } from 'chai';
import { AbacusApp, ChainName, chainMetadata } from '@abacus-network/sdk'; import {
import { types, utils } from '@abacus-network/utils'; AbacusApp,
ChainName,
RouterContracts,
chainMetadata,
} from '@abacus-network/sdk';
import { utils } from '@abacus-network/utils';
import { AbacusAppChecker, Ownable } from '../check'; import { AbacusAppChecker, Ownable } from '../check';
import { Router, RouterConfig } from './types'; import { RouterConfig } from './types';
export abstract class AbacusRouterChecker< export class AbacusRouterChecker<
Chain extends ChainName, Chain extends ChainName,
App extends AbacusApp<any, Chain>, App extends AbacusApp<RouterContracts, Chain>,
Config extends RouterConfig & { Config extends RouterConfig,
owner: types.Address;
},
> extends AbacusAppChecker<Chain, App, Config> { > extends AbacusAppChecker<Chain, App, Config> {
abstract mustGetRouter(chain: Chain): Router; // TODO: implement on AbacusRouterApp
checkOwnership(chain: Chain) { checkOwnership(chain: Chain) {
const owner = this.configMap[chain].owner; const owner = this.configMap[chain].owner;
const ownables = this.ownables(chain); const ownables = this.ownables(chain);
@ -29,11 +30,11 @@ export abstract class AbacusRouterChecker<
} }
async checkEnrolledRouters(chain: Chain): Promise<void> { async checkEnrolledRouters(chain: Chain): Promise<void> {
const router = this.mustGetRouter(chain); const router = this.app.getContracts(chain).router;
await Promise.all( await Promise.all(
this.app.remoteChains(chain).map(async (remoteNetwork) => { this.app.remoteChains(chain).map(async (remoteNetwork) => {
const remoteRouter = this.mustGetRouter(remoteNetwork); const remoteRouter = this.app.getContracts(remoteNetwork).router;
const remoteChainId = chainMetadata[remoteNetwork].id; const remoteChainId = chainMetadata[remoteNetwork].id;
expect(await router.routers(remoteChainId)).to.equal( expect(await router.routers(remoteChainId)).to.equal(
utils.addressToBytes32(remoteRouter.address), utils.addressToBytes32(remoteRouter.address),
@ -43,12 +44,12 @@ export abstract class AbacusRouterChecker<
} }
ownables(chain: Chain): Ownable[] { ownables(chain: Chain): Ownable[] {
const ownables: Ownable[] = [this.mustGetRouter(chain)]; const contracts = this.app.getContracts(chain);
const ownables: Ownable[] = [contracts.router];
const config = this.configMap[chain]; const config = this.configMap[chain];
// If the config specifies that an abacusConnectionManager should have been deployed, // If the config specifies that an abacusConnectionManager should have been deployed,
// it should be owned by the owner. // it should be owned by the owner.
if (config.abacusConnectionManager) { if (config.abacusConnectionManager && contracts.abacusConnectionManager) {
const contracts: any = this.app.getContracts(chain);
ownables.push(contracts.abacusConnectionManager); ownables.push(contracts.abacusConnectionManager);
} }
return ownables; return ownables;
@ -56,10 +57,11 @@ export abstract class AbacusRouterChecker<
async checkAbacusConnectionManager(chain: Chain): Promise<void> { async checkAbacusConnectionManager(chain: Chain): Promise<void> {
const config = this.configMap[chain]; const config = this.configMap[chain];
if (!config.abacusConnectionManager) { const contracts = this.app.getContracts(chain);
if (!config.abacusConnectionManager || !contracts.abacusConnectionManager) {
return; return;
} }
const actual = await this.mustGetRouter(chain).abacusConnectionManager(); const actual = contracts.abacusConnectionManager.address;
expect(actual).to.equal(config.abacusConnectionManager); expect(actual).to.equal(config.abacusConnectionManager);
} }
} }

@ -4,54 +4,51 @@ import {
ChainMap, ChainMap,
ChainName, ChainName,
MultiProvider, MultiProvider,
RouterContracts,
RouterFactories,
chainMetadata, chainMetadata,
objMap, objMap,
promiseObjAll, promiseObjAll,
} from '@abacus-network/sdk'; } from '@abacus-network/sdk';
import { utils } from '@abacus-network/utils'; import { utils } from '@abacus-network/utils';
import { AbacusAppDeployer, DeployerOptions } from '../deploy'; import { AbacusDeployer, DeployerOptions } from '../deploy';
import { Router, RouterConfig } from './types'; import { RouterConfig } from './types';
export abstract class AbacusRouterDeployer< export abstract class AbacusRouterDeployer<
Chain extends ChainName, Chain extends ChainName,
Config, Config extends RouterConfig,
Addresses, Factories extends RouterFactories,
> extends AbacusAppDeployer<Chain, Config & RouterConfig, Addresses> { Contracts extends RouterContracts,
abstract mustGetRouter(chain: Chain, addresses: Addresses): Router; > extends AbacusDeployer<Chain, Config, Factories, Contracts> {
constructor( constructor(
multiProvider: MultiProvider<Chain>, multiProvider: MultiProvider<Chain>,
configMap: ChainMap<Chain, Config & RouterConfig>, configMap: ChainMap<Chain, Config>,
factories: Factories,
options?: DeployerOptions, options?: DeployerOptions,
) { ) {
const logger = options?.logger || debug('abacus:RouterDeployer'); const logger = options?.logger || debug('abacus:RouterDeployer');
super(multiProvider, configMap, { ...options, logger }); super(multiProvider, configMap, factories, { ...options, logger });
} }
async deploy() { async deploy() {
const deploymentOutput = await super.deploy(); const contractsMap = await super.deploy();
this.logger(`Enroll Routers with each other`); this.logger(`Enrolling deployed routers with each other...`);
// Make all routers aware of eachother. // Make all routers aware of eachother.
await promiseObjAll( await promiseObjAll(
objMap(deploymentOutput, async (local, addresses) => { objMap(contractsMap, async (local, contracts) => {
const localRouter = this.mustGetRouter(local, addresses);
for (const remote of this.multiProvider.remoteChains(local)) { for (const remote of this.multiProvider.remoteChains(local)) {
const remoteRouter = this.mustGetRouter(
remote,
deploymentOutput[remote],
);
this.logger(`Enroll ${remote}'s router on ${local}`); this.logger(`Enroll ${remote}'s router on ${local}`);
await localRouter.enrollRemoteRouter( await contracts.router.enrollRemoteRouter(
chainMetadata[remote].id, chainMetadata[remote].id,
utils.addressToBytes32(remoteRouter.address), utils.addressToBytes32(contractsMap[remote].router.address),
); );
} }
}), }),
); );
return deploymentOutput; return contractsMap;
} }
} }

@ -1,3 +1,3 @@
export { AbacusRouterChecker } from './check'; export { AbacusRouterChecker } from './check';
export { AbacusRouterDeployer } from './deploy'; export { AbacusRouterDeployer } from './deploy';
export { RouterConfig, Router } from './types'; export { RouterConfig } from './types';

@ -1,15 +1,6 @@
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
export interface Router {
address: types.Address;
enrollRemoteRouter(domain: types.Domain, router: types.Address): Promise<any>;
// Technically a bytes32...
routers(domain: types.Domain): Promise<types.Address>;
abacusConnectionManager(): Promise<types.Address>;
transferOwnership(owner: types.Address): Promise<any>;
owner(): Promise<types.Address>;
}
export type RouterConfig = { export type RouterConfig = {
abacusConnectionManager: types.Address; abacusConnectionManager: types.Address;
owner: types.Address;
}; };

@ -1,16 +1,9 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import yargs from 'yargs'; import yargs from 'yargs';
import { import { ChainName, MultiProvider, objMap } from '@abacus-network/sdk';
AbacusCore,
ChainMap,
ChainName,
MultiProvider,
objMap,
} from '@abacus-network/sdk';
import { EnvironmentConfig } from './config'; import { EnvironmentConfig } from './config';
import { RouterConfig } from './router';
export function getArgs() { export function getArgs() {
return yargs(process.argv.slice(2)) return yargs(process.argv.slice(2))
@ -24,15 +17,6 @@ export async function getEnvironment(): Promise<string> {
return (await getArgs().argv).e as Promise<string>; return (await getArgs().argv).e as Promise<string>;
} }
export function getRouterConfig<N extends ChainName>(
core: AbacusCore<N>,
): ChainMap<N, RouterConfig> {
return objMap(core.contractsMap, (_, coreContacts) => ({
abacusConnectionManager:
coreContacts.contracts.abacusConnectionManager.address,
}));
}
export const getMultiProviderFromConfigAndSigner = <Chain extends ChainName>( export const getMultiProviderFromConfigAndSigner = <Chain extends ChainName>(
environmentConfig: EnvironmentConfig<Chain>, environmentConfig: EnvironmentConfig<Chain>,
signer: ethers.Signer, signer: ethers.Signer,

@ -1,3 +1,3 @@
export { ContractVerifier } from './ContractVerifier'; export { ContractVerifier } from './ContractVerifier';
export { getContractVerificationInput } from './utils';
export { ContractVerificationInput, VerificationInput } from './types'; export { ContractVerificationInput, VerificationInput } from './types';
export { getConstructorArguments, getContractVerificationInput } from './utils';

@ -10,7 +10,7 @@ export function formatFunctionArguments(fragment: Fragment, args: any[]) {
return JSON.stringify(params, null, 2); return JSON.stringify(params, null, 2);
} }
function getConstructorArguments( export function getConstructorArguments(
contract: ethers.Contract, contract: ethers.Contract,
bytecode: string, bytecode: string,
): any { ): any {

@ -1,38 +1,45 @@
import { import { TestInbox, TestOutbox } from '@abacus-network/core';
TestInbox,
TestInbox__factory,
TestOutbox__factory,
} from '@abacus-network/core';
import { import {
AbacusCore, AbacusCore,
ChainMap,
CoreContracts,
DomainIdToChainName, DomainIdToChainName,
InboxContracts,
OutboxContracts,
ProxiedContract,
Remotes,
TestChainNames, TestChainNames,
chainMetadata, chainMetadata,
objMap,
} from '@abacus-network/sdk'; } from '@abacus-network/sdk';
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
export class TestCoreApp extends AbacusCore<TestChainNames> { type MockProxyAddresses = {
getContracts<Local extends TestChainNames>(chain: Local) { kind: 'MOCK';
const contracts = super.getContracts(chain); proxy: string;
return { implementation: string;
...contracts, };
outbox: {
...contracts.outbox, export type TestOutboxContracts = OutboxContracts & {
outbox: TestOutbox__factory.connect( outbox: ProxiedContract<TestOutbox, MockProxyAddresses>;
contracts.outbox.outbox.address, };
contracts.outbox.outbox.signer, export type TestInboxContracts = InboxContracts & {
), inbox: ProxiedContract<TestInbox, MockProxyAddresses>;
},
inboxes: objMap(contracts.inboxes, (_, inbox) => ({
...inbox,
inbox: TestInbox__factory.connect(
inbox.inbox.address,
inbox.inbox.signer,
),
})),
}; };
export type TestCoreContracts<Local extends TestChainNames> = CoreContracts<
TestChainNames,
Local
> &
TestOutboxContracts & {
inboxes: ChainMap<Remotes<TestChainNames, Local>, TestInboxContracts>;
};
export class TestCoreApp extends AbacusCore<TestChainNames> {
getContracts<Local extends TestChainNames>(
chain: Local,
): TestCoreContracts<Local> {
return super.getContracts(chain) as TestCoreContracts<Local>;
} }
async processMessages(): Promise< async processMessages(): Promise<
@ -56,7 +63,7 @@ export class TestCoreApp extends AbacusCore<TestChainNames> {
async processOutboundMessages<Local extends TestChainNames>(origin: Local) { async processOutboundMessages<Local extends TestChainNames>(origin: Local) {
const responses = new Map(); const responses = new Map();
const contracts = this.getContracts(origin); const contracts = this.getContracts(origin);
const outbox = contracts.outbox.outbox; const outbox: TestOutbox = contracts.outbox.contract;
const dispatchFilter = outbox.filters.Dispatch(); const dispatchFilter = outbox.filters.Dispatch();
const dispatches = await outbox.queryFilter(dispatchFilter); const dispatches = await outbox.queryFilter(dispatchFilter);
@ -68,7 +75,7 @@ export class TestCoreApp extends AbacusCore<TestChainNames> {
const destinationChain = DomainIdToChainName[destination]; const destinationChain = DomainIdToChainName[destination];
const inbox: TestInbox = const inbox: TestInbox =
// @ts-ignore // @ts-ignore
this.getContracts(destinationChain).inboxes[origin].inbox; this.getContracts(destinationChain).inboxes[origin].inbox.contract;
const status = await inbox.messages(dispatch.args.messageHash); const status = await inbox.messages(dispatch.args.messageHash);
if (status !== types.MessageStatus.PROCESSED) { if (status !== types.MessageStatus.PROCESSED) {
const response = await inbox.testProcess( const response = await inbox.testProcess(

@ -1,7 +1,22 @@
import { TestCoreApp } from './TestCoreApp'; import {
TestCoreApp,
TestInboxContracts,
TestOutboxContracts,
} from './TestCoreApp';
import { TestInbox__factory, TestOutbox__factory } from '@abacus-network/core'; import { TestInbox__factory, TestOutbox__factory } from '@abacus-network/core';
import { AbacusCoreDeployer, CoreConfig } from '@abacus-network/deploy'; import {
import { MultiProvider, TestChainNames } from '@abacus-network/sdk'; AbacusCoreDeployer,
CoreConfig,
ValidatorManagerConfig,
} from '@abacus-network/deploy';
import {
chainMetadata,
coreFactories,
MultiProvider,
ProxiedContract,
Remotes,
TestChainNames,
} from '@abacus-network/sdk';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
// dummy config as TestInbox and TestOutbox do not use deployed ValidatorManager // dummy config as TestInbox and TestOutbox do not use deployed ValidatorManager
@ -12,22 +27,79 @@ const testValidatorManagerConfig: CoreConfig = {
}, },
}; };
const testCoreFactories = {
...coreFactories,
inbox: new TestInbox__factory(),
outbox: new TestOutbox__factory(),
};
function mockProxy(contract: ethers.Contract) {
return new ProxiedContract(contract, {
kind: 'MOCK',
proxy: contract.address,
implementation: contract.address,
});
}
export class TestCoreDeploy extends AbacusCoreDeployer<TestChainNames> { export class TestCoreDeploy extends AbacusCoreDeployer<TestChainNames> {
constructor(public readonly multiProvider: MultiProvider<TestChainNames>) { constructor(public readonly multiProvider: MultiProvider<TestChainNames>) {
super(multiProvider, { super(
multiProvider,
{
test1: testValidatorManagerConfig, test1: testValidatorManagerConfig,
test2: testValidatorManagerConfig, test2: testValidatorManagerConfig,
test3: testValidatorManagerConfig, test3: testValidatorManagerConfig,
}); },
testCoreFactories,
);
} }
inboxFactoryBuilder = (signer: ethers.Signer) => // skip proxying
new TestInbox__factory(signer); async deployOutbox<LocalChain extends TestChainNames>(
outboxFactoryBuilder = (signer: ethers.Signer) => chain: LocalChain,
new TestOutbox__factory(signer); config: ValidatorManagerConfig,
): Promise<TestOutboxContracts> {
const localDomain = chainMetadata[chain].id;
const outboxContract = await this.deployContract(chain, 'outbox', [
localDomain,
]);
const outboxValidatorManager = await this.deployContract(
chain,
'outboxValidatorManager',
[localDomain, config.validators, config.threshold],
);
// validator manager must be contract
await outboxContract.initialize(outboxValidatorManager.address);
return {
outbox: mockProxy(outboxContract),
outboxValidatorManager,
} as TestOutboxContracts;
}
// skip proxying
async deployInbox<LocalChain extends TestChainNames>(
local: LocalChain,
remote: Remotes<TestChainNames, LocalChain>,
config: ValidatorManagerConfig,
): Promise<TestInboxContracts> {
const localDomain = chainMetadata[local].id;
const remoteDomain = chainMetadata[remote].id;
const inboxContract = await this.deployContract(local, 'inbox', [
localDomain,
]);
const inboxValidatorManager = await this.deployContract(
local,
'inboxValidatorManager',
[remoteDomain, config.validators, config.threshold],
);
await inboxContract.initialize(remoteDomain, inboxValidatorManager.address);
return {
inbox: mockProxy(inboxContract),
inboxValidatorManager,
} as TestInboxContracts;
}
async deployCore() { async deployCore() {
const result = await super.deploy(); return new TestCoreApp(await this.deploy(), this.multiProvider);
return new TestCoreApp(result, this.multiProvider);
} }
} }

@ -23,7 +23,7 @@ describe('TestCoreDeploy', async () => {
abacus = await deployer.deployCore(); abacus = await deployer.deployCore();
const recipient = await new TestRecipient__factory(signer).deploy(); const recipient = await new TestRecipient__factory(signer).deploy();
localOutbox = abacus.getContracts(localChain).outbox.outbox; localOutbox = abacus.getContracts(localChain).outbox.contract;
await expect( await expect(
localOutbox.dispatch( localOutbox.dispatch(
remoteDomain, remoteDomain,
@ -31,7 +31,7 @@ describe('TestCoreDeploy', async () => {
message, message,
), ),
).to.emit(localOutbox, 'Dispatch'); ).to.emit(localOutbox, 'Dispatch');
remoteOutbox = abacus.getContracts(remoteChain).outbox.outbox; remoteOutbox = abacus.getContracts(remoteChain).outbox.contract;
await expect( await expect(
remoteOutbox.dispatch( remoteOutbox.dispatch(
localDomain, localDomain,

@ -21,12 +21,13 @@ const chainSummary = async <Chain extends ChainName>(
chain: Chain, chain: Chain,
) => { ) => {
const coreContracts = core.getContracts(chain); const coreContracts = core.getContracts(chain);
const outbox = coreContracts.outbox.outbox; const outbox = coreContracts.outbox.contract;
const count = (await outbox.tree()).toNumber(); const count = (await outbox.tree()).toNumber();
const inboxSummary = async (remote: Chain) => { const inboxSummary = async (remote: Chain) => {
const remoteContracts = core.getContracts(remote); const remoteContracts = core.getContracts(remote);
const inbox = remoteContracts.inboxes[chain as Exclude<Chain, Chain>].inbox; const inbox =
remoteContracts.inboxes[chain as Exclude<Chain, Chain>].inbox.contract;
const [inboxCheckpointRoot, inboxCheckpointIndex] = const [inboxCheckpointRoot, inboxCheckpointIndex] =
await inbox.latestCachedCheckpoint(); await inbox.latestCachedCheckpoint();
const processFilter = inbox.filters.Process(); const processFilter = inbox.filters.Process();
@ -53,14 +54,13 @@ const chainSummary = async <Chain extends ChainName>(
task('kathy', 'Dispatches random abacus messages').setAction( task('kathy', 'Dispatches random abacus messages').setAction(
async (_, hre: HardhatRuntimeEnvironment) => { async (_, hre: HardhatRuntimeEnvironment) => {
const environment = 'test'; const config = getCoreEnvironmentConfig('test');
const config = getCoreEnvironmentConfig(environment);
const [signer] = await hre.ethers.getSigners(); const [signer] = await hre.ethers.getSigners();
const multiProvider = deployUtils.getMultiProviderFromConfigAndSigner( const multiProvider = deployUtils.getMultiProviderFromConfigAndSigner(
config.transactionConfigs, config.transactionConfigs,
signer, signer,
); );
const core = AbacusCore.fromEnvironment(environment, multiProvider); const core = AbacusCore.fromEnvironment('test', multiProvider);
const randomElement = <T>(list: T[]) => const randomElement = <T>(list: T[]) =>
list[Math.floor(Math.random() * list.length)]; list[Math.floor(Math.random() * list.length)];
@ -76,7 +76,7 @@ task('kathy', 'Dispatches random abacus messages').setAction(
const remote: ChainName = randomElement(core.remoteChains(local)); const remote: ChainName = randomElement(core.remoteChains(local));
const remoteId = ChainNameToDomainId[remote]; const remoteId = ChainNameToDomainId[remote];
const coreContracts = core.getContracts(local); const coreContracts = core.getContracts(local);
const outbox = coreContracts.outbox.outbox; const outbox = coreContracts.outbox.contract;
// Send a batch of messages to the destination chain to test // Send a batch of messages to the destination chain to test
// the relayer submitting only greedily // the relayer submitting only greedily
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {

@ -9,7 +9,8 @@ async function check() {
const config = getCoreEnvironmentConfig(environment); const config = getCoreEnvironmentConfig(environment);
const multiProvider = await config.getMultiProvider(); const multiProvider = await config.getMultiProvider();
const core = AbacusCore.fromEnvironment(environment, multiProvider); // environments union doesn't work well with typescript
const core = AbacusCore.fromEnvironment(environment, multiProvider as any);
const coreChecker = new AbacusCoreChecker<any>( const coreChecker = new AbacusCoreChecker<any>(
multiProvider, multiProvider,
core, core,

@ -1,4 +1,5 @@
import { AbacusCoreInfraDeployer } from '../src/core/deploy'; import { AbacusCoreInfraDeployer } from '../src/core/deploy';
import { writeJSON } from '../src/utils/utils';
import { import {
getCoreContractsSdkFilepath, getCoreContractsSdkFilepath,
@ -14,14 +15,22 @@ async function main() {
const multiProvider = await config.getMultiProvider(); const multiProvider = await config.getMultiProvider();
const deployer = new AbacusCoreInfraDeployer(multiProvider, config.core); const deployer = new AbacusCoreInfraDeployer(multiProvider, config.core);
const addresses = await deployer.deploy(); const contracts = await deployer.deploy();
deployer.writeContracts(addresses, getCoreContractsSdkFilepath(environment)); writeJSON(
deployer.writeVerification(getCoreVerificationDirectory(environment)); getCoreContractsSdkFilepath(environment),
'addresses.json',
contracts,
);
writeJSON(
getCoreVerificationDirectory(environment),
'verification.json',
deployer.verificationInputs,
);
deployer.writeRustConfigs( deployer.writeRustConfigs(
environment, environment,
getCoreRustDirectory(environment), getCoreRustDirectory(environment),
addresses, contracts,
); );
} }

@ -59,7 +59,7 @@ export async function getMultiProviderFromGCP<Chain extends ChainName>(
} }
function getContractsSdkFilepath(mod: string, environment: DeployEnvironment) { function getContractsSdkFilepath(mod: string, environment: DeployEnvironment) {
return path.join('../sdk/src/', mod, 'environments', `${environment}.ts`); return path.join('../sdk/src/', mod, 'environments', environment);
} }
export function getCoreContractsSdkFilepath(environment: DeployEnvironment) { export function getCoreContractsSdkFilepath(environment: DeployEnvironment) {

@ -8,8 +8,8 @@ import {
} from '@abacus-network/deploy'; } from '@abacus-network/deploy';
import { import {
AbacusCore, AbacusCore,
BeaconProxyAddresses,
ChainName, ChainName,
MailboxAddresses,
chainMetadata, chainMetadata,
objMap, objMap,
promiseObjAll, promiseObjAll,
@ -52,6 +52,7 @@ export class AbacusCoreChecker<
await this.checkValidatorManagers(chain); await this.checkValidatorManagers(chain);
} }
// CoreConfig does not have `owner`
// async checkDomainOwnership(chain: Chain): Promise<void> { // async checkDomainOwnership(chain: Chain): Promise<void> {
// const config = this.configMap[chain]; // const config = this.configMap[chain];
// const contracts = this.app.getContracts(chain); // const contracts = this.app.getContracts(chain);
@ -59,7 +60,7 @@ export class AbacusCoreChecker<
// contracts.abacusConnectionManager, // contracts.abacusConnectionManager,
// contracts.upgradeBeaconController, // contracts.upgradeBeaconController,
// contracts.outbox.outbox, // contracts.outbox.outbox,
// contracts.outbox.validatorManager, // contracts.outbox.outboxValidatorManager,
// ...Object.values(contracts.inboxes) // ...Object.values(contracts.inboxes)
// .map((inbox: any) => [inbox.inbox, inbox.validatorManager]) // .map((inbox: any) => [inbox.inbox, inbox.validatorManager])
// .flat(), // .flat(),
@ -69,8 +70,8 @@ export class AbacusCoreChecker<
async checkOutbox(chain: Chain): Promise<void> { async checkOutbox(chain: Chain): Promise<void> {
const contracts = this.app.getContracts(chain); const contracts = this.app.getContracts(chain);
const actualManager = await contracts.outbox.outbox.validatorManager(); const actualManager = await contracts.outbox.contract.validatorManager();
const expectedManager = contracts.outbox.validatorManager.address; const expectedManager = contracts.outboxValidatorManager.address;
if (actualManager !== expectedManager) { if (actualManager !== expectedManager) {
const violation: ValidatorManagerViolation = { const violation: ValidatorManagerViolation = {
chain, chain,
@ -89,11 +90,11 @@ export class AbacusCoreChecker<
await this.checkValidatorManager( await this.checkValidatorManager(
chain, chain,
chain, chain,
coreContracts.outbox.validatorManager, coreContracts.outboxValidatorManager,
); );
return promiseObjAll( return promiseObjAll(
objMap(coreContracts.inboxes, (remote, inbox) => objMap(coreContracts.inboxes, (remote, inbox) =>
this.checkValidatorManager(chain, remote, inbox.validatorManager), this.checkValidatorManager(chain, remote, inbox.inboxValidatorManager),
), ),
); );
} }
@ -175,8 +176,8 @@ export class AbacusCoreChecker<
// manager. // manager.
await promiseObjAll( await promiseObjAll(
objMap(coreContracts.inboxes, async (_, inbox) => { objMap(coreContracts.inboxes, async (_, inbox) => {
const expected = inbox.validatorManager.address; const expected = inbox.inboxValidatorManager.address;
const actual = await inbox.inbox.validatorManager(); const actual = await inbox.inbox.contract.validatorManager();
expect(actual).to.equal(expected); expect(actual).to.equal(expected);
}), }),
); );
@ -184,7 +185,9 @@ export class AbacusCoreChecker<
// Check that all inboxes on this chain share the same implementation and // Check that all inboxes on this chain share the same implementation and
// UpgradeBeacon. // UpgradeBeacon.
const coreAddresses = this.app.getAddresses(chain); const coreAddresses = this.app.getAddresses(chain);
const inboxes: MailboxAddresses[] = Object.values(coreAddresses.inboxes); const inboxes: BeaconProxyAddresses[] = Object.values(
coreAddresses.inboxes,
);
const implementations = inboxes.map((r) => r.implementation); const implementations = inboxes.map((r) => r.implementation);
const identical = (a: any, b: any) => (a === b ? a : false); const identical = (a: any, b: any) => (a === b ? a : false);
const upgradeBeacons = inboxes.map((r) => r.beacon); const upgradeBeacons = inboxes.map((r) => r.beacon);
@ -206,16 +209,15 @@ export class AbacusCoreChecker<
// Outbox is set on abacusConnectionManager // Outbox is set on abacusConnectionManager
const outbox = await coreContracts.abacusConnectionManager.outbox(); const outbox = await coreContracts.abacusConnectionManager.outbox();
expect(outbox).to.equal(coreContracts.outbox.outbox.address); expect(outbox).to.equal(coreContracts.outbox.address);
} }
async checkProxiedContracts(chain: Chain): Promise<void> { async checkProxiedContracts(chain: Chain): Promise<void> {
// Outbox upgrade setup contracts are defined const contracts = this.app.getContracts(chain);
const addresses = this.app.getAddresses(chain); await this.checkUpgradeBeacon(chain, 'Outbox', contracts.outbox.addresses);
await this.checkUpgradeBeacon(chain, 'Outbox', addresses.outbox);
await promiseObjAll( await promiseObjAll(
objMap(addresses.inboxes, (chain, inbox) => objMap(contracts.inboxes, (chain, inbox) =>
this.checkUpgradeBeacon(chain, 'Inbox', inbox), this.checkUpgradeBeacon(chain, 'Inbox', inbox.inbox.addresses),
), ),
); );
} }

@ -1,9 +1,8 @@
import path from 'path'; import { AbacusCoreDeployer } from '@abacus-network/deploy';
import { AbacusAppDeployer, AbacusCoreDeployer } from '@abacus-network/deploy';
import { ChainName, chainMetadata, objMap } from '@abacus-network/sdk'; import { ChainName, chainMetadata, objMap } from '@abacus-network/sdk';
import { DeployEnvironment, RustConfig } from '../config'; import { DeployEnvironment, RustConfig } from '../config';
import { writeJSON } from '../utils/utils';
export class AbacusCoreInfraDeployer< export class AbacusCoreInfraDeployer<
Chain extends ChainName, Chain extends ChainName,
@ -11,15 +10,14 @@ export class AbacusCoreInfraDeployer<
writeRustConfigs( writeRustConfigs(
environment: DeployEnvironment, environment: DeployEnvironment,
directory: string, directory: string,
contractAddresses: Awaited<ReturnType<AbacusCoreDeployer<Chain>['deploy']>>, contractsMap: Awaited<ReturnType<AbacusCoreDeployer<Chain>['deploy']>>,
) { ) {
objMap(this.configMap, (chain) => { objMap(this.configMap, (chain) => {
const filepath = path.join(directory, `${chain}_config.json`); const contracts = contractsMap[chain];
const addresses = contractAddresses[chain];
const outbox = { const outbox = {
addresses: { addresses: {
outbox: addresses.outbox.proxy, outbox: contracts.outbox.address,
}, },
domain: chainMetadata[chain].id.toString(), domain: chainMetadata[chain].id.toString(),
name: chain, name: chain,
@ -51,9 +49,9 @@ export class AbacusCoreInfraDeployer<
this.multiProvider.remoteChains(chain).forEach((remote) => { this.multiProvider.remoteChains(chain).forEach((remote) => {
// The agent configuration file should contain the `chain`'s inbox on // The agent configuration file should contain the `chain`'s inbox on
// all the remote chains // all the remote chains
const remoteAddresses = contractAddresses[remote]; const remoteContracts = contractsMap[remote];
const inboxAddresses = const inboxContracts =
remoteAddresses.inboxes[chain as Exclude<Chain, Chain>]; remoteContracts.inboxes[chain as Exclude<Chain, Chain>];
const inbox = { const inbox = {
domain: chainMetadata[remote].id.toString(), domain: chainMetadata[remote].id.toString(),
@ -64,14 +62,14 @@ export class AbacusCoreInfraDeployer<
url: '', url: '',
}, },
addresses: { addresses: {
inbox: inboxAddresses.proxy, inbox: inboxContracts.inbox.address,
validatorManager: inboxAddresses.validatorManager, validatorManager: inboxContracts.inboxValidatorManager.address,
}, },
}; };
rustConfig.inboxes[remote] = inbox; rustConfig.inboxes[remote] = inbox;
}); });
AbacusAppDeployer.writeJson(filepath, rustConfig); writeJSON(directory, `${chain}_config.json`, rustConfig);
}); });
} }
} }

@ -152,6 +152,9 @@ export function warn(text: string, padded = false) {
} }
export function writeJSON(directory: string, filename: string, obj: any) { export function writeJSON(directory: string, filename: string, obj: any) {
if (!fs.existsSync(directory)) {
fs.mkdirSync(directory, { recursive: true });
}
fs.writeFileSync( fs.writeFileSync(
path.join(directory, filename), path.join(directory, filename),
JSON.stringify(obj, null, 2), JSON.stringify(obj, null, 2),

@ -7,15 +7,17 @@ import { getMultiProviderFromConfigAndSigner } from '@abacus-network/deploy/dist
import { import {
AbacusCore, AbacusCore,
ChainMap, ChainMap,
CoreContractAddresses, CoreContractsMap,
MultiProvider, MultiProvider,
objMap, objMap,
serializeContracts,
} from '@abacus-network/sdk'; } from '@abacus-network/sdk';
import { environment as testConfig } from '../config/environments/test'; import { environment as testConfig } from '../config/environments/test';
import { TestChains } from '../config/environments/test/chains'; import { TestChains } from '../config/environments/test/chains';
import { AbacusCoreChecker } from '../src/core'; import { AbacusCoreChecker } from '../src/core';
import { AbacusCoreInfraDeployer } from '../src/core/deploy'; import { AbacusCoreInfraDeployer } from '../src/core/deploy';
import { writeJSON } from '../src/utils/utils';
describe('core', async () => { describe('core', async () => {
const environment = 'test'; const environment = 'test';
@ -23,7 +25,7 @@ describe('core', async () => {
let multiProvider: MultiProvider<TestChains>; let multiProvider: MultiProvider<TestChains>;
let deployer: AbacusCoreInfraDeployer<TestChains>; let deployer: AbacusCoreInfraDeployer<TestChains>;
let core: AbacusCore<TestChains>; let core: AbacusCore<TestChains>;
let addresses: ChainMap<TestChains, CoreContractAddresses<TestChains, any>>; let contracts: CoreContractsMap<TestChains>;
let coreConfig: ChainMap<TestChains, CoreConfig>; let coreConfig: ChainMap<TestChains, CoreConfig>;
let owners: ChainMap<TestChains, string>; let owners: ChainMap<TestChains, string>;
@ -40,18 +42,18 @@ describe('core', async () => {
}); });
it('deploys', async () => { it('deploys', async () => {
addresses = await deployer.deploy(); // TODO: return AbacusApp from AbacusDeployer.deploy() contracts = await deployer.deploy();
}); });
it('writes', async () => { it('writes', async () => {
const base = './test/outputs/core'; const base = './test/outputs/core';
deployer.writeVerification(path.join(base, 'verification')); writeJSON(base, 'contracts.json', serializeContracts(contracts));
deployer.writeContracts(addresses, path.join(base, 'contracts.ts')); writeJSON(base, 'verification.json', deployer.verificationInputs);
deployer.writeRustConfigs(environment, path.join(base, 'rust'), addresses); deployer.writeRustConfigs(environment, path.join(base, 'rust'), contracts);
}); });
it('transfers ownership', async () => { it('transfers ownership', async () => {
core = new AbacusCore(addresses, multiProvider); core = new AbacusCore(contracts, multiProvider);
await AbacusCoreDeployer.transferOwnership(core, owners, multiProvider); await AbacusCoreDeployer.transferOwnership(core, owners, multiProvider);
}); });

@ -1,44 +1,39 @@
import { ContractsBuilder, IAbacusContracts } from './contracts'; import {
AbacusAddresses,
AbacusContracts,
connectContracts,
serializeContracts,
} from './contracts';
import { MultiProvider } from './provider'; import { MultiProvider } from './provider';
import { ChainMap, ChainName, Connection } from './types'; import { ChainMap, ChainName, Connection } from './types';
import { MultiGeneric, objMap } from './utils'; import { MultiGeneric, objMap } from './utils';
export class AbacusApp< export class AbacusApp<
Contracts extends IAbacusContracts<any, any>, Contracts extends AbacusContracts,
Chain extends ChainName = ChainName, Chain extends ChainName = ChainName,
> extends MultiGeneric<Chain, Contracts> { > extends MultiGeneric<Chain, Contracts> {
constructor( constructor(
builder: ContractsBuilder<any, Contracts>, public contractsMap: ChainMap<Chain, Contracts>,
contractAddresses: ChainMap<Chain, any>, multiProvider: MultiProvider<Chain>,
readonly multiProvider: MultiProvider<Chain>,
) { ) {
super( const connectedContractsMap = objMap(contractsMap, (chain, contracts) =>
objMap( connectContracts(
contractAddresses, contracts,
(chain, addresses) => multiProvider.getChainConnection(chain).getConnection(),
new builder(
addresses,
multiProvider.getChainConnection(chain).getConnection()!,
),
), ),
); );
super(connectedContractsMap);
} }
public contractsMap = this.chainMap; getContracts(chain: Chain): Contracts {
return this.get(chain);
getContracts(
chain: Chain,
): Contracts extends IAbacusContracts<any, infer C> ? C : never {
return this.get(chain).contracts;
} }
getAddresses( getAddresses(chain: Chain): AbacusAddresses {
chain: Chain, return serializeContracts(this.get(chain));
): Contracts extends IAbacusContracts<infer A, any> ? A : never {
return this.get(chain).addresses;
} }
reconnect(chain: Chain, connection: Connection): void { connectToChain(chain: Chain, connection: Connection): void {
this.get(chain).reconnect(connection); this.set(chain, connectContracts(this.get(chain), connection));
} }
} }

@ -1,79 +1,84 @@
import { Contract } from 'ethers'; import { BaseContract, ethers } from 'ethers';
import { Router__factory } from '@abacus-network/app';
import { AbacusConnectionManager__factory } from '@abacus-network/core';
import { types } from '@abacus-network/utils'; import { types } from '@abacus-network/utils';
import { Connection, ProxiedAddress } from './types'; import { ProxiedContract, ProxyAddresses, isProxyAddresses } from './proxy';
import { Connection } from './types';
import { objMap } from './utils';
// address types generated from AbacusDeployer deployContract or deployProxiedContract export type AbacusFactories = {
export type AbacusContractAddresses = { [key: string]: ethers.ContractFactory;
[key in string]: ProxiedAddress | types.Address;
}; };
// from concrete ethers.ContractFactory static connect() type export type AbacusContracts = {
type EthersFactory<C> = ( [key: Exclude<string, 'address'>]:
address: types.Address, // TODO: generic on ProxiedAddress for proxy utilities | ethers.Contract
connection: Connection, | ProxiedContract<any, any>
) => C; | AbacusContracts;
export type Factories<A extends AbacusContractAddresses> = Record< };
keyof A,
EthersFactory<any>
>;
export interface IAbacusContracts<Addresses, Contracts> { export type AbacusAddresses = {
readonly addresses: Addresses; [key: string]: types.Address | ProxyAddresses<any> | AbacusAddresses;
readonly contracts: Contracts; };
reconnect(connection: Connection): void;
}
export interface ContractsBuilder< export function serializeContracts(
Addresses, contractOrObject: AbacusContracts,
Contracts extends IAbacusContracts<Addresses, any>, ): AbacusAddresses {
> { return objMap(
new (addresses: Addresses, connection: Connection): Contracts; contractOrObject,
(_, contract): string | ProxyAddresses<any> | AbacusAddresses => {
if (contract instanceof BaseContract) {
return contract.address;
} else if (contract instanceof ProxiedContract) {
return contract.addresses;
} else {
return serializeContracts(contract);
} }
export abstract class AbacusContracts<
A extends AbacusContractAddresses,
F extends Factories<A> = Factories<A>,
CM = {
[key in keyof A]: F[key] extends EthersFactory<infer C> ? C : never;
}, },
> implements IAbacusContracts<A, CM>
{
abstract factories(): F;
// complexity here allows for subclasses to have strong typing on `this.contracts` inferred
// from the return types of the factory functions provided to the constructor
readonly contracts: CM;
constructor(readonly addresses: A, connection: Connection) {
const factories = this.factories();
const contractEntries = Object.entries(addresses).map(([key, addr]) => {
const contractAddress = typeof addr === 'string' ? addr : addr.proxy;
return [key, factories[key](contractAddress, connection)];
});
this.contracts = Object.fromEntries(contractEntries);
}
reconnect(connection: Connection): void {
Object.values(this.contracts).forEach((contract: Contract) =>
contract.connect(connection),
); );
} }
protected onlySigner(actual: types.Address, expected: types.Address): void { function getFactory(
if (actual !== expected) { key: string,
throw new Error(`Signer ${actual} must be ${expected} for this method`); factories: AbacusFactories,
} ): ethers.ContractFactory {
if (!(key in factories)) {
throw new Error(`Factories entry missing for ${key}`);
} }
return factories[key];
} }
export type RouterAddresses = { export function buildContracts(
abacusConnectionManager: types.Address; addressOrObject: AbacusAddresses,
router: types.Address; factories: AbacusFactories,
}; ): AbacusContracts {
return objMap(
addressOrObject,
(key, address): ProxiedContract<any, any> | AbacusContracts => {
if (typeof address === 'string') {
return getFactory(key, factories).attach(address);
} else if (isProxyAddresses(address)) {
const contract = getFactory(key, factories).attach(address.proxy);
return new ProxiedContract(contract, address);
} else {
return buildContracts(address as AbacusAddresses, factories);
}
},
);
}
export const routerFactories: Factories<RouterAddresses> = { export function connectContracts<Contracts extends AbacusContracts>(
router: Router__factory.connect, contractOrObject: Contracts,
abacusConnectionManager: AbacusConnectionManager__factory.connect, connection: Connection,
}; ): Contracts {
return objMap(contractOrObject, (_, contract) => {
if (
contract instanceof BaseContract ||
contract instanceof ProxiedContract
) {
return contract.connect(connection);
} else {
return connectContracts(contract, connection);
}
}) as Contracts;
}

@ -1,74 +1,57 @@
import { Inbox, Outbox } from '@abacus-network/core'; import { Inbox, Outbox } from '@abacus-network/core';
import { AbacusApp } from '../app'; import { AbacusApp } from '../app';
import { buildContracts } from '../contracts';
import { MultiProvider } from '../provider'; import { MultiProvider } from '../provider';
import { ChainMap, ChainName, Remotes } from '../types'; import { ChainName, Remotes } from '../types';
import { objMap } from '../utils';
import { import { CoreContracts, coreFactories } from './contracts';
CoreContractAddresses,
CoreContractSchema,
CoreContracts,
} from './contracts';
import { environments } from './environments'; import { environments } from './environments';
export const CoreEnvironments = Object.keys(environments);
export type CoreEnvironment = keyof typeof environments; export type CoreEnvironment = keyof typeof environments;
export type CoreEnvironmentChain<E extends CoreEnvironment> = Extract< export type CoreEnvironmentChain<E extends CoreEnvironment> = Extract<
keyof typeof environments[E], keyof typeof environments[E],
ChainName ChainName
>; >;
export type CoreContractsMap<Chain extends ChainName> = {
[local in Chain]: CoreContracts<Chain, local>;
};
export class AbacusCore<Chain extends ChainName = ChainName> extends AbacusApp< export class AbacusCore<Chain extends ChainName = ChainName> extends AbacusApp<
CoreContracts<Chain>, CoreContracts<Chain, Chain>,
Chain Chain
> { > {
constructor( constructor(
addresses: { contractsMap: CoreContractsMap<Chain>,
[local in Chain]: CoreContractAddresses<Chain, local>;
},
multiProvider: MultiProvider<Chain>, multiProvider: MultiProvider<Chain>,
) { ) {
super(CoreContracts, addresses, multiProvider); super(contractsMap, multiProvider);
}
static fromEnvironment<E extends CoreEnvironment>(
name: E,
multiProvider: MultiProvider<any>, // TODO: fix networks
): AbacusCore<any> {
return new AbacusCore(environments[name], multiProvider);
} }
extendWithConnectionManagers<T>( static fromEnvironment<Env extends CoreEnvironment>(
config: ChainMap<Chain, T>, env: Env,
): ChainMap<Chain, T & { abacusConnectionManager: string }> { multiProvider: MultiProvider<CoreEnvironmentChain<Env>>,
return objMap(config, (chain, config) => ({ ): AbacusCore<CoreEnvironmentChain<Env>> {
...config, const contractsMap = buildContracts(
abacusConnectionManager: environments[env],
this.getContracts(chain).abacusConnectionManager.address, coreFactories,
})); ) as CoreContractsMap<CoreEnvironmentChain<Env>>;
} return new AbacusCore(contractsMap, multiProvider);
// override type to be derived from chain key
getContracts<Local extends Chain>(
chain: Local,
): CoreContractSchema<Chain, Local> {
return super.getContracts(chain) as any;
} }
// override type to be derived from chain key // override type to be derived from chain key
getAddresses<Local extends Chain>( getContracts<Local extends Chain>(chain: Local): CoreContracts<Chain, Local> {
chain: Local, return super.getContracts(chain) as CoreContracts<Chain, Local>;
): CoreContractAddresses<Chain, Local> {
return super.getAddresses(chain) as any;
} }
getMailboxPair<Local extends Chain>( getMailboxPair<Local extends Chain>(
origin: Remotes<Chain, Local>, origin: Remotes<Chain, Local>,
destination: Local, destination: Local,
): { outbox: Outbox; inbox: Inbox } { ): { originOutbox: Outbox; destinationInbox: Inbox } {
const outbox = this.getContracts(origin).outbox.outbox; const originOutbox = this.getContracts(origin).outbox.contract;
const inbox = this.getContracts(destination).inboxes[origin].inbox; const destinationInbox =
return { outbox, inbox }; this.getContracts(destination).inboxes[origin].inbox.contract;
return { originOutbox, destinationInbox };
} }
} }

@ -14,123 +14,44 @@ import {
UpgradeBeaconController, UpgradeBeaconController,
UpgradeBeaconController__factory, UpgradeBeaconController__factory,
} from '@abacus-network/core'; } from '@abacus-network/core';
import { types } from '@abacus-network/utils';
import { IAbacusContracts } from '../contracts'; import { BeaconProxyAddresses, ProxiedContract } from '../proxy';
import { import { ChainName, RemoteChainMap } from '../types';
ChainName,
Connection,
ProxiedAddress,
RemoteChainMap,
Remotes,
} from '../types';
import { objMap } from '../utils';
type InboxAddress = ProxiedAddress; export type InboxContracts = {
type OutboxAddress = ProxiedAddress; inbox: ProxiedContract<Inbox, BeaconProxyAddresses>;
export type MailboxAddresses = (InboxAddress | OutboxAddress) & { inboxValidatorManager: InboxValidatorManager;
validatorManager: types.Address;
}; };
export type CoreContractAddresses<N extends ChainName, L extends N> = { const inboxFactories = {
upgradeBeaconController: types.Address; inbox: new Inbox__factory(),
abacusConnectionManager: types.Address; inboxValidatorManager: new InboxValidatorManager__factory(),
interchainGasPaymaster: types.Address;
outbox: MailboxAddresses;
inboxes: RemoteChainMap<N, L, MailboxAddresses>;
}; };
export type InboxContracts = { export type OutboxContracts = {
inbox: Inbox; outbox: ProxiedContract<Outbox, BeaconProxyAddresses>;
validatorManager: InboxValidatorManager; outboxValidatorManager: OutboxValidatorManager;
};
const outboxFactories = {
outbox: new Outbox__factory(),
outboxValidatorManager: new OutboxValidatorManager__factory(),
}; };
export type CoreContractSchema< export type CoreContracts<
Networks extends ChainName, Networks extends ChainName,
Local extends Networks, Local extends Networks,
> = { > = {
abacusConnectionManager: AbacusConnectionManager; abacusConnectionManager: AbacusConnectionManager;
upgradeBeaconController: UpgradeBeaconController; upgradeBeaconController: UpgradeBeaconController;
outbox: {
outbox: Outbox;
validatorManager: OutboxValidatorManager;
};
inboxes: RemoteChainMap<Networks, Local, InboxContracts>;
interchainGasPaymaster: InterchainGasPaymaster; interchainGasPaymaster: InterchainGasPaymaster;
}; inboxes: RemoteChainMap<Networks, Local, InboxContracts>;
} & OutboxContracts;
export const coreFactories = { export const coreFactories = {
interchainGasPaymaster: InterchainGasPaymaster__factory.connect, interchainGasPaymaster: new InterchainGasPaymaster__factory(),
outbox: Outbox__factory.connect, abacusConnectionManager: new AbacusConnectionManager__factory(),
outboxValidatorManager: OutboxValidatorManager__factory.connect, upgradeBeaconController: new UpgradeBeaconController__factory(),
inbox: Inbox__factory.connect, ...inboxFactories,
inboxValidatorManager: InboxValidatorManager__factory.connect, ...outboxFactories,
abacusConnectionManager: AbacusConnectionManager__factory.connect,
upgradeBeaconController: UpgradeBeaconController__factory.connect,
}; };
// TODO: extend AbacusContracts for more generic behavior
export class CoreContracts<N extends ChainName = ChainName, L extends N = N>
implements
IAbacusContracts<CoreContractAddresses<N, L>, CoreContractSchema<N, L>>
{
readonly contracts: CoreContractSchema<N, L>;
constructor(
readonly addresses: CoreContractAddresses<N, L>,
connection: Connection,
) {
const factories = coreFactories;
this.contracts = {
outbox: {
outbox: factories.outbox(addresses.outbox.proxy, connection),
validatorManager: factories.outboxValidatorManager(
addresses.outbox.validatorManager,
connection,
),
},
inboxes: objMap(addresses.inboxes, (_, mailboxAddresses) => ({
inbox: factories.inbox(mailboxAddresses.proxy, connection),
validatorManager: factories.inboxValidatorManager(
mailboxAddresses.validatorManager,
connection,
),
})),
interchainGasPaymaster: factories.interchainGasPaymaster(
addresses.interchainGasPaymaster,
connection,
),
abacusConnectionManager: factories.abacusConnectionManager(
addresses.abacusConnectionManager,
connection,
),
upgradeBeaconController: factories.upgradeBeaconController(
addresses.upgradeBeaconController,
connection,
),
};
}
reconnect(connection: Connection): void {
this.contracts.outbox.outbox.connect(connection);
this.contracts.outbox.validatorManager.connect(connection);
this.contracts.interchainGasPaymaster.connect(connection);
this.contracts.abacusConnectionManager.connect(connection);
this.contracts.upgradeBeaconController.connect(connection);
objMap(this.contracts.inboxes, (_, inboxContracts) => {
inboxContracts.inbox.connect(connection);
inboxContracts.validatorManager.connect(connection);
});
}
getOutbox = (): Outbox => this.contracts.outbox.outbox;
getOutboxValidatorManager = (): OutboxValidatorManager =>
this.contracts.outbox.validatorManager;
getInbox = (chain: Remotes<N, L>): Inbox =>
this.contracts.inboxes[chain].inbox;
getInboxValidatorManager = (chain: Remotes<N, L>): InboxValidatorManager =>
this.contracts.inboxes[chain].validatorManager;
}

@ -0,0 +1,52 @@
{
"alfajores": {
"upgradeBeaconController": "0x1f15e8b9C5ABf2D6f7f9033f95Fcd66b90c8aa27",
"abacusConnectionManager": "0xD57Ff4d8d3872322bD628ed8f9C6bB3617A5ef13",
"interchainGasPaymaster": "0x63BDfEF81688ddd5f135D8a8680f942205E030c2",
"inboxes": {
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x0fda1FDfEaDADdAE9C07C2bdA184935E317688C6",
"implementation": "0x9632B89f335F6f48d8ea32fC95ccc2eA36B33570",
"beacon": "0xc8571652Fe648d2873Af278C4982Ecd07dBb0870"
},
"inboxValidatorManager": "0x78BEAd8669B1657BCA3F7aC202D8098f37Eb6c6A"
}
},
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x71f37188d27788ea86E12557edbc9b07E5BDdf03",
"implementation": "0x3219827B9D028Cec62b996147076b4cFCeac282a",
"beacon": "0xe0B98662f15B12E4aCfd950cBe53FAad4b0C0b98"
},
"outboxValidatorManager": "0xCfC4862Df4544923265873f2d288AcEd9919d679"
}
},
"kovan": {
"upgradeBeaconController": "0x74A77C554685651F7dB3784359E1436604794438",
"abacusConnectionManager": "0x3c3b0367A960a6ea1cDe58Bb8A7E33bfC38554D3",
"interchainGasPaymaster": "0x33bE4eAa1A7c04E6Bba63e4F9cfff1eb98CF59F0",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x24D05ae06F3Ce4CF146958714c2B2FBE8B6a29c4",
"implementation": "0xbA2C920a863122a42c249d89D5954506F00513C3",
"beacon": "0xE8bF352efbC50754442095a04e81A5141fe75e16"
},
"outboxValidatorManager": "0x3f0e80FfACE85DC573F57b2f552f6F98Fc5984c4"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x125379056774C4246d016b2C58c6fbb80ab8829b",
"implementation": "0x6D91F26Fb1430bC0F557cC8BD7F815b441541c68",
"beacon": "0xdCCA08dC4ec34d58f69415b0C7C8e0042779c559"
},
"validatorManager": "0x63C950170534907d40B77ecF61bd07980B51f2a4"
}
}
}
}

@ -1,40 +0,0 @@
export const addresses = {
alfajores: {
upgradeBeaconController: '0x1f15e8b9C5ABf2D6f7f9033f95Fcd66b90c8aa27',
abacusConnectionManager: '0xD57Ff4d8d3872322bD628ed8f9C6bB3617A5ef13',
interchainGasPaymaster: '0x63BDfEF81688ddd5f135D8a8680f942205E030c2',
inboxes: {
kovan: {
proxy: '0x0fda1FDfEaDADdAE9C07C2bdA184935E317688C6',
implementation: '0x9632B89f335F6f48d8ea32fC95ccc2eA36B33570',
beacon: '0xc8571652Fe648d2873Af278C4982Ecd07dBb0870',
validatorManager: '0x78BEAd8669B1657BCA3F7aC202D8098f37Eb6c6A',
},
},
outbox: {
validatorManager: '0xCfC4862Df4544923265873f2d288AcEd9919d679',
proxy: '0x71f37188d27788ea86E12557edbc9b07E5BDdf03',
implementation: '0x3219827B9D028Cec62b996147076b4cFCeac282a',
beacon: '0xe0B98662f15B12E4aCfd950cBe53FAad4b0C0b98',
},
},
kovan: {
upgradeBeaconController: '0x74A77C554685651F7dB3784359E1436604794438',
abacusConnectionManager: '0x3c3b0367A960a6ea1cDe58Bb8A7E33bfC38554D3',
interchainGasPaymaster: '0x33bE4eAa1A7c04E6Bba63e4F9cfff1eb98CF59F0',
outbox: {
validatorManager: '0x3f0e80FfACE85DC573F57b2f552f6F98Fc5984c4',
proxy: '0x24D05ae06F3Ce4CF146958714c2B2FBE8B6a29c4',
implementation: '0xbA2C920a863122a42c249d89D5954506F00513C3',
beacon: '0xE8bF352efbC50754442095a04e81A5141fe75e16',
},
inboxes: {
alfajores: {
validatorManager: '0x63C950170534907d40B77ecF61bd07980B51f2a4',
proxy: '0x125379056774C4246d016b2C58c6fbb80ab8829b',
implementation: '0x6D91F26Fb1430bC0F557cC8BD7F815b441541c68',
beacon: '0xdCCA08dC4ec34d58f69415b0C7C8e0042779c559',
},
},
},
};

@ -1,6 +1,6 @@
import { addresses as dev } from './dev'; import dev from './dev.json';
import { addresses as test } from './test'; import test from './test.json';
import { addresses as testnet } from './testnet'; import testnet from './testnet.json';
export const environments = { export const environments = {
test, test,

@ -0,0 +1,104 @@
{
"test1": {
"upgradeBeaconController": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
"abacusConnectionManager": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
"interchainGasPaymaster": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
"implementation": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
"beacon": "0x0165878A594ca255338adfa4d48449f69242Eb8F"
},
"outboxValidatorManager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9"
},
"inboxes": {
"test2": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
"implementation": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
"beacon": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
},
"inboxValidatorManager": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"
},
"test3": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
"implementation": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
"beacon": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
},
"inboxValidatorManager": "0x9A676e781A523b5d0C0e43731313A708CB607508"
}
}
},
"test2": {
"upgradeBeaconController": "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
"abacusConnectionManager": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
"interchainGasPaymaster": "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
"implementation": "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
"beacon": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44"
},
"outboxValidatorManager": "0x59b670e9fA9D0A427751Af201D676719a970857b"
},
"inboxes": {
"test1": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
"implementation": "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
"beacon": "0xc5a5C42992dECbae36851359345FE25997F5C42d"
},
"inboxValidatorManager": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F"
},
"test3": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
"implementation": "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
"beacon": "0xc5a5C42992dECbae36851359345FE25997F5C42d"
},
"inboxValidatorManager": "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690"
}
}
},
"test3": {
"upgradeBeaconController": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",
"abacusConnectionManager": "0x851356ae760d987E095750cCeb3bC6014560891C",
"interchainGasPaymaster": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x4826533B4897376654Bb4d4AD88B7faFD0C98528",
"implementation": "0x998abeb3E57409262aE5b751f60747921B33613E",
"beacon": "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49"
},
"outboxValidatorManager": "0x95401dc811bb5740090279Ba06cfA8fcF6113778"
},
"inboxes": {
"test1": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00",
"implementation": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf",
"beacon": "0x9d4454B023096f34B160D6B654540c56A1F81688"
},
"inboxValidatorManager": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF"
},
"test2": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029",
"implementation": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf",
"beacon": "0x9d4454B023096f34B160D6B654540c56A1F81688"
},
"inboxValidatorManager": "0x809d550fca64d94Bd9F66E60752A544199cfAC3D"
}
}
}
}

@ -1,77 +0,0 @@
export const addresses = {
test1: {
upgradeBeaconController: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
abacusConnectionManager: '0x0165878A594ca255338adfa4d48449f69242Eb8F',
interchainGasPaymaster: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707',
outbox: {
proxy: '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9',
implementation: '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0',
beacon: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9',
validatorManager: '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512',
},
inboxes: {
test2: {
proxy: '0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0',
implementation: '0x610178dA211FEF7D417bC0e6FeD39F05609AD788',
beacon: '0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e',
validatorManager: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318',
},
test3: {
proxy: '0x9A676e781A523b5d0C0e43731313A708CB607508',
implementation: '0x610178dA211FEF7D417bC0e6FeD39F05609AD788',
beacon: '0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e',
validatorManager: '0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82',
},
},
},
test2: {
upgradeBeaconController: '0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE',
abacusConnectionManager: '0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44',
interchainGasPaymaster: '0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1',
outbox: {
proxy: '0x59b670e9fA9D0A427751Af201D676719a970857b',
implementation: '0x3Aa5ebB10DC797CAC828524e59A333d0A371443c',
beacon: '0xc6e7DF5E7b4f2A278906862b61205850344D4e7d',
validatorManager: '0x68B1D87F95878fE05B998F19b66F4baba5De1aed',
},
inboxes: {
test1: {
proxy: '0x67d269191c92Caf3cD7723F116c85e6E9bf55933',
implementation: '0x09635F643e140090A9A8Dcd712eD6285858ceBef',
beacon: '0xc5a5C42992dECbae36851359345FE25997F5C42d',
validatorManager: '0x7a2088a1bFc9d81c55368AE168C2C02570cB814F',
},
test3: {
proxy: '0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690',
implementation: '0x09635F643e140090A9A8Dcd712eD6285858ceBef',
beacon: '0xc5a5C42992dECbae36851359345FE25997F5C42d',
validatorManager: '0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E',
},
},
},
test3: {
upgradeBeaconController: '0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9',
abacusConnectionManager: '0x70e0bA845a1A0F2DA3359C97E0285013525FFC49',
interchainGasPaymaster: '0x998abeb3E57409262aE5b751f60747921B33613E',
outbox: {
proxy: '0x95401dc811bb5740090279Ba06cfA8fcF6113778',
implementation: '0x851356ae760d987E095750cCeb3bC6014560891C',
beacon: '0xf5059a5D33d5853360D16C683c16e67980206f36',
validatorManager: '0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8',
},
inboxes: {
test1: {
proxy: '0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00',
implementation: '0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf',
beacon: '0x9d4454B023096f34B160D6B654540c56A1F81688',
validatorManager: '0x0E801D84Fa97b50751Dbf25036d067dCf18858bF',
},
test2: {
proxy: '0x809d550fca64d94Bd9F66E60752A544199cfAC3D',
implementation: '0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf',
beacon: '0x9d4454B023096f34B160D6B654540c56A1F81688',
validatorManager: '0x36C02dA8a0983159322a80FFE9F24b1acfF8B570',
},
},
},
};

@ -0,0 +1,493 @@
{
"alfajores": {
"upgradeBeaconController": "0x19Be55D859368e02d7b9C00803Eb677BDC1359Bd",
"abacusConnectionManager": "0x433f7d6d0cB9eb8FF2902Ad01C1BEd6C09934a33",
"interchainGasPaymaster": "0x28B02B97a850872C4D33C3E024fab6499ad96564",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0xD0680F80F4f947968206806C2598Cbc5b6FE5b03",
"implementation": "0x267B6B6eAf6790faE5D5E9070F28a9cE64CbF279",
"beacon": "0xc756cFc1b7d0d4646589EDf10eD54b201237F5e8"
},
"outboxValidatorManager": "0x5821f3B6eE05F3dC62b43B74AB1C8F8E6904b1C8"
},
"inboxes": {
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x783c4a0bB6663359281aD4a637D5af68F83ae213",
"implementation": "0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C",
"beacon": "0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9"
},
"inboxValidatorManager": "0x1b33611fCc073aB0737011d5512EF673Bff74962"
},
"fuji": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xae7a78916Ba4c507aCB2F0e474ace545Ff4bF841",
"implementation": "0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C",
"beacon": "0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9"
},
"inboxValidatorManager": "0x66b71A4e18FbE09a6977A6520B47fEDdffA82a1c"
},
"mumbai": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xFCc63b537e70652A280c4E7883C5BB5a1700e897",
"implementation": "0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C",
"beacon": "0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9"
},
"inboxValidatorManager": "0x04438ef7622f5412f82915F59caD4f704C61eA48"
},
"bsctestnet": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x51A0a100e7BC63Ea7821A3a023B6F17fb94FF011",
"implementation": "0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C",
"beacon": "0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9"
},
"inboxValidatorManager": "0xb94F96D398eA5BAB5CA528EE9Fdc19afaA825818"
},
"arbitrumrinkeby": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xe0B988062A0C6492177d64823Ab95a9c256c2a5F",
"implementation": "0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C",
"beacon": "0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9"
},
"inboxValidatorManager": "0xB057Fb841027a8554521DcCdeC3c3474CaC99AB5"
},
"optimismkovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x628BC518ED1e0E8C6cbcD574EbA0ee29e7F6943E",
"implementation": "0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C",
"beacon": "0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9"
},
"inboxValidatorManager": "0xA2cf52064c921C11adCd83588CbEa08cc3bfF5d8"
}
}
},
"kovan": {
"upgradeBeaconController": "0xcf5BaaF976C80a66Fa7839715C45788f60041A33",
"abacusConnectionManager": "0xF7561c34f17A32D5620583A3397C304e7038a7F6",
"interchainGasPaymaster": "0x07009DA2249c388aD0f416a235AfE90D784e1aAc",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x98AAE089CaD930C64a76dD2247a2aC5773a4B8cE",
"implementation": "0x679Dc08cC3A4acFeea2f7CAFAa37561aE0b41Ce7",
"beacon": "0x4926a10788306D84202A2aDbd290b7743146Cc17"
},
"outboxValidatorManager": "0x58483b754Abb1E8947BE63d6b95DF75b8249543A"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x68311418D79fE8d96599384ED767d225635d88a8",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x5CE550e14B82a9F32A0aaF9eFc4Fce548D8A0B3e"
},
"fuji": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x6b1bb4ce664Bb4164AEB4d3D2E7DE7450DD8084C",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x863E8c26621c52ACa1849C53500606e73BA272F0"
},
"mumbai": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x86fb9F1c124fB20ff130C41a79a432F770f67AFD",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0xAb9B273366D794B7F80B4378bc8Aaca75C6178E2"
},
"bsctestnet": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x5821f3B6eE05F3dC62b43B74AB1C8F8E6904b1C8",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x19Be55D859368e02d7b9C00803Eb677BDC1359Bd"
},
"arbitrumrinkeby": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xD0680F80F4f947968206806C2598Cbc5b6FE5b03",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0xc756cFc1b7d0d4646589EDf10eD54b201237F5e8"
},
"optimismkovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x75f3E2a4f424401195A5E176246Ecc9f7e7680ff",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x433f7d6d0cB9eb8FF2902Ad01C1BEd6C09934a33"
}
}
},
"fuji": {
"upgradeBeaconController": "0xcf5BaaF976C80a66Fa7839715C45788f60041A33",
"abacusConnectionManager": "0xF7561c34f17A32D5620583A3397C304e7038a7F6",
"interchainGasPaymaster": "0x07009DA2249c388aD0f416a235AfE90D784e1aAc",
"inboxValidatorManagers": {},
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x98AAE089CaD930C64a76dD2247a2aC5773a4B8cE",
"implementation": "0x679Dc08cC3A4acFeea2f7CAFAa37561aE0b41Ce7",
"beacon": "0x4926a10788306D84202A2aDbd290b7743146Cc17"
},
"outboxValidatorManager": "0x58483b754Abb1E8947BE63d6b95DF75b8249543A"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x68311418D79fE8d96599384ED767d225635d88a8",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x5CE550e14B82a9F32A0aaF9eFc4Fce548D8A0B3e"
},
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x6b1bb4ce664Bb4164AEB4d3D2E7DE7450DD8084C",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x863E8c26621c52ACa1849C53500606e73BA272F0"
},
"mumbai": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x86fb9F1c124fB20ff130C41a79a432F770f67AFD",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0xAb9B273366D794B7F80B4378bc8Aaca75C6178E2"
},
"bsctestnet": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x5821f3B6eE05F3dC62b43B74AB1C8F8E6904b1C8",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x19Be55D859368e02d7b9C00803Eb677BDC1359Bd"
},
"arbitrumrinkeby": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xD0680F80F4f947968206806C2598Cbc5b6FE5b03",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0xc756cFc1b7d0d4646589EDf10eD54b201237F5e8"
},
"optimismkovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x75f3E2a4f424401195A5E176246Ecc9f7e7680ff",
"implementation": "0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450",
"beacon": "0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9"
},
"inboxValidatorManager": "0x433f7d6d0cB9eb8FF2902Ad01C1BEd6C09934a33"
}
}
},
"mumbai": {
"upgradeBeaconController": "0x6966b0E55883d49BFB24539356a2f8A673E02039",
"abacusConnectionManager": "0x46f7C5D896bbeC89bE1B19e4485e59b4Be49e9Cc",
"interchainGasPaymaster": "0xB08d78F439e55D02C398519eef61606A5926245F",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x33dB966328Ea213b0f76eF96CA368AB37779F065",
"implementation": "0x589C201a07c26b4725A4A829d772f24423da480B",
"beacon": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD"
},
"outboxValidatorManager": "0x54148470292C24345fb828B003461a9444414517"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x1D5EbC3e15e9ECDe0e3530C85899556797eeaea5",
"implementation": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E",
"beacon": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692"
},
"inboxValidatorManager": "0x304cAb315c93B87AAdb2B826A791b2c1Bf749996"
},
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x0526E47C49742C15F8817ef8cf0d8FFc72139D4F",
"implementation": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E",
"beacon": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692"
},
"inboxValidatorManager": "0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc"
},
"fuji": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xef48bd850E5827B96B55C4D28FB32Bbaa73616F2",
"implementation": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E",
"beacon": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692"
},
"inboxValidatorManager": "0x666a24F62f7A97BA33c151776Eb3D9441a059eB8"
},
"bsctestnet": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x3C5154a193D6e2955650f9305c8d80c18C814A68",
"implementation": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E",
"beacon": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692"
},
"inboxValidatorManager": "0x7914A3349107A7295Bbf2374db5A973d73D1b324"
},
"arbitrumrinkeby": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x05Ea36Caee7d92C173334C9D97DcD39ABdCB2b69",
"implementation": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E",
"beacon": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692"
},
"inboxValidatorManager": "0x5d56B8a669F50193b54319442c6EEE5edD662381"
},
"optimismkovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x679Dc08cC3A4acFeea2f7CAFAa37561aE0b41Ce7",
"implementation": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E",
"beacon": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692"
},
"inboxValidatorManager": "0x58483b754Abb1E8947BE63d6b95DF75b8249543A"
}
}
},
"bsctestnet": {
"upgradeBeaconController": "0x6E7b29CB2A7617405B4d30C6f84bBD51b4Bb4be8",
"abacusConnectionManager": "0xC2E36cd6e32e194EE11f15D9273B64461A4D49A2",
"interchainGasPaymaster": "0x44b764045BfDC68517e10e783E69B376cef196B2",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x16B710b86CAd07E6F1C531861a16F5feC29dba37",
"implementation": "0x275aCcCa81cAD931dC6fB6E49ED233Bc99Bed4A7",
"beacon": "0xeb6f11189197223c656807a83B0DD374f9A6dF44"
},
"outboxValidatorManager": "0xfc6e546510dC9d76057F1f76633FCFfC188CB213"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xB08d78F439e55D02C398519eef61606A5926245F",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x589C201a07c26b4725A4A829d772f24423da480B"
},
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xD3d062a5dcBA85ae863618d4c264d2358300c283",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x833Dad7FF66884389D5F0cEcba446ffaa7d2837e"
},
"fuji": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E"
},
"mumbai": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0xF7F0DaB0BECE4498dAc7eb616e288809D4499371"
},
"arbitrumrinkeby": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x666a24F62f7A97BA33c151776Eb3D9441a059eB8",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0xd785272D240B07719e417622cbd2cfA0E584d1bd"
},
"optimismkovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x7914A3349107A7295Bbf2374db5A973d73D1b324",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x598facE78a4302f11E3de0bee1894Da0b2Cb71F8"
}
}
},
"arbitrumrinkeby": {
"upgradeBeaconController": "0x6E7b29CB2A7617405B4d30C6f84bBD51b4Bb4be8",
"abacusConnectionManager": "0xC2E36cd6e32e194EE11f15D9273B64461A4D49A2",
"interchainGasPaymaster": "0x44b764045BfDC68517e10e783E69B376cef196B2",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x16B710b86CAd07E6F1C531861a16F5feC29dba37",
"implementation": "0x275aCcCa81cAD931dC6fB6E49ED233Bc99Bed4A7",
"beacon": "0xeb6f11189197223c656807a83B0DD374f9A6dF44"
},
"outboxValidatorManager": "0xfc6e546510dC9d76057F1f76633FCFfC188CB213"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xB08d78F439e55D02C398519eef61606A5926245F",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x589C201a07c26b4725A4A829d772f24423da480B"
},
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xD3d062a5dcBA85ae863618d4c264d2358300c283",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x833Dad7FF66884389D5F0cEcba446ffaa7d2837e"
},
"fuji": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E"
},
"mumbai": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0xF7F0DaB0BECE4498dAc7eb616e288809D4499371"
},
"bsctestnet": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x666a24F62f7A97BA33c151776Eb3D9441a059eB8",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0xd785272D240B07719e417622cbd2cfA0E584d1bd"
},
"optimismkovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x7914A3349107A7295Bbf2374db5A973d73D1b324",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x598facE78a4302f11E3de0bee1894Da0b2Cb71F8"
}
}
},
"optimismkovan": {
"upgradeBeaconController": "0x6E7b29CB2A7617405B4d30C6f84bBD51b4Bb4be8",
"abacusConnectionManager": "0xC2E36cd6e32e194EE11f15D9273B64461A4D49A2",
"interchainGasPaymaster": "0x44b764045BfDC68517e10e783E69B376cef196B2",
"outbox": {
"outbox": {
"kind": "UpgradeBeacon",
"proxy": "0x16B710b86CAd07E6F1C531861a16F5feC29dba37",
"implementation": "0x275aCcCa81cAD931dC6fB6E49ED233Bc99Bed4A7",
"beacon": "0xeb6f11189197223c656807a83B0DD374f9A6dF44"
},
"outboxValidatorManager": "0xfc6e546510dC9d76057F1f76633FCFfC188CB213"
},
"inboxes": {
"alfajores": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xB08d78F439e55D02C398519eef61606A5926245F",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x589C201a07c26b4725A4A829d772f24423da480B"
},
"kovan": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xD3d062a5dcBA85ae863618d4c264d2358300c283",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x833Dad7FF66884389D5F0cEcba446ffaa7d2837e"
},
"fuji": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x7FE7EA170cf08A25C2ff315814D96D93C311E692",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E"
},
"mumbai": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0xF7F0DaB0BECE4498dAc7eb616e288809D4499371"
},
"bsctestnet": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x666a24F62f7A97BA33c151776Eb3D9441a059eB8",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0xd785272D240B07719e417622cbd2cfA0E584d1bd"
},
"arbitrumrinkeby": {
"inbox": {
"kind": "UpgradeBeacon",
"proxy": "0x7914A3349107A7295Bbf2374db5A973d73D1b324",
"implementation": "0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD",
"beacon": "0x33dB966328Ea213b0f76eF96CA368AB37779F065"
},
"inboxValidatorManager": "0x598facE78a4302f11E3de0bee1894Da0b2Cb71F8"
}
}
}
}

@ -1,346 +0,0 @@
export const addresses = {
alfajores: {
upgradeBeaconController: '0x19Be55D859368e02d7b9C00803Eb677BDC1359Bd',
abacusConnectionManager: '0x433f7d6d0cB9eb8FF2902Ad01C1BEd6C09934a33',
interchainGasPaymaster: '0x28B02B97a850872C4D33C3E024fab6499ad96564',
outbox: {
validatorManager: '0x5821f3B6eE05F3dC62b43B74AB1C8F8E6904b1C8',
proxy: '0xD0680F80F4f947968206806C2598Cbc5b6FE5b03',
implementation: '0x267B6B6eAf6790faE5D5E9070F28a9cE64CbF279',
beacon: '0xc756cFc1b7d0d4646589EDf10eD54b201237F5e8',
},
inboxes: {
kovan: {
validatorManager: '0x1b33611fCc073aB0737011d5512EF673Bff74962',
proxy: '0x783c4a0bB6663359281aD4a637D5af68F83ae213',
implementation: '0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C',
beacon: '0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9',
},
fuji: {
validatorManager: '0x66b71A4e18FbE09a6977A6520B47fEDdffA82a1c',
proxy: '0xae7a78916Ba4c507aCB2F0e474ace545Ff4bF841',
implementation: '0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C',
beacon: '0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9',
},
mumbai: {
validatorManager: '0x04438ef7622f5412f82915F59caD4f704C61eA48',
proxy: '0xFCc63b537e70652A280c4E7883C5BB5a1700e897',
implementation: '0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C',
beacon: '0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9',
},
bsctestnet: {
validatorManager: '0xb94F96D398eA5BAB5CA528EE9Fdc19afaA825818',
proxy: '0x51A0a100e7BC63Ea7821A3a023B6F17fb94FF011',
implementation: '0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C',
beacon: '0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9',
},
arbitrumrinkeby: {
validatorManager: '0xB057Fb841027a8554521DcCdeC3c3474CaC99AB5',
proxy: '0xe0B988062A0C6492177d64823Ab95a9c256c2a5F',
implementation: '0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C',
beacon: '0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9',
},
optimismkovan: {
validatorManager: '0xA2cf52064c921C11adCd83588CbEa08cc3bfF5d8',
proxy: '0x628BC518ED1e0E8C6cbcD574EbA0ee29e7F6943E',
implementation: '0x6c13643B3927C57DB92c790E4E3E7Ee81e13f78C',
beacon: '0x20c44b1E3BeaDA1e9826CFd48BeEDABeE9871cE9',
},
},
},
kovan: {
upgradeBeaconController: '0xcf5BaaF976C80a66Fa7839715C45788f60041A33',
abacusConnectionManager: '0xF7561c34f17A32D5620583A3397C304e7038a7F6',
interchainGasPaymaster: '0x07009DA2249c388aD0f416a235AfE90D784e1aAc',
outbox: {
validatorManager: '0x58483b754Abb1E8947BE63d6b95DF75b8249543A',
proxy: '0x98AAE089CaD930C64a76dD2247a2aC5773a4B8cE',
implementation: '0x679Dc08cC3A4acFeea2f7CAFAa37561aE0b41Ce7',
beacon: '0x4926a10788306D84202A2aDbd290b7743146Cc17',
},
inboxes: {
alfajores: {
validatorManager: '0x5CE550e14B82a9F32A0aaF9eFc4Fce548D8A0B3e',
proxy: '0x68311418D79fE8d96599384ED767d225635d88a8',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
fuji: {
validatorManager: '0x863E8c26621c52ACa1849C53500606e73BA272F0',
proxy: '0x6b1bb4ce664Bb4164AEB4d3D2E7DE7450DD8084C',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
mumbai: {
validatorManager: '0xAb9B273366D794B7F80B4378bc8Aaca75C6178E2',
proxy: '0x86fb9F1c124fB20ff130C41a79a432F770f67AFD',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
bsctestnet: {
validatorManager: '0x19Be55D859368e02d7b9C00803Eb677BDC1359Bd',
proxy: '0x5821f3B6eE05F3dC62b43B74AB1C8F8E6904b1C8',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
arbitrumrinkeby: {
validatorManager: '0xc756cFc1b7d0d4646589EDf10eD54b201237F5e8',
proxy: '0xD0680F80F4f947968206806C2598Cbc5b6FE5b03',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
optimismkovan: {
validatorManager: '0x433f7d6d0cB9eb8FF2902Ad01C1BEd6C09934a33',
proxy: '0x75f3E2a4f424401195A5E176246Ecc9f7e7680ff',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
},
},
fuji: {
upgradeBeaconController: '0xcf5BaaF976C80a66Fa7839715C45788f60041A33',
abacusConnectionManager: '0xF7561c34f17A32D5620583A3397C304e7038a7F6',
interchainGasPaymaster: '0x07009DA2249c388aD0f416a235AfE90D784e1aAc',
inboxValidatorManagers: {},
outbox: {
validatorManager: '0x58483b754Abb1E8947BE63d6b95DF75b8249543A',
proxy: '0x98AAE089CaD930C64a76dD2247a2aC5773a4B8cE',
implementation: '0x679Dc08cC3A4acFeea2f7CAFAa37561aE0b41Ce7',
beacon: '0x4926a10788306D84202A2aDbd290b7743146Cc17',
},
inboxes: {
alfajores: {
validatorManager: '0x5CE550e14B82a9F32A0aaF9eFc4Fce548D8A0B3e',
proxy: '0x68311418D79fE8d96599384ED767d225635d88a8',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
kovan: {
validatorManager: '0x863E8c26621c52ACa1849C53500606e73BA272F0',
proxy: '0x6b1bb4ce664Bb4164AEB4d3D2E7DE7450DD8084C',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
mumbai: {
validatorManager: '0xAb9B273366D794B7F80B4378bc8Aaca75C6178E2',
proxy: '0x86fb9F1c124fB20ff130C41a79a432F770f67AFD',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
bsctestnet: {
validatorManager: '0x19Be55D859368e02d7b9C00803Eb677BDC1359Bd',
proxy: '0x5821f3B6eE05F3dC62b43B74AB1C8F8E6904b1C8',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
arbitrumrinkeby: {
validatorManager: '0xc756cFc1b7d0d4646589EDf10eD54b201237F5e8',
proxy: '0xD0680F80F4f947968206806C2598Cbc5b6FE5b03',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
optimismkovan: {
validatorManager: '0x433f7d6d0cB9eb8FF2902Ad01C1BEd6C09934a33',
proxy: '0x75f3E2a4f424401195A5E176246Ecc9f7e7680ff',
implementation: '0xeC7eb4196Bd601DEa7585A744FbFB4CF11278450',
beacon: '0x5CBf4e70448Ed46c2616b04e9ebc72D29FF0cfA9',
},
},
},
mumbai: {
upgradeBeaconController: '0x6966b0E55883d49BFB24539356a2f8A673E02039',
abacusConnectionManager: '0x46f7C5D896bbeC89bE1B19e4485e59b4Be49e9Cc',
interchainGasPaymaster: '0xB08d78F439e55D02C398519eef61606A5926245F',
outbox: {
validatorManager: '0x54148470292C24345fb828B003461a9444414517',
proxy: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
implementation: '0x589C201a07c26b4725A4A829d772f24423da480B',
beacon: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
},
inboxes: {
alfajores: {
validatorManager: '0x304cAb315c93B87AAdb2B826A791b2c1Bf749996',
proxy: '0x1D5EbC3e15e9ECDe0e3530C85899556797eeaea5',
implementation: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
beacon: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
},
kovan: {
validatorManager: '0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc',
proxy: '0x0526E47C49742C15F8817ef8cf0d8FFc72139D4F',
implementation: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
beacon: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
},
fuji: {
validatorManager: '0x666a24F62f7A97BA33c151776Eb3D9441a059eB8',
proxy: '0xef48bd850E5827B96B55C4D28FB32Bbaa73616F2',
implementation: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
beacon: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
},
bsctestnet: {
validatorManager: '0x7914A3349107A7295Bbf2374db5A973d73D1b324',
proxy: '0x3C5154a193D6e2955650f9305c8d80c18C814A68',
implementation: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
beacon: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
},
arbitrumrinkeby: {
validatorManager: '0x5d56B8a669F50193b54319442c6EEE5edD662381',
proxy: '0x05Ea36Caee7d92C173334C9D97DcD39ABdCB2b69',
implementation: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
beacon: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
},
optimismkovan: {
validatorManager: '0x58483b754Abb1E8947BE63d6b95DF75b8249543A',
proxy: '0x679Dc08cC3A4acFeea2f7CAFAa37561aE0b41Ce7',
implementation: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
beacon: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
},
},
},
bsctestnet: {
upgradeBeaconController: '0x6E7b29CB2A7617405B4d30C6f84bBD51b4Bb4be8',
abacusConnectionManager: '0xC2E36cd6e32e194EE11f15D9273B64461A4D49A2',
interchainGasPaymaster: '0x44b764045BfDC68517e10e783E69B376cef196B2',
outbox: {
validatorManager: '0xfc6e546510dC9d76057F1f76633FCFfC188CB213',
proxy: '0x16B710b86CAd07E6F1C531861a16F5feC29dba37',
implementation: '0x275aCcCa81cAD931dC6fB6E49ED233Bc99Bed4A7',
beacon: '0xeb6f11189197223c656807a83B0DD374f9A6dF44',
},
inboxes: {
alfajores: {
validatorManager: '0x589C201a07c26b4725A4A829d772f24423da480B',
proxy: '0xB08d78F439e55D02C398519eef61606A5926245F',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
kovan: {
validatorManager: '0x833Dad7FF66884389D5F0cEcba446ffaa7d2837e',
proxy: '0xD3d062a5dcBA85ae863618d4c264d2358300c283',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
fuji: {
validatorManager: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
proxy: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
mumbai: {
validatorManager: '0xF7F0DaB0BECE4498dAc7eb616e288809D4499371',
proxy: '0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
arbitrumrinkeby: {
validatorManager: '0xd785272D240B07719e417622cbd2cfA0E584d1bd',
proxy: '0x666a24F62f7A97BA33c151776Eb3D9441a059eB8',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
optimismkovan: {
validatorManager: '0x598facE78a4302f11E3de0bee1894Da0b2Cb71F8',
proxy: '0x7914A3349107A7295Bbf2374db5A973d73D1b324',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
},
},
arbitrumrinkeby: {
upgradeBeaconController: '0x6E7b29CB2A7617405B4d30C6f84bBD51b4Bb4be8',
abacusConnectionManager: '0xC2E36cd6e32e194EE11f15D9273B64461A4D49A2',
interchainGasPaymaster: '0x44b764045BfDC68517e10e783E69B376cef196B2',
outbox: {
validatorManager: '0xfc6e546510dC9d76057F1f76633FCFfC188CB213',
proxy: '0x16B710b86CAd07E6F1C531861a16F5feC29dba37',
implementation: '0x275aCcCa81cAD931dC6fB6E49ED233Bc99Bed4A7',
beacon: '0xeb6f11189197223c656807a83B0DD374f9A6dF44',
},
inboxes: {
alfajores: {
validatorManager: '0x589C201a07c26b4725A4A829d772f24423da480B',
proxy: '0xB08d78F439e55D02C398519eef61606A5926245F',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
kovan: {
validatorManager: '0x833Dad7FF66884389D5F0cEcba446ffaa7d2837e',
proxy: '0xD3d062a5dcBA85ae863618d4c264d2358300c283',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
fuji: {
validatorManager: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
proxy: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
mumbai: {
validatorManager: '0xF7F0DaB0BECE4498dAc7eb616e288809D4499371',
proxy: '0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
bsctestnet: {
validatorManager: '0xd785272D240B07719e417622cbd2cfA0E584d1bd',
proxy: '0x666a24F62f7A97BA33c151776Eb3D9441a059eB8',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
optimismkovan: {
validatorManager: '0x598facE78a4302f11E3de0bee1894Da0b2Cb71F8',
proxy: '0x7914A3349107A7295Bbf2374db5A973d73D1b324',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
},
},
optimismkovan: {
upgradeBeaconController: '0x6E7b29CB2A7617405B4d30C6f84bBD51b4Bb4be8',
abacusConnectionManager: '0xC2E36cd6e32e194EE11f15D9273B64461A4D49A2',
interchainGasPaymaster: '0x44b764045BfDC68517e10e783E69B376cef196B2',
outbox: {
validatorManager: '0xfc6e546510dC9d76057F1f76633FCFfC188CB213',
proxy: '0x16B710b86CAd07E6F1C531861a16F5feC29dba37',
implementation: '0x275aCcCa81cAD931dC6fB6E49ED233Bc99Bed4A7',
beacon: '0xeb6f11189197223c656807a83B0DD374f9A6dF44',
},
inboxes: {
alfajores: {
validatorManager: '0x589C201a07c26b4725A4A829d772f24423da480B',
proxy: '0xB08d78F439e55D02C398519eef61606A5926245F',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
kovan: {
validatorManager: '0x833Dad7FF66884389D5F0cEcba446ffaa7d2837e',
proxy: '0xD3d062a5dcBA85ae863618d4c264d2358300c283',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
fuji: {
validatorManager: '0x7d498740A4572f2B5c6b0A1Ba9d1d9DbE207e89E',
proxy: '0x7FE7EA170cf08A25C2ff315814D96D93C311E692',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
mumbai: {
validatorManager: '0xF7F0DaB0BECE4498dAc7eb616e288809D4499371',
proxy: '0xfc8d0D2E15A36f1A3F3aE3Cb127B706c1f23Aadc',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
bsctestnet: {
validatorManager: '0xd785272D240B07719e417622cbd2cfA0E584d1bd',
proxy: '0x666a24F62f7A97BA33c151776Eb3D9441a059eB8',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
arbitrumrinkeby: {
validatorManager: '0x598facE78a4302f11E3de0bee1894Da0b2Cb71F8',
proxy: '0x7914A3349107A7295Bbf2374db5A973d73D1b324',
implementation: '0xDDcFEcF17586D08A5740B7D91735fcCE3dfe3eeD',
beacon: '0x33dB966328Ea213b0f76eF96CA368AB37779F065',
},
},
},
};

@ -1,10 +1,9 @@
export { AbacusCore } from './app'; export { AbacusCore, CoreContractsMap } from './app';
export { export {
CoreContractAddresses,
CoreContracts, CoreContracts,
coreFactories, coreFactories,
InboxContracts, InboxContracts,
MailboxAddresses, OutboxContracts,
} from './contracts'; } from './contracts';
export { environments as coreEnvironments } from './environments'; export { environments as coreEnvironments } from './environments';
export { export {

@ -124,8 +124,8 @@ export class AbacusMessage {
messageNetworks.destination, messageNetworks.destination,
); );
this.outbox = mailboxes.outbox; this.outbox = mailboxes.originOutbox;
this.inbox = mailboxes.inbox; this.inbox = mailboxes.destinationInbox;
this.cache = {}; this.cache = {};
} }

@ -3,8 +3,7 @@ import { BigNumber, FixedNumber, ethers } from 'ethers';
import { utils } from '@abacus-network/utils'; import { utils } from '@abacus-network/utils';
import { InboxContracts } from '../core/contracts'; import { ChainName, Remotes } from '../types';
import { ChainName, RemoteChainMap, Remotes } from '../types';
import { DefaultTokenPriceGetter, TokenPriceGetter } from './token-prices'; import { DefaultTokenPriceGetter, TokenPriceGetter } from './token-prices';
import { convertDecimalValue, mulBigAndFixed } from './utils'; import { convertDecimalValue, mulBigAndFixed } from './utils';
@ -285,7 +284,7 @@ export class InterchainGasCalculator<Chain extends ChainName> {
const provider = this.multiProvider.getChainConnection(message.destination) const provider = this.multiProvider.getChainConnection(message.destination)
.provider!; .provider!;
const { inbox } = this.core.getMailboxPair<LocalChain>( const { destinationInbox } = this.core.getMailboxPair<LocalChain>(
message.origin, message.origin,
message.destination, message.destination,
); );
@ -298,7 +297,7 @@ export class InterchainGasCalculator<Chain extends ChainName> {
// This includes intrinsic gas. // This includes intrinsic gas.
const directHandleCallGas = await provider.estimateGas({ const directHandleCallGas = await provider.estimateGas({
to: utils.bytes32ToAddress(message.recipient), to: utils.bytes32ToAddress(message.recipient),
from: inbox.address, from: destinationInbox.address,
data: handlerInterface.encodeFunctionData('handle', [ data: handlerInterface.encodeFunctionData('handle', [
message.origin, message.origin,
message.sender, message.sender,
@ -325,10 +324,8 @@ export class InterchainGasCalculator<Chain extends ChainName> {
origin: Remotes<Chain, Destination>, origin: Remotes<Chain, Destination>,
destination: Destination, destination: Destination,
): Promise<BigNumber> { ): Promise<BigNumber> {
const inboxes: RemoteChainMap<Chain, Destination, InboxContracts> = const inboxes = this.core.getContracts(destination).inboxes;
this.core.getContracts(destination).inboxes; const threshold = await inboxes[origin].inboxValidatorManager.threshold();
const inboxValidatorManager = inboxes[origin].validatorManager;
const threshold = await inboxValidatorManager.threshold();
return threshold return threshold
.mul(CHECKPOINT_RELAY_GAS_PER_SIGNATURE) .mul(CHECKPOINT_RELAY_GAS_PER_SIGNATURE)

@ -2,11 +2,12 @@ export { AbacusApp } from './app';
export { chainMetadata } from './chain-metadata'; export { chainMetadata } from './chain-metadata';
export { addSignerToConnection, chainConnectionConfigs } from './chains'; export { addSignerToConnection, chainConnectionConfigs } from './chains';
export { export {
AbacusContractAddresses, AbacusAddresses,
AbacusContracts, AbacusContracts,
Factories, AbacusFactories,
RouterAddresses, buildContracts,
routerFactories, connectContracts,
serializeContracts,
} from './contracts'; } from './contracts';
export { export {
AbacusCore, AbacusCore,
@ -15,13 +16,13 @@ export {
AbacusStatus, AbacusStatus,
AnnotatedDispatch, AnnotatedDispatch,
AnnotatedLifecycleEvent, AnnotatedLifecycleEvent,
CoreContractAddresses,
CoreContracts, CoreContracts,
CoreContractsMap,
coreEnvironments, coreEnvironments,
coreFactories, coreFactories,
InboxContracts, InboxContracts,
MailboxAddresses,
MessageStatus, MessageStatus,
OutboxContracts,
parseMessage, parseMessage,
resolveDomain, resolveDomain,
resolveId, resolveId,
@ -39,6 +40,8 @@ export {
TokenPriceGetter, TokenPriceGetter,
} from './gas'; } from './gas';
export { ChainConnection, IChainConnection, MultiProvider } from './provider'; export { ChainConnection, IChainConnection, MultiProvider } from './provider';
export { BeaconProxyAddresses, ProxiedContract, ProxyAddresses } from './proxy';
export { RouterContracts, RouterFactories } from './router';
export { export {
AllChains, AllChains,
ChainMap, ChainMap,
@ -49,7 +52,6 @@ export {
Connection, Connection,
DomainIdToChainName, DomainIdToChainName,
NameOrDomain, NameOrDomain,
ProxiedAddress,
RemoteChainMap, RemoteChainMap,
Remotes, Remotes,
TestChainNames, TestChainNames,

@ -0,0 +1,49 @@
import { Contract } from 'ethers';
import { types } from '@abacus-network/utils';
import { Connection } from './types';
export enum ProxyKind {
UpgradeBeacon = 'UpgradeBeacon',
}
export interface ProxyAddresses<Kind extends ProxyKind> {
kind: Kind;
proxy: types.Address;
implementation: types.Address;
}
export function isProxyAddresses(
addresses: object,
): addresses is ProxyAddresses<any> {
return (
'proxy' in addresses &&
'implementation' in addresses &&
'kind' in addresses &&
Object.keys(ProxyKind).includes((addresses as any).kind)
);
}
export interface BeaconProxyAddresses
extends ProxyAddresses<ProxyKind.UpgradeBeacon> {
beacon: types.Address;
}
export class ProxiedContract<
C extends Contract,
A extends ProxyAddresses<any>,
> {
constructor(public readonly contract: C, public readonly addresses: A) {}
get address(): string {
return this.contract.address;
}
connect(connection: Connection): ProxiedContract<C, A> {
return new ProxiedContract(
this.contract.connect(connection) as C,
this.addresses,
);
}
}

@ -0,0 +1,20 @@
import { Router, Router__factory } from '@abacus-network/app';
import {
AbacusConnectionManager,
AbacusConnectionManager__factory,
} from '@abacus-network/core';
import { AbacusContracts, AbacusFactories } from './contracts';
export type RouterContracts<RouterContract extends Router = Router> =
AbacusContracts & {
router: RouterContract;
abacusConnectionManager: AbacusConnectionManager;
};
export type RouterFactories<
RouterFactory extends Router__factory = Router__factory,
> = AbacusFactories & {
router: RouterFactory;
abacusConnectionManager: AbacusConnectionManager__factory;
};

@ -1,7 +1,5 @@
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { types } from '@abacus-network/utils';
import { chainMetadata } from './chain-metadata'; import { chainMetadata } from './chain-metadata';
/** /**
@ -69,9 +67,3 @@ export type ChainMetadata = {
}; };
export type Connection = ethers.providers.Provider | ethers.Signer; export type Connection = ethers.providers.Provider | ethers.Signer;
export type ProxiedAddress = {
proxy: types.Address;
implementation: types.Address;
beacon: types.Address;
};

@ -59,7 +59,13 @@ export function delay(ms: number): Promise<void> {
export class MultiGeneric<Chain extends ChainName, Value> { export class MultiGeneric<Chain extends ChainName, Value> {
constructor(protected readonly chainMap: ChainMap<Chain, Value>) {} constructor(protected readonly chainMap: ChainMap<Chain, Value>) {}
protected get = (chain: Chain) => this.chainMap[chain]; protected get(chain: Chain) {
return this.chainMap[chain];
}
protected set(chain: Chain, value: Value) {
this.chainMap[chain] = value;
}
chains = () => Object.keys(this.chainMap) as Chain[]; chains = () => Object.keys(this.chainMap) as Chain[];

@ -10,6 +10,7 @@ import {
InterchainGasCalculator, InterchainGasCalculator,
MultiProvider, MultiProvider,
} from '../..'; } from '../..';
import { CoreContracts } from '../../src';
import { ParsedMessage } from '../../src/gas/calculator'; import { ParsedMessage } from '../../src/gas/calculator';
import { TestChainNames } from '../../src/types'; import { TestChainNames } from '../../src/types';
import { MockProvider, MockTokenPriceGetter } from '../utils'; import { MockProvider, MockTokenPriceGetter } from '../utils';
@ -31,10 +32,10 @@ describe('InterchainGasCalculator', () => {
test2: { provider }, test2: { provider },
test3: { provider }, test3: { provider },
}); });
const core = AbacusCore.fromEnvironment( const core: AbacusCore<TestChainNames> = AbacusCore.fromEnvironment(
'test', 'test',
multiProvider, multiProvider,
) as AbacusCore<TestChainNames>; );
const origin = Chains.test1; const origin = Chains.test1;
const destination = Chains.test2; const destination = Chains.test2;
@ -202,14 +203,15 @@ describe('InterchainGasCalculator', () => {
let thresholdStub: sinon.SinonStub | undefined; let thresholdStub: sinon.SinonStub | undefined;
getContractsStub.callsFake((chain) => { getContractsStub.callsFake((chain) => {
// Get the "real" return value of getContracts. // Get the "real" return value of getContracts.
const contracts = getContractsStub.wrappedMethod.bind(core)(chain); const contracts: CoreContracts<TestChainNames, TestChainNames> =
getContractsStub.wrappedMethod.bind(core)(chain);
// Ethers contracts are frozen using Object.freeze, so we make a copy // Ethers contracts are frozen using Object.freeze, so we make a copy
// of the object so we can stub `threshold`. // of the object so we can stub `threshold`.
const validatorManager = Object.assign( const validatorManager = Object.assign(
{}, {},
// @ts-ignore Typescript has trouble properly typing the stubbed getContracts // @ts-ignore
contracts.inboxes[origin].validatorManager, contracts.inboxes[origin].inboxValidatorManager,
); );
// Because we are stubbing vaidatorManager.threshold when core.getContracts gets called, // Because we are stubbing vaidatorManager.threshold when core.getContracts gets called,
@ -219,8 +221,8 @@ describe('InterchainGasCalculator', () => {
.stub(validatorManager, 'threshold') .stub(validatorManager, 'threshold')
.callsFake(() => Promise.resolve(BigNumber.from(threshold))); .callsFake(() => Promise.resolve(BigNumber.from(threshold)));
// @ts-ignore Typescript has trouble properly typing the stubbed getContracts // @ts-ignore
contracts.inboxes[origin].validatorManager = validatorManager; contracts.inboxes[origin].inboxValidatorManager = validatorManager;
} }
return contracts; return contracts;
}); });

@ -2,7 +2,8 @@
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./dist/", "outDir": "./dist/",
"rootDir": "./src/" "rootDir": "./src/",
"resolveJsonModule": true
}, },
"exclude": ["./node_modules/", "./dist/", "./test/"], "exclude": ["./node_modules/", "./dist/", "./test/"],
"include": ["./src/*.ts", "./src/**/*.ts"] "include": ["./src/*.ts", "./src/**/*.ts"]

Loading…
Cancel
Save