Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

ethers: Webpack bundle and browser-html example #552

Merged
merged 34 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3c1bbb4
ethers: Webpack bundle and web-html example
blukat29 Dec 3, 2023
4bfe000
ethers: Browser example imports ethers cdn
blukat29 Dec 4, 2023
8a9efce
Initial test version
nohkwak Dec 5, 2023
f5f203c
Declare path
nohkwak Dec 5, 2023
d67ce80
Initial porting
nohkwak Dec 5, 2023
035da04
Create child classes
Dec 6, 2023
1899224
Web3Provider's getSigner call succeeds
Dec 6, 2023
8a5d9d3
Update browser-html
blukat29 Dec 6, 2023
f76bb27
ethers: Web3Provider and JsonRpcSigner skeleton
blukat29 Dec 6, 2023
09e1abf
Test signMessage and sendLegacyTx
Dec 8, 2023
d05ede3
ethers: Fix browser-html signMsg
blukat29 Dec 8, 2023
f466fb4
ethers: Fix browser-html to use klay_recoverFromMessage
blukat29 Dec 8, 2023
7a1ade8
ethers: Fix browser-html sendLegacy
blukat29 Dec 8, 2023
dae22b8
ethers: Implement JsonRpcSigner.signMessage
blukat29 Dec 8, 2023
f118520
ethers: Add JsonRpcSigner.isKaikas
blukat29 Dec 8, 2023
2befa3e
ethers: Bump deps
blukat29 Dec 8, 2023
57909b4
ethers: Add JsonRpcSigner.sendTransaction
Dec 12, 2023
48e688b
ethers: Refactor JsonRpcSigner.sendTransaction
Dec 12, 2023
51955c3
ethers: request VT to Kaikas
Dec 12, 2023
efc67b9
ethers: Separate logics in sendUncheckedTransaction
Dec 13, 2023
0fe25ab
ethers: Kaikas sign for FeeDelegatedVT
Dec 13, 2023
79674c0
ethers: Export providers like ethers v5
blukat29 Dec 15, 2023
82c11ec
ethers: Web3Provider and FeePayer
blukat29 Dec 15, 2023
1331ae5
ethers: Add deps TypeDoc
blukat29 Dec 15, 2023
848b32f
ethers: Update README
blukat29 Dec 15, 2023
95b2de0
Update README
blukat29 Dec 15, 2023
66f6540
ethers: Refactor
blukat29 Dec 15, 2023
3ee6bb4
Merge branch 'dev' into ethers/browser-bundle
blukat29 Dec 18, 2023
3125bde
ethers: Directly depend on @ethersproject packages
blukat29 Dec 18, 2023
1473a09
ethers: Update package.json informational metadata
blukat29 Dec 18, 2023
a2a4881
ethers: Update README
blukat29 Dec 18, 2023
64af1a8
ethers: Update browser-html example
blukat29 Dec 18, 2023
2773baf
jscore: Add parseTxType and getKaikasTxType
blukat29 Dec 18, 2023
463fe28
jscore: Add getChainIdFromSignatureTuples
blukat29 Dec 18, 2023
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
16 changes: 14 additions & 2 deletions ethers-ext/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ module.exports = {
"import/order": ["warn", {
"alphabetize": { "order": "asc", "caseInsensitive": true },
"pathGroups": [
{ "pattern": "@klaytn/**", "group": "external", "position": "after" },
{ "pattern": "@klaytn/**", "group": "parent", "position": "after" },
],
"newlines-between": "always",
"pathGroupsExcludedImportTypes": ["@klaytn/**"],
}],
"import/no-unresolved": [
"error", // eslint-plugin-import cannot resolve subpaths https://github.com/firebase/firebase-admin-node/discussions/1359
Expand Down Expand Up @@ -94,5 +95,16 @@ module.exports = {
"prefer-const": "off",
}
},
]
{ // browser examples use browser globals
"files": ["example/browser-html/*"],
"rules": {
"no-undef": "off",
"no-unused-vars": "off",
"no-constant-condition": "off",
}
},
],
"ignorePatterns": [
"example/browser-html/ethers-ext.bundle.js",
],
};
3 changes: 3 additions & 0 deletions ethers-ext/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ yarn.lock

# eslint
.eslintcache

# TypeDoc
docs
291 changes: 142 additions & 149 deletions ethers-ext/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,172 +2,165 @@

Ethers.js Extension for Klaytn offers:

- Drop-in replacement to `ethers.Wallet` that handles both Ethereum and Klaytn transactions
- Drop-in replacement to `ethers.Wallet` that handles both Ethereum and Klaytn transaction types
involving AccountKey and TxTypes.
- Drop-in replacement to `ethers.JsonRpcProvider` that provides Ethereum RPC as well as
- Drop-in replacement to `ethers.JsonRpcProvider` that provides accesses to both Ethereum RPCs and
Klaytn-specific RPCs.
- AccountStore to manage Klaytn account keys.
- Drop-in replacement to `ethers.Web3Provider` to work with both MetaMask (`window.ethereum`) and Kaikas (`window.klaytn`)

## Install

```
npm install --save @klaytn/ethers-ext
```

## Usage

See [example](./example) and [test](./test).


## Build

- Install dependencies
### Node.js

- Install
```sh
npm install --save @klaytn/ethers-ext
```
npm install
- ESM or TypeScript
```ts
import { Wallet, JsonRpcProvider } from "@klaytn/ethers-ext";
const provider = new JsonRpcProvider("https://public-en-baobab.klaytn.net");
const wallet = new Wallet("<private key>", provider);
```

- Build the library

```
npm run build
- CommonJS
```js
const { Wallet, JsonRpcProvider } = require("@klaytn/ethers-ext");
const provider = new JsonRpcProvider("https://public-en-baobab.klaytn.net");
const wallet = new Wallet("<private key>", provider);
```

- Run examples
### Browser

```
node example/rpc/rpc.js
```
It is not recommended to use CDNs in production, But you can use below for quick prototyping.

## Core classes

```mermaid
classDiagram
FieldType ..|> FieldTypeBytes
FieldType ..|> FieldTypeSignatureTuples
FieldType ..|> FieldTypeAccountKey
FieldType ..|> etc
class FieldType {
<<interface>>
canonicalize(any): any
emptyValue(): any
}
class FieldTypeBytes {
canonicalize(any): string
emptyValue(): string
}
class FieldTypeSignatureTuples {
canonicalize( SignatureLike[]): SignatureTuple[]
emptyValue(): SignatureTuple[]
}
class FieldTypeAccountKey {
canonicalize(TypedAccountKey | string | any): string
emptyValue(): string
}
```html
<script src="https://cdn.jsdelivr.net/npm/@klaytn/ethers-ext@latest/dist/ethers-ext.bundle.js"></script>
<script>
const provider = new ethers_ext.providers.Web3Provider(window.klaytn);
</script>
```

```mermaid
classDiagram
FieldSet <|-- KlaytnTx
KlaytnTx <|-- TxTypeValueTransfer
KlaytnTx <|-- TxTypeFeeDelegatedValueTransfer
KlaytnTx <|-- other TxTypes
FieldSet <|-- AccountKey
AccountKey <|-- AccountKeyLegacy
AccountKey <|-- AccountKeyPublic
AccountKey <|-- other AccountKey
class FieldSet {
type: number
typeName: string
fieldTypes: string -> FieldType
setFields(any)
setFieldsFromArray( string[], any[] )
getField( string ): any
getFields( string[] ): any[]
toObject(): any
}
class KlaytnTx {
sigRLP(): string
sigFeePayerRLP(): string
senderTxHashRLP(): string
txHashRLP(): string
addSenderSig(sig)
addFeePayerSig(sig)
setFieldsFromRLP(string): void
}
class AccountKey {
toRLP(): string
}
```
## Usage

```mermaid
classDiagram
FieldSetFactory <|.. KlaytnTxFactory
FieldSetFactory <|.. AccountKeyFactory
class FieldSetFactory {
private registry: [number] -> FieldSet
private requiredFields: string[]
add(typeof T)
has(type?): boolean
lookup(type?): typeof T
fromObject(any): T
}
class KlaytnTxFactory {
fromRLP(string): KlaytnTx
}
class AccountKeyFactory {
}
```
See [example](./example) and [test](./test).

## Class extension design

## ethers extension classes
If diagram does not render, view it [here](https://mermaid.live/edit#pako:eNrVV02P0zAQ_SuVTyB1q35vW3FZtMsBqLSiICQIqmbtaTdqYgfbXTWU_nfcJLRx4jRZISHIpfXz84w9M36294QKhmRGaABK3fqwlhB6vGU-DiGqCCi2UD-iVK19ih-_hJ3hy4W_5ii_eiRtd9K2R77lRxy_SIonn5kuC6WPSDcfJXAFVPuCv3hZGCWibQAaL1AUclbRfaiY9GcIAtTnSadtx6Sp4BypLrpco75hTKJSpcmY5c8NDmt0dV1ahgbt09ZKivCOUxlHGtlb1Zy3iDltsvYj90NEi3mz4OaRyOBPPEkksr8SKZPwk8MLvGWAa6DxotrRMvEUR8huQUOxVzyhlKZkayqsIs73Wb2fQ_wbKUS3KlGvQWHZSB5taChLbdlWocORdZO-tCJcOWi00_BhUHacRx1ercA38XK30yg5BGVPxR6HN1_NUcMc1MbGJX7fotIO_we3Ri5xp8s6mWpL5RKrN8iJUqeRJ2IDsTyH9vIea1L7Nq-hfNUOKOqYQxBu1BvEe4jdZdmMWOH9va_0c7i1qmvpamUV1Mnoc8rlgrD-GyVVr8tn6h8LdIlXd3I4FL2gk8UsAgt9bkMMH7brgpQeZ8GBU7TxTQCxjXBzFbEvQUZchBExG9W7SIjA49WV4pbu5uqal-n_eNGldRUPhfKJ8A78DSiX8Kd_rMtv69XPqyv7alnHsm9bttHswEjoDmu2oCSskjVrwGmV-QlY14g8O9_hmrJzUHGDWAHJn_W8ftglP1ZBpgGyrOeopRwn9NJ1gJM2CVGG4DPzDkrqwCPGQogemZm_DFewDczTwOMHQ4WtFkfJJ7MVBArbZBsxo47Z0-mERsC_CGG1yWxPdmTWm_Y6_elg0r3u9Qe98bQ7apOYzMajznDS7Y-G3eFkOBiOpoc2-ZFY6HauB6Nhfzzp9Ue98XV_MmkTZL4Wcp693Y4_h18MVzCG)

```mermaid
classDiagram
ethers_Wallet <|-- KlaytnWallet
ethers_Signer <|-- ethers_Wallet
class ethers_Signer {
provider
abstract getAddress()
abstract signMessage()
abstract signTransaction()
sendTransaction()
}
class ethers_Wallet {
address
privateKey
getAddress()
signMessage()
signTransaction()
checkTransaction()
populateTransaction()
sendTransaction()
}
class KlaytnWallet {
signTransaction()
checkTransaction()
populateTransaction()
sendTransaction()
}

ethers_Provider <|-- ethers_BaseProvider
ethers_BaseProvider <|-- ethers_JsonRpcProvider
ethers_JsonRpcProvider <|-- KlaytnJsonRpcProvider
class ethers_Provider {
abstract sendTransaction()
abstract call()
abstract estimateGas()
}
class ethers_BaseProvider {
sendTransaction()
waitForTransaction()
}
class ethers_JsonRpcProvider {
perform()
send()
prepareRequest() // "eth_sendRawTransaction"
}
class KlaytnJsonRpcProvider {
sendTransaction()
prepareRequest() // "klay_sendRawTransaction"
}
namespace ethers {
class ethers_Signer["ethers.Signer"] {
provider
checkTransaction()
populateTransaction()
sendTransaction()
}
class ethers_Wallet["ethers.Wallet"] {
connect()
getAddress()
signMessage()
signTransaction()
static fromEncryptedJson()
static fromEncryptedJsonSync()
}
class ethers_JsonRpcSigner["ethers.JsonRpcSigner"] {
connect()
connectUnchecked()
getAddress()
signMessage()
signTransaction()
sendUncheckedTransaction()
_legacySignMessage()
_signTypedData()
override sendTransaction()
}

class ethers_Provider["ethers.Provider"] {
}
class ethers_BaseProvider["ethers.BaseProvider"] {
}
class ethers_JsonRpcProvider["ethers.JsonRpcProvider"] {
getSigner()
send()
}
class ethers_Web3Provider["ethers.Web3Provider"] {
override send()
}
class ethers_ExternalProvider["ethers.ExternalProvider"] {
isMetaMask
request()
}
}
namespace ethers_ext {
class Wallet {
override getAddress()
override checkTransaction()
override populateTransaction()
override signTransaction()
override sendTransaction()
override static fromEncryptedJson()
override static fromEncryptedJsonSync()
signTransactionAsFeePayer()
sendTransactionAsFeePayer()
static fromEncryptedJsonList()
static fromEncryptedJsonListSync()
}
class JsonRpcSigner {
override connectUnchecked()
override getAddress()
override signMessage()
override checkTransaction()
override populateTransaction()
override signTransaction()
override _legacySignMessage()
override _signTypedData()
override sendTransaction()
override sendUncheckedTransaction()
}

class JsonRpcProvider {
admin
debug
governance
klay
net
personal
txpool

override getSigner()
override send()
}
class Web3Provider {
admin
debug
governance
klay
net
personal
txpool

override getSigner()
}
class ExternalProvider {
isKaikas
}
}

ethers_Signer <|-- ethers_Wallet
ethers_Signer <|-- ethers_JsonRpcSigner

ethers_Wallet <|-- Wallet
ethers_JsonRpcSigner <|-- JsonRpcSigner


ethers_Provider <|-- ethers_BaseProvider
ethers_BaseProvider <|-- ethers_JsonRpcProvider
ethers_JsonRpcProvider <|-- ethers_Web3Provider

ethers_JsonRpcProvider <|-- JsonRpcProvider
ethers_Web3Provider <|-- Web3Provider
ethers_ExternalProvider <|-- ExternalProvider

```
1 change: 1 addition & 0 deletions ethers-ext/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- [accountKey](./accountKey) Klaytn AccountKey types
- [accountStore](./accountStore) AccountStore usage
- [browser-html](./browser-html) Browser extension wallets (e.g. Kaikas) interaction in plain HTML
- [rpc](./rpc) Klaytn node RPC wrappers
- [smartContract](./smartContract) Smart contract usage
- [transactions](./transactions) Klaytn transaction types
Expand Down
13 changes: 13 additions & 0 deletions ethers-ext/example/browser-html/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Running the browser extension example

Run a HTTP server to serve the HTML and JS files. Use python3 http.server for example:

```
python3 -m http.server 3000
```

Then open `http://localhost:3000` with the browser.

Note that the browser extension wallets (e.g. MetaMask and Kaikas) does not work in the `file:///` page.
Therefore you cannot run this example by double-clicking the `index.html`.

1 change: 1 addition & 0 deletions ethers-ext/example/browser-html/ethers-ext.bundle.js
Loading