diff --git a/typescript/base/src/domain/types.ts b/typescript/base/src/domain/types.ts index 9b8b905..1720a8a 100644 --- a/typescript/base/src/domain/types.ts +++ b/typescript/base/src/domain/types.ts @@ -1,6 +1,9 @@ -export type ContractAddress = string; +export type ContractAddress = `0x${string}`; export type ContractName = string; export type MainContractAddress = ContractAddress; +export type ContractAddressMap = { + [contractName: ContractName]: ContractAddress +} export interface AbiFragmentType { readonly name?: string; diff --git a/typescript/base/src/instance.ts b/typescript/base/src/instance.ts index 58a55c7..6e27785 100644 --- a/typescript/base/src/instance.ts +++ b/typescript/base/src/instance.ts @@ -1,6 +1,7 @@ import * as semver from "semver"; import { ContractAddress, + ContractAddressMap, ContractName, MainContractAddress, SkaleABIFile @@ -64,7 +65,7 @@ const processPep440 = (pyVersion: Pep440Version) => { export abstract class Instance { protected project: Project; - address: MainContractAddress; + addressContainer: ContractAddressMap; abi: SkaleABIFile | undefined; @@ -72,10 +73,16 @@ export abstract class Instance { constructor ( project: Project, - address: MainContractAddress + addressOrAddressContainer: MainContractAddress | ContractAddressMap ) { this.project = project; - this.address = address; + if (typeof addressOrAddressContainer === "string") { + this.addressContainer = { + [this.project.mainContractName]: addressOrAddressContainer + }; + } else { + this.addressContainer = addressOrAddressContainer; + } } get adapter () { @@ -103,7 +110,7 @@ export abstract class Instance { return this.project.network.adapter.makeCall( { "abi": defaultVersionAbi, - "address": this.address + "address": this.mainContractAddress }, { "args": [], @@ -117,6 +124,10 @@ export abstract class Instance { return abi[contractName]; } + get mainContractAddress () { + return this.addressContainer[this.project.mainContractName]; + } + // Private private async getVersion () { diff --git a/typescript/base/src/project.ts b/typescript/base/src/project.ts index 9610b4f..31ef703 100644 --- a/typescript/base/src/project.ts +++ b/typescript/base/src/project.ts @@ -1,6 +1,10 @@ import * as semver from "semver"; +import { + ContractAddressMap, + MainContractAddress, + SkaleABIFile +} from "./domain/types"; import { Instance, InstanceData } from "./instance"; -import { MainContractAddress, SkaleABIFile } from "./domain/types"; import axios, { HttpStatusCode } from "axios"; import { InstanceNotFound } from "./domain/errors/instance/instanceNotFound"; import { ListedNetwork } from "./listedNetwork"; @@ -34,6 +38,8 @@ export abstract class Project { abstract githubRepo: string; + abstract mainContractName: string; + constructor ( network: Network, metadata: ProjectMetadata @@ -42,11 +48,12 @@ export abstract class Project { this.metadata = metadata; } - getInstance (aliasOrAddress: string) { - if (this.network.adapter.isAddress(aliasOrAddress)) { - return this.getInstanceByAddress(aliasOrAddress); + getInstance (target: string | MainContractAddress | ContractAddressMap) { + if (typeof target === "string" && this.network.adapter.isAddress(target) || typeof target === "object") { + return this.getInstanceByAddress( + target as MainContractAddress | ContractAddressMap); } - return this.getInstanceByAlias(aliasOrAddress); + return this.getInstanceByAlias(target); } async downloadAbiFile (version: string) { @@ -89,12 +96,12 @@ export abstract class Project { throw new NetworkNotFoundError("Network is unknown"); } - abstract createInstance(address: MainContractAddress): + abstract createInstance(address: MainContractAddress | ContractAddressMap): Instance; // Private - private getInstanceByAddress (address: string) { + private getInstanceByAddress (address: MainContractAddress | ContractAddressMap) { return this.createInstance(address); } diff --git a/typescript/base/src/projects/ima/ImaInstance.ts b/typescript/base/src/projects/ima/ImaInstance.ts index 2f80f7f..a3e63d5 100644 --- a/typescript/base/src/projects/ima/ImaInstance.ts +++ b/typescript/base/src/projects/ima/ImaInstance.ts @@ -33,7 +33,7 @@ export abstract class ImaInstance extends return this.project.network.adapter.makeCall( { "abi": messageProxyAbi, - "address": this.address + "address": this.mainContractAddress }, { args, diff --git a/typescript/base/src/projects/ima/mainnet/MainnetImaInstance.ts b/typescript/base/src/projects/ima/mainnet/MainnetImaInstance.ts index 92e614c..1c5bffd 100644 --- a/typescript/base/src/projects/ima/mainnet/MainnetImaInstance.ts +++ b/typescript/base/src/projects/ima/mainnet/MainnetImaInstance.ts @@ -1,4 +1,5 @@ import { ContractData } from "../../../adapter"; +import { ContractAddress } from "../../../domain/types"; import { ImaInstance } from "../ImaInstance"; @@ -29,9 +30,9 @@ export class MainnetImaInstance extends ImaInstance { private contractManager: ContractData | undefined; - async getContractAddress (name: string): Promise { + async getContractAddress (name: string): Promise { if (name === "MessageProxyForMainnet") { - return Promise.resolve(this.address); + return Promise.resolve(this.mainContractAddress); } else if (name === "CommunityPool") { return this.project.network.adapter.makeCall( { @@ -43,7 +44,7 @@ export class MainnetImaInstance extends "args": [], "functionName": "communityPool" } - ) as Promise; + ) as Promise; } return this.project.network.adapter.makeCall( await this.getContractManager(), @@ -51,7 +52,7 @@ export class MainnetImaInstance extends "args": [name], "functionName": "getContract" } - ) as Promise; + ) as Promise; } // Private @@ -63,7 +64,7 @@ export class MainnetImaInstance extends { "abi": await this.getContractAbi("MessageProxyForMainnet"), - "address": this.address + "address": this.mainContractAddress }, { "args": [], diff --git a/typescript/base/src/projects/ima/mainnet/MainnetImaProject.ts b/typescript/base/src/projects/ima/mainnet/MainnetImaProject.ts index 7b15055..db16b65 100644 --- a/typescript/base/src/projects/ima/mainnet/MainnetImaProject.ts +++ b/typescript/base/src/projects/ima/mainnet/MainnetImaProject.ts @@ -1,17 +1,21 @@ +import { ContractAddressMap, MainContractAddress } from "../../../domain/types"; import { ImaProject } from "../ImaProject"; import { Instance } from "../../../instance"; import { MainnetImaInstance } from "./MainnetImaInstance"; export class MainnetImaProject extends ImaProject { + mainContractName = "MessageProxyForMainnet"; + getAbiFilename (version: string) { return `${this.metadata.name}-${version}-abi.json`; } - createInstance (address: string): Instance { + createInstance (target: MainContractAddress | ContractAddressMap) + : Instance { return new MainnetImaInstance( this, - address + target ); } } diff --git a/typescript/base/src/projects/ima/schain/SchainImaInstance.ts b/typescript/base/src/projects/ima/schain/SchainImaInstance.ts index b130074..e4a76ec 100644 --- a/typescript/base/src/projects/ima/schain/SchainImaInstance.ts +++ b/typescript/base/src/projects/ima/schain/SchainImaInstance.ts @@ -1,3 +1,4 @@ +import { ContractAddress } from "../../../domain/types"; import { ImaInstance } from "../ImaInstance"; @@ -46,13 +47,13 @@ export class SchainImaInstance extends ] ]); - getContractAddress (name: string): Promise { - if (name === "MessageProxyForSchain") { - return Promise.resolve(this.address); + getContractAddress (name: string): Promise { + if (name in this.addressContainer) { + return Promise.resolve(this.addressContainer[name]); } if (SchainImaInstance.PREDEPLOYED.has(name)) { return Promise.resolve(SchainImaInstance.PREDEPLOYED. - get(name) as string); + get(name) as ContractAddress); } throw new Error(`Can't get address of ${name} contract`); } diff --git a/typescript/base/src/projects/ima/schain/SchainImaProject.ts b/typescript/base/src/projects/ima/schain/SchainImaProject.ts index 9a4fd24..fc881f3 100644 --- a/typescript/base/src/projects/ima/schain/SchainImaProject.ts +++ b/typescript/base/src/projects/ima/schain/SchainImaProject.ts @@ -1,3 +1,8 @@ +import { + ContractAddress, + ContractAddressMap, + MainContractAddress +} from "../../../domain/types"; import { ImaProject } from "../ImaProject"; import { Instance } from "../../../instance"; import { PREDEPLOYED_ALIAS } from "../../../domain/constants"; @@ -5,22 +10,25 @@ import { SchainImaInstance } from "./SchainImaInstance"; export class SchainImaProject extends ImaProject { + mainContractName = "MessageProxyForSchain"; + getAbiFilename (version: string) { return `${this.metadata.name}-${version}-abi.json`; } - getInstance (aliasOrAddress: string) { - if (aliasOrAddress === PREDEPLOYED_ALIAS) { + getInstance (target: string | MainContractAddress | ContractAddressMap) { + if (target === PREDEPLOYED_ALIAS) { return this.createInstance(SchainImaInstance.PREDEPLOYED. - get("MessageProxyForSchain")!); + get("MessageProxyForSchain")! as ContractAddress); } - return super.getInstance(aliasOrAddress); + return super.getInstance(target); } - createInstance (address: string): Instance { + createInstance (target: MainContractAddress | ContractAddressMap) + : Instance { return new SchainImaInstance( this, - address + target ); } } diff --git a/typescript/base/src/projects/paymaster/paymasterInstance.ts b/typescript/base/src/projects/paymaster/paymasterInstance.ts index d8318e9..a0781f8 100644 --- a/typescript/base/src/projects/paymaster/paymasterInstance.ts +++ b/typescript/base/src/projects/paymaster/paymasterInstance.ts @@ -12,7 +12,7 @@ export class PaymasterInstance extends "Paymaster", "FastForwardPaymaster" ].includes(name)) { - return this.address; + return this.mainContractAddress; } if (name === "PaymasterAccessManager") { return await this.callPaymaster( @@ -29,7 +29,7 @@ export class PaymasterInstance extends return this.project.network.adapter.makeCall( { "abi": await this.getContractAbi("Paymaster"), - "address": this.address + "address": this.mainContractAddress }, { args, diff --git a/typescript/base/src/projects/paymaster/paymasterProject.ts b/typescript/base/src/projects/paymaster/paymasterProject.ts index 94991ab..5eac072 100644 --- a/typescript/base/src/projects/paymaster/paymasterProject.ts +++ b/typescript/base/src/projects/paymaster/paymasterProject.ts @@ -1,3 +1,4 @@ +import { ContractAddressMap, MainContractAddress } from "../../domain/types"; import { Instance } from "../../instance"; import { PaymasterInstance } from "./paymasterInstance"; import { Project } from "../../project"; @@ -6,7 +7,10 @@ export class PaymasterProject extends Project { githubRepo = "https://github.com/skalenetwork/paymaster/"; - createInstance (address: string): Instance { + mainContractName = "Paymaster"; + + createInstance (address: MainContractAddress | ContractAddressMap) + : Instance { return new PaymasterInstance( this, address diff --git a/typescript/base/src/projects/skale-allocator/skaleAllocatorInstance.ts b/typescript/base/src/projects/skale-allocator/skaleAllocatorInstance.ts index b223498..c032db2 100644 --- a/typescript/base/src/projects/skale-allocator/skaleAllocatorInstance.ts +++ b/typescript/base/src/projects/skale-allocator/skaleAllocatorInstance.ts @@ -12,7 +12,7 @@ export class SkaleAllocatorInstance extends args?: unknown[] ): Promise { if (name === "Allocator") { - return Promise.resolve(this.address); + return Promise.resolve(this.mainContractAddress); } if (name === "Escrow") { const firstArgument = 0; diff --git a/typescript/base/src/projects/skale-allocator/skaleAllocatorProject.ts b/typescript/base/src/projects/skale-allocator/skaleAllocatorProject.ts index 949cafb..359d032 100644 --- a/typescript/base/src/projects/skale-allocator/skaleAllocatorProject.ts +++ b/typescript/base/src/projects/skale-allocator/skaleAllocatorProject.ts @@ -1,3 +1,4 @@ +import { ContractAddressMap, MainContractAddress } from "../../domain/types"; import { Instance } from "../../instance"; import { Project } from "../../project"; import { SkaleAllocatorInstance } from "./skaleAllocatorInstance"; @@ -6,7 +7,10 @@ export class SkaleAllocatorProject extends Project { githubRepo = "https://github.com/skalenetwork/skale-allocator/"; - createInstance (address: string): Instance { + mainContractName = "SkaleAllocator"; + + createInstance (address: MainContractAddress | ContractAddressMap) + : Instance { return new SkaleAllocatorInstance( this, address diff --git a/typescript/base/src/projects/skale-manager/skaleManagerInstance.ts b/typescript/base/src/projects/skale-manager/skaleManagerInstance.ts index 34990d3..d9e45b2 100644 --- a/typescript/base/src/projects/skale-manager/skaleManagerInstance.ts +++ b/typescript/base/src/projects/skale-manager/skaleManagerInstance.ts @@ -1,6 +1,7 @@ import { ContractAddress, - ContractName + ContractName, + MainContractAddress } from "../../domain/types"; import { Instance } from "../../instance"; @@ -72,7 +73,7 @@ export class SkaleManagerInstance extends "args": [this.actualName(name)], "functionName": "getContract" } - ) as string; + ) as MainContractAddress; } // Private @@ -88,7 +89,7 @@ export class SkaleManagerInstance extends return this.project.network.adapter.makeCall( { "abi": skaleManagerAbi, - "address": this.address + "address": this.mainContractAddress }, { args, diff --git a/typescript/base/src/projects/skale-manager/skaleManagerProject.ts b/typescript/base/src/projects/skale-manager/skaleManagerProject.ts index e425ff7..c3894b9 100644 --- a/typescript/base/src/projects/skale-manager/skaleManagerProject.ts +++ b/typescript/base/src/projects/skale-manager/skaleManagerProject.ts @@ -1,3 +1,4 @@ +import { ContractAddressMap, MainContractAddress } from "../../domain/types"; import { Instance } from "../../instance"; import { Project } from "../../project"; import { SkaleManagerInstance } from "./skaleManagerInstance"; @@ -6,7 +7,10 @@ export class SkaleManagerProject extends Project { githubRepo = "https://github.com/skalenetwork/skale-manager/"; - createInstance (address: string): Instance { + mainContractName = "SkaleManager"; + + createInstance (address: MainContractAddress | ContractAddressMap) + : Instance { return new SkaleManagerInstance( this, address