Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add skale-allocator project #45

Merged
merged 4 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion typescript/base/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = {
rules: {
"object-curly-spacing": [ "error", "always" ],
"padded-blocks": [ "error", "never" ],
"one-var": ["error", "consecutive"]
"one-var": ["error", "never"]
},
ignorePatterns: [
"lib/**",
Expand Down
42 changes: 38 additions & 4 deletions typescript/base/src/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ export type InstanceData = {
[contractName: string]: MainContractAddress
}

const defaultVersionAbi = [
{
"constant": true,
"inputs": [],
"name": "version",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
];

export abstract class Instance<ContractType> {
protected project: Project<ContractType>;

Expand All @@ -31,18 +48,35 @@ export abstract class Instance<ContractType> {
return this.project.network.adapter;
}

abstract getContractAddress(name: ContractName): Promise<ContractAddress>;
abstract getContractAddress(
name: ContractName,
args?: unknown[]
): Promise<ContractAddress>;

async getContract (name: ContractName) {
async getContract (name: ContractName, args?: unknown[]) {
return this.adapter.createContract(
await this.getContractAddress(name),
await this.getContractAddress(
name,
args
),
await this.getContractAbi(name)
);
}

// Protected

protected abstract queryVersion(): Promise<string>;
protected queryVersion () {
return this.project.network.adapter.makeCall(
{
"abi": defaultVersionAbi,
"address": this.address
},
{
"args": [],
"functionName": "version"
}
) as Promise<string>;
}

protected async getContractAbi (contractName: string) {
const abi = await this.getAbi();
Expand Down
10 changes: 10 additions & 0 deletions typescript/base/src/projects/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Project } from "../project";
import {
ProjectNotFoundError
} from "../domain/errors/project/projectNotFoundError";
import { SkaleAllocatorProject } from "./skale-allocator/skaleAllocatorProject";
import { SkaleManagerProject } from "./skale-manager/skaleManagerProject";


Expand All @@ -12,6 +13,10 @@ export const projects = {
"name": "mainnet-ima",
"path": "mainnet-ima"
},
"skaleAllocator": {
"name": "skale-allocator",
"path": "skale-allocator"
},
"skaleManager": {
"name": "skale-manager",
"path": "skale-manager"
Expand All @@ -33,6 +38,11 @@ export const createProject =
network,
projects.mainnetIma
);
} else if (name === projects.skaleAllocator.name) {
return new SkaleAllocatorProject<ContractType>(
network,
projects.skaleAllocator
);
}
throw new ProjectNotFoundError(`Project with name ${name} is unknown`);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
ContractAddress,
ContractName
} from "../../domain/types";
import { Instance } from "../../instance";


export class SkaleAllocatorInstance<ContractType> extends
Instance<ContractType> {
getContractAddress (
name: ContractName,
args?: unknown[]
): Promise<ContractAddress> {
if (name === "Allocator") {
return Promise.resolve(this.address);
}
if (name === "Escrow") {
const firstArgument = 0;
const beneficiary = args?.at(firstArgument) as string;
if (!this.project.network.adapter.isAddress(beneficiary)) {
throw Error("Beneficiary is not set");
}
return this.getEscrow(beneficiary);
}
throw new Error(`Contract ${name} is not found`);
}

// Private

private async getEscrow (beneficiary: string) {
const allocatorAddress = await this.getContractAddress("Allocator");
const allocatorAbi = await this.getContractAbi("Allocator");

return await this.project.network.adapter.makeCall(
{
"abi": allocatorAbi,
"address": allocatorAddress
},
{
"args": [beneficiary],
"functionName": "getEscrowAddress"
}
) as ContractAddress;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Instance } from "../../instance";
import { Project } from "../../project";
import { SkaleAllocatorInstance } from "./skaleAllocatorInstance";

export class SkaleAllocatorProject<ContractType> extends
Project<ContractType> {
githubRepo = "https://github.com/skalenetwork/skale-allocator/";

createInstance (address: string): Instance<ContractType> {
return new SkaleAllocatorInstance(
this,
address
);
}

getAbiFilename (version: string) {
return `${this.metadata.name}-${version}-abi.json`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ export class SkaleManagerInstance<ContractType> extends

async getContractAddress (name: ContractName): Promise<ContractAddress> {
const contractManagerAbi =
await this.getContractAbi("ContractManager"),
contractManagerAddress = await this.callSkaleManager(
"contractManager",
[]
) as string;
await this.getContractAbi("ContractManager");
const contractManagerAddress = await this.callSkaleManager(
"contractManager",
[]
) as string;

return await this.project.network.adapter.makeCall(
{
Expand Down
16 changes: 7 additions & 9 deletions typescript/base/src/retryAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Adapter, ContractData, FunctionCall } from "./adapter";
import { Abi } from "./domain/types";

const
defaultRetryCount = 100,
maxDelayMs = 5000,
minDelayMs = 10,
slowDownCoefficient = 2,
speedUpCoefficient = 1.5;
const defaultRetryCount = 100;
const maxDelayMs = 5000;
const minDelayMs = 10;
const slowDownCoefficient = 2;
const speedUpCoefficient = 1.5;


export class RetryAdapter<ContractType> implements Adapter<ContractType> {
Expand Down Expand Up @@ -83,9 +82,8 @@ export class RetryAdapter<ContractType> implements Adapter<ContractType> {
}

private async waitIfNeeded () {
const
now = Date.now(),
timeFromPreviousCall = now - this.previousCallTimestampMs;
const now = Date.now();
const timeFromPreviousCall = now - this.previousCallTimestampMs;
this.previousCallTimestampMs = now;

if (timeFromPreviousCall < this.delayMs) {
Expand Down
23 changes: 11 additions & 12 deletions typescript/ethers-v5/src/ethers5Adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ export class Ethers5Adapter implements Adapter<BaseContract> {
contract: ContractData,
targetFunction: FunctionCall
): Promise<unknown> {
const
contractInterface = new ethers.utils.Interface(contract.abi),
[result] = contractInterface.decodeFunctionResult(
targetFunction.functionName,
await this.provider.call({
"data": contractInterface.encodeFunctionData(
targetFunction.functionName,
targetFunction.args
),
"to": contract.address
})
);
const contractInterface = new ethers.utils.Interface(contract.abi);
const [result] = contractInterface.decodeFunctionResult(
targetFunction.functionName,
await this.provider.call({
"data": contractInterface.encodeFunctionData(
targetFunction.functionName,
targetFunction.args
),
"to": contract.address
})
);
return result;
}

Expand Down
23 changes: 11 additions & 12 deletions typescript/ethers-v6/src/ethers6Adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,17 @@ export class Ethers6Adapter implements Adapter<BaseContract> {
contract: ContractData,
targetFunction: FunctionCall
): Promise<unknown> {
const
contractInterface = new ethers.Interface(contract.abi),
[result] = contractInterface.decodeFunctionResult(
targetFunction.functionName,
await this.provider.call({
"data": contractInterface.encodeFunctionData(
targetFunction.functionName,
targetFunction.args
),
"to": contract.address
})
);
const contractInterface = new ethers.Interface(contract.abi);
const [result] = contractInterface.decodeFunctionResult(
targetFunction.functionName,
await this.provider.call({
"data": contractInterface.encodeFunctionData(
targetFunction.functionName,
targetFunction.args
),
"to": contract.address
})
);
return result;
}

Expand Down
Loading