Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create erc20 wrap #1

Merged
merged 4 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/erc20-cd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: erc20-cd

on:
pull_request:
types: [closed]
branches:
- main

jobs:
cd:
name: erc20-cd
if: |
github.event.pull_request.merged &&
endsWith(github.event.pull_request.title, '/workflows/cd') &&
github.event.pull_request.user.login != 'github-actions'
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Read .nvmrc
run: echo ::set-output name=NVMRC::$(cat .nvmrc)
id: nvm

- name: Setup Node.js
uses: actions/setup-node@master
with:
node-version: '${{ steps.nvm.outputs.NVMRC }}'

- name: Install dependencies
run: yarn install --nonInteractive --frozen-lockfile --prefer-offline

- name: Build
run: yarn build

- name: Deploy
run: yarn deploy
env:
POLYWRAP_WRAPSCAN_AUTH_HEADER_PROD: ${{secrets.POLYWRAP_WRAPSCAN_AUTH_HEADER_PROD}}

- name: PR New URI
uses: peter-evans/create-pull-request@v3
with:
branch: erc20-cd-pr-${{github.event.number}}
commit-message: "[CD] erc20"
title: "[CD] erc20"
body: "Triggered by: https://github.com/${{github.repository}}/pull/${{github.event.number}}"
31 changes: 31 additions & 0 deletions .github/workflows/erc20-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: erc20-ci

on:
pull_request:

jobs:
ci:
name: erc20-ci
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Read .nvmrc
run: echo ::set-output name=NVMRC::$(cat .nvmrc)
id: nvm

- name: Setup Node.js
uses: actions/setup-node@master
with:
node-version: '${{ steps.nvm.outputs.NVMRC }}'

- name: Install dependencies
run: yarn install --nonInteractive --frozen-lockfile --prefer-offline

- name: Build
run: yarn build

- name: Test
run: yarn test
113 changes: 113 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Project
wrap
build
.polywrap
target
__pycache__
.vscode
.idea
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18
71 changes: 69 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,69 @@
# erc20
ERC20 Wrap
# ERC20 Wrap

## Introduction

The ERC20 Wrap offers developers an intuitive interface to interact with any ERC20 token on the Ethereum blockchain, leveraging the Polywrap framework. By using the Wasm wrap written in Rust, developers can effortlessly interact with ERC20 tokens on any platform without dealing with the intricacies of direct smart contract interactions.

## Features

- **Token Information**: Fetch metadata like the token's name, symbol, and decimals.
- **Balance Queries**: Determine the balance of a particular address.
- **Token Transfers**: Facilitate token transfers between addresses.
- **Allowance Management**: Set and query allowances between owner and spender addresses.
- **Total Supply**: Retrieve the total supply of the ERC20 token.
- **Cross-Platform**: Thanks to Polywrap, this Wrap is compatible with virtually any platform.

## Installation

To install the ERC20 Wrap, make sure to have the `@polywrap/client-js` package:

```bash
npm install @polywrap/client-js
```

> Note: Installation steps can vary based on your environment. Refer to the [Polywrap documentation](https://docs.polywrap.io/) for comprehensive guidelines.

## Usage

To illustrate the Wrap's utility, here's an example of how you can fetch the metadata of an ERC20 token:

```javascript
import {PolywrapClient} from "@polywrap/client-js";

async function fetchTokenMeta(tokenAddress) {
const client = new PolywrapClient();

const result = await client.invoke({
uri: "wrapscan.io/polywrap/[email protected]",
method: "tokenMeta",
args: { address: tokenAddress },
});

console.log(result); // Should display the token's metadata
}

const DAI_ADDRESS = "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359";
fetchTokenMeta(DAI_ADDRESS).then(() => {
console.log("Metadata fetched!");
});
```

## ERC20 Wrap Overview

This Wrap provides essential methods to interact with ERC20 tokens:

- **tokenMeta**: Retrieve general metadata of the token.
- **totalSupply**: Determine the token's total circulating supply.
- **balanceOf**: Check the balance of an address.
- **transfer**: Transfer tokens between addresses.
- **transferFrom**: Facilitate transfers on behalf of a user (requires approval).
- **approve**: Allow another address to manage a certain amount of tokens.
- **allowance**: Check the permitted token amount an address can spend on behalf of another.

## Feedback and Contributions

For any issues, feature requests, or contributions, please raise an issue on our GitHub repository. Community involvement is encouraged, but make sure to adhere to our contribution guidelines and code of conduct.

## License

This SDK is released under the [MIT License](LICENSE). For more details, please check the LICENSE file.
15 changes: 15 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
collectCoverage: false,
preset: "ts-jest",
testEnvironment: "node",
testMatch: ["**/__tests__/**/?(*.)+(spec|test).[jt]s?(x)"],
globals: {
"ts-jest": {
tsconfig: "tsconfig.json",
diagnostics: false,
},
},
testPathIgnorePatterns: [
"/.polywrap/"
],
};
30 changes: 30 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "erc20",
"description": "ERC20 Wrapper",
"private": true,
"version": "1.0.0",
"scripts": {
"codegen": "npx polywrap codegen",
"build": "npx polywrap build",
"test:env:up": "npx polywrap infra up --modules=eth-ens-ipfs",
"test:env:down": "npx polywrap infra down --modules=eth-ens-ipfs",
"deploy": "npx polywrap deploy",
"test": "yarn test:e2e",
"test:e2e": "yarn test:e2e:codegen && jest --passWithNoTests --runInBand --verbose",
"test:e2e:codegen": "npx polywrap codegen -m ./src/__tests__/types/polywrap.app.yaml -g ./src/__tests__/types/wrap",
"test:workflow:mock": "echo not implemented",
"test:workflow": "echo not implemented"
},
"devDependencies": {
"@types/jest": "27.0.3",
"jest": "26.6.3",
"nock": "13.0.7",
"polywrap": "0.12.0",
"ts-jest": "26.5.4",
"typescript": "4.0.7"
},
"dependencies": {
"@polywrap/wasm-as": "^0.12.0",
"as-container": "^0.8.0"
}
}
18 changes: 18 additions & 0 deletions polywrap.deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
format: 0.4.0
primaryJobName: ipfs_deploy
jobs:
ipfs_deploy:
steps:
- name: ipfs_deploy
package: ipfs
uri: fs/./build
config:
gatewayUri: https://ipfs.wrappers.io
- name: http_deploy
package: http
uri: $$ipfs_deploy
config:
postUrl: https://wraps.wrapscan.io/r/polywrap/[email protected]
headers:
- name: Authorization
value: $POLYWRAP_WRAPSCAN_AUTH_HEADER_PROD
18 changes: 18 additions & 0 deletions polywrap.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#import * into Ethers from "wrapscan.io/polywrap/[email protected]"

type Module {
tokenMeta(address: String!): TokenMeta!
totalSupply(address: String!): BigInt
balanceOf(address: String!, owner: String!): BigInt!
transfer(address: String!, to: String!, value: BigInt!): Ethers_TxResponse!
transferFrom(address: String!, from: String!, to: String!, value: BigInt!): Ethers_TxResponse!
approve(address: String!, spender: String!, value: BigInt!): Ethers_TxResponse!
allowance(address: String!, owner: String!, spender: String!): BigInt!
}

type TokenMeta {
address: String!
name: String!
symbol: String!
decimals: Int!
}
7 changes: 7 additions & 0 deletions polywrap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
format: 0.5.0
project:
name: erc20
type: wasm/assemblyscript
source:
schema: ./polywrap.graphql
module: ./src/index.ts
25 changes: 25 additions & 0 deletions src/ERC20/IERC20/allowance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { BigInt } from "@polywrap/wasm-as";
import { Ethers_Module } from "../../wrap";

export function allowance(
tokenAddress: string,
owner: string,
spender: string
): BigInt {

// If tokenAddress is for Ether, throw an error since allowance does not apply to Ether
if (tokenAddress.toLowerCase() == "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") {
throw new Error("allowance function is not supported for native Ether");
}

// For ERC20 token allowance
const methodSignature = "function allowance(address,address) external view returns (uint256)";
const allowanceResult = Ethers_Module.callContractView({
address: tokenAddress,
method: methodSignature,
args: [owner, spender], // Pass the owner and spender addresses as arguments
connection: null,
}).unwrap();

return BigInt.fromString(allowanceResult);
}
Loading
Loading