Skip to content

Commit

Permalink
Combine with package micro-web3
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Jan 5, 2024
1 parent 8767474 commit 844470f
Show file tree
Hide file tree
Showing 23 changed files with 4,821 additions and 4 deletions.
115 changes: 114 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ Create, sign and validate Ethereum transactions & addresses with minimum deps.
- Validated against 3MB of [ethers](https://github.com/ethers-io/ethers.js/) test vectors
- Using audited [noble](https://paulmillr.com/noble/) cryptography under the hood

*Check out all web3 utility libraries:* [ETH](https://github.com/paulmillr/micro-eth-signer), [BTC](https://github.com/paulmillr/scure-btc-signer), [SOL](https://github.com/paulmillr/micro-sol-signer), [micro-web3](https://github.com/paulmillr/micro-web3), [tx-tor-broadcaster](https://github.com/paulmillr/tx-tor-broadcaster)
Typesafe Web3 with minimum deps: call eth contracts directly from JS. Batteries included.

- Connect to web3 nodes
- Write typesafe code with auto inference of TypeScript types from ABI JSON
- Fetch token balances, resolve ENS domains, watch token prices with chainlink web3 oracle
- Decode transactions: create readable tx descriptions from tx data & ABIs
- No network code in main package: allows simpler audits and offline usage

*Check out all web3 utility libraries:* [ETH](https://github.com/paulmillr/micro-eth-signer), [BTC](https://github.com/paulmillr/scure-btc-signer), [SOL](https://github.com/paulmillr/micro-sol-signer), [tx-tor-broadcaster](https://github.com/paulmillr/tx-tor-broadcaster)

## Usage

Expand Down Expand Up @@ -76,6 +84,111 @@ const berlinTx = new Transaction({
}, undefined, undefined, 'eip2930');
```


```ts
import web3 from 'micro-eth-signer/web3';
import contracts from 'micro-eth-signer/web3/contracts';
import web3net from 'micro-eth-signer/web3-net';
const DEF_CONTRACTS = contracts.DEFAULT_CONTRACTS;
```

### Decode transactions without network

```ts
import { hex } from '@scure/base';
const tx =
'a9059cbb000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000542598700';
const decoder = new web3.Decoder();
const USDT = contracts.tokenFromSymbol('USDT').contract;
decoder.add(USDT, contracts.ERC20);
const info = decoder.decode(USDT, hex.decode(tx), { contractInfo: DEF_CONTRACTS[USDT] });
console.log(info);
// { name: 'transfer', signature: 'transfer(address,uint256)',
// value: { to: '0xdac17f958d2ee523a2206206994597c13d831ec7', value: 22588000000n },
// hint: 'Transfer 22588 USDT to 0xdac17f958d2ee523a2206206994597c13d831ec7' }
```

### Decode events

```ts
const BAT = '0x0d8775f648430679a709e98d2b0cb6250d2887ef';
const decoder = new web3.Decoder();
decoder.add(BAT, contracts.ERC20);
const info = decoder.decodeEvent(
BAT,
[
'0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925',
'0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045',
'0x000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564',
],
'0x00000000000000000000000000000000000000000000003635c9adc5dea00000',
{ contract: BAT, contracts: { ...DEF_CONTRACTS }, contractInfo: DEF_CONTRACTS[BAT] }
);
console.log(info.hint);
// Allow 0xe592427a0aece92de3edee1f18e0157c05861564 spending up to 1000 BAT from 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
```

### Fetch Chainlink oracle prices

```ts
import chainlink from 'micro-eth-signer/web3/api/chainlink';
const provider = new web3net.Web3({
url: 'https://nodes.mewapi.io/rpc/eth',
headers: { Origin: 'https://www.myetherwallet.com' },
});
const btc = await chainlink.coinPrice(provider, 'BTC');
const bat = await chainlink.tokenPrice(provider, 'BAT');
console.log({ btc, bat }); // BTC 19188.68870991, BAT 0.39728989 in USD
```

### Uniswap

Swap 12.12 USDT to BAT with uniswap V3 defaults of 0.5% slippage, 30 min expiration.

```ts
import univ2 from 'micro-eth-signer/web3/api/uniswap-v2';
import univ3 from 'micro-eth-signer/web3/api/uniswap-v3';

const provider = new web3net.Web3({
url: 'https://nodes.mewapi.io/rpc/eth',
headers: { Origin: 'https://www.myetherwallet.com' },
});
const USDT = contracts.tokenFromSymbol('USDT');
const BAT = contracts.tokenFromSymbol('BAT');
const u3 = new univ3.UniswapV3(provider); // or new univ2.UniswapV2(provider)
const fromAddress = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045';
const toAddress = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045';
const swap = await u3.swap(USDT, BAT, '12.12', { slippagePercent: 0.5, ttl: 30 * 60 });
const swapData = await swap.tx(fromAddress, toAddress);
console.log(swapData.amount, swapData.expectedAmount, swapData.allowance);
```

### Type inference

The ABI is type-safe with following limitations:

- Fixed size arrays can have 999 elements at max: string[], string[1], ..., string[999]
- Fixed size 2d arrays can have 39 elements at max: string[][], string[][1], ..., string[39][39]
- Which is enough for almost all cases
- ABI must be described as constant value: `[...] as const`
- We're not able to handle contracts with method overload (same function names with different args) — the code will still work, but not types

We're parsing values as:

```js
// no inputs
{} -> encodeInput();
// single input
{inputs: [{type: 'uint'}]} -> encodeInput(bigint);
// all inputs named
{inputs: [{type: 'uint', name: 'lol}, {type: 'address', name: 'wut'}]} -> encodeInput({lol: bigint, wut: string})
// at least one input is unnamed
{inputs: [{type: 'uint', name: 'lol}, {type: 'address'}]} -> encodeInput([bigint, string])
// Same applies for output!
```

Check out [`src/api/ens.ts`](./src/api/ens.ts) for type-safe contract execution example.

## API

### Address
Expand Down
38 changes: 37 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"dependencies": {
"@ethereumjs/rlp": "5.0.0",
"@noble/curves": "~1.3.0",
"@noble/hashes": "~1.3.3"
"@noble/hashes": "~1.3.3",
"micro-packed": "~0.4.0"
},
"devDependencies": {
"micro-bmark": "0.3.0",
Expand Down Expand Up @@ -49,6 +50,6 @@
"bench": "node test/benchmark.js",
"lint": "prettier --print-width 100 --single-quote --check src",
"format": "prettier --print-width 100 --single-quote --write src",
"test": "node test/test.js"
"test": "node test/test.js && node test/web3.test.js"
}
}
Loading

0 comments on commit 844470f

Please sign in to comment.