Skip to content

Commit

Permalink
Add viem implementation - wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dmytrotkk committed Dec 16, 2024
1 parent 63565b5 commit de92bf2
Show file tree
Hide file tree
Showing 12 changed files with 1,759 additions and 1 deletion.
2 changes: 1 addition & 1 deletion dictionary
Submodule dictionary updated 2 files
+1 −0 libraries.txt
+2 −0 names.txt
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"typescript-base-check": "yarn ./typescript/base fullCheck",
"ethers5-check": "yarn ./typescript/ethers-v5 fullCheck",
"ethers6-check": "yarn ./typescript/ethers-v6 fullCheck",
"viem-check": "yarn ./typescript/viem fullCheck",
"typescript-check": "yarn typescript-base-check && yarn ethers5-check && yarn ethers6-check",
"fullCheck": "yarn cspell && yarn typescript-check && yarn python-check",
"cspell": "npx cspell \"**/*\"",
Expand Down
6 changes: 6 additions & 0 deletions typescript/viem/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-env node */
module.exports = {
extends: [
'../base/.eslintrc.cjs'
]
};
15 changes: 15 additions & 0 deletions typescript/viem/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

lib/
*.log
node_modules/
cache
src/debug.ts

.editorconfig
.gitattributes
7 changes: 7 additions & 0 deletions typescript/viem/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nodeLinker: node-modules

plugins:
- path: ../base/.yarn/plugins/@yarnpkg/plugin-version.cjs
spec: "@yarnpkg/plugin-version"

yarnPath: ../base/.yarn/releases/yarn-berry.js
71 changes: 71 additions & 0 deletions typescript/viem/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# SKALE Contracts Viem

## Description

The library simplifies development of dApps that interact with smart contracts in SKALE infrastructure using viem.

## Features

- Resolving of addresses of SKALE contracts on different networks
- Providing up to date ABI for SKALE contracts (they may change over time due to upgradeable nature of some contracts)
- Automatic creation of Contract objects using viem
- Full TypeScript support with viem types

## Installation

```bash
yarn add @skalenetwork/skale-contracts-viem
```

## Glossary

Main abstractions used by the library is provided below:

### Network

Represents blockchain where smart contracts are deployed.

It could be Ethereum mainnet, goerli, SKALE chain or similar ethereum compatible chains

### Project

SKALE smart contracts grouped into projects to serve particular purpose.

Examples of projects are [IMA](https://github.com/skalenetwork/IMA/), [skale-manager](https://github.com/skalenetwork/skale-manager) or [etherbase](https://github.com/skalenetwork/etherbase/).

### Instance

An instance is a particular project deployed to a particular network.

For example `IMA` on Ethereum mainnet or `etherbase` on some of SKALE chains.

### Alias

An alias is a textual name of an instance.

## Usage

The library provides master object `skaleContracts`.

This object is used to provide desired [network](#network), [project](#project) and [instance](#instance) using it's [alias](#alias) or direct address.

When target instance is received it can be queried for information (address, ABI or Contract object) about a particular contract by it's name.

### Example

```typescript
import { skaleContracts } from "@skalenetwork/skale-contracts-viem";
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";

const client = createPublicClient({
chain: mainnet,
transport: http(),
});

const network = await skaleContracts.getNetworkByProvider(client);
const project = await network.getProject("skale-manager");
const instance = await project.getInstance("production");
const nodes = await instance.getContract("Nodes");
const numberOfActiveNodes = await nodes.read.numberOfActiveNodes();
```
29 changes: 29 additions & 0 deletions typescript/viem/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"engines": {
"node": ">=20.0.0"
},
"devDependencies": {
"@skalenetwork/skale-contracts": "portal:../base/",
"@types/node": "^22.9.3",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^8.13.0",
"eslint": "^8.45.0",
"typescript": "^5.7.2"
},
"files": [
"lib/**/*"
],
"main": "lib/index.js",
"name": "@skalenetwork/skale-contracts-viem",
"packageManager": "[email protected]",
"scripts": {
"compile": "npx tsc",
"fullCheck": "yarn compile && yarn eslint",
"prepare": "yarn compile",
"eslint": "npx eslint ."
},
"types": "lib/index.d.ts",
"dependencies": {
"viem": "^2.21.55"
}
}
4 changes: 4 additions & 0 deletions typescript/viem/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { SkaleContracts } from "./skaleContracts";
export { Instance } from "./skaleContracts";

export const skaleContracts = new SkaleContracts();
16 changes: 16 additions & 0 deletions typescript/viem/src/skaleContracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { GetContractReturnType, PublicClient, Abi as ViemAbi } from 'viem';
import {
Instance as BaseInstance
} from "@skalenetwork/skale-contracts/lib/instance";
import {
SkaleContracts as BaseSkaleContracts
} from "@skalenetwork/skale-contracts";
import { ViemAdapter } from './viemAdapter';

export type Instance = BaseInstance<GetContractReturnType<ViemAbi>>;

export class SkaleContracts extends BaseSkaleContracts<GetContractReturnType<ViemAbi>> {
getNetworkByProvider(client: PublicClient) {
return this.getNetworkByAdapter(new ViemAdapter(client));
}
}
60 changes: 60 additions & 0 deletions typescript/viem/src/viemAdapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Abi, Adapter, ContractData, FunctionCall } from '@skalenetwork/skale-contracts';
import {
Address,
WalletClient,
GetContractReturnType,
PublicClient,
Abi as ViemAbi,
getContract as getContractViem,
isAddress
} from 'viem';


type ViemContract = GetContractReturnType<ViemAbi, PublicClient>


export class ViemAdapter implements Adapter<ViemContract> {
client: PublicClient;

constructor(client: PublicClient) {
this.client = client;
}

// createContract(address: string, abi: Abi) {
// return getContractViem({
// abi: abi as ViemAbi,
// address: address as Address,
// client: this.client
// }) as GetContractReturnType<ViemAbi, PublicClient | WalletClient>;
// }

createContract(address: string, abi: Abi): ViemContract {
return getContractViem({
abi: abi as ViemAbi,
address: address as Address,
client: this.client
}) as ViemContract;
}

async makeCall(
contract: ContractData,
targetFunction: FunctionCall
): Promise<unknown> {
return await this.client.readContract({
abi: contract.abi as ViemAbi,
address: contract.address as Address,
args: targetFunction.args,
functionName: targetFunction.functionName
});
}

async getChainId(): Promise<bigint> {
const chainId = await this.client.getChainId();
return BigInt(chainId);
}

// eslint-disable-next-line class-methods-use-this
isAddress(value: string): boolean {
return isAddress(value);
}
}
9 changes: 9 additions & 0 deletions typescript/viem/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../base/tsconfig.json",

"compilerOptions": {
"outDir": "./lib",
},
"include": ["src"],
"exclude": ["node_modules"]
}
Loading

0 comments on commit de92bf2

Please sign in to comment.