Skip to content
This repository has been archived by the owner on Oct 31, 2024. It is now read-only.

feat: migrate ethers to v6 #18

Merged
merged 6 commits into from
Jan 8, 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
21,034 changes: 5,529 additions & 15,505 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"test:e2e:watch": "jest --watch --config ./test/jest-e2e.json"
},
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@nestjs/bull": "^0.6.1",
"@nestjs/common": "^9.4.0",
"@nestjs/config": "^2.2.0",
Expand All @@ -37,13 +36,13 @@
"@opentelemetry/exporter-metrics-otlp-proto": "^0.44.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.44.0",
"@opentelemetry/sdk-node": "^0.44.0",
"@topos-protocol/topos-smart-contracts": "^2.0.0",
"@topos-protocol/topos-smart-contracts": "^3.1.0",
"bcrypt": "^5.1.0",
"bull": "^4.10.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"elastic-apm-node": "^4.0.0",
"ethers": "^5.7.1",
"ethers": "^6.9.0",
"jwks-rsa": "^2.1.5",
"passport": "^0.6.0",
"passport-headerapikey": "^1.2.2",
Expand All @@ -69,15 +68,15 @@
"eslint": "^8.19.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^27.0.3",
"jest": "^29.7.0",
"prettier": "^2.7.1",
"source-map-support": "^0.5.21",
"supertest": "^6.2.4",
"ts-jest": "^27.1.5",
"ts-jest": "^29.1.1",
"ts-loader": "^9.3.1",
"ts-node": "^10.8.2",
"tsconfig-paths": "^4.0.0",
"typescript": "^4.7.4"
"typescript": "^5.0.4"
},
"jest": {
"moduleFileExtensions": [
Expand All @@ -98,6 +97,9 @@
"text",
"cobertura"
],
"testEnvironment": "node"
"testEnvironment": "node",
"transformIgnorePatterns": [
"/node_modules/(?!(@topos-protocol)/)"
]
}
}
8 changes: 4 additions & 4 deletions src/execute/execute.errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ export enum PROVIDER_ERRORS {
INVALID_ENDPOINT = 'Provider // Invalid endpoint!',
}

export enum WALLET_ERRORS {
INVALID_PRIVATE_KEY = 'Wallet // Invalid private key!',
}

export enum CONTRACT_ERRORS {
INVALID_CONTRACT = 'Contract // Invalid contract!',
}

export enum WALLET_ERRORS {
INVALID_PRIVATE_KEY = 'Wallet // Invalid private key!',
}

export enum QUEUE_ERRORS {
JOB_NOT_FOUND = 'Queue // A job with the provided id could not be found!',
REDIS_NOT_AVAILABLE = 'Queue // Could not connect to Redis!',
Expand Down
9 changes: 7 additions & 2 deletions src/execute/execute.processor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ConfigService } from '@nestjs/config'
import { Test, TestingModule } from '@nestjs/testing'
import {
SubnetRegistrator__factory,
ToposCore__factory,
ToposMessaging__factory,
} from '@topos-protocol/topos-smart-contracts/typechain-types'
import { Job } from 'bull'
import { ethers } from 'ethers'
import * as ethers from 'ethers'
import { EventEmitter } from 'stream'

import { ExecuteDto } from './execute.dto'
Expand Down Expand Up @@ -81,7 +86,7 @@ describe('ExecuteProcessor', () => {
describe('execute', () => {
it('should go through if processed job is valid', async () => {
const ethersProviderMock = jest
.spyOn<any, any>(ethers.providers, 'WebSocketProvider')
.spyOn<any, any>(ethers, 'getDefaultProvider')
.mockReturnValue(providerMock)

const ethersWalletMock = jest
Expand Down
85 changes: 40 additions & 45 deletions src/execute/execute.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,26 @@ import {
SpanStatusCode,
trace,
} from '@opentelemetry/api'
import * as ToposCoreJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/ToposCore.sol/ToposCore.json'
import * as ToposMessagingJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/ToposMessaging.sol/ToposMessaging.json'
import * as SubnetRegistratorJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/SubnetRegistrator.sol/SubnetRegistrator.json'
import {
SubnetRegistrator,
ToposCore,
ToposMessaging,
} from '@topos-protocol/topos-smart-contracts/typechain-types/contracts/topos-core'
} from '@topos-protocol/topos-smart-contracts/typechain-types'
import * as ToposCoreJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/ToposCore.sol/ToposCore.json'
import * as ToposMessagingJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/ToposMessaging.sol/ToposMessaging.json'
import * as SubnetRegistratorJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/SubnetRegistrator.sol/SubnetRegistrator.json'
import { Job } from 'bull'
import { Contract, ethers, providers } from 'ethers'
import {
Contract,
getDefaultProvider,
InterfaceAbi,
Provider,
Wallet,
} from 'ethers'

import { getErrorMessage } from '../utils'
import { ExecuteDto } from './execute.dto'
import {
CONTRACT_ERRORS,
JOB_ERRORS,
PROVIDER_ERRORS,
WALLET_ERRORS,
} from './execute.errors'
import { CONTRACT_ERRORS, JOB_ERRORS, PROVIDER_ERRORS } from './execute.errors'
import { TracingOptions } from './execute.service'

const UNDEFINED_CERTIFICATE_ID =
Expand Down Expand Up @@ -91,6 +92,7 @@ export class ExecutionProcessorV1 {

const provider = await this._createProvider(receivingSubnetEndpoint)
this.logger.debug(`ReceivingSubnet: ${receivingSubnetEndpoint}`)

span.addEvent('got provider', {
provider: JSON.stringify(provider),
})
Expand All @@ -102,14 +104,14 @@ export class ExecutionProcessorV1 {
toposCoreProxyContractAddress,
ToposCoreJSON.abi,
wallet
)) as ToposCore
)) as unknown as ToposCore

const messagingContract = (await this._getContract(
provider,
messagingContractAddress,
ToposMessagingJSON.abi,
wallet
)) as ToposMessaging
)) as unknown as ToposMessaging

this.logger.debug(`Trie root: ${receiptTrieRoot}`)

Expand Down Expand Up @@ -169,11 +171,11 @@ export class ExecutionProcessorV1 {

const provider = await this._createProvider(toposSubnetEndpoint)

const toposCoreContract = await this._getContract(
const toposCoreContract = (await this._getContract(
provider,
toposCoreContractAddress,
ToposCoreJSON.abi
)
)) as unknown as ToposCore

const toposSubnetId = await toposCoreContract.networkSubnetId()

Expand All @@ -184,48 +186,41 @@ export class ExecutionProcessorV1 {
provider,
subnetRegistratorContractAddress,
SubnetRegistratorJSON.abi
)) as SubnetRegistrator
)) as unknown as SubnetRegistrator

const receivingSubnet = await subnetRegistratorContract.subnets(subnetId)
return receivingSubnet.endpointWs || receivingSubnet.endpointHttp
}
}

private _createProvider(endpoint: string) {
return new Promise<providers.WebSocketProvider | providers.JsonRpcProvider>(
(resolve, reject) => {
const url = new URL(endpoint)
const provider = url.protocol.startsWith('ws')
? new providers.WebSocketProvider(endpoint)
: new providers.JsonRpcProvider(endpoint)

// Fix: Timeout to leave time to errors to be asynchronously caught
const timeoutId = setTimeout(() => {
resolve(provider)
}, 1000)

provider.on('debug', (data) => {
if (data.error) {
clearTimeout(timeoutId)
reject(new Error(PROVIDER_ERRORS.INVALID_ENDPOINT))
}
})
}
)
return new Promise<Provider>((resolve, reject) => {
const provider = getDefaultProvider(endpoint)

// Fix: Timeout to leave time to errors to be asynchronously caught
const timeoutId = setTimeout(() => {
resolve(provider)
}, 1000)

provider.on('debug', (data) => {
if (data.error) {
clearTimeout(timeoutId)
reject(new Error(PROVIDER_ERRORS.INVALID_ENDPOINT))
}
})
})
}

private _createWallet(
provider: providers.WebSocketProvider | providers.JsonRpcProvider
) {
private _createWallet(provider: Provider) {
const privateKey = this.configService.getOrThrow('PRIVATE_KEY')
return new ethers.Wallet(privateKey, provider)
return new Wallet(privateKey, provider)
}

private async _getContract(
provider: providers.WebSocketProvider | providers.JsonRpcProvider,
provider: Provider,
contractAddress: string,
contractInterface: ethers.ContractInterface,
wallet?: ethers.Wallet
contractInterfaceAbi: InterfaceAbi,
wallet?: Wallet
) {
try {
const code = await provider.getCode(contractAddress)
Expand All @@ -234,9 +229,9 @@ export class ExecutionProcessorV1 {
throw new Error()
}

return new ethers.Contract(
return new Contract(
contractAddress,
contractInterface,
contractInterfaceAbi,
wallet || provider
)
} catch (error) {
Expand Down
6 changes: 3 additions & 3 deletions src/execute/execute.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { InjectQueue } from '@nestjs/bull'
import { Injectable, Logger, MessageEvent } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { context, propagation, SpanStatusCode, trace } from '@opentelemetry/api'
import { context, SpanStatusCode, trace } from '@opentelemetry/api'
import { Queue } from 'bull'
import { ethers } from 'ethers'
import { isHexString } from 'ethers'
import { Observable } from 'rxjs'

import { ExecuteDto } from './execute.dto'
Expand Down Expand Up @@ -151,7 +151,7 @@ export class ExecuteServiceV1 {
private _verifyPrivateKey() {
const privateKey = this.configService.get<string>('PRIVATE_KEY')

if (!ethers.utils.isHexString(privateKey, 32)) {
if (!isHexString(privateKey, 32)) {
throw new Error(WALLET_ERRORS.INVALID_PRIVATE_KEY)
}
}
Expand Down
3 changes: 2 additions & 1 deletion test/jest-e2e.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
},
"transformIgnorePatterns": ["/node_modules/(?!(@topos-protocol)/)"]
}
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"compilerOptions": {
"module": "commonjs",
"module": "node16",
"moduleResolution": "node16",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"target": "es2020",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
Expand Down
Loading