Skip to content

Commit

Permalink
Migrate ethers side dependencies to v6 (#232)
Browse files Browse the repository at this point in the history
* migrate ethers side dependencies to v6

* added peer deps to relay package

* format

* format

* fix tests

* update sdk base dependency

* missing return keyword
  • Loading branch information
MCarlomagno authored Mar 5, 2024
1 parent 8dc4654 commit e6985c3
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 354 deletions.
20 changes: 13 additions & 7 deletions examples/ethers-signer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,46 @@ async function main() {

const client = new Defender(creds);
const provider = client.relaySigner.getProvider();
const signer = client.relaySigner.getSigner(provider, { speed: 'fast', validUntil });
const signer = await client.relaySigner.getSigner(provider, { speed: 'fast', validUntil });
const signerAddress = await signer.getAddress();

const factory = new ethers.ContractFactory(ERC20Abi, ERC20Bytecode, signer);

console.log(`Deploying ERC20 contract`);
const erc20 = await factory.deploy(100, { gasLimit: 8000000 });
console.log(`Contract deployed at address ${erc20.address}`);

console.log(`Waiting for contract deployment...`);
await erc20.deploymentTransaction().wait();

const contractAddress = await erc20.getAddress();
console.log(`Contract deployed at address ${contractAddress}`);

const beneficiary = await ethers.Wallet.createRandom().getAddress();

const addr = await signer.getAddress();
console.log(`Relayer address is ${addr}`);

console.log(`Sending approve transaction for ${beneficiary} to token ${erc20.address}...`);
const tx = await erc20.approve(beneficiary, (1e17).toString(), { gasPrice: 1e8 });
console.log(`Sending approve transaction for ${beneficiary} to token ${contractAddress}...`);
const tx = await erc20.approve(beneficiary, (1e17).toString(), { gasPrice: 1e8, gasLimit: 8000000 });
console.log(`Transaction sent:`, tx);

const mined = await tx.wait();
console.log(`Transaction mined:`, mined);

const allowance = await erc20.allowance(tx.from, beneficiary);
const allowance = await erc20.allowance(addr, beneficiary);
console.log(`Allowance now is:`, allowance.toString());

const sig = await signer.signMessage('0xdead');
console.log(`Signature is ${sig}`);

const sigAddress = ethers.verifyMessage('Funds are safu!', sig);
console.log(`Signature address is ${sigAddress} matching relayer address ${mined.from}`);
console.log(`Signature address is ${sigAddress} matching relayer address ${signerAddress}`);

const typedSig = await signer._signTypedData(domain, types, value);
console.log(`Typed data signature is ${typedSig}`);

const typedSigAddress = ethers.verifyTypedData(domain, types, value, typedSig);
console.log(`Typed data signature address is ${typedSigAddress} matching relayer address ${mined.from}`);
console.log(`Typed data signature address is ${typedSigAddress} matching relayer address ${signerAddress}`);
}

if (require.main === module) {
Expand Down
1 change: 0 additions & 1 deletion packages/deploy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"author": "Dylan Kilkenny <[email protected]>",
"license": "MIT",
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@openzeppelin/defender-sdk-base-client": "^1.10.0",
"axios": "^1.6.7",
"lodash": "^4.17.21"
Expand Down
2 changes: 1 addition & 1 deletion packages/monitor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"author": "OpenZeppelin Defender <[email protected]>",
"license": "MIT",
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"ethers": "^6.9.0",
"@openzeppelin/defender-sdk-base-client": "^1.10.0",
"axios": "^1.6.7",
"lodash": "^4.17.21"
Expand Down
2 changes: 1 addition & 1 deletion packages/monitor/src/models/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export interface NotificationReference {

// Copied from ui/src/components/monitor/types.ts

import { EventFragment, FunctionFragment } from '@ethersproject/abi';
import { EventFragment, FunctionFragment } from 'ethers';

export type Description = EventFragment | FunctionFragment;
export type Condition = EventCondition | FunctionCondition | undefined;
Expand Down
8 changes: 5 additions & 3 deletions packages/monitor/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
TxCondition,
} from '../models/monitor';

import { Interface, EventFragment, FunctionFragment } from '@ethersproject/abi';
import { Interface, EventFragment, FunctionFragment } from 'ethers';
import { isTransactionMethod } from '../models/ethers';

// converts to payload for save API
Expand Down Expand Up @@ -109,8 +109,10 @@ export function getMonitorConditions(addressRules: AddressRule[]): Conditions {
const abiInterface = getAbiInterface(rule.abi);

if (abiInterface) {
const events = uniqBy(Object.values(abiInterface.events), (e) => e.format());
const functions = uniqBy(Object.values(abiInterface.functions), (e) => e.format()).filter(isTransactionMethod);
const events = [] as EventFragment[];
const functions = [] as FunctionFragment[];
abiInterface.forEachEvent((e) => events.push(e));
abiInterface.forEachFunction((f) => (isTransactionMethod(f) ? functions.push(f) : null));

if (events.length) abiEvents.push(...events);
if (functions.length) abiFunctions.push(...functions);
Expand Down
1 change: 0 additions & 1 deletion packages/network/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"author": "OpenZeppelin Defender <[email protected]>",
"license": "MIT",
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@openzeppelin/defender-sdk-base-client": "^1.10.0",
"axios": "^1.6.7",
"lodash": "^4.17.21"
Expand Down
1 change: 0 additions & 1 deletion packages/notification-channel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"author": "OpenZeppelin Defender <[email protected]>",
"license": "MIT",
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@openzeppelin/defender-sdk-base-client": "^1.10.0",
"axios": "^1.6.7",
"lodash": "^4.17.21"
Expand Down
6 changes: 5 additions & 1 deletion packages/relay-signer/jest.config.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
module.exports = require('../../jest.config');
module.exports = {
// https://github.com/jestjs/jest/issues/11617
maxWorkers: 1,
...require('../../jest.config'),
};
15 changes: 2 additions & 13 deletions packages/relay-signer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,14 @@
"web3-core-helpers": "^1.8.2"
},
"dependencies": {
"@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
"@ethersproject/networks": "^5.7.1",
"@ethersproject/properties": "^5.7.0",
"@ethersproject/random": "^5.7.0",
"@ethersproject/strings": "^5.7.0",
"ethers": "^6.9.0",
"@openzeppelin/defender-sdk-base-client": "^1.10.0",
"amazon-cognito-identity-js": "^6.3.6",
"axios": "^1.6.7",
"lodash": "^4.17.21"
},
"peerDependencies": {
"@ethersproject/abstract-provider": "^5.6.1",
"@ethersproject/abstract-signer": "^5.6.2",
"@ethersproject/hash": "^5.6.1",
"@ethersproject/providers": "^5.6.8",
"@ethersproject/transactions": "^5.6.2",
"ethers": "^6.9.0",
"web3": "^1.8.2",
"web3-core": "^1.10.3",
"web3-core-helpers": "^1.8.2",
Expand Down
87 changes: 51 additions & 36 deletions packages/relay-signer/src/ethers/provider.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,63 @@
import { JsonRpcSigner, Network, StaticJsonRpcProvider } from '@ethersproject/providers';
import { RelayerParams } from '../models/relayer';
import { DefenderRelaySigner } from './signer';
import { defineReadOnly, getStatic } from '@ethersproject/properties';
import { Networkish } from '@ethersproject/networks';
import { BigNumber } from '@ethersproject/bignumber';
import { getRelaySignerApiUrl } from '../api';
import { Relayer } from '../relayer';
import {
JsonRpcError,
JsonRpcProvider,
JsonRpcResult,
Network,
getBigInt,
JsonRpcSigner,
JsonRpcPayload,
} from 'ethers';

export class DefenderRelayProvider extends StaticJsonRpcProvider {
export class DefenderRelayProvider extends JsonRpcProvider {
private relayer: Relayer;
private pendingNetwork: Promise<Network> | null = null;

constructor(readonly credentials: RelayerParams) {
super(getRelaySignerApiUrl());
this.relayer = new Relayer(credentials);
}

async detectNetwork(): Promise<Network> {
if (this.network != null) {
return this.network;
}

// Logic from JsonRpcProvider.detectNetwork
let chainId = null;
try {
chainId = await this.send('eth_chainId', []);
} catch (error) {
async _detectNetwork(): Promise<Network> {
this.pendingNetwork = (async () => {
let result: JsonRpcResult | JsonRpcError;
try {
chainId = await this.send('net_version', []);
result = await this.send('eth_chainId', []);
this.pendingNetwork = null;
} catch (error) {
// Key difference from JsonRpcProvider.detectNetwork logic
// This surfaces error to caller (like QuotaExceeded) instead of squashing it
this.pendingNetwork = null;
throw error;
}
}

if (chainId === null) {
throw new Error('could not detect chainId');
}
this.emit('debug', { action: 'receiveRpcResult', result });

// Logic from JsonRpcProvider.detectNetwork
const getNetwork = getStatic<(network: Networkish) => Network>(this.constructor, 'getNetwork');
const network = getNetwork(BigNumber.from(chainId).toNumber());
if ((result && typeof result === 'string') || typeof result === 'number') {
return Network.from(getBigInt(result));
}

if (!network) {
throw new Error('could not detect network');
}
if (result && 'result' in result) {
return Network.from(getBigInt(result.result));
}

// Logic from StaticJsonRpcProvider.detectNetwork
if (this._network == null) {
defineReadOnly(this, '_network', network);
this.emit('network', network, null);
}
throw this.getRpcError({ id: 1, jsonrpc: '2.0', method: 'eth_chainId', params: [] }, result);
})();

return network;
return await this.pendingNetwork;
}

// Logic from JsonRpcProvider.detectNetwork
async detectNetwork(): Promise<Network> {
return this._detectNetwork();
}

async _send(payload: JsonRpcPayload | JsonRpcPayload[]): Promise<JsonRpcResult[]> {
if (Array.isArray(payload)) {
return Promise.all(payload.map((p) => this.send(p.method, p.params as Array<any>)));
}
return [await this.send(payload.method, payload.params as Array<any>)];
}

async send(method: string, params: Array<any>): Promise<any> {
Expand All @@ -74,7 +79,17 @@ export class DefenderRelayProvider extends StaticJsonRpcProvider {
}
}

getSigner(): JsonRpcSigner {
return new DefenderRelaySigner(this.relayer, this, {}) as any as JsonRpcSigner;
// Logic from JsonRpcProvider.getSigner
async getSigner(address?: number | string): Promise<JsonRpcSigner> {
if (typeof address === 'number') {
throw new Error(
'Invalid address: cannot provide an index number as address, only one relayer address is supported.',
);
}
if (address) {
return new DefenderRelaySigner(this.relayer, this, address, {}) as any as JsonRpcSigner;
}
const relayer = await this.relayer.getRelayer();
return new DefenderRelaySigner(this.relayer, this, relayer.address, {}) as any as JsonRpcSigner;
}
}
Loading

0 comments on commit e6985c3

Please sign in to comment.