Skip to content

Commit

Permalink
Add call, encodeFunctionReturn, and decodeFunctionReturn method…
Browse files Browse the repository at this point in the history
…s to ethers-v5
  • Loading branch information
ryangoree committed Dec 18, 2024
1 parent 48711ef commit def8abc
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-rules-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@delvtech/drift-ethers-v5": patch
---

Added `call`, `encodeFunctionReturn`, and `decodeFunctionReturn` methods
52 changes: 51 additions & 1 deletion packages/drift-ethers-v5/src/EthersReadAdapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
Transaction,
TransactionReceipt,
} from "@delvtech/drift";
import { erc20 } from "@delvtech/drift/testing";
import { erc20, mockErc20 } from "@delvtech/drift/testing";
import { providers } from "ethers";
import { EthersReadAdapter } from "src/EthersReadAdapter";
import { describe, expect, it } from "vitest";
Expand Down Expand Up @@ -104,6 +104,34 @@ describe("EthersReadAdapter", () => {
} as TransactionReceipt);
});

describe("call", () => {
it("reads from deployed contracts", async () => {
const adapter = new EthersReadAdapter({ provider });
const data = adapter.encodeFunctionData({
abi: erc20.abi,
fn: "symbol",
});
const result = await adapter.call({
to: address,
data,
});
expect(result).toEqual(expect.stringMatching(/^0x/));
});

it("reads from bytecodes", async () => {
const adapter = new EthersReadAdapter({ provider });
const data = adapter.encodeFunctionData({
abi: mockErc20.abi,
fn: "name",
});
const result = await adapter.call({
bytecode: mockErc20.bytecode,
data,
});
expect(result).toEqual(expect.stringMatching(/^0x/));
});
});

it("fetches events", async () => {
const adapter = new EthersReadAdapter({ provider });
const currentBlock = await provider.getBlockNumber();
Expand Down Expand Up @@ -174,6 +202,18 @@ describe("EthersReadAdapter", () => {
expect(encoded).toBeTypeOf("string");
});

it("encodes function return data", async () => {
const adapter = new EthersReadAdapter({ provider });
const encoded = adapter.encodeFunctionReturn({
abi: erc20.abi,
fn: "balanceOf",
value: 123n,
});
expect(encoded).toEqual(
"0x000000000000000000000000000000000000000000000000000000000000007b",
);
});

it("decodes function data", async () => {
const adapter = new EthersReadAdapter({ provider });
const args: FunctionArgs<typeof erc20.abi, "transfer"> = {
Expand All @@ -194,4 +234,14 @@ describe("EthersReadAdapter", () => {
functionName: "transfer",
} as DecodedFunctionData<typeof erc20.abi, "transfer">);
});

it("decodes function return data", async () => {
const adapter = new EthersReadAdapter({ provider });
const decoded = adapter.decodeFunctionReturn({
abi: erc20.abi,
fn: "balanceOf",
data: "0x000000000000000000000000000000000000000000000000000000000000007b",
});
expect(decoded).toEqual(123n);
});
});
64 changes: 63 additions & 1 deletion packages/drift-ethers-v5/src/EthersReadAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import {
type Block,
type Bytes,
type CallParams,
type DecodeFunctionDataParams,
type DecodeFunctionReturnParams,
type DecodedFunctionData,
DriftError,
type EncodeFunctionDataParams,
type EncodeFunctionReturnParams,
type EventLog,
type EventName,
type FunctionName,
Expand All @@ -19,7 +23,10 @@ import {
type WriteParams,
arrayToObject,
convertType,
decodeFunctionReturn,
encodeFunctionReturn,
objectToArray,
prepareBytecodeCallData,
} from "@delvtech/drift";
import type { Abi } from "abitype";
import {
Expand All @@ -29,7 +36,7 @@ import {
getDefaultProvider,
providers,
} from "ethers";
import { Interface } from "ethers/lib/utils";
import { type AccessList, Interface } from "ethers/lib/utils";
import type { EthersAbi, Provider } from "src/types";

export interface EthersReadAdapterParams<
Expand Down Expand Up @@ -149,6 +156,47 @@ export class EthersReadAdapter<TProvider extends Provider = Provider>
return receipt;
}

async call({
accessList,
block,
bytecode,
chainId,
data,
from,
gas,
gasPrice,
maxFeePerGas,
maxPriorityFeePerGas,
nonce,
to,
type,
value,
}: CallParams) {
if (bytecode && data) {
data = prepareBytecodeCallData(bytecode, data);
}
if (typeof block === "bigint") {
block = await this.getBlockNumber();
}
return this.provider.call(
{
accessList: accessList as AccessList,
chainId: chainId === undefined ? undefined : Number(chainId),
data,
from,
gasLimit: gas,
gasPrice,
maxFeePerGas,
maxPriorityFeePerGas,
nonce: nonce === undefined ? undefined : Number(nonce),
to,
type: type === undefined ? undefined : Number(type),
value,
},
block === undefined ? undefined : blockParam(block),
) as Promise<Bytes>;
}

async getEvents<TAbi extends Abi, TEventName extends EventName<TAbi>>({
abi,
address,
Expand Down Expand Up @@ -263,6 +311,13 @@ export class EthersReadAdapter<TProvider extends Provider = Provider>
return iface.encodeFunctionData(fn, arrayArgs);
}

encodeFunctionReturn<
TAbi extends Abi,
TFunctionName extends FunctionName<TAbi>,
>(params: EncodeFunctionReturnParams<TAbi, TFunctionName>) {
return encodeFunctionReturn(params);
}

decodeFunctionData<
TAbi extends Abi,
TFunctionName extends FunctionName<TAbi>,
Expand All @@ -288,6 +343,13 @@ export class EthersReadAdapter<TProvider extends Provider = Provider>
}),
} as DecodedFunctionData<TAbi, TFunctionName>;
}

decodeFunctionReturn<
TAbi extends Abi,
TFunctionName extends FunctionName<TAbi>,
>(params: DecodeFunctionReturnParams<TAbi, TFunctionName>) {
return decodeFunctionReturn(params);
}
}

function blockParam(block?: bigint | string): string {
Expand Down
15 changes: 15 additions & 0 deletions packages/drift-ethers-v5/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,19 @@ declare module "@delvtech/drift" {
effectiveGasPrice: bigint;
transactionIndex: bigint;
}

interface ContractCallOptions {
/**
* Unavailable in ethers.js.
*/
blobs?: undefined;
/**
* Unavailable in ethers.js.
*/
blobVersionedHashes?: undefined;
/**
* Unavailable in ethers.js.
*/
maxFeePerBlobGas?: undefined;
}
}

0 comments on commit def8abc

Please sign in to comment.