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

Commit

Permalink
feat: migrate ethers to v6 (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastiendan authored Jan 8, 2024
1 parent f3ae2c2 commit a7a1a87
Show file tree
Hide file tree
Showing 8 changed files with 5,597 additions and 15,569 deletions.
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

0 comments on commit a7a1a87

Please sign in to comment.