ees-sdk
Version:
SDK for EES (Ethereum Execution Service)
717 lines (716 loc) • 32.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EESSDK = void 0;
const viem_1 = require("viem");
const coordinator_1 = require("./abis/coordinator");
const jobRegistry_1 = require("./abis/jobRegistry");
const querier_1 = require("./abis/querier");
const configProvider_1 = require("./abis/configProvider");
const chainlinkOracle_1 = require("./abis/chainlinkOracle");
const batchSlasher_1 = require("./abis/batchSlasher");
class EESSDK {
constructor(publicClient, walletClient, simulateBeforeWrite = true) {
this.publicClient = publicClient;
this.walletClient = walletClient;
}
static async init(configProviderAddress, publicClient, walletClient) {
if (walletClient && walletClient.chain?.id !== publicClient.chain?.id)
throw new Error('Chain ID mismatch between public client and wallet client.');
const instance = new EESSDK(publicClient, walletClient);
await instance.fetchAndSetConfig(configProviderAddress);
return instance;
}
async fetchAndSetConfig(configProviderAddress) {
const config = await this.publicClient.readContract({
address: configProviderAddress,
abi: configProvider_1.configProviderAbi,
functionName: 'getConfig',
});
if (!config)
throw new Error('Failed to fetch protocol config.');
const decodedAddresses = (0, viem_1.decodeAbiParameters)([
{ name: 'jobRegistry', type: 'address' },
{ name: 'coordinator', type: 'address' },
{ name: 'querier', type: 'address' },
{ name: 'batchSlasher', type: 'address' }
], config[0]);
const decodedJobRegistryConfig = (0, viem_1.decodeAbiParameters)([
{ name: 'executionGasOverhead', type: 'uint256' }
], config[1]);
const decodedcoordinatorConfig = (0, viem_1.decodeAbiParameters)([
{ name: 'stakingToken', type: 'address' },
{ name: 'stakingAmountPerModule', type: 'uint256' },
{ name: 'minimumRegistrationPeriod', type: 'uint256' },
{ name: 'stakingBalanceThresholdPerModule', type: 'uint256' },
{ name: 'inactiveSlashingAmountPerModule', type: 'uint256' },
{ name: 'commitSlashingAmountPerModule', type: 'uint256' },
{ name: 'roundsPerEpoch', type: 'uint8' },
{ name: 'roundDuration', type: 'uint8' },
{ name: 'roundBuffer', type: 'uint8' },
{ name: 'slashingDuration', type: 'uint8' },
{ name: 'commitPhaseDuration', type: 'uint8' },
{ name: 'revealPhaseDuration', type: 'uint8' },
{ name: 'modulesLength', type: 'uint256' },
{ name: 'executionTax', type: 'uint256' },
{ name: 'zeroFeeExecutionTax', type: 'uint256' },
{ name: 'protocolPoolCutBps', type: 'uint256' }
], config[2]);
this.protocolConfig = {
jobRegistry: decodedAddresses[0],
coordinator: decodedAddresses[1],
querier: decodedAddresses[2],
batchSlasher: decodedAddresses[3],
executionGasOverhead: decodedJobRegistryConfig[0],
stakingToken: decodedcoordinatorConfig[0],
stakingAmountPerModule: decodedcoordinatorConfig[1],
minimumRegistrationPeriod: decodedcoordinatorConfig[2],
stakingBalanceThresholdPerModule: decodedcoordinatorConfig[3],
inactiveSlashingAmountPerModule: decodedcoordinatorConfig[4],
commitSlashingAmountPerModule: decodedcoordinatorConfig[5],
roundsPerEpoch: decodedcoordinatorConfig[6],
roundDuration: decodedcoordinatorConfig[7],
roundBuffer: decodedcoordinatorConfig[8],
slashingDuration: decodedcoordinatorConfig[9],
commitPhaseDuration: decodedcoordinatorConfig[10],
revealPhaseDuration: decodedcoordinatorConfig[11],
selectionPhaseDuration: decodedcoordinatorConfig[10] + decodedcoordinatorConfig[11],
totalRoundDuration: decodedcoordinatorConfig[7] + decodedcoordinatorConfig[8],
epochDuration: (decodedcoordinatorConfig[10] + decodedcoordinatorConfig[11]) + (decodedcoordinatorConfig[7] + decodedcoordinatorConfig[8]) * decodedcoordinatorConfig[6] + decodedcoordinatorConfig[9],
modulesLength: decodedcoordinatorConfig[12],
executionTax: decodedcoordinatorConfig[13],
zeroFeeExecutionTax: decodedcoordinatorConfig[14],
protocolPoolCutBps: decodedcoordinatorConfig[15]
};
}
async getAllowance(token, allower, spender) {
this.checkProtocolConfig();
const allowance = await this.publicClient.readContract({
address: token,
abi: viem_1.erc20Abi,
functionName: 'allowance',
args: [allower, spender]
});
return allowance;
}
async getBalance(token, account) {
this.checkProtocolConfig();
const balance = await this.publicClient.readContract({
address: token,
abi: viem_1.erc20Abi,
functionName: 'balanceOf',
args: [account]
});
return balance;
}
getProtocolConfig() {
this.checkProtocolConfig();
return this.protocolConfig;
}
checkProtocolConfig() {
if (!this.protocolConfig) {
throw new Error('Protocol config not initialized. Make sure to call init() first.');
}
}
async getTokenPrice(oracleAddress, token, auxData) {
this.checkProtocolConfig();
const data = await this.publicClient.readContract({
address: oracleAddress,
abi: chainlinkOracle_1.chainlinkOracleAbi,
functionName: 'getPrice',
args: [token, auxData]
});
return data;
}
async getJobsArrayLength() {
this.checkProtocolConfig();
const data = await this.publicClient.readContract({
address: this.protocolConfig.jobRegistry,
abi: jobRegistry_1.jobRegistryAbi,
functionName: 'getJobsArrayLength'
});
return data;
}
async getJobs(indices) {
this.checkProtocolConfig();
const data = await this.publicClient.readContract({
address: this.protocolConfig.querier,
abi: querier_1.querierAbi,
functionName: 'getJobs',
args: [indices]
});
const jobs = [];
for (let i = 0; i < data.length; i++) {
const job = this.formatJobData(indices[i], data[i]);
jobs.push(job);
}
return jobs;
}
async executeTransaction(contractCall, options) {
if (!this.walletClient)
throw new Error('Wallet client not provided.');
let txHash;
if (options?.simulate !== false) {
const { request } = await this.publicClient.simulateContract({
...contractCall,
chain: this.walletClient.chain,
account: this.walletClient.account,
...options
});
if (!request)
throw new Error(`Failed to simulate ${contractCall.functionName}.`);
txHash = await this.walletClient.writeContract(request);
}
else {
txHash = await this.walletClient.writeContract({
...contractCall,
chain: this.walletClient.chain,
account: this.walletClient.account,
...options
});
}
if (options?.waitForReceipt !== false) {
const transactionReceipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });
return { transactionHash: txHash, transactionReceipt };
}
else {
return { transactionHash: txHash };
}
}
async createJob(jobSpecification, sponsor, sponsorSignature, ownerSignature, index, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.jobRegistry,
abi: jobRegistry_1.jobRegistryAbi,
functionName: 'createJob',
args: [jobSpecification, sponsor, sponsorSignature, ownerSignature, index],
}, options);
let jobIndex;
if (result.transactionReceipt) {
const jobCreatedEvent = result.transactionReceipt.logs
.find(log => log.address.toLowerCase() === this.protocolConfig.jobRegistry.toLowerCase() &&
log.topics[0] === (0, viem_1.keccak256)((0, viem_1.toBytes)('JobCreated(uint256,address,address,bool)')));
if (jobCreatedEvent && jobCreatedEvent.topics[1]) {
jobIndex = BigInt(jobCreatedEvent.topics[1]);
}
}
return {
transactionHash: result.transactionHash,
transactionReceipt: result.transactionReceipt,
jobIndex
};
}
async deleteJob(index, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.jobRegistry,
abi: jobRegistry_1.jobRegistryAbi,
functionName: 'deleteJob',
args: [index],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
watchCreatedJobs(application, onCreatedJob) {
this.checkProtocolConfig();
const unwatch = this.publicClient.watchEvent({
address: this.protocolConfig.jobRegistry,
event: (0, viem_1.parseAbiItem)('event JobCreated(uint256 indexed index, address indexed owner, address indexed application)'),
args: {
application: application
},
onLogs: logs => {
for (const log of logs) {
onCreatedJob(log.args.index);
}
}
});
return unwatch;
}
watchExecutedJobs(application, onExecutedJob) {
this.checkProtocolConfig();
const unwatch = this.publicClient.watchEvent({
address: this.protocolConfig.jobRegistry,
event: (0, viem_1.parseAbiItem)('event JobExecuted(uint256 indexed index,address indexed owner,address indexed application,uint256 executionFee,address executionFeeToken)'),
args: {
application: application
},
onLogs: logs => {
for (const log of logs) {
onExecutedJob(log.args.index);
}
}
});
return unwatch;
}
watchDeletedJobs(application, onDeletedJob) {
this.checkProtocolConfig();
const unwatch = this.publicClient.watchEvent({
address: this.protocolConfig.jobRegistry,
event: (0, viem_1.parseAbiItem)('event JobDeleted(uint256 indexed index, address indexed owner, address indexed application)'),
args: {
application: application
},
onLogs: logs => {
for (const log of logs) {
onDeletedJob(log.args.index);
}
}
});
return unwatch;
}
async signJobSpecificationSponsor(jobSpecification) {
this.checkProtocolConfig();
if (!this.walletClient)
throw new Error('Wallet client not provided.');
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "JobRegistry",
chainId: this.walletClient.chain.id,
verifyingContract: this.protocolConfig.jobRegistry,
},
types: {
JobSpecification: [
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
{ name: 'reusableNonce', type: 'bool' },
{ name: 'sponsorFallbackToOwner', type: 'bool' },
{ name: 'sponsorCanUpdateFeeModule', type: 'bool' },
{ name: 'application', type: 'address' },
{ name: 'executionWindow', type: 'uint24' },
{ name: 'zeroFeeWindow', type: 'uint24' },
{ name: 'maxExecutions', type: 'uint48' },
{ name: 'ignoreAppRevert', type: 'bool' },
{ name: 'executionModule', type: 'bytes1' },
{ name: 'feeModule', type: 'bytes1' },
{ name: 'executionModuleInputHash', type: 'bytes32' },
{ name: 'feeModuleInputHash', type: 'bytes32' },
{ name: 'applicationInputHash', type: 'bytes32' }
],
},
primaryType: 'JobSpecification',
message: {
nonce: jobSpecification.nonce,
deadline: jobSpecification.deadline,
reusableNonce: jobSpecification.reusableNonce,
sponsorFallbackToOwner: jobSpecification.sponsorFallbackToOwner,
sponsorCanUpdateFeeModule: jobSpecification.sponsorCanUpdateFeeModule,
application: jobSpecification.application,
executionWindow: jobSpecification.executionWindow,
zeroFeeWindow: jobSpecification.zeroFeeWindow,
maxExecutions: jobSpecification.maxExecutions,
ignoreAppRevert: jobSpecification.ignoreAppRevert,
executionModule: jobSpecification.executionModule,
feeModule: jobSpecification.feeModule,
executionModuleInputHash: (0, viem_1.keccak256)(jobSpecification.executionModuleInput),
feeModuleInputHash: (0, viem_1.keccak256)(jobSpecification.feeModuleInput),
applicationInputHash: (0, viem_1.keccak256)(jobSpecification.applicationInput)
},
});
return signature;
}
async signJobSpecificationOwner(jobSpecification) {
this.checkProtocolConfig();
if (!this.walletClient)
throw new Error('Wallet client not provided.');
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "JobRegistry",
chainId: this.walletClient.chain.id,
verifyingContract: this.protocolConfig.jobRegistry,
},
types: {
JobSpecification: [
{ name: 'owner', type: 'address' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
{ name: 'reusableNonce', type: 'bool' },
{ name: 'sponsorFallbackToOwner', type: 'bool' },
{ name: 'sponsorCanUpdateFeeModule', type: 'bool' },
{ name: 'application', type: 'address' },
{ name: 'executionWindow', type: 'uint24' },
{ name: 'zeroFeeWindow', type: 'uint24' },
{ name: 'maxExecutions', type: 'uint48' },
{ name: 'ignoreAppRevert', type: 'bool' },
{ name: 'executionModule', type: 'bytes1' },
{ name: 'feeModule', type: 'bytes1' },
{ name: 'executionModuleInputHash', type: 'bytes32' },
{ name: 'feeModuleInputHash', type: 'bytes32' },
{ name: 'applicationInputHash', type: 'bytes32' }
],
},
primaryType: 'JobSpecification',
message: {
owner: jobSpecification.owner,
nonce: jobSpecification.nonce,
deadline: jobSpecification.deadline,
reusableNonce: jobSpecification.reusableNonce,
sponsorFallbackToOwner: jobSpecification.sponsorFallbackToOwner,
sponsorCanUpdateFeeModule: jobSpecification.sponsorCanUpdateFeeModule,
application: jobSpecification.application,
executionWindow: jobSpecification.executionWindow,
zeroFeeWindow: jobSpecification.zeroFeeWindow,
maxExecutions: jobSpecification.maxExecutions,
ignoreAppRevert: jobSpecification.ignoreAppRevert,
executionModule: jobSpecification.executionModule,
feeModule: jobSpecification.feeModule,
executionModuleInputHash: (0, viem_1.keccak256)(jobSpecification.executionModuleInput),
feeModuleInputHash: (0, viem_1.keccak256)(jobSpecification.feeModuleInput),
applicationInputHash: (0, viem_1.keccak256)(jobSpecification.applicationInput)
},
});
return signature;
}
async signFeeModuleInput(feeModuleInput) {
this.checkProtocolConfig();
if (!this.walletClient)
throw new Error('Wallet client not provided.');
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "JobRegistry",
chainId: this.walletClient.chain.id,
verifyingContract: this.protocolConfig.jobRegistry,
},
types: {
FeeModuleInput: [
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
{ name: 'index', type: 'uint256' },
{ name: 'feeModule', type: 'bytes1' },
{ name: 'feeModuleInputHash', type: 'bytes32' },
],
},
primaryType: 'FeeModuleInput',
message: {
nonce: feeModuleInput.nonce,
deadline: feeModuleInput.deadline,
index: feeModuleInput.index,
feeModule: feeModuleInput.feeModule,
feeModuleInputHash: (0, viem_1.keccak256)(feeModuleInput.feeModuleInput)
},
});
return signature;
}
async getExecutorInfo(executors) {
this.checkProtocolConfig();
const data = await this.publicClient.readContract({
address: this.protocolConfig.querier,
abi: querier_1.querierAbi,
functionName: 'getExecutors',
args: [executors]
});
return data.map(obj => obj);
}
async getEpochInfo() {
this.checkProtocolConfig();
const data = await this.publicClient.readContract({
address: this.protocolConfig.querier,
abi: querier_1.querierAbi,
functionName: 'getCurrentEpochInfo'
});
const epochStartTime = data[1] - BigInt(this.protocolConfig.epochDuration);
const revealPhaseStartTime = epochStartTime + BigInt(this.protocolConfig.commitPhaseDuration);
const roundsStartTime = revealPhaseStartTime + BigInt(this.protocolConfig.revealPhaseDuration);
const roundPeriods = [];
const roundBufferPeriods = [];
for (let i = 0; i < this.protocolConfig.roundsPerEpoch; i++) {
const midTime = roundsStartTime + BigInt(this.protocolConfig.roundDuration) + BigInt(i) * (BigInt(this.protocolConfig.roundDuration) + BigInt(this.protocolConfig.roundBuffer));
roundPeriods.push([midTime - BigInt(this.protocolConfig.roundDuration), midTime]);
roundBufferPeriods.push([midTime, midTime + BigInt(this.protocolConfig.roundBuffer)]);
}
const epochInfo = {
epoch: data[0],
epochPeriod: [epochStartTime, data[1]],
seed: data[2],
numberOfActiveExecutors: data[3],
commitPhasePeriod: [epochStartTime, revealPhaseStartTime],
revealPhasePeriod: [revealPhaseStartTime, roundsStartTime],
roundPeriods: roundPeriods,
roundBufferPeriods: roundBufferPeriods,
slashingPhasePeriod: [data[1] - BigInt(this.protocolConfig.slashingDuration), data[1]],
selectedExecutors: data[4],
epochPoolBalance: data[5],
nextEpochPoolBalance: data[6]
};
return epochInfo;
}
async getCommitData(executors) {
this.checkProtocolConfig();
const data = await this.publicClient.readContract({
address: this.protocolConfig.querier,
abi: querier_1.querierAbi,
functionName: 'getCommitData',
args: [executors]
});
return executors.map((executor, index) => ({
executor,
...data[index]
}));
}
async executeBatch(indices, gasLimits, feeRecipient, jobRegistryIndex, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'executeBatch',
args: [indices, gasLimits, feeRecipient, jobRegistryIndex],
}, options);
let failedIndices;
if (result.transactionReceipt) {
const batchExecutionEvent = result.transactionReceipt.logs
.find(log => log.address.toLowerCase() === this.protocolConfig.coordinator.toLowerCase() &&
log.topics[0] === (0, viem_1.keccak256)((0, viem_1.toBytes)('BatchExecution(uint256[])')));
if (batchExecutionEvent && batchExecutionEvent.data) {
failedIndices = [...(0, viem_1.decodeAbiParameters)([{ type: 'uint256[]' }], batchExecutionEvent.data)[0]];
}
}
return {
transactionHash: result.transactionHash,
transactionReceipt: result.transactionReceipt,
failedIndices
};
}
async estimateBatchExecutionGas(indices, gasLimits, feeRecipient, jobRegistryIndex) {
this.checkProtocolConfig();
const gas = await this.publicClient.estimateContractGas({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'executeBatch',
args: [indices, gasLimits, feeRecipient, jobRegistryIndex],
});
return gas;
}
async estimateExecutionGas(index, feeRecipient) {
this.checkProtocolConfig();
const gas = await this.publicClient.estimateContractGas({
address: this.protocolConfig.jobRegistry,
abi: jobRegistry_1.jobRegistryAbi,
functionName: 'execute',
args: [index, feeRecipient],
account: this.protocolConfig.coordinator
});
return gas;
}
async revokeSponsorship(index, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.jobRegistry,
abi: jobRegistry_1.jobRegistryAbi,
functionName: 'revokeSponsorship',
args: [index],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async approveFeeToken(token, amount, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: token,
abi: viem_1.erc20Abi,
functionName: 'approve',
args: [this.protocolConfig.jobRegistry, amount],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async approveAppToken(application, token, amount, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: token,
abi: viem_1.erc20Abi,
functionName: 'approve',
args: [application, amount],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async approveStakingToken(amount, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.stakingToken,
abi: viem_1.erc20Abi,
functionName: 'approve',
args: [this.protocolConfig.coordinator, amount],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async calculateCurrentFee(job) {
const currentTime = BigInt(Math.floor(Date.now() / 1000));
if (currentTime >= job.nextExecution) {
const timeSinceNextExecution = currentTime - job.nextExecution;
if (timeSinceNextExecution < job.executionWindow) {
if (job.feeModuleCode === "0x01") {
const feeDiff = job.feeModule.maxExecutionFee - job.feeModule.minExecutionFee;
const fee = ((feeDiff * timeSinceNextExecution) / (BigInt(job.executionWindow) - 1n)) + job.feeModule.minExecutionFee;
return { fee: fee, token: job.feeModule.executionFeeToken };
}
}
}
return null;
}
async initiateEpoch(options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'initiateEpoch',
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async stake(modules, options) {
this.checkProtocolConfig();
const bitset = this.modulesToBitset(modules);
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'stake',
args: [bitset],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async unstake(options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'unstake',
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async topup(amount, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'topup',
args: [amount],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async commit(epoch, options) {
this.checkProtocolConfig();
const msgHash = (0, viem_1.keccak256)((0, viem_1.encodePacked)(['uint192', 'uint256'], [epoch, BigInt(this.publicClient.chain?.id)]));
const signature = await this.walletClient.signMessage({
account: this.walletClient.account,
message: { raw: msgHash },
});
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'commit',
args: [(0, viem_1.keccak256)((0, viem_1.encodePacked)(['bytes'], [signature]))],
}, options);
return {
transactionHash: result.transactionHash,
transactionReceipt: result.transactionReceipt,
secret: signature
};
}
async reveal(secret, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'reveal',
args: [secret],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async slashInactiveExecutor(executor, recipient, round, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'slashInactiveExecutor',
args: [executor, round, recipient],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async slashCommitter(executor, recipient, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'slashCommitter',
args: [executor, recipient],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async batchSlash(committerExecutors, inactiveExecutors, rounds, recipient, options) {
this.checkProtocolConfig();
const result = await this.executeTransaction({
address: this.protocolConfig.batchSlasher,
abi: batchSlasher_1.batchSlasherAbi,
functionName: 'batchSlash',
args: [committerExecutors, inactiveExecutors, rounds, recipient],
}, options);
return { transactionHash: result.transactionHash, transactionReceipt: result.transactionReceipt };
}
async getEpoch() {
this.checkProtocolConfig();
const epoch = await this.publicClient.readContract({
address: this.protocolConfig.coordinator,
abi: coordinator_1.coordinatorAbi,
functionName: 'epoch',
});
return epoch;
}
jobIsExpired(job) {
const currentTime = BigInt(Math.floor(Date.now() / 1000));
return currentTime >= job.nextExecution + BigInt(job.executionWindow);
}
jobInExecutionWindow(job) {
const currentTime = BigInt(Math.floor(Date.now() / 1000));
return currentTime >= job.nextExecution && currentTime < job.nextExecution + BigInt(job.executionWindow);
}
jobIsDeleted(job) {
return job.owner === '0x0000000000000000000000000000000000000000';
}
modulesToBitset(modules) {
return modules.reduce((acc, module) => {
const bitPosition = parseInt(module.slice(2), 16);
return acc | (1n << BigInt(bitPosition));
}, 0n);
}
formatJobData(index, jobData) {
let executionModule;
let nextExecution = 0n;
let feeModule;
if (jobData.executionModule === "0x00") {
const executionModuleData = (0, viem_1.decodeAbiParameters)([{ name: 'lastExecution', type: 'uint40' }, { name: 'cooldown', type: 'uint32' }], jobData.executionModuleData);
executionModule = {
lastExecution: executionModuleData[0],
cooldown: executionModuleData[1],
};
nextExecution = BigInt(executionModule.lastExecution + executionModule.cooldown);
}
if (jobData.feeModule === "0x01") {
const feeModuleData = (0, viem_1.decodeAbiParameters)([{ name: 'executionFeeToken', type: 'address' }, { name: 'minExecutionFee', type: 'uint256' }, { name: 'maxExecutionFee', type: 'uint256' }], jobData.feeModuleData);
feeModule = {
executionFeeToken: feeModuleData[0],
minExecutionFee: feeModuleData[1],
maxExecutionFee: feeModuleData[2]
};
}
const job = {
index: index,
owner: jobData.owner,
active: jobData.active,
ignoreAppRevert: jobData.ignoreAppRevert,
sponsorFallbackToOwner: jobData.sponsorFallbackToOwner,
sponsorCanUpdateFeeModule: jobData.sponsorCanUpdateFeeModule,
sponsor: jobData.sponsor,
application: jobData.application,
executionWindow: jobData.executionWindow,
zeroFeeWindow: jobData.zeroFeeWindow,
executionCounter: jobData.executionCounter,
maxExecutions: jobData.maxExecutions,
creationTime: jobData.creationTime,
executionModuleCode: jobData.executionModule,
feeModuleCode: jobData.feeModule,
executionModule: executionModule,
feeModule: feeModule,
nextExecution: nextExecution
};
return job;
}
}
exports.EESSDK = EESSDK;