Skip to content

Commit

Permalink
feat: Repeatable setup for Endpoint & Uln302 deployment & configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
janjakubnanista committed Dec 5, 2023
1 parent 08a659d commit 71793cb
Show file tree
Hide file tree
Showing 32 changed files with 814 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/protocol-utils-evm/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
node_modules
2 changes: 2 additions & 0 deletions packages/protocol-utils-evm/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
33 changes: 33 additions & 0 deletions packages/protocol-utils-evm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<p align="center">
<a href="https://layerzero.network">
<img alt="LayerZero" style="max-width: 500px" src="https://d3a2dpnnrypp5h.cloudfront.net/bridge-app/lz.png"/>
</a>
</p>

<h1 align="center">@layerzerolabs/protocol-utils-evm</h1>

<!-- The badges section -->
<p align="center">
<!-- Shields.io NPM published package version -->
<a href="https://www.npmjs.com/package/@layerzerolabs/protocol-utils-evm"><img alt="NPM Version" src="https://img.shields.io/npm/v/@layerzerolabs/protocol-utils-evm"/></a>
<!-- Shields.io NPM downloads -->
<a href="https://www.npmjs.com/package/@layerzerolabs/protocol-utils-evm"><img alt="Downloads" src="https://img.shields.io/npm/dm/@layerzerolabs/protocol-utils-evm"/></a>
<!-- Shields.io license badge -->
<a href="https://www.npmjs.com/package/@layerzerolabs/protocol-utils-evm"><img alt="NPM License" src="https://img.shields.io/npm/l/@layerzerolabs/protocol-utils-evm"/></a>
</p>

Utilities for LayerZero EVM protocol contracts.

## Installation

```bash
npm install --save @layerzerolabs/protocol-utils-evm
```

```bash
yarn install @layerzerolabs/protocol-utils-evm
```

```bash
pnpm install @layerzerolabs/protocol-utils-evm
```
8 changes: 8 additions & 0 deletions packages/protocol-utils-evm/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
69 changes: 69 additions & 0 deletions packages/protocol-utils-evm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"name": "@layerzerolabs/protocol-utils-evm",
"version": "0.0.1",
"private": true,
"description": "Utilities for LayerZero EVM protocol contracts",
"repository": {
"type": "git",
"url": "git+https://github.com/LayerZero-Labs/lz-utils.git",
"directory": "packages/protocol-utils-evm"
},
"license": "MIT",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./*": {
"types": "./dist/*.d.ts",
"require": "./dist/*.js",
"import": "./dist/*.mjs"
}
},
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"./dist/index.*"
],
"scripts": {
"prebuild": "npx tsc --noEmit -p tsconfig.build.json",
"build": "npx tsup",
"clean": "rm -rf dist",
"dev": "npx tsup --watch",
"lint": "npx eslint '**/*.{js,ts,json}'",
"test": "jest --passWithNoTests"
},
"dependencies": {
"p-memoize": "~4.0.1"
},
"devDependencies": {
"@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/providers": "^5.7.0",
"@layerzerolabs/lz-definitions": "~1.5.68",
"@layerzerolabs/protocol-utils": "~0.0.1",
"@layerzerolabs/test-utils": "~0.0.1",
"@layerzerolabs/utils": "~0.0.1",
"@layerzerolabs/utils-evm": "~0.0.1",
"@types/jest": "^29.5.10",
"fast-check": "^3.14.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tsup": "~8.0.1",
"typescript": "^5.2.2"
},
"peerDependencies": {
"@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/providers": "^5.7.0",
"@layerzerolabs/lz-definitions": "~1.5.68",
"@layerzerolabs/protocol-utils": "~0.0.1",
"@layerzerolabs/utils": "~0.0.1",
"@layerzerolabs/utils-evm": "~0.0.1"
}
}
1 change: 1 addition & 0 deletions packages/protocol-utils-evm/src/endpoint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './sdk'
62 changes: 62 additions & 0 deletions packages/protocol-utils-evm/src/endpoint/sdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { IEndpoint } from '@layerzerolabs/protocol-utils'
import { formatEid, type Address, type OmniTransaction } from '@layerzerolabs/utils'
import type { EndpointId } from '@layerzerolabs/lz-definitions'
import { ignoreZero, makeZero, omniContractToPoint, type OmniContract } from '@layerzerolabs/utils-evm'

export class Endpoint implements IEndpoint {
constructor(public readonly contract: OmniContract) {}

async defaultReceiveLibrary(eid: EndpointId): Promise<string | undefined> {
return ignoreZero(await this.contract.contract.defaultReceiveLibrary(eid))
}

async setDefaultReceiveLibrary(
eid: EndpointId,
lib: string | null | undefined,
gracePeriod: number = 0
): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('setDefaultReceiveLibrary', [
eid,
makeZero(lib),
gracePeriod,
])

return {
...this.createTransaction(data),
description: `Setting default receive library for ${formatEid(eid)} to ${makeZero(lib)}`,
}
}

async defaultSendLibrary(eid: EndpointId): Promise<string | undefined> {
return ignoreZero(await this.contract.contract.defaultSendLibrary(eid))
}

async setDefaultSendLibrary(eid: EndpointId, lib: Address | null | undefined): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('setDefaultSendLibrary', [eid, makeZero(lib)])

return {
...this.createTransaction(data),
description: `Setting default send library for ${formatEid(eid)} to ${lib}`,
}
}

isRegisteredLibrary(lib: Address): Promise<boolean> {
return this.contract.contract.isRegisteredLibrary(lib)
}

async registerLibrary(lib: string): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('registerLibrary', [lib])

return {
...this.createTransaction(data),
description: `Registering library ${lib}`,
}
}

protected createTransaction(data: string): OmniTransaction {
return {
point: omniContractToPoint(this.contract),
data,
}
}
}
2 changes: 2 additions & 0 deletions packages/protocol-utils-evm/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './endpoint'
export * from './uln302'
1 change: 1 addition & 0 deletions packages/protocol-utils-evm/src/uln302/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './sdk'
23 changes: 23 additions & 0 deletions packages/protocol-utils-evm/src/uln302/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { AddressSchema } from '@layerzerolabs/utils'
import { BigNumberishBigintSchema } from '@layerzerolabs/utils-evm'
import { z } from 'zod'

/**
* Schema for parsing an ethers-specific UlnConfig into a common format
*/
export const Uln302UlnConfigSchema = z.object({
confirmations: BigNumberishBigintSchema,
requiredDVNs: z.array(AddressSchema),
optionalDVNs: z.array(AddressSchema),
optionalDVNThreshold: z.coerce.number().int().nonnegative(),
})

/**
* Schema for parsing a common UlnConfig into a ethers-specific format
*/
export const Uln302UlnConfigInputSchema = Uln302UlnConfigSchema.transform((config) => ({
...config,
confirmations: String(config.confirmations),
requiredDVNCount: config.requiredDVNs.length,
optionalDVNCount: config.optionalDVNs.length,
}))
51 changes: 51 additions & 0 deletions packages/protocol-utils-evm/src/uln302/sdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { EndpointId } from '@layerzerolabs/lz-definitions'
import type { IUln302, Uln302ExecutorConfig, Uln302UlnConfig } from '@layerzerolabs/protocol-utils'
import { formatEid, type OmniTransaction } from '@layerzerolabs/utils'
import { omniContractToPoint, type OmniContract } from '@layerzerolabs/utils-evm'
import { Uln302UlnConfigInputSchema, Uln302UlnConfigSchema } from './schema'

export class Uln302 implements IUln302 {
constructor(public readonly contract: OmniContract) {}

async getUlnConfig(eid: EndpointId, address: string): Promise<Uln302UlnConfig> {
const config = await this.contract.contract.getUlnConfig(address, eid)

// Now we convert the ethers-specific object into the common structure
//
// Here we need to spread the config into an object because what ethers gives us
// is actually an array with extra properties
return Uln302UlnConfigSchema.parse({ ...config })
}

async setDefaultExecutorConfig(eid: EndpointId, config: Uln302ExecutorConfig): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('setDefaultExecutorConfigs', [
[{ eid, config }],
])

return this.createTransaction(data)
}

async setDefaultUlnConfig(eid: EndpointId, config: Uln302UlnConfig): Promise<OmniTransaction> {
const serializedConfig = Uln302UlnConfigInputSchema.parse(config)
const data = this.contract.contract.interface.encodeFunctionData('setDefaultUlnConfigs', [
[
{
eid,
config: serializedConfig,
},
],
])

return {
...this.createTransaction(data),
description: `Setting default ULN config for ${formatEid(eid)}: ${JSON.stringify(serializedConfig)}`,
}
}

protected createTransaction(data: string): OmniTransaction {
return {
point: omniContractToPoint(this.contract),
data,
}
}
}
4 changes: 4 additions & 0 deletions packages/protocol-utils-evm/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "dist", "test"]
}
11 changes: 11 additions & 0 deletions packages/protocol-utils-evm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"exclude": ["dist", "node_modules"],
"include": ["src", "test", "*.config.ts"],
"compilerOptions": {
"types": ["node", "jest"],
"paths": {
"@/*": ["./src/*"]
}
}
}
14 changes: 14 additions & 0 deletions packages/protocol-utils-evm/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from 'tsup'

export default defineConfig([
{
entry: ['src/index.ts'],
outDir: './dist',
clean: true,
dts: true,
sourcemap: true,
splitting: false,
treeshake: true,
format: ['esm', 'cjs'],
},
])
3 changes: 3 additions & 0 deletions packages/protocol-utils/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.turbo
dist
node_modules
3 changes: 3 additions & 0 deletions packages/protocol-utils/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../.eslintrc.json"
}
31 changes: 31 additions & 0 deletions packages/protocol-utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<p align="center">
<a href="https://layerzero.network">
<img alt="LayerZero" style="max-width: 500px" src="https://d3a2dpnnrypp5h.cloudfront.net/bridge-app/lz.png"/>
</a>
</p>

<h1 align="center">@layerzerolabs/protocol-utils</h1>

<!-- The badges section -->
<p align="center">
<!-- Shields.io NPM published package version -->
<a href="https://www.npmjs.com/package/@layerzerolabs/protocol-utils"><img alt="NPM Version" src="https://img.shields.io/npm/v/@layerzerolabs/protocol-utils"/></a>
<!-- Shields.io NPM downloads -->
<a href="https://www.npmjs.com/package/@layerzerolabs/protocol-utils"><img alt="Downloads" src="https://img.shields.io/npm/dm/@layerzerolabs/protocol-utils"/></a>
<!-- Shields.io license badge -->
<a href="https://www.npmjs.com/package/@layerzerolabs/protocol-utils"><img alt="NPM License" src="https://img.shields.io/npm/l/@layerzerolabs/protocol-utils"/></a>
</p>

## Installation

```bash
npm install --save @layerzerolabs/protocol-utils
```

```bash
yarn install @layerzerolabs/protocol-utils
```

```bash
pnpm install @layerzerolabs/protocol-utils
```
8 changes: 8 additions & 0 deletions packages/protocol-utils/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
Loading

0 comments on commit 71793cb

Please sign in to comment.