Skip to content

Commit

Permalink
fix lint
Browse files Browse the repository at this point in the history
  • Loading branch information
vanruch committed Apr 8, 2024
1 parent ebfe244 commit fc62cf6
Show file tree
Hide file tree
Showing 21 changed files with 995 additions and 1,140 deletions.
7 changes: 7 additions & 0 deletions evm/evm-codec/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"trailingComma": "all",
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"printWidth": 120
}
3 changes: 1 addition & 2 deletions evm/evm-codec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
"build": "rm -rf lib && tsc -p tsconfig.build.json",
"test": "vitest run"
},
"dependencies": {
},
"dependencies": {},
"devDependencies": {
"@types/node": "^18.18.14",
"ethers": "^5.7.2",
Expand Down
50 changes: 24 additions & 26 deletions evm/evm-codec/src/abi-components/event.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import { bytes32 } from "../codecs/primitives";
import { Src } from "../src";
import { Codec, StructTypes } from "../codec";
import type { Pretty } from "../utils";
import { bytes32 } from '../codecs/primitives'
import { Src } from '../src'
import { Codec, StructTypes } from '../codec'
import type { Pretty } from '../utils'

export interface EventRecord {
topics: string[];
data: string;
topics: string[]
data: string
}

type EventArgs = {
[key: string]: Pretty<Codec<any> & { indexed?: boolean }>;
};
[key: string]: Pretty<Codec<any> & { indexed?: boolean }>
}

export type IndexedCodecs<T extends EventArgs> = Pretty<{
[K in keyof T]: T[K] extends { indexed: true; isDynamic: true }
? typeof bytes32 & { indexed: true }
: T[K];
}>;
[K in keyof T]: T[K] extends { indexed: true; isDynamic: true } ? typeof bytes32 & { indexed: true } : T[K]
}>

export class AbiEvent<const T extends EventArgs> {
public readonly params: any;
public readonly params: any
constructor(public readonly topic: string, args: T) {
const entries = Object.entries(args);
const entries = Object.entries(args)
this.params = Object.fromEntries(
entries.map(
([key, arg]) =>
Expand All @@ -34,28 +32,28 @@ export class AbiEvent<const T extends EventArgs> {
indexed: true,
}
: arg,
] as const
)
) as IndexedCodecs<T>;
] as const,
),
) as IndexedCodecs<T>
}

is(rec: EventRecord): boolean {
return rec.topics[0] === this.topic;
return rec.topics[0] === this.topic
}

decode(rec: EventRecord): StructTypes<IndexedCodecs<T>> {
const src = new Src(Buffer.from(rec.data.slice(2), "hex"));
const result = {} as any;
let topicCounter = 1;
const src = new Src(Buffer.from(rec.data.slice(2), 'hex'))
const result = {} as any
let topicCounter = 1
for (let i in this.params) {
if (this.params[i].indexed) {
const topic = rec.topics[topicCounter++];
const topicSrc = new Src(Buffer.from(topic.slice(2), "hex"));
result[i] = this.params[i].decode(topicSrc);
const topic = rec.topics[topicCounter++]
const topicSrc = new Src(Buffer.from(topic.slice(2), 'hex'))
result[i] = this.params[i].decode(topicSrc)
} else {
result[i] = this.params[i].decode(src);
result[i] = this.params[i].decode(src)
}
}
return result;
return result
}
}
86 changes: 35 additions & 51 deletions evm/evm-codec/src/abi-components/function.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,62 @@
import { Codec, Struct, StructTypes } from "../codec";
import { Sink } from "../sink";
import { slotsCount } from "../utils";
import { Src } from "../src";
import assert from "node:assert";

type FunctionReturn<T> = T extends Codec<infer U>
? U
: T extends Struct
? StructTypes<T>
: undefined;

export class AbiFunction<
const T extends Struct,
const R extends Codec<any> | Struct | undefined
> {
readonly #selector: Buffer;
private readonly slotsCount: number;

constructor(
public selector: string,
public readonly args: T,
public readonly returnType?: R
) {
assert(selector.startsWith("0x"), "selector must start with 0x");
assert(selector.length === 10, "selector must be 4 bytes long");
this.#selector = Buffer.from(selector.slice(2), "hex");
this.args = args;
this.slotsCount = slotsCount(Object.values(args));
import { Codec, Struct, StructTypes } from '../codec'
import { Sink } from '../sink'
import { slotsCount } from '../utils'
import { Src } from '../src'
import assert from 'node:assert'

type FunctionReturn<T> = T extends Codec<infer U> ? U : T extends Struct ? StructTypes<T> : undefined

export class AbiFunction<const T extends Struct, const R extends Codec<any> | Struct | undefined> {
readonly #selector: Buffer
private readonly slotsCount: number

constructor(public selector: string, public readonly args: T, public readonly returnType?: R) {
assert(selector.startsWith('0x'), 'selector must start with 0x')
assert(selector.length === 10, 'selector must be 4 bytes long')
this.#selector = Buffer.from(selector.slice(2), 'hex')
this.args = args
this.slotsCount = slotsCount(Object.values(args))
}

is(calldata: string) {
return calldata.startsWith(this.selector);
return calldata.startsWith(this.selector)
}

encode(args: StructTypes<T>) {
const sink = new Sink(this.slotsCount);
const sink = new Sink(this.slotsCount)
for (let i in this.args) {
this.args[i].encode(sink, args[i]);
this.args[i].encode(sink, args[i])
}
return `0x${Buffer.concat([this.#selector, sink.result()]).toString(
"hex"
)}`;
return `0x${Buffer.concat([this.#selector, sink.result()]).toString('hex')}`
}

decode(calldata: string): StructTypes<T> {
assert(
this.is(calldata),
`unexpected function signature: ${calldata.slice(0, 10)}`
);
const src = new Src(Buffer.from(calldata.slice(10), "hex"));
const result = {} as any;
assert(this.is(calldata), `unexpected function signature: ${calldata.slice(0, 10)}`)
const src = new Src(Buffer.from(calldata.slice(10), 'hex'))
const result = {} as any
for (let i in this.args) {
result[i] = this.args[i].decode(src);
result[i] = this.args[i].decode(src)
}
return result;
return result
}

private isCodecs(value: any): value is Codec<any> {
return "decode" in value && "encode" in value;
return 'decode' in value && 'encode' in value
}

decodeResult(output: string): FunctionReturn<R> {
if (!this.returnType) {
return undefined as any;
return undefined as any
}
const src = new Src(Buffer.from(output.slice(2), "hex"));
const src = new Src(Buffer.from(output.slice(2), 'hex'))
if (this.isCodecs(this.returnType)) {
return this.returnType.decode(src) as any;
return this.returnType.decode(src) as any
}
const result = {} as any;
const result = {} as any
for (let i in this.returnType) {
const codec = this.returnType[i] as Codec<any>;
result[i] = codec.decode(src);
const codec = this.returnType[i] as Codec<any>
result[i] = codec.decode(src)
}
return result;
return result
}
}
24 changes: 12 additions & 12 deletions evm/evm-codec/src/codec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type { Sink } from "./sink";
import type { Src } from "./src";
import type { Pretty } from "./utils";
import type { Sink } from './sink'
import type { Src } from './src'
import type { Pretty } from './utils'

export const WORD_SIZE = 32;
export const WORD_SIZE = 32

export interface Codec<T> {
encode(sink: Sink, val: T): void;
decode(src: Src): T;
isDynamic: boolean;
slotsCount?: number;
encode(sink: Sink, val: T): void
decode(src: Src): T
isDynamic: boolean
slotsCount?: number
}

export type Struct = {
[key: string]: Codec<any>;
};
[key: string]: Codec<any>
}

export type StructTypes<T extends Struct> = Pretty<{
[K in keyof T]: T[K] extends Codec<infer U> ? U : never;
}>;
[K in keyof T]: T[K] extends Codec<infer U> ? U : never
}>
72 changes: 35 additions & 37 deletions evm/evm-codec/src/codecs/array.ts
Original file line number Diff line number Diff line change
@@ -1,85 +1,83 @@
import { Codec, WORD_SIZE } from "../codec";
import { Sink } from "../sink";
import { Src } from "../src";
import { Codec, WORD_SIZE } from '../codec'
import { Sink } from '../sink'
import { Src } from '../src'

export class ArrayCodec<const T> implements Codec<readonly T[]> {
public readonly isDynamic = true;
public readonly isDynamic = true

constructor(public readonly item: Codec<T>) {}

encode(sink: Sink, val: T[]) {
sink.dynamicOffset(val.length);
sink.dynamicOffset(val.length)
for (let i = 0; i < val.length; i++) {
this.item.encode(sink, val[i]);
this.item.encode(sink, val[i])
}
sink.increaseSize(WORD_SIZE);
sink.endDynamic();
sink.increaseSize(WORD_SIZE)
sink.endDynamic()
}

decode(src: Src): T[] {
const offset = src.u32();
const offset = src.u32()

src.safeJump(offset);
const len = src.u32();
src.safeJump(offset)
const len = src.u32()

const tmpSrc = src.slice(offset + WORD_SIZE);
const val = new Array(len);
const tmpSrc = src.slice(offset + WORD_SIZE)
const val = new Array(len)
for (let i = 0; i < val.length; i++) {
val[i] = this.item.decode(tmpSrc);
val[i] = this.item.decode(tmpSrc)
}
src.jumpBack();
return val;
src.jumpBack()
return val
}
}

export class FixedSizeArrayCodec<const T> implements Codec<readonly T[]> {
public isDynamic: boolean;
public slotsCount: number;
public isDynamic: boolean
public slotsCount: number
constructor(public readonly item: Codec<T>, public readonly size: number) {
this.isDynamic = item.isDynamic && size > 0;
this.slotsCount = this.isDynamic ? 1 : size;
this.isDynamic = item.isDynamic && size > 0
this.slotsCount = this.isDynamic ? 1 : size
}

encode(sink: Sink, val: T[]) {
if (val.length !== this.size) {
throw new Error(
`invalid array length: ${val.length}. Expected: ${this.size}`
);
throw new Error(`invalid array length: ${val.length}. Expected: ${this.size}`)
}
if (this.isDynamic) {
return this.encodeDynamic(sink, val);
return this.encodeDynamic(sink, val)
}
for (let i = 0; i < this.size; i++) {
this.item.encode(sink, val[i]);
this.item.encode(sink, val[i])
}
}

private encodeDynamic(sink: Sink, val: T[]) {
sink.offset(this.size);
sink.offset(this.size)
for (let i = 0; i < val.length; i++) {
this.item.encode(sink, val[i]);
this.item.encode(sink, val[i])
}
sink.endDynamic();
sink.endDynamic()
}

decode(src: Src): T[] {
if (this.isDynamic) {
return this.decodeDynamic(src);
return this.decodeDynamic(src)
}
let val = new Array(this.size);
let val = new Array(this.size)
for (let i = 0; i < val.length; i++) {
val[i] = this.item.decode(src);
val[i] = this.item.decode(src)
}
return val;
return val
}

private decodeDynamic(src: Src): T[] {
const offset = src.u32();
const tmpSrc = src.slice(offset);
let val = new Array(this.size);
const offset = src.u32()
const tmpSrc = src.slice(offset)
let val = new Array(this.size)
for (let i = 0; i < val.length; i++) {
val[i] = this.item.decode(tmpSrc);
val[i] = this.item.decode(tmpSrc)
}
return val;
return val
}
}
Loading

0 comments on commit fc62cf6

Please sign in to comment.