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

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

@ -1,21 +1,23 @@
import { Debugger, debug } from 'debug';
import { ethers } from 'ethers';
import fs from 'fs';
import path from 'path';
import {
UpgradeBeaconProxy__factory,
UpgradeBeacon__factory,
} from '@abacus-network/core';
import {
AbacusContracts,
AbacusFactories,
BeaconProxyAddresses,
ChainMap,
ChainName,
MultiProvider,
ProxiedContract,
objMap,
} from '@abacus-network/sdk';
import { ProxyKind } from '@abacus-network/sdk/dist/proxy';
import { types } from '@abacus-network/utils';
import { ProxiedContract } from './proxy';
import {
ContractVerificationInput,
getContractVerificationInput,
@ -25,47 +27,54 @@ export interface DeployerOptions {
logger?: Debugger;
}
// TODO: Make AppDeployer generic on AbacusApp and return instance from deploy()
export abstract class AbacusAppDeployer<Chain extends ChainName, C, A> {
export abstract class AbacusDeployer<
Chain extends ChainName,
Config,
Factories extends AbacusFactories,
Contracts extends AbacusContracts,
> {
verificationInputs: ChainMap<Chain, ContractVerificationInput[]>;
protected logger: Debugger;
constructor(
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,
) {
this.verificationInputs = objMap(configMap, () => []);
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() {
this.logger('Start Deploy');
this.verificationInputs = objMap(this.configMap, () => []);
const chains = this.multiProvider.chains();
const entries: [Chain, A][] = [];
const entries: [Chain, Contracts][] = [];
for (const chain of chains) {
this.logger(`Deploying to ${chain}...`);
const result = await this.deployContracts(chain, this.configMap[chain]);
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,
contractName: string,
factory: F,
args: Parameters<F['deploy']>,
): Promise<ReturnType<F['deploy']>> {
this.logger(`Deploy ${contractName} on ${chain}`);
contractName: K,
args: Parameters<Factories[K]['deploy']>,
): Promise<ReturnType<Factories[K]['deploy']>> {
this.logger(`Deploy ${contractName.toString()} on ${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);
const verificationInput = getContractVerificationInput(
contractName,
contractName.toString(),
contract,
factory.bytecode,
);
@ -78,48 +87,43 @@ export abstract class AbacusAppDeployer<Chain extends ChainName, C, A> {
*
*/
async deployProxiedContract<
F extends ethers.ContractFactory,
C extends ethers.Contract = Awaited<ReturnType<F['deploy']>>,
K extends keyof Factories,
C extends Awaited<ReturnType<Factories[K]['deploy']>>,
>(
chain: Chain,
contractName: string,
factory: F,
deployArgs: Parameters<F['deploy']>,
contractName: K,
deployArgs: Parameters<Factories[K]['deploy']>,
ubcAddress: types.Address,
initArgs: Parameters<C['initialize']>,
) {
): Promise<ProxiedContract<C, BeaconProxyAddresses>> {
const chainConnection = this.multiProvider.getChainConnection(chain);
const signer = chainConnection.signer;
const implementation = await this.deployContract(
const implementation = await this.deployContract<K>(
chain,
`${contractName} Implementation`,
factory,
contractName,
deployArgs,
);
const beacon = await this.deployContract(
chain,
`${contractName} UpgradeBeacon`,
new UpgradeBeacon__factory(signer),
[implementation.address, ubcAddress],
const beacon = await new UpgradeBeacon__factory(signer).deploy(
implementation.address,
ubcAddress,
);
const initData = implementation.interface.encodeFunctionData(
'initialize',
initArgs,
);
const proxy = await this.deployContract(
chain,
`${contractName} Proxy`,
new UpgradeBeaconProxy__factory(signer),
[beacon.address, initData],
const beaconProxy = await new UpgradeBeaconProxy__factory(signer).deploy(
beacon.address,
initData,
);
const proxiedContract = new ProxiedContract(factory.attach(proxy.address), {
proxy: proxy.address,
return new ProxiedContract<C, BeaconProxyAddresses>(
implementation.attach(beaconProxy.address) as any,
{
kind: ProxyKind.UpgradeBeacon,
proxy: beaconProxy.address,
implementation: implementation.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>(
chain: Chain,
contractName: string,
proxy: ProxiedContract<C>,
proxy: ProxiedContract<C, BeaconProxyAddresses>,
initArgs: Parameters<C['initialize']>,
) {
const chainConnection = this.multiProvider.getChainConnection(chain);
): Promise<ProxiedContract<C, BeaconProxyAddresses>> {
const signer = this.multiProvider.getChainConnection(chain).signer!;
const initData = proxy.contract.interface.encodeFunctionData(
'initialize',
initArgs,
);
const newProxy = await this.deployContract(
chain,
`${contractName} Proxy`,
new UpgradeBeaconProxy__factory(chainConnection.signer!),
[proxy.addresses.beacon, initData],
const proxyAddresses = proxy.addresses as BeaconProxyAddresses;
const newProxy = await new UpgradeBeaconProxy__factory(signer).deploy(
proxyAddresses.beacon,
initData,
);
const newProxiedContract = new ProxiedContract(
proxy.contract.attach(newProxy.address),
return new ProxiedContract<C, BeaconProxyAddresses>(
proxy.contract.attach(newProxy.address) as C,
{
...proxy.addresses,
...proxyAddresses,
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,
ValidatorManagerConfig,
} from './core/deploy';
export { AbacusAppDeployer } from './deploy';
export {
ProxiedContract,
ProxyViolationType,
UpgradeBeaconViolation,
} from './proxy';
export { AbacusDeployer } from './deploy';
export { UpgradeBeaconViolation } from './proxy';
export {
AbacusRouterChecker,
AbacusRouterDeployer,
Router,
RouterConfig,
} from './router';
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 { ChainName, ProxiedAddress } from '@abacus-network/sdk';
import { BeaconProxyAddresses, ChainName } from '@abacus-network/sdk';
import { types } from '@abacus-network/utils';
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 {
type: ProxyViolationType.UpgradeBeacon;
type: BeaconProxyAddresses['kind'];
data: {
proxiedAddress: ProxiedAddress;
proxiedAddress: BeaconProxyAddresses;
name: string;
};
actual: string;
@ -42,12 +27,12 @@ export async function upgradeBeaconImplementation(
export function upgradeBeaconViolation<Chain extends ChainName>(
chain: Chain,
name: string,
proxiedAddress: ProxiedAddress,
proxiedAddress: BeaconProxyAddresses,
actual: types.Address,
): UpgradeBeaconViolation {
return {
chain,
type: ProxyViolationType.UpgradeBeacon,
type: proxiedAddress.kind,
actual,
expected: proxiedAddress.implementation,
data: {

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

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

@ -1,15 +1,6 @@
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 = {
abacusConnectionManager: types.Address;
owner: types.Address;
};

@ -1,16 +1,9 @@
import { ethers } from 'ethers';
import yargs from 'yargs';
import {
AbacusCore,
ChainMap,
ChainName,
MultiProvider,
objMap,
} from '@abacus-network/sdk';
import { ChainName, MultiProvider, objMap } from '@abacus-network/sdk';
import { EnvironmentConfig } from './config';
import { RouterConfig } from './router';
export function getArgs() {
return yargs(process.argv.slice(2))
@ -24,15 +17,6 @@ export async function getEnvironment(): 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>(
environmentConfig: EnvironmentConfig<Chain>,
signer: ethers.Signer,

@ -1,3 +1,3 @@
export { ContractVerifier } from './ContractVerifier';
export { getContractVerificationInput } from './utils';
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);
}
function getConstructorArguments(
export function getConstructorArguments(
contract: ethers.Contract,
bytecode: string,
): any {

@ -1,38 +1,45 @@
import {
TestInbox,
TestInbox__factory,
TestOutbox__factory,
} from '@abacus-network/core';
import { TestInbox, TestOutbox } from '@abacus-network/core';
import {
AbacusCore,
ChainMap,
CoreContracts,
DomainIdToChainName,
InboxContracts,
OutboxContracts,
ProxiedContract,
Remotes,
TestChainNames,
chainMetadata,
objMap,
} from '@abacus-network/sdk';
import { types } from '@abacus-network/utils';
import { ethers } from 'ethers';
export class TestCoreApp extends AbacusCore<TestChainNames> {
getContracts<Local extends TestChainNames>(chain: Local) {
const contracts = super.getContracts(chain);
return {
...contracts,
outbox: {
...contracts.outbox,
outbox: TestOutbox__factory.connect(
contracts.outbox.outbox.address,
contracts.outbox.outbox.signer,
),
},
inboxes: objMap(contracts.inboxes, (_, inbox) => ({
...inbox,
inbox: TestInbox__factory.connect(
inbox.inbox.address,
inbox.inbox.signer,
),
})),
type MockProxyAddresses = {
kind: 'MOCK';
proxy: string;
implementation: string;
};
export type TestOutboxContracts = OutboxContracts & {
outbox: ProxiedContract<TestOutbox, MockProxyAddresses>;
};
export type TestInboxContracts = InboxContracts & {
inbox: ProxiedContract<TestInbox, MockProxyAddresses>;
};
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<
@ -56,7 +63,7 @@ export class TestCoreApp extends AbacusCore<TestChainNames> {
async processOutboundMessages<Local extends TestChainNames>(origin: Local) {
const responses = new Map();
const contracts = this.getContracts(origin);
const outbox = contracts.outbox.outbox;
const outbox: TestOutbox = contracts.outbox.contract;
const dispatchFilter = outbox.filters.Dispatch();
const dispatches = await outbox.queryFilter(dispatchFilter);
@ -68,7 +75,7 @@ export class TestCoreApp extends AbacusCore<TestChainNames> {
const destinationChain = DomainIdToChainName[destination];
const inbox: TestInbox =
// @ts-ignore
this.getContracts(destinationChain).inboxes[origin].inbox;
this.getContracts(destinationChain).inboxes[origin].inbox.contract;
const status = await inbox.messages(dispatch.args.messageHash);
if (status !== types.MessageStatus.PROCESSED) {
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 { AbacusCoreDeployer, CoreConfig } from '@abacus-network/deploy';
import { MultiProvider, TestChainNames } from '@abacus-network/sdk';
import {
AbacusCoreDeployer,
CoreConfig,
ValidatorManagerConfig,
} from '@abacus-network/deploy';
import {
chainMetadata,
coreFactories,
MultiProvider,
ProxiedContract,
Remotes,
TestChainNames,
} from '@abacus-network/sdk';
import { ethers } from 'ethers';
// 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> {
constructor(public readonly multiProvider: MultiProvider<TestChainNames>) {
super(multiProvider, {
super(
multiProvider,
{
test1: testValidatorManagerConfig,
test2: testValidatorManagerConfig,
test3: testValidatorManagerConfig,
});
},
testCoreFactories,
);
}
inboxFactoryBuilder = (signer: ethers.Signer) =>
new TestInbox__factory(signer);
outboxFactoryBuilder = (signer: ethers.Signer) =>
new TestOutbox__factory(signer);
// skip proxying
async deployOutbox<LocalChain extends TestChainNames>(
chain: LocalChain,
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() {
const result = await super.deploy();
return new TestCoreApp(result, this.multiProvider);
return new TestCoreApp(await this.deploy(), this.multiProvider);
}
}

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

@ -21,12 +21,13 @@ const chainSummary = async <Chain extends ChainName>(
chain: Chain,
) => {
const coreContracts = core.getContracts(chain);
const outbox = coreContracts.outbox.outbox;
const outbox = coreContracts.outbox.contract;
const count = (await outbox.tree()).toNumber();
const inboxSummary = async (remote: Chain) => {
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] =
await inbox.latestCachedCheckpoint();
const processFilter = inbox.filters.Process();
@ -53,14 +54,13 @@ const chainSummary = async <Chain extends ChainName>(
task('kathy', 'Dispatches random abacus messages').setAction(
async (_, hre: HardhatRuntimeEnvironment) => {
const environment = 'test';
const config = getCoreEnvironmentConfig(environment);
const config = getCoreEnvironmentConfig('test');
const [signer] = await hre.ethers.getSigners();
const multiProvider = deployUtils.getMultiProviderFromConfigAndSigner(
config.transactionConfigs,
signer,
);
const core = AbacusCore.fromEnvironment(environment, multiProvider);
const core = AbacusCore.fromEnvironment('test', multiProvider);
const randomElement = <T>(list: T[]) =>
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 remoteId = ChainNameToDomainId[remote];
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
// the relayer submitting only greedily
for (let i = 0; i < 10; i++) {

@ -9,7 +9,8 @@ async function check() {
const config = getCoreEnvironmentConfig(environment);
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>(
multiProvider,
core,

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

@ -59,7 +59,7 @@ export async function getMultiProviderFromGCP<Chain extends ChainName>(
}
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) {

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

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

@ -7,15 +7,17 @@ import { getMultiProviderFromConfigAndSigner } from '@abacus-network/deploy/dist
import {
AbacusCore,
ChainMap,
CoreContractAddresses,
CoreContractsMap,
MultiProvider,
objMap,
serializeContracts,
} from '@abacus-network/sdk';
import { environment as testConfig } from '../config/environments/test';
import { TestChains } from '../config/environments/test/chains';
import { AbacusCoreChecker } from '../src/core';
import { AbacusCoreInfraDeployer } from '../src/core/deploy';
import { writeJSON } from '../src/utils/utils';
describe('core', async () => {
const environment = 'test';
@ -23,7 +25,7 @@ describe('core', async () => {
let multiProvider: MultiProvider<TestChains>;
let deployer: AbacusCoreInfraDeployer<TestChains>;
let core: AbacusCore<TestChains>;
let addresses: ChainMap<TestChains, CoreContractAddresses<TestChains, any>>;
let contracts: CoreContractsMap<TestChains>;
let coreConfig: ChainMap<TestChains, CoreConfig>;
let owners: ChainMap<TestChains, string>;
@ -40,18 +42,18 @@ describe('core', async () => {
});
it('deploys', async () => {
addresses = await deployer.deploy(); // TODO: return AbacusApp from AbacusDeployer.deploy()
contracts = await deployer.deploy();
});
it('writes', async () => {
const base = './test/outputs/core';
deployer.writeVerification(path.join(base, 'verification'));
deployer.writeContracts(addresses, path.join(base, 'contracts.ts'));
deployer.writeRustConfigs(environment, path.join(base, 'rust'), addresses);
writeJSON(base, 'contracts.json', serializeContracts(contracts));
writeJSON(base, 'verification.json', deployer.verificationInputs);
deployer.writeRustConfigs(environment, path.join(base, 'rust'), contracts);
});
it('transfers ownership', async () => {
core = new AbacusCore(addresses, multiProvider);
core = new AbacusCore(contracts, 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 { ChainMap, ChainName, Connection } from './types';
import { MultiGeneric, objMap } from './utils';
export class AbacusApp<
Contracts extends IAbacusContracts<any, any>,
Contracts extends AbacusContracts,
Chain extends ChainName = ChainName,
> extends MultiGeneric<Chain, Contracts> {
constructor(
builder: ContractsBuilder<any, Contracts>,
contractAddresses: ChainMap<Chain, any>,
readonly multiProvider: MultiProvider<Chain>,
public contractsMap: ChainMap<Chain, Contracts>,
multiProvider: MultiProvider<Chain>,
) {
super(
objMap(
contractAddresses,
(chain, addresses) =>
new builder(
addresses,
multiProvider.getChainConnection(chain).getConnection()!,
),
const connectedContractsMap = objMap(contractsMap, (chain, contracts) =>
connectContracts(
contracts,
multiProvider.getChainConnection(chain).getConnection(),
),
);
super(connectedContractsMap);
}
public contractsMap = this.chainMap;
getContracts(
chain: Chain,
): Contracts extends IAbacusContracts<any, infer C> ? C : never {
return this.get(chain).contracts;
getContracts(chain: Chain): Contracts {
return this.get(chain);
}
getAddresses(
chain: Chain,
): Contracts extends IAbacusContracts<infer A, any> ? A : never {
return this.get(chain).addresses;
getAddresses(chain: Chain): AbacusAddresses {
return serializeContracts(this.get(chain));
}
reconnect(chain: Chain, connection: Connection): void {
this.get(chain).reconnect(connection);
connectToChain(chain: Chain, connection: Connection): void {
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 { 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 AbacusContractAddresses = {
[key in string]: ProxiedAddress | types.Address;
export type AbacusFactories = {
[key: string]: ethers.ContractFactory;
};
// from concrete ethers.ContractFactory static connect() type
type EthersFactory<C> = (
address: types.Address, // TODO: generic on ProxiedAddress for proxy utilities
connection: Connection,
) => C;
export type Factories<A extends AbacusContractAddresses> = Record<
keyof A,
EthersFactory<any>
>;
export type AbacusContracts = {
[key: Exclude<string, 'address'>]:
| ethers.Contract
| ProxiedContract<any, any>
| AbacusContracts;
};
export interface IAbacusContracts<Addresses, Contracts> {
readonly addresses: Addresses;
readonly contracts: Contracts;
reconnect(connection: Connection): void;
}
export type AbacusAddresses = {
[key: string]: types.Address | ProxyAddresses<any> | AbacusAddresses;
};
export interface ContractsBuilder<
Addresses,
Contracts extends IAbacusContracts<Addresses, any>,
> {
new (addresses: Addresses, connection: Connection): Contracts;
export function serializeContracts(
contractOrObject: AbacusContracts,
): AbacusAddresses {
return objMap(
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);
function getFactory(
key: string,
factories: AbacusFactories,
): ethers.ContractFactory {
if (!(key in factories)) {
throw new Error(`Factories entry missing for ${key}`);
}
return factories[key];
}
reconnect(connection: Connection): void {
Object.values(this.contracts).forEach((contract: Contract) =>
contract.connect(connection),
);
export function buildContracts(
addressOrObject: AbacusAddresses,
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);
}
},
);
}
protected onlySigner(actual: types.Address, expected: types.Address): void {
if (actual !== expected) {
throw new Error(`Signer ${actual} must be ${expected} for this method`);
}
export function connectContracts<Contracts extends AbacusContracts>(
contractOrObject: Contracts,
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;
}
export type RouterAddresses = {
abacusConnectionManager: types.Address;
router: types.Address;
};
export const routerFactories: Factories<RouterAddresses> = {
router: Router__factory.connect,
abacusConnectionManager: AbacusConnectionManager__factory.connect,
};

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

@ -14,123 +14,44 @@ import {
UpgradeBeaconController,
UpgradeBeaconController__factory,
} from '@abacus-network/core';
import { types } from '@abacus-network/utils';
import { IAbacusContracts } from '../contracts';
import {
ChainName,
Connection,
ProxiedAddress,
RemoteChainMap,
Remotes,
} from '../types';
import { objMap } from '../utils';
import { BeaconProxyAddresses, ProxiedContract } from '../proxy';
import { ChainName, RemoteChainMap } from '../types';
type InboxAddress = ProxiedAddress;
type OutboxAddress = ProxiedAddress;
export type MailboxAddresses = (InboxAddress | OutboxAddress) & {
validatorManager: types.Address;
export type InboxContracts = {
inbox: ProxiedContract<Inbox, BeaconProxyAddresses>;
inboxValidatorManager: InboxValidatorManager;
};
export type CoreContractAddresses<N extends ChainName, L extends N> = {
upgradeBeaconController: types.Address;
abacusConnectionManager: types.Address;
interchainGasPaymaster: types.Address;
outbox: MailboxAddresses;
inboxes: RemoteChainMap<N, L, MailboxAddresses>;
const inboxFactories = {
inbox: new Inbox__factory(),
inboxValidatorManager: new InboxValidatorManager__factory(),
};
export type InboxContracts = {
inbox: Inbox;
validatorManager: InboxValidatorManager;
export type OutboxContracts = {
outbox: ProxiedContract<Outbox, BeaconProxyAddresses>;
outboxValidatorManager: OutboxValidatorManager;
};
const outboxFactories = {
outbox: new Outbox__factory(),
outboxValidatorManager: new OutboxValidatorManager__factory(),
};
export type CoreContractSchema<
export type CoreContracts<
Networks extends ChainName,
Local extends Networks,
> = {
abacusConnectionManager: AbacusConnectionManager;
upgradeBeaconController: UpgradeBeaconController;
outbox: {
outbox: Outbox;
validatorManager: OutboxValidatorManager;
};
inboxes: RemoteChainMap<Networks, Local, InboxContracts>;
interchainGasPaymaster: InterchainGasPaymaster;
};
inboxes: RemoteChainMap<Networks, Local, InboxContracts>;
} & OutboxContracts;
export const coreFactories = {
interchainGasPaymaster: InterchainGasPaymaster__factory.connect,
outbox: Outbox__factory.connect,
outboxValidatorManager: OutboxValidatorManager__factory.connect,
inbox: Inbox__factory.connect,
inboxValidatorManager: InboxValidatorManager__factory.connect,
abacusConnectionManager: AbacusConnectionManager__factory.connect,
upgradeBeaconController: UpgradeBeaconController__factory.connect,
interchainGasPaymaster: new InterchainGasPaymaster__factory(),
abacusConnectionManager: new AbacusConnectionManager__factory(),
upgradeBeaconController: new UpgradeBeaconController__factory(),
...inboxFactories,
...outboxFactories,
};
// 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 { addresses as test } from './test';
import { addresses as testnet } from './testnet';
import dev from './dev.json';
import test from './test.json';
import testnet from './testnet.json';
export const environments = {
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 {
CoreContractAddresses,
CoreContracts,
coreFactories,
InboxContracts,
MailboxAddresses,
OutboxContracts,
} from './contracts';
export { environments as coreEnvironments } from './environments';
export {

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

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

@ -2,11 +2,12 @@ export { AbacusApp } from './app';
export { chainMetadata } from './chain-metadata';
export { addSignerToConnection, chainConnectionConfigs } from './chains';
export {
AbacusContractAddresses,
AbacusAddresses,
AbacusContracts,
Factories,
RouterAddresses,
routerFactories,
AbacusFactories,
buildContracts,
connectContracts,
serializeContracts,
} from './contracts';
export {
AbacusCore,
@ -15,13 +16,13 @@ export {
AbacusStatus,
AnnotatedDispatch,
AnnotatedLifecycleEvent,
CoreContractAddresses,
CoreContracts,
CoreContractsMap,
coreEnvironments,
coreFactories,
InboxContracts,
MailboxAddresses,
MessageStatus,
OutboxContracts,
parseMessage,
resolveDomain,
resolveId,
@ -39,6 +40,8 @@ export {
TokenPriceGetter,
} from './gas';
export { ChainConnection, IChainConnection, MultiProvider } from './provider';
export { BeaconProxyAddresses, ProxiedContract, ProxyAddresses } from './proxy';
export { RouterContracts, RouterFactories } from './router';
export {
AllChains,
ChainMap,
@ -49,7 +52,6 @@ export {
Connection,
DomainIdToChainName,
NameOrDomain,
ProxiedAddress,
RemoteChainMap,
Remotes,
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 { types } from '@abacus-network/utils';
import { chainMetadata } from './chain-metadata';
/**
@ -69,9 +67,3 @@ export type ChainMetadata = {
};
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> {
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[];

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

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

Loading…
Cancel
Save