From 38e384225a7437ee50e24d7c7c31e0f33757f22d Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 17:14:26 +0900 Subject: [PATCH 01/69] ethers: Add deps @klaytn/js-ext-core --- ethers-ext/package-lock.json | 37 ++++++++++++++---------------------- ethers-ext/package.json | 2 +- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index f17f0744b..a48aed3e2 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -9,7 +9,7 @@ "version": "0.9.5-beta", "license": "MIT", "dependencies": { - "@klaytn/ethers-ext": "^0.9.3-beta", + "@klaytn/js-ext-core": "^0.9.6-beta", "@klaytn/web3rpc": "^0.9.0", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", @@ -689,7 +689,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/bytes": "^5.7.0", @@ -751,7 +750,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0", @@ -772,7 +770,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/logger": "^5.7.0" } @@ -791,7 +788,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0" } @@ -926,7 +922,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "js-sha3": "0.8.0" @@ -945,8 +940,7 @@ "type": "individual", "url": "https://www.buymeacoffee.com/ricmoo" } - ], - "peer": true + ] }, "node_modules/@ethersproject/networks": { "version": "5.7.1", @@ -1001,7 +995,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/logger": "^5.7.0" } @@ -1078,7 +1071,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0" @@ -1119,7 +1111,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0", @@ -1188,7 +1179,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", @@ -1215,7 +1205,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/constants": "^5.7.0", @@ -1401,16 +1390,19 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@klaytn/ethers-ext": { - "version": "0.9.3-beta", - "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.3-beta.tgz", - "integrity": "sha512-As3iP/KhxG6+EVbnEln4QtF5A/M5HI7uGFzbFXFSQCd4LpQlLovQcI31fjaD9tgCw4DA4agAqHNcnBPBnX6j6A==", + "node_modules/@klaytn/js-ext-core": { + "version": "0.9.6-beta", + "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.6-beta.tgz", + "integrity": "sha512-t4rYzZ0SOOqFoyhkvgYPG16Yb54zzsa/3IrIfrm40OMWwaVuCdje6rUoPAcQryoGviBZel8B04o/2l17Bm4c0Q==", "dependencies": { - "@klaytn/web3rpc": "^0.9.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/units": "^5.7.0", + "elliptic": "^6.5.4", "lodash": "^4.17.21" - }, - "peerDependencies": { - "ethers": "^5.7.2" } }, "node_modules/@klaytn/web3rpc": { @@ -4419,8 +4411,7 @@ "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "peer": true + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "node_modules/js-tokens": { "version": "4.0.0", diff --git a/ethers-ext/package.json b/ethers-ext/package.json index 1e81ceca5..566802bbc 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -37,7 +37,7 @@ "typescript": "^5.0.4" }, "dependencies": { - "@klaytn/ethers-ext": "^0.9.3-beta", + "@klaytn/js-ext-core": "^0.9.6-beta", "@klaytn/web3rpc": "^0.9.0", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", From 14b082d61ece3d459e47bf83fc636c9c75eed1b9 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 17:24:49 +0900 Subject: [PATCH 02/69] ethers: Use jscore keystore --- ethers-ext/package.json | 2 +- ethers-ext/src/ethers/keystore/decrypt.ts | 82 -------- ethers-ext/src/ethers/keystore/index.ts | 2 - ethers-ext/src/ethers/keystore/type.ts | 33 --- ethers-ext/src/ethers/signer.ts | 37 ++-- ethers-ext/src/index.ts | 3 + ethers-ext/src/keystore.ts | 77 +++++++ .../test/ethers/decrypt_encrypt.spec.ts | 198 ------------------ ethers-ext/test/ethers/keystore.spec.ts | 51 +++++ 9 files changed, 156 insertions(+), 329 deletions(-) delete mode 100644 ethers-ext/src/ethers/keystore/decrypt.ts delete mode 100644 ethers-ext/src/ethers/keystore/index.ts delete mode 100644 ethers-ext/src/ethers/keystore/type.ts create mode 100644 ethers-ext/src/keystore.ts delete mode 100644 ethers-ext/test/ethers/decrypt_encrypt.spec.ts create mode 100644 ethers-ext/test/ethers/keystore.spec.ts diff --git a/ethers-ext/package.json b/ethers-ext/package.json index 566802bbc..a7843fae1 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -12,7 +12,7 @@ "lint": "npm run lint:check", "lint:check": "eslint example src test --cache --quiet", "lint:fix": "eslint example src test --cache --fix", - "test": "mocha test/**/*.ts -r ts-node/register", + "test": "mocha --timeout 10000 -r ts-node/register \"test/**/*.ts\"", "prepublishOnly": "npm run build" }, "license": "MIT", diff --git a/ethers-ext/src/ethers/keystore/decrypt.ts b/ethers-ext/src/ethers/keystore/decrypt.ts deleted file mode 100644 index cc9939961..000000000 --- a/ethers-ext/src/ethers/keystore/decrypt.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Bytes } from "@ethersproject/bytes"; -import { decryptKeystoreSync } from "@ethersproject/json-wallets"; -import * as _ from "lodash"; -import { IKeyStore } from "."; - -// Modified from KeystoreAccount at @ethersproject/json-wallets/src.ts/keystore.ts -interface KeystoreAccountList { - address: string; - privateKeys: string[]; -} - -function decryptKey(crypto: any, password: Bytes | string): string { - const datav3 = { - version: 3, - crypto: crypto, - }; - const jsonv3 = JSON.stringify(datav3); - const ka = decryptKeystoreSync(jsonv3, password); - return ka.privateKey; -} - -/** - * Decrypts the Klaytn KIP-3 (https://github.com/klaytn/kips/blob/main/KIPs/kip-3.md) JSON wallet. - * KIP-3 v4 wallet comes in one of three shapes: - * - An array of one key = [key] - * - An array of multiple keys = [key, key, key] - * - * Regardless of how they are organized, each encrytped key object is decrypted - * then returned in a flattend array of private keys. - * - */ -function decryptKeystoreV4(json: string, password: Bytes | string): KeystoreAccountList { - const data: IKeyStore = JSON.parse(json); - const privateKeys: string[] = []; - - if (!_.has(data, "keyring")) { - throw new Error("invalid JSON wallet v4 (KIP-3)"); - } - if (!_.isArray(data.keyring)) { - throw new Error("invalid JSON wallet v4 (KIP-3)"); - } - - _.each(data.keyring, (keyOrKeys: any) => { - if (!_.isArray(keyOrKeys)) { - const key: any = keyOrKeys; - privateKeys.push(decryptKey(key, password)); - } else { - const keys: any[] = keyOrKeys; - _.each(keys, (key: any) => { - privateKeys.push(decryptKey(key, password)); - }); - } - }); - - return { - address: _.toString(data.address), - privateKeys: privateKeys, - }; -} - -/** - * Decrypts a JSON keystore wallet and returns the account details containing - * the account address and the list of private keys. - * It accepts a Crowdsale wallet, V3 keystore, and KIP-3 V4 keystore wallets. - * - */ -export function decryptKeystoreListSync(json: string, password: Bytes | string): KeystoreAccountList { - const data: IKeyStore = JSON.parse(json); - const version = data.version; - - // decryptKeystoreV4 handles v4 (KIP-3) wallets. - if (version == 4) { - return decryptKeystoreV4(json, password); - } - - // decryptKeystoreSync handles v3 and Crowdsale wallets. - const ka = decryptKeystoreSync(json, password); - return { - address: ka.address, - privateKeys: [ka.privateKey], - }; -} \ No newline at end of file diff --git a/ethers-ext/src/ethers/keystore/index.ts b/ethers-ext/src/ethers/keystore/index.ts deleted file mode 100644 index 5cfd2c109..000000000 --- a/ethers-ext/src/ethers/keystore/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { decryptKeystoreListSync } from "./decrypt"; -export * from "./type"; diff --git a/ethers-ext/src/ethers/keystore/type.ts b/ethers-ext/src/ethers/keystore/type.ts deleted file mode 100644 index 0bd7e88f5..000000000 --- a/ethers-ext/src/ethers/keystore/type.ts +++ /dev/null @@ -1,33 +0,0 @@ - - -export interface IKeyStore { - address: string, - id: string, - version: number, - keyring?: Keyring[] | Keyring [][], - crypto?: Keyring, - -} -export interface Keyring { - cipher: string, - cipherparams: CipherParams, - ciphertext: string, - kdf: string, - kdfparams: KdfParam, - mac?: string -} - -interface CipherParams { - iv: string -} - -export interface KdfParam { - salt: string, - n: number, - dklen: number, - p: number, - r: number, - c?: number, - prf?: string, -} - diff --git a/ethers-ext/src/ethers/signer.ts b/ethers-ext/src/ethers/signer.ts index 3e1fff95a..a48334f78 100644 --- a/ethers-ext/src/ethers/signer.ts +++ b/ethers-ext/src/ethers/signer.ts @@ -3,14 +3,13 @@ import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/provide import { Wallet as EthersWallet } from "@ethersproject/wallet"; import { poll } from "@ethersproject/web"; import { ethers } from "ethers"; -import { Bytes, Deferrable, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; +import { Bytes, Deferrable, ProgressCallback, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; import _ from "lodash"; import { KlaytnTxFactory } from "../core"; import { encodeTxForRPC, objectFromRLP } from "../core/klaytn_tx"; import { HexStr } from "../core/util"; - -import { decryptKeystoreListSync } from "./keystore"; +import { decryptKeystoreList, decryptKeystoreListSync } from "../keystore"; // @ethersproject/abstract-signer/src.ts/index.ts:allowedTransactionKeys const ethersAllowedTransactionKeys: Array = [ @@ -58,6 +57,28 @@ function restoreCustomFields(tx: Deferrable, savedFields: an export class Wallet extends EthersWallet { + // Override Wallet factories accepting keystores to support KIP-3 (v4) format + static override async fromEncryptedJson(json: string, password: string | Bytes, progress?: ProgressCallback): Promise { + const { address, privateKey } = await decryptKeystoreList(json, password, progress); + return new Wallet(address, privateKey); + } + + static override fromEncryptedJsonSync(json: string, password: string | Bytes): Wallet { + const { address, privateKey } = decryptKeystoreListSync(json, password); + return new Wallet(address, privateKey); + } + + // New Wallet[] factories accepting keystores supporting KIP-3 (v4) format + static async fromEncryptedJsonList(json: string, password: string | Bytes, progress?: ProgressCallback): Promise { + const { address, privateKeyList } = await decryptKeystoreList(json, password, progress); + return _.map(privateKeyList, (privateKey) => new Wallet(address, privateKey)); + } + + static fromEncryptedJsonListSync(json: string, password: string | Bytes): Wallet[] { + const { address, privateKeyList } = decryptKeystoreListSync(json, password); + return _.map(privateKeyList, (privateKey) => new Wallet(address, privateKey)); + } + private klaytn_address: string | undefined; constructor(address: any, privateKey?: any, provider?: Provider) { @@ -287,16 +308,6 @@ export class Wallet extends EthersWallet { return poll(pollFunc) as Promise; } } - - static fromEncryptedJsonSync(json: string, password: string | Bytes): Wallet { - const { address, privateKeys } = decryptKeystoreListSync(json, password); - return new Wallet(address, privateKeys[0]); - } - - static fromEncryptedJsonListSync(json: string, password: string | Bytes): Wallet[] { - const { address, privateKeys } = decryptKeystoreListSync(json, password); - return _.map(privateKeys, (privateKey) => new Wallet(address, privateKey)); - } } export async function verifyMessageAsKlaytnAccountKey(provider: Provider, address: string, message: Bytes | string, signature: any): Promise { diff --git a/ethers-ext/src/index.ts b/ethers-ext/src/index.ts index 66f79a6ac..db13cdc99 100644 --- a/ethers-ext/src/index.ts +++ b/ethers-ext/src/index.ts @@ -1,4 +1,7 @@ +// TODO: move files to src/*.ts export { KlaytnTxFactory, AccountKeyFactory, objectFromRLP } from "./core"; export { TxType, AccountKeyType, formatKlaytnUnits, formatKlay, parseKlaytnUnits, parseKlay } from "./core/util"; export { Wallet, JsonRpcProvider, Accounts, AccountStore } from "./ethers"; export { verifyMessageAsKlaytnAccountKey } from "./ethers/signer"; + +export * from "./keystore"; \ No newline at end of file diff --git a/ethers-ext/src/keystore.ts b/ethers-ext/src/keystore.ts new file mode 100644 index 000000000..b8bd6e141 --- /dev/null +++ b/ethers-ext/src/keystore.ts @@ -0,0 +1,77 @@ +import { getAddress } from "@ethersproject/address"; +import { Bytes } from "@ethersproject/bytes"; +import { ProgressCallback, decryptKeystore, decryptKeystoreSync } from "@ethersproject/json-wallets"; +import { isKIP3Json, splitKeystoreKIP3 } from "@klaytn/js-ext-core"; +import _ from "lodash"; + +// Decrypted keystore private keys. +export interface KeystoreAccountList { + address: string; + // The first private key in the privateKeyList. For backward compatilibilty with KeystoreAccount. + privateKey: string; + privateKeyList: string[]; +} + +function decryptKIP3(json: string, password: Bytes | string, progressCallback?: ProgressCallback): Promise { + const obj = JSON.parse(json); + const jsonList = splitKeystoreKIP3(json); + const count = jsonList.length; + + const accounts = _.map(jsonList, (json, index) => { + const result = decryptKeystoreSync(json, password); + if (progressCallback) { + progressCallback((index + 1) / count); + } + return result; + }); + + return Promise.resolve({ + address: getAddress(obj.address), // the address may not coincide with private keys, get directly from the json. + privateKey: accounts[0].privateKey, + privateKeyList: _.map(accounts, (account) => account.privateKey), + }); +} + +function decryptKIP3Sync(json: string, password: Bytes | string): KeystoreAccountList { + const obj = JSON.parse(json); + const jsonList = splitKeystoreKIP3(json); + + const accounts = _.map(jsonList, (json) => { + return decryptKeystoreSync(json, password); + }); + + return { + address: getAddress(obj.address), // the address may not coincide with private keys, get directly from the json. + privateKey: accounts[0].privateKey, + privateKeyList: _.map(accounts, (account) => account.privateKey), + }; +} + +export function decryptKeystoreList(json: string, password: Bytes | string, progressCallback?: ProgressCallback): Promise { + if (isKIP3Json(json)) { + return decryptKIP3(json, password, progressCallback); + } else { + // Because ethers decryptJsonWallet is not an async function, + // decryptJsonWalletList is not an async function either, hence using 'then'. + return decryptKeystore(json, password, progressCallback).then((account) => { + return { + address: account.address, + privateKey: account.privateKey, + privateKeyList: [account.privateKey], + }; + }); + } +} + +export function decryptKeystoreListSync(json: string, password: Bytes | string): KeystoreAccountList { + if (isKIP3Json(json)) { + return decryptKIP3Sync(json, password); + } else { + const account = decryptKeystoreSync(json, password); + return { + address: account.address, + privateKey: account.privateKey, + privateKeyList: [account.privateKey], + }; + } +} \ No newline at end of file diff --git a/ethers-ext/test/ethers/decrypt_encrypt.spec.ts b/ethers-ext/test/ethers/decrypt_encrypt.spec.ts deleted file mode 100644 index 17702cf72..000000000 --- a/ethers-ext/test/ethers/decrypt_encrypt.spec.ts +++ /dev/null @@ -1,198 +0,0 @@ -import chai from "chai"; - -import * as keystore from "../../src/ethers/keystore"; - -const assert = chai.assert; -const expect = chai.expect; - -describe("decrypt and encrypt", async () => { - describe("decrypt ", async () => { - async function testOK(res: any) { - assert.isDefined(res); - } - - it("decrypt multiple keyring", async () => { - const decryptData = await keystore.decryptKeystoreListSync(JSON.stringify({ - "version": 4, - "id": "54d86643-64c9-4b17-b220-ee8ac8e37a38", - "address": "0xea27c011093b3ab28ae932905e058b0eba503490", - "keyring": [ - { - "ciphertext": "713589f0bc2049b05da09460a0daa84ebe616fa6c8631a57ea4a2c22128e5889", - "cipherparams": { - "iv": "708114437171614deb96a8fc67caf48c" - }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "84f2b9b74bc32d3b2582203c9059445af8cd15b2f40eb8e35c2a82dd0da06904", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "3a801695ece35aa5613a2920e4a2f40d52c5fac10e836c6a90ca6627d389c9c0" - }, - { - "ciphertext": "db7479883998e423b9aeaed224e6e513a7ae6b330d44a3c7a8001ecef501b227", - "cipherparams": { - "iv": "c51db43ee7ae7780c6f20b176bd1281f" - }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "638066e26ccb00147d07d693ad4363600d76f7681a1a94360d2ae02c32a6105f", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "9f768ee8fa8c2f87310ee8e2ed5b96d316ff07a057be86ed4d800bf006bfbea4" - }, - { - "ciphertext": "4e001471284bd65303196e33fa4c1cfdc9186b2190030635d540e69d25cd4ffa", - "cipherparams": { - "iv": "5cad01c2ffc3e705c6d473bd9d97622e" - }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "9983a8774a7eaf22b547db1f948a4e604b7c07e5d7425069432586901ce6b8b7", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "5feaee72ba98059cf8021b5fd6d648c80e5b9572f1712ae1f5170397abd10e0d" - } - ] - }), "Hahaa"); - testOK(decryptData); - }); - - it("decrypt role base keyring", async () => { - const decryptData = await keystore.decryptKeystoreListSync(JSON.stringify({ - "version": 4, - "id": "c903083c-a42c-4774-8cea-f4c5a7962732", - "address": "0x17226c9b4e130551c258eb7b1cdc927c13998cd6", - "keyring": [ - [ - { - "ciphertext": "e341cf7fb7f19031374a61abb7f2d5d643ca6408bc1e8398de4ac9dd3e0697c1", - "cipherparams": { "iv": "fb46dcc6521dc880b54f78891b479dc3" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "f48e0cd5625e55f62d831d12378fad49ff1a715d490e5996d4a5a275f6a277c2", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "a03c2c7b6dff1ad793d2ede88a679d82c734e266fcd40bb875d765e50955edb1" - }, - { - "ciphertext": "668b1a501bbf756016647397078982e6a413a89ed45e8eefd85fb5de52ea5c10", - "cipherparams": { "iv": "ad52c6deefe8fd64ae41dd445c966e08" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "31cd14d3d15f902989db0f0f9b839a420384252eb7daf7c93ebe1c19c11b0ff2", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "36b47e3cc20656349ca2477b28ed04585eb5712691ea724437d77c7a876faacd" - } - ], - [ - { - "ciphertext": "6b0f9f13bb721aa97e7eda08cbaaeb873c0ec41f1707b5cd58b8f4932b252067", - "cipherparams": { "iv": "755c7b650ac384e45d1825f5e73a7bae" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "b9e984fe8f8630638aefaf7ad4d112c47acb56ef2b36fb2aaaa29cf149ad32f1", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "f1bec38f3c815f09d4a4244596b0514c0e24a837979f70773b313c3a873d7b9b" - } - ], - [ - { - "ciphertext": "4ca2438538f560570efe0a862d384d6822513d92fb00503b0cf5f20d5ed959af", - "cipherparams": { "iv": "6d578196eff13d42a71d61b54a7a56ac" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "3a5521134feb81fdd47e91165fc391a2f52984a5fd65b15807843b9bbed3d6dc", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "b7db297d0a8f7e2044ff7a88da3a27af4a4a3489a210b34911a5c87399075873" - }, - { - "ciphertext": "91a2d31625ec96fedf58f0ee48987cf39f6e517103b25d5d0afeac5674c62752", - "cipherparams": { "iv": "26821451fdaf5215c028eaea756c2797" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "a958903f3d1e0065bab28a3c5fb14a2b78804869e1f82a93aabecdc4beded6fd", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "e9e004e310fa6648b82839c8ace5e215866ef4ae6db9a4b9987678de5817d533" - }, - { - "ciphertext": "7ab47009dd5762dd10990f5182228a01cfaef00e8b581c51908de296bbb10cb2", - "cipherparams": { "iv": "65d76971b9fae3eca2ff18fca4b23097" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "288ea98e079125403157a9e9f0546cb1db234637e8d65550dfab607e2e65d065", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "0a60b6b58b7f6bb50aed38b738deffbe7a9cee593829342ebbd57083a80ac508" - } - ] - ] - }), "Klaytn"); - testOK(decryptData); - }); - - - it("decrypt single keyring", async () => { - const decryptData = await keystore.decryptKeystoreListSync(JSON.stringify({ - "version": 3, - "id": "b5a77191-c954-4ed8-962f-41326e585489", - "address": "0x17226c9b4e130551c258eb7b1cdc927c13998cd6", - "crypto": { - "ciphertext": "e341cf7fb7f19031374a61abb7f2d5d643ca6408bc1e8398de4ac9dd3e0697c1", - "cipherparams": { "iv": "fb46dcc6521dc880b54f78891b479dc3" }, - "cipher": "aes-128-ctr", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "salt": "f48e0cd5625e55f62d831d12378fad49ff1a715d490e5996d4a5a275f6a277c2", - "n": 4096, - "r": 8, - "p": 1 - }, - "mac": "a03c2c7b6dff1ad793d2ede88a679d82c734e266fcd40bb875d765e50955edb1" - }, - }), "Klaytn"); - testOK(decryptData); - }); - }); -}); diff --git a/ethers-ext/test/ethers/keystore.spec.ts b/ethers-ext/test/ethers/keystore.spec.ts new file mode 100644 index 000000000..3855eb759 --- /dev/null +++ b/ethers-ext/test/ethers/keystore.spec.ts @@ -0,0 +1,51 @@ +import { assert } from "chai"; + +import { decryptKeystoreList, decryptKeystoreListSync } from "../../src"; + +describe("keystore", () => { + const testcases = [ + { // Eth V3. ethers.Wallet.createRandom().encrypt("password") + json: '{"address":"029e786304c1531af3ac7db24a02448e543a099e","id":"9d492c95-b9e3-42e3-af73-5c77e932208d","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"bfcb88a1501e2bb1e6694c03da18953d"},"ciphertext":"076510b4e25d5cfc31239bffcad6036fe543cbbb04b9f3ec719bf4f61b58fc05","kdf":"scrypt","kdfparams":{"salt":"79124f05995aae98b3088d8365f59a6dfadd1c9ed249abae3c07733f4cbbee53","n":131072,"dklen":32,"p":1,"r":8},"mac":"d70f83824c2c30dc5cd3a244d87147b6aa713a6000165789a82a467651284ac7"}}', + password: "password", + address: "0x029e786304c1531aF3aC7db24A02448e543A099E", + keys: ["0x1b33a48f58d8c85ab142a7375fcf18714d88271f6647cfa6b54f1be66b05a762"], + }, + { // Klaytn V4 with one key. kcn account new --lightkdf + json: '{"address":"ec5eaa07b4d3cbafe7bf437a1ea9a898209f617c","keyring":[[{"cipher":"aes-128-ctr","ciphertext":"0a5aa3749b9e83c2a4238445aeb66f59355c0363a54c163e34e454f76e061e47","cipherparams":{"iv":"2a0b2e02a61e0f721bd800ea6e23a588"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"538ead57745bcd946b05fe294de08256628d9a0a393fd29ced933ba5fc045b07"},"mac":"30b5488bc97165bc7ecac8ff8dfec65a75a8ad206450aecff0ac2dfea6f79b08"}]],"id":"362c0766-f5e3-4b4d-af22-7e89d5fb613a","version":4}', + password: "password", + address: "0xEc5eAa07b4d3CbAfe7bf437a1Ea9A898209F617c", + keys: ["0x4062512193ef1dab8ccf3e3d7a4862e3c740bdf11d852954ed48bc73643e354f"], + }, + { // Klaytn V4 with multiple role-based keys. https://toolkit.klaytn.foundation/misc/generateKeystore + json: '{"version":4,"id":"2d7ad5c1-880f-4920-9b8e-51f852c4802c","address":"0x17226c9b4e130551c258eb7b1cdc927c13998cd6","keyring":[[{"ciphertext":"eb9bd884ac3cc8bf92e6b0082e9d07198bfc4c1223ccc6e5edf7452ad612b2b5","cipherparams":{"iv":"47faf7b0991a051eef698c73fc246f78"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"ba0a3e8dc49a04f8e590f8df5a590bc6e134b031ce10f46d73d4c459aa4c08f8","n":4096,"r":8,"p":1},"mac":"4978d7325e1b9b3ec9fdfd1ec709a5a86fdfade0297ea9ddeeb8c3a7a62ae898"}],[{"ciphertext":"1a80c8666bea1a8dfa3082b001ff64c818fb14cf4e02017785e0edcc7a277af4","cipherparams":{"iv":"eafbecc65ccc177a5579bf56d5f4ed31"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6472845219e11e4de094cac8c32a6a4d13e69cd4507780a7a37f5e411e1d895d","n":4096,"r":8,"p":1},"mac":"86379236d2fd6e9bb3f99f7eebaa3325b51e9fa5ec150ade7a461555c0a14ca3"},{"ciphertext":"0071c41d2956b12be5ebc08a9a5b3a9684b9e410fe2de91d614be977fb2a0bdb","cipherparams":{"iv":"1492dfb771030d3d9c9d996c193c03e5"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"f8145aa907a649866e0fbff86011244584ddc86559cf4901f8f69b670c234fd7","n":4096,"r":8,"p":1},"mac":"eacc58c1ad717ca375697c9fcc80f463a26600f5da1b21327715bf3efa047be5"}],[{"ciphertext":"68ffc1e2800a7288ba7baba0f0f8049daeed05379fabfdd3bc017fa85c49ab50","cipherparams":{"iv":"17f22d7b8aa1a8a2948fd3629f0b89ed"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"ff5e577ec8294320cfe59ef7b1b01ee44d4c9f19c8fbc31f333059c74eb8c6d2","n":4096,"r":8,"p":1},"mac":"de65d669be044df5e39e678b099424a8692a2da6f3746832862cf2e5d6ada612"},{"ciphertext":"fd4810ee850f0aa5f61a2eafbfc5ca36cfebb42df5c2465cc8ae5188029b188b","cipherparams":{"iv":"b00ead13b38e449c268d09fced80ce49"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"af5dbbfb7383045dc7f8a3bfc56cccfc22a5150a1f87e454d40893a4b6fea9a1","n":4096,"r":8,"p":1},"mac":"6234352852eb18246b94f28f3c3454103289ecf2faaa91115927c53729bb0805"},{"ciphertext":"03b758de6372aa6bedde513ccb282bf8af32bca227c258f3e0fc85ce454d72a4","cipherparams":{"iv":"5c20f3e96d0802eaf56670e57fbe3e98"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"b5ec4e40f5a09a59e90317ce45eb7bcd73a2a9afe70f6f2e32548fd38ed2da3b","n":4096,"r":8,"p":1},"mac":"99b7f59855f0aa04531cc4a24c7923f75ed8052084de9ec49a2794e3899c3274"}]]}', + password: "password", + address: "0x17226c9B4e130551c258Eb7B1Cdc927c13998cd6", + keys: [ + "0x278c3d035328daf04ab2597da96dd2d8868fd61a8837030f7d8a85f27b7f1bad", + "0xa06d13800719307ea7e2503ea441c2ea49279d0d600a2eec2887b50928869676", "0xc32f4007ffad303db99dee0d79a720e1d70c4b2babf8e33cb28170a16bac467d", + "0xc274d13302891d0d91a60891a48fde8c2860018f8dcb6293dcc0b28a238590b0", "0x83c127e5207b70086a702c93f1c9a041f15ce49ee5183ce848f35c64de196eff", "0x48f97204ac4886dfbd819ada04ea31a730c6fc43fcb08900566360ee7402f93b"], + } + ]; + it("sync", () => { + for (const tc of testcases) { + const account = decryptKeystoreListSync(tc.json, tc.password); + assert.equal(account.address, tc.address); + assert.equal(account.privateKey, tc.keys[0]); + assert.deepEqual(account.privateKeyList, tc.keys); + } + }); + it("async", async () => { + for (const tc of testcases) { + const callback = (progress: number) => { + // If the callback is ever going to be called, a valid progress value must be passed. + assert.isNumber(progress); + assert.isTrue(progress >= 0 && progress <= 1); + }; + + const account = await decryptKeystoreList(tc.json, tc.password, callback); + assert.equal(account.address, tc.address); + assert.equal(account.privateKey, tc.keys[0]); + assert.deepEqual(account.privateKeyList, tc.keys); + } + }); +}); \ No newline at end of file From d6878f9058fb910bbe88d4aa952f995c19c994cd Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 17:56:09 +0900 Subject: [PATCH 03/69] ethers: Use jscore asyncOpenApi --- ethers-ext/src/ethers/index.ts | 1 - ethers-ext/src/ethers/provider.ts | 125 ------------------------ ethers-ext/src/index.ts | 3 +- ethers-ext/src/provider.ts | 34 +++++++ ethers-ext/test/ethers/mock_provider.ts | 6 +- ethers-ext/test/ethers/provider.spec.ts | 41 ++++++++ ethers-ext/test/ethers/signer.spec.ts | 2 +- 7 files changed, 81 insertions(+), 131 deletions(-) delete mode 100644 ethers-ext/src/ethers/provider.ts create mode 100644 ethers-ext/src/provider.ts create mode 100644 ethers-ext/test/ethers/provider.spec.ts diff --git a/ethers-ext/src/ethers/index.ts b/ethers-ext/src/ethers/index.ts index 754961f87..62c10e381 100644 --- a/ethers-ext/src/ethers/index.ts +++ b/ethers-ext/src/ethers/index.ts @@ -1,3 +1,2 @@ export { Wallet } from "./signer"; -export { JsonRpcProvider } from "./provider"; export { Accounts, AccountStore } from "./accountStore"; diff --git a/ethers-ext/src/ethers/provider.ts b/ethers-ext/src/ethers/provider.ts deleted file mode 100644 index 9230db21d..000000000 --- a/ethers-ext/src/ethers/provider.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Networkish } from "@ethersproject/networks"; -import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/providers"; -import { ConnectionInfo } from "@ethersproject/web"; -// @ts-ignore: package @klaytn/web3rpc has no .d.ts file. -import { ApiClient, AdminApi, DebugApi, GovernanceApi, KlayApi, NetApi, PersonalApi, TxpoolApi } from "@klaytn/web3rpc"; -import _ from "lodash"; - -// NamespaceApi classes generated by openapi-generator-javascript. -type OpenApiMethod = (...args: any[]) => any; -declare class OpenApi { - constructor(apiClient: any); - [method: string]: OpenApiMethod; -} -interface OpenApiClass { - new (apiClient: any): OpenApi; -} - -export class JsonRpcProvider extends EthersJsonRpcProvider { - openApiClient: any; - - constructor(url?: ConnectionInfo | string, network?: Networkish) { - super(url, network); - - this.openApiClient = makeApiClient(url); - } - - /* eslint-disable no-multi-spaces */ - get admin(): AsyncOpenApi { return this.getAsyncOpenApi(AdminApi); } - get debug(): AsyncOpenApi { return this.getAsyncOpenApi(DebugApi); } - get governance(): AsyncOpenApi { return this.getAsyncOpenApi(GovernanceApi); } - get klay(): AsyncOpenApi { return this.getAsyncOpenApi(KlayApi); } - get net(): AsyncOpenApi { return this.getAsyncOpenApi(NetApi); } - get personal(): AsyncOpenApi { return this.getAsyncOpenApi(PersonalApi); } - get txpol(): AsyncOpenApi { return this.getAsyncOpenApi(TxpoolApi); } - /* eslint-enable no-multi-spaces */ - - getAsyncOpenApi(clazz: OpenApiClass): AsyncOpenApi { - return new AsyncOpenApi(new clazz(this.openApiClient)); - } -} - -// Make OpenAPI-Generator ApiClient from ConnectionInfo -function makeApiClient(url?: ConnectionInfo | string): any { - if (_.isString(url)) { - return new ApiClient(url); - } - - // Transplant ethers ConnectionInfo settings to OpenAPI ApiClient settings. - // Some ConnectionInfo settings are sliently ignored. - // See https://github.com/ethers-io/ethers.js/blob/v5/packages/web/src.ts/index.ts#L97:_fetchData - // See https://github.com/klaytn/web3klaytn/blob/dev/web3rpc/sdk/client/javascript/template/libraries/javascript/ApiClient.mustache - const conn = url as ConnectionInfo; - const client = new ApiClient(conn.url); - - if (conn.user && conn.password) { - client.authentications = { - "basic": { - username: conn.user, - password: conn.password, - } - }; - } - if (_.isNumber(conn.timeout)) { - // Both timeouts are in milliseconds. - client.timeout = conn.timeout; - } - if (conn.headers) { - _.forOwn(conn.headers, (value, key) => { - client.defaultHeaders[key] = value; - }); - } - - return client; -} - -// A wrapper to OpenApi class where all its methods are promisified. -class AsyncOpenApi { - openApi: any; - [method: string | symbol]: OpenApiMethod; // dynamically generated methods - - constructor(openApi: any) { - this.openApi = openApi; - this._promisifyApi(); - } - - _promisifyApi() { - const proto = Reflect.getPrototypeOf(this.openApi); - if (proto) { - const methods = Reflect.ownKeys(proto); - // Promisify each methods - _.forEach(methods, (methodName) => { - // Assume that the prototype only has a constructor and API methods. - if (methodName == "constructor") { - return; - } - - const method: OpenApiMethod = this.openApi[methodName]; - // Function.length is the number of function arguments. - // RPC args = method args - opts - callback - const numArgs = method.length - 2; - - this[methodName] = async (...args: any[]): Promise => { - return this._asyncCall(methodName, numArgs, ...args); - }; - }); - } - } - - async _asyncCall(name: string | symbol, numArgs: number, ...args: any[]) { - const opts = {}; - if (args.length != numArgs) { - throw new Error(`RPC ${String(name)} requires ${numArgs} parameters, ${args.length} given`); - } - - return new Promise((resolve, reject) => { - this.openApi[name](...args, opts, (err: any, data: any) => { - if (err) { - reject(err); - } else { - resolve(data); - } - }); - }); - } -} diff --git a/ethers-ext/src/index.ts b/ethers-ext/src/index.ts index db13cdc99..53ef6bc90 100644 --- a/ethers-ext/src/index.ts +++ b/ethers-ext/src/index.ts @@ -1,7 +1,8 @@ // TODO: move files to src/*.ts export { KlaytnTxFactory, AccountKeyFactory, objectFromRLP } from "./core"; export { TxType, AccountKeyType, formatKlaytnUnits, formatKlay, parseKlaytnUnits, parseKlay } from "./core/util"; -export { Wallet, JsonRpcProvider, Accounts, AccountStore } from "./ethers"; +export { Wallet, Accounts, AccountStore } from "./ethers"; export { verifyMessageAsKlaytnAccountKey } from "./ethers/signer"; +export * from "./provider"; export * from "./keystore"; \ No newline at end of file diff --git a/ethers-ext/src/provider.ts b/ethers-ext/src/provider.ts new file mode 100644 index 000000000..cc756496d --- /dev/null +++ b/ethers-ext/src/provider.ts @@ -0,0 +1,34 @@ +import { Networkish } from "@ethersproject/networks"; +import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/providers"; +import { ConnectionInfo } from "@ethersproject/web"; +import { asyncOpenApi, AsyncNamespaceApi } from "@klaytn/js-ext-core"; +// @ts-ignore: package @klaytn/web3rpc has no .d.ts file. +import { AdminApi, DebugApi, GovernanceApi, KlayApi, NetApi, PersonalApi, TxpoolApi } from "@klaytn/web3rpc"; + +/* eslint-disable no-multi-spaces */ +export class JsonRpcProvider extends EthersJsonRpcProvider { + // API methods other than eth_ namespaces + admin: AsyncNamespaceApi; + debug: AsyncNamespaceApi; + governance: AsyncNamespaceApi; + klay: AsyncNamespaceApi; + net: AsyncNamespaceApi; + personal: AsyncNamespaceApi; + txpool: AsyncNamespaceApi; + + constructor(url?: ConnectionInfo | string, network?: Networkish) { + super(url, network); + + const send = (method: string, params: any) => { + return this.send(method, params); + }; + + this.admin = asyncOpenApi(send, AdminApi); + this.debug = asyncOpenApi(send, DebugApi); + this.governance = asyncOpenApi(send, GovernanceApi); + this.klay = asyncOpenApi(send, KlayApi); + this.net = asyncOpenApi(send, NetApi); + this.personal = asyncOpenApi(send, PersonalApi); + this.txpool = asyncOpenApi(send, TxpoolApi); + } +} \ No newline at end of file diff --git a/ethers-ext/test/ethers/mock_provider.ts b/ethers-ext/test/ethers/mock_provider.ts index ea59c5226..c766f7e0e 100644 --- a/ethers-ext/test/ethers/mock_provider.ts +++ b/ethers-ext/test/ethers/mock_provider.ts @@ -3,7 +3,7 @@ import { JsonRpcProvider as EthersProvider } from "@ethersproject/providers"; import { ConnectionInfo } from "ethers/lib/utils"; import _ from "lodash"; -import { JsonRpcProvider as KlaytnProvider } from "../../src/ethers"; +import { JsonRpcProvider as KlaytnProvider } from "../../src"; type mockRpcHandler = (params: Array) => (Promise | any); @@ -19,7 +19,7 @@ export class MockEthersProvider extends EthersProvider { send(method: string, params: Array): Promise { let handler = this.overrides[method]; if (handler) { - return handler(params); + return Promise.resolve(handler(params)); } else { console.log("mock fallback", method, params); return super.send(method, params); @@ -45,7 +45,7 @@ export class MockKlaytnProvider extends KlaytnProvider { send(method: string, params: Array): Promise { let handler = this.overrides[method]; if (handler) { - return handler(params); + return Promise.resolve(handler(params)); } else { return super.send(method, params); } diff --git a/ethers-ext/test/ethers/provider.spec.ts b/ethers-ext/test/ethers/provider.spec.ts new file mode 100644 index 000000000..6360647ab --- /dev/null +++ b/ethers-ext/test/ethers/provider.spec.ts @@ -0,0 +1,41 @@ +import { assert } from "chai"; + +import { MockKlaytnProvider } from "./mock_provider"; + +const blockNum = "0x82f89d8"; +const txhash = "0x2e9babadc8453a986e9996baed595a0bb89d233290913e2d88cb26a3bff8be75"; +const trace = [{ txhash: txhash, result: "" }]; +const txpoolStatus = { pending: 4, queued: 2 }; + +// Test that P.func() or P.namespace.func() correctly invokes the +// underlying P.send() function. This test does not actually query the Internet. +describe("Provider", () => { + let P: MockKlaytnProvider; + + before(async () => { + P = new MockKlaytnProvider("http://127.0.0.1:8545"); + P.mock_override("eth_chainId", () => "0x7a69"); + P.mock_override("eth_blockNumber", () => blockNum); + P.mock_override("admin_datadir", () => "/home/ubuntu/klaytn/data"); + P.mock_override("debug_traceTransaction", ([num]) => { + assert.equal(num, blockNum); // Check that RPC parameters are passed correctly. + return trace; + }); + P.mock_override("governance_myVotes", () => []); + P.mock_override("klay_gasPrice", () => "0xba43b7400"); + P.mock_override("net_networkID", () => "0x7a69"); + P.mock_override("personal_listAccounts", () => []); + P.mock_override("txpool_status", () => txpoolStatus); + }); + + it.only("non-eth namespaces", async () => { + assert.deepEqual(await P.getBlockNumber(), parseInt(blockNum)); // eth_blockNumber + assert.deepEqual(await P.admin.datadir(), "/home/ubuntu/klaytn/data"); + assert.deepEqual(await P.debug.traceTransaction(blockNum), trace); + assert.deepEqual(await P.governance.myVotes(), []); + assert.deepEqual(await P.klay.gasPrice(), "0xba43b7400"); + assert.deepEqual(await P.net.networkID(), "0x7a69"); + assert.deepEqual(await P.personal.listAccounts(), []); + assert.deepEqual(await P.txpool.status(), txpoolStatus); + }); +}); \ No newline at end of file diff --git a/ethers-ext/test/ethers/signer.spec.ts b/ethers-ext/test/ethers/signer.spec.ts index 7809c6143..99327308b 100644 --- a/ethers-ext/test/ethers/signer.spec.ts +++ b/ethers-ext/test/ethers/signer.spec.ts @@ -3,7 +3,7 @@ import chaiAsPromised from "chai-as-promised"; import { BigNumber, Wallet as EthersWallet } from "ethers"; import _ from "lodash"; -import { Wallet as KlaytnWallet } from "../../src/ethers"; +import { Wallet as KlaytnWallet } from "../../src"; import { MockEthersProvider, MockKlaytnProvider } from "./mock_provider"; From c3c76dc6debc8a2d3ff7bcbd82fece67c898679b Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 18:06:46 +0900 Subject: [PATCH 04/69] ethers: Export js-ext-core/util as-is --- ethers-ext/.eslintrc.js | 4 + ethers-ext/src/index.ts | 5 +- ethers-ext/test/{ethers => }/keystore.spec.ts | 2 +- ethers-ext/test/{ethers => }/mock_provider.ts | 2 +- ethers-ext/test/{ethers => }/provider.spec.ts | 2 +- ethers-ext/test/{ethers => }/signer.spec.ts | 2 +- ethers-ext/test/util.spec.ts | 93 +++++++++++++++++++ ethers-ext/tsconfig.json | 3 +- 8 files changed, 106 insertions(+), 7 deletions(-) rename ethers-ext/test/{ethers => }/keystore.spec.ts (99%) rename ethers-ext/test/{ethers => }/mock_provider.ts (96%) rename ethers-ext/test/{ethers => }/provider.spec.ts (97%) rename ethers-ext/test/{ethers => }/signer.spec.ts (99%) create mode 100644 ethers-ext/test/util.spec.ts diff --git a/ethers-ext/.eslintrc.js b/ethers-ext/.eslintrc.js index 77c016632..593d82b79 100644 --- a/ethers-ext/.eslintrc.js +++ b/ethers-ext/.eslintrc.js @@ -42,6 +42,10 @@ module.exports = { ], "newlines-between": "always", }], + "import/no-unresolved": [ + "error", // eslint-plugin-import cannot resolve subpaths https://github.com/firebase/firebase-admin-node/discussions/1359 + { ignore: ["^@klaytn/js-ext-core/util$"] } + ], // formatting "curly": ["warn", "all"], diff --git a/ethers-ext/src/index.ts b/ethers-ext/src/index.ts index 53ef6bc90..07e089918 100644 --- a/ethers-ext/src/index.ts +++ b/ethers-ext/src/index.ts @@ -1,8 +1,9 @@ // TODO: move files to src/*.ts -export { KlaytnTxFactory, AccountKeyFactory, objectFromRLP } from "./core"; -export { TxType, AccountKeyType, formatKlaytnUnits, formatKlay, parseKlaytnUnits, parseKlay } from "./core/util"; +export { formatKlaytnUnits, formatKlay, parseKlaytnUnits, parseKlay } from "./core/util"; export { Wallet, Accounts, AccountStore } from "./ethers"; export { verifyMessageAsKlaytnAccountKey } from "./ethers/signer"; +export * from "@klaytn/js-ext-core/util"; + export * from "./provider"; export * from "./keystore"; \ No newline at end of file diff --git a/ethers-ext/test/ethers/keystore.spec.ts b/ethers-ext/test/keystore.spec.ts similarity index 99% rename from ethers-ext/test/ethers/keystore.spec.ts rename to ethers-ext/test/keystore.spec.ts index 3855eb759..5695e3631 100644 --- a/ethers-ext/test/ethers/keystore.spec.ts +++ b/ethers-ext/test/keystore.spec.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; -import { decryptKeystoreList, decryptKeystoreListSync } from "../../src"; +import { decryptKeystoreList, decryptKeystoreListSync } from "../src"; describe("keystore", () => { const testcases = [ diff --git a/ethers-ext/test/ethers/mock_provider.ts b/ethers-ext/test/mock_provider.ts similarity index 96% rename from ethers-ext/test/ethers/mock_provider.ts rename to ethers-ext/test/mock_provider.ts index c766f7e0e..ed765ff8d 100644 --- a/ethers-ext/test/ethers/mock_provider.ts +++ b/ethers-ext/test/mock_provider.ts @@ -3,7 +3,7 @@ import { JsonRpcProvider as EthersProvider } from "@ethersproject/providers"; import { ConnectionInfo } from "ethers/lib/utils"; import _ from "lodash"; -import { JsonRpcProvider as KlaytnProvider } from "../../src"; +import { JsonRpcProvider as KlaytnProvider } from "../src"; type mockRpcHandler = (params: Array) => (Promise | any); diff --git a/ethers-ext/test/ethers/provider.spec.ts b/ethers-ext/test/provider.spec.ts similarity index 97% rename from ethers-ext/test/ethers/provider.spec.ts rename to ethers-ext/test/provider.spec.ts index 6360647ab..f90482e41 100644 --- a/ethers-ext/test/ethers/provider.spec.ts +++ b/ethers-ext/test/provider.spec.ts @@ -28,7 +28,7 @@ describe("Provider", () => { P.mock_override("txpool_status", () => txpoolStatus); }); - it.only("non-eth namespaces", async () => { + it("non-eth namespaces", async () => { assert.deepEqual(await P.getBlockNumber(), parseInt(blockNum)); // eth_blockNumber assert.deepEqual(await P.admin.datadir(), "/home/ubuntu/klaytn/data"); assert.deepEqual(await P.debug.traceTransaction(blockNum), trace); diff --git a/ethers-ext/test/ethers/signer.spec.ts b/ethers-ext/test/signer.spec.ts similarity index 99% rename from ethers-ext/test/ethers/signer.spec.ts rename to ethers-ext/test/signer.spec.ts index 99327308b..a8780e309 100644 --- a/ethers-ext/test/ethers/signer.spec.ts +++ b/ethers-ext/test/signer.spec.ts @@ -3,7 +3,7 @@ import chaiAsPromised from "chai-as-promised"; import { BigNumber, Wallet as EthersWallet } from "ethers"; import _ from "lodash"; -import { Wallet as KlaytnWallet } from "../../src"; +import { Wallet as KlaytnWallet } from "../src"; import { MockEthersProvider, MockKlaytnProvider } from "./mock_provider"; diff --git a/ethers-ext/test/util.spec.ts b/ethers-ext/test/util.spec.ts new file mode 100644 index 000000000..106760234 --- /dev/null +++ b/ethers-ext/test/util.spec.ts @@ -0,0 +1,93 @@ +import { BigNumber } from "@ethersproject/bignumber"; +import { assert } from "chai"; + +import { + TxType, isKlaytnTxType, isBasicTxType, isFeeDelegationTxType, isPartialFeeDelegationTxType, isFeePayerSigTxType, + AccountKeyType, isKlaytnAccountKeyType, isEmbeddableAccountKeyType, CodeFormatEVM, + RLP, HexStr, + getCompressedPublicKey, getSignatureTuple, + splitKeystoreKIP3, isKIP3Json, + asyncOpenApi, rpcSendFunction, + getRpcTxObject, + formatKlayUnits, formatKlay, parseKlayUnits, parseKlay, +} from "../src"; + +// Test that js-ext-core utils are properly exported. +// Do not test the correctness. That is done in js-ext-core/test. +describe("utils", () => { + it("const", () => { + assert.equal(TxType.ValueTransfer, 8); + assert.equal(isKlaytnTxType(8), true); + assert.equal(isBasicTxType(9), false); + assert.equal(isFeeDelegationTxType(9), true); + assert.equal(isPartialFeeDelegationTxType(10), true); + assert.equal(isFeePayerSigTxType(9), true); + + assert.equal(AccountKeyType.Public, 2); + assert.equal(isKlaytnAccountKeyType(2), true); + assert.equal(isEmbeddableAccountKeyType(5), false); + + assert.equal(CodeFormatEVM, 0); + }); + + it("data", () => { + assert.equal(RLP.encode(["0x01", "0x02", "0x03"]), "0xc3010203"); + assert.equal(HexStr.from("0xabcd"), "0xabcd"); + }); + + it("ec", () => { + const uncompressed = "0x04c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e61a443ac3ffff164d1fb3617875f07641014cf17af6b7dc38e429fe838763712"; + const compressed = "0x02c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e"; + assert.equal(getCompressedPublicKey(uncompressed), compressed); + + const object = { v: 27, r: "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", s: "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508" }; + const tuple = ["0x1b", "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508"]; + assert.deepEqual(getSignatureTuple(object), tuple); + }); + + it("keystore", () => { + assert.isFalse(isKIP3Json("asdf")); + + const v4 = '{"address":"ec5eaa07b4d3cbafe7bf437a1ea9a898209f617c","keyring":[[{"cipher":"aes-128-ctr","ciphertext":"0a5aa3749b9e83c2a4238445aeb66f59355c0363a54c163e34e454f76e061e47","cipherparams":{"iv":"2a0b2e02a61e0f721bd800ea6e23a588"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"538ead57745bcd946b05fe294de08256628d9a0a393fd29ced933ba5fc045b07"},"mac":"30b5488bc97165bc7ecac8ff8dfec65a75a8ad206450aecff0ac2dfea6f79b08"}]],"id":"362c0766-f5e3-4b4d-af22-7e89d5fb613a","version":4}'; + const split = splitKeystoreKIP3(v4); + const v3 = JSON.parse(split[0]); + assert.equal(v3.version, 3); + }); + + it("openapi", async () => { + const send: rpcSendFunction = (_method: string, _params: any[]) => Promise.resolve("0x1234"); + + class MockKlayApi { + apiClient: any; + constructor(apiClient: any) { + this.apiClient = apiClient; + } + + blockNumber(_opts: any, callback: any) { + const bodyParams = { method: "klay_blockNumber", params: [] }; + this.apiClient.callApi("/", "POST", null, null, null, null, bodyParams, + [], ["application/json"], ["application/json"], {}, null, callback); + } + } + const KlayApi = MockKlayApi as any; + + const klay = asyncOpenApi(send, KlayApi); + const ret = await klay.blockNumber(); + assert.isTrue(HexStr.isHex(ret)); + }); + + it("rpc", () => { + const tx = { nonce: 0 }; + const formatted = { nonce: "0x0" }; + assert.deepEqual(getRpcTxObject(tx), formatted); + }); + + it("units", () => { + const peb = BigNumber.from("1000000000000000000"); + assert.equal(formatKlayUnits(peb, "ston"), "1000000000.0"); + assert.equal(formatKlay(peb), "1.0"); + + assert.equal(parseKlayUnits("25.0", "ston").toString(), "25000000000"); + assert.equal(parseKlay("123.456").toString(), "123456000000000000000"); + }); +}); \ No newline at end of file diff --git a/ethers-ext/tsconfig.json b/ethers-ext/tsconfig.json index f89fdc9d4..3febbc51c 100644 --- a/ethers-ext/tsconfig.json +++ b/ethers-ext/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { "target": "ES2017", - "module": "commonjs", + "module": "nodenext", + "moduleResolution": "nodenext", "declaration": true, "declarationMap": true, "sourceMap": true, From f4741096fde1cb9949e9942948f9bf197cd13984 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 18:34:13 +0900 Subject: [PATCH 05/69] ethers: Move files out of src/ethers directory --- ethers-ext/src/{ethers => }/accountStore.ts | 3 +-- ethers-ext/src/ethers/index.ts | 2 -- ethers-ext/src/index.ts | 9 +++------ ethers-ext/src/{ethers => }/signer.ts | 8 ++++---- 4 files changed, 8 insertions(+), 14 deletions(-) rename ethers-ext/src/{ethers => }/accountStore.ts (99%) delete mode 100644 ethers-ext/src/ethers/index.ts rename ethers-ext/src/{ethers => }/signer.ts (98%) diff --git a/ethers-ext/src/ethers/accountStore.ts b/ethers-ext/src/accountStore.ts similarity index 99% rename from ethers-ext/src/ethers/accountStore.ts rename to ethers-ext/src/accountStore.ts index cdcd41ce0..7da39d6cf 100644 --- a/ethers-ext/src/ethers/accountStore.ts +++ b/ethers-ext/src/accountStore.ts @@ -3,8 +3,7 @@ import { computeAddress } from "@ethersproject/transactions"; import { BigNumber, ethers } from "ethers"; import { computePublicKey } from "ethers/lib/utils"; -import { HexStr } from "../core/util"; - +import { HexStr } from "./core/util"; import { Wallet } from "./signer"; // Accounts is array of Wallet in ethers.js Ext diff --git a/ethers-ext/src/ethers/index.ts b/ethers-ext/src/ethers/index.ts deleted file mode 100644 index 62c10e381..000000000 --- a/ethers-ext/src/ethers/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Wallet } from "./signer"; -export { Accounts, AccountStore } from "./accountStore"; diff --git a/ethers-ext/src/index.ts b/ethers-ext/src/index.ts index 07e089918..d3d2a1920 100644 --- a/ethers-ext/src/index.ts +++ b/ethers-ext/src/index.ts @@ -1,9 +1,6 @@ -// TODO: move files to src/*.ts -export { formatKlaytnUnits, formatKlay, parseKlaytnUnits, parseKlay } from "./core/util"; -export { Wallet, Accounts, AccountStore } from "./ethers"; -export { verifyMessageAsKlaytnAccountKey } from "./ethers/signer"; - export * from "@klaytn/js-ext-core/util"; +export * from "./accountStore"; +export * from "./keystore"; export * from "./provider"; -export * from "./keystore"; \ No newline at end of file +export * from "./signer"; \ No newline at end of file diff --git a/ethers-ext/src/ethers/signer.ts b/ethers-ext/src/signer.ts similarity index 98% rename from ethers-ext/src/ethers/signer.ts rename to ethers-ext/src/signer.ts index a48334f78..8b0c76e1f 100644 --- a/ethers-ext/src/ethers/signer.ts +++ b/ethers-ext/src/signer.ts @@ -6,10 +6,10 @@ import { ethers } from "ethers"; import { Bytes, Deferrable, ProgressCallback, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; import _ from "lodash"; -import { KlaytnTxFactory } from "../core"; -import { encodeTxForRPC, objectFromRLP } from "../core/klaytn_tx"; -import { HexStr } from "../core/util"; -import { decryptKeystoreList, decryptKeystoreListSync } from "../keystore"; +import { KlaytnTxFactory } from "./core"; +import { encodeTxForRPC, objectFromRLP } from "./core/klaytn_tx"; +import { HexStr } from "./core/util"; +import { decryptKeystoreList, decryptKeystoreListSync } from "./keystore"; // @ethersproject/abstract-signer/src.ts/index.ts:allowedTransactionKeys const ethersAllowedTransactionKeys: Array = [ From f650eb3229d6ae2d15b715146843fa68b68239fb Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 18:39:03 +0900 Subject: [PATCH 06/69] ethers: Remove dependency to core/HexStr --- ethers-ext/src/accountStore.ts | 38 ++++++++++++++++++++-------------- ethers-ext/src/signer.ts | 2 +- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/ethers-ext/src/accountStore.ts b/ethers-ext/src/accountStore.ts index 7da39d6cf..86798903f 100644 --- a/ethers-ext/src/accountStore.ts +++ b/ethers-ext/src/accountStore.ts @@ -1,11 +1,19 @@ +import { BigNumber } from "@ethersproject/bignumber"; import { JsonRpcProvider } from "@ethersproject/providers"; +import { SigningKey } from "@ethersproject/signing-key"; import { computeAddress } from "@ethersproject/transactions"; -import { BigNumber, ethers } from "ethers"; -import { computePublicKey } from "ethers/lib/utils"; +import { HexStr } from "@klaytn/js-ext-core"; +import { computePublicKey, getAddress } from "ethers/lib/utils"; -import { HexStr } from "./core/util"; import { Wallet } from "./signer"; +function isSameAddress(a: string, b: string) { + return getAddress(a) == getAddress(b); +} +function isSamePrivateKey(a: string, b: string) { + return computeAddress(a) == computeAddress(b); +} + // Accounts is array of Wallet in ethers.js Ext export class Accounts { public wallets : Wallet[]; @@ -40,7 +48,7 @@ export class Accounts { let priv: string; if (account.length == 1) { - const signingKey = new ethers.utils.SigningKey(account[0]); + const signingKey = new SigningKey(account[0]); addr = computeAddress(signingKey.compressedPublicKey); priv = account[0]; } else if (account.length == 2 && account[1] != undefined) { @@ -51,8 +59,8 @@ export class Accounts { } for (let i = 0; i < this.wallets.length; i++) { - if (HexStr.isSameAddress(await this.wallets[i].getAddress(), addr) && - HexStr.isSamePrivKey(this.wallets[i].privateKey, priv)) { + if (isSameAddress(await this.wallets[i].getAddress(), addr) && + isSamePrivateKey(this.wallets[i].privateKey, priv)) { return false; } } @@ -66,7 +74,7 @@ export class Accounts { let priv: string; if (account.length == 1) { - const signingKey = new ethers.utils.SigningKey(account[0]); + const signingKey = new SigningKey(account[0]); addr = computeAddress(signingKey.compressedPublicKey); priv = account[0]; } else if (account.length == 2 && account[1] != undefined) { @@ -77,9 +85,9 @@ export class Accounts { } for (let i = 0; i < this.wallets.length; i++) { - if (HexStr.isSameAddress(await this.wallets[i].getAddress(), addr) && + if (isSameAddress(await this.wallets[i].getAddress(), addr) && // @ts-ignore - HexStr.isSamePrivKey(await this.wallets[i].privateKey, priv)) { + isSamePrivateKey(await this.wallets[i].privateKey, priv)) { delete this.wallets[i]; this.wallets.splice(i, 1); return true; @@ -103,7 +111,7 @@ export class Accounts { const ret: Wallet[] = []; for (let i = 0; i < this.wallets.length; i++) { - if (HexStr.isSamePrivKey(this.wallets[i].privateKey, privateKey)) { + if (isSameAddress(this.wallets[i].privateKey, privateKey)) { ret.push(this.wallets[i]); } } @@ -114,7 +122,7 @@ export class Accounts { const ret: Wallet[] = []; for (let i = 0; i < this.wallets.length; i++) { - if (HexStr.isSameAddress(await this.wallets[i].getAddress(), address)) { + if (isSameAddress(await this.wallets[i].getAddress(), address)) { ret.push(this.wallets[i]); } } @@ -283,7 +291,7 @@ export class AccountStore { hasAccountInfos(address: string) :boolean { let i:number; for (i = 0; this.accountInfos != undefined && i < this.accountInfos.length; i++) { - if (HexStr.isSameAddress(this.accountInfos[i].address, address)) { + if (isSameAddress(this.accountInfos[i].address, address)) { return true; } } @@ -293,7 +301,7 @@ export class AccountStore { getType(address:string) : number | null { let i:number; for (i = 0; this.accountInfos != undefined && i < this.accountInfos.length; i++) { - if (HexStr.isSameAddress(this.accountInfos[i].address, address)) { + if (isSameAddress(this.accountInfos[i].address, address)) { return this.accountInfos[i].key.type; } } @@ -303,7 +311,7 @@ export class AccountStore { getAccountInfo(address: string) : AccountInfo | null { let i:number; for (i = 0; this.accountInfos != undefined && i < this.accountInfos.length; i++) { - if (HexStr.isSameAddress(this.accountInfos[i].address, address)) { + if (isSameAddress(this.accountInfos[i].address, address)) { return this.accountInfos[i]; } } @@ -331,4 +339,4 @@ export class AccountStore { hasPrivateKey: hasPrivateKey }; } -} +} \ No newline at end of file diff --git a/ethers-ext/src/signer.ts b/ethers-ext/src/signer.ts index 8b0c76e1f..3bc4f430a 100644 --- a/ethers-ext/src/signer.ts +++ b/ethers-ext/src/signer.ts @@ -2,13 +2,13 @@ import { Provider, TransactionRequest, TransactionResponse } from "@ethersprojec import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/providers"; import { Wallet as EthersWallet } from "@ethersproject/wallet"; import { poll } from "@ethersproject/web"; +import { HexStr } from "@klaytn/js-ext-core"; import { ethers } from "ethers"; import { Bytes, Deferrable, ProgressCallback, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; import _ from "lodash"; import { KlaytnTxFactory } from "./core"; import { encodeTxForRPC, objectFromRLP } from "./core/klaytn_tx"; -import { HexStr } from "./core/util"; import { decryptKeystoreList, decryptKeystoreListSync } from "./keystore"; // @ethersproject/abstract-signer/src.ts/index.ts:allowedTransactionKeys From 21825c993dc7880fda2745c3f31382f2441e61af Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 18:47:27 +0900 Subject: [PATCH 07/69] ethers: Rewrite Wallet --- ethers-ext/src/signer.ts | 246 +++++++++++++++++---------------------- 1 file changed, 109 insertions(+), 137 deletions(-) diff --git a/ethers-ext/src/signer.ts b/ethers-ext/src/signer.ts index 3bc4f430a..aa762914b 100644 --- a/ethers-ext/src/signer.ts +++ b/ethers-ext/src/signer.ts @@ -1,14 +1,13 @@ import { Provider, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider"; +import { ExternallyOwnedAccount } from "@ethersproject/abstract-signer"; import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/providers"; import { Wallet as EthersWallet } from "@ethersproject/wallet"; import { poll } from "@ethersproject/web"; -import { HexStr } from "@klaytn/js-ext-core"; +import { KlaytnTxFactory, HexStr, isFeePayerSigTxType, parseTransaction } from "@klaytn/js-ext-core"; import { ethers } from "ethers"; -import { Bytes, Deferrable, ProgressCallback, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; +import { Bytes, BytesLike, Deferrable, ProgressCallback, SigningKey, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; import _ from "lodash"; -import { KlaytnTxFactory } from "./core"; -import { encodeTxForRPC, objectFromRLP } from "./core/klaytn_tx"; import { decryptKeystoreList, decryptKeystoreListSync } from "./keystore"; // @ethersproject/abstract-signer/src.ts/index.ts:allowedTransactionKeys @@ -55,6 +54,16 @@ function restoreCustomFields(tx: Deferrable, savedFields: an } } +async function getTransactionRequest(transactionOrRLP: Deferrable | string): Promise { + if (_.isString(transactionOrRLP)) { + return parseTransaction(transactionOrRLP) as TransactionRequest; + } else { + const tx = transactionOrRLP; + return resolveProperties(tx); + } +} + +type PrivateKeyLike = BytesLike | ExternallyOwnedAccount | SigningKey; export class Wallet extends EthersWallet { // Override Wallet factories accepting keystores to support KIP-3 (v4) format @@ -79,40 +88,47 @@ export class Wallet extends EthersWallet { return _.map(privateKeyList, (privateKey) => new Wallet(address, privateKey)); } - private klaytn_address: string | undefined; - - constructor(address: any, privateKey?: any, provider?: Provider) { - const str_addr = String(address); - - if (HexStr.isHex(address) && (str_addr.length == 40 || str_addr.length == 42)) { - super(privateKey, provider); - this.klaytn_address = ethers.utils.getAddress(address); - } else { - provider = privateKey; - privateKey = address; + // Decoupled account address. Defined only if specified in constructor. + private klaytnAddr: string | undefined; + + // new KlaytnWallet(privateKey, provider?) or + // new KlaytnWallet(address, privateKey, provider?) + constructor( + addressOrPrivateKey: string | PrivateKeyLike, + privateKeyOrProvider?: PrivateKeyLike | Provider, + provider?: Provider) { + // First argument is an address. + if (HexStr.isHex(addressOrPrivateKey, 20)) { + const address = HexStr.from(addressOrPrivateKey); + const privateKey = privateKeyOrProvider as PrivateKeyLike; super(privateKey, provider); + this.klaytnAddr = address; + } else { // First argument is a private key. + const privateKey = addressOrPrivateKey as PrivateKeyLike; + const _provider = privateKeyOrProvider as Provider; + super(privateKey, _provider); } } - getAddress(): Promise { - if (this.klaytn_address == undefined) { + getAddress(legacy?: boolean): Promise { + if (legacy || !this.klaytnAddr) { return super.getAddress(); + } else { + return Promise.resolve(this.klaytnAddr); } - return Promise.resolve(String(this.klaytn_address)); } + // @deprecated in favor of getAddress(true) getEtherAddress(): Promise { return super.getAddress(); } async isDecoupled(): Promise { - if (this.klaytn_address == undefined) { + if (!this.klaytnAddr) { return false; + } else { + return (await this.getAddress(false)) == (await this.getAddress(true)); } - - const addr = await this.getAddress(); - const Eaddr = await this.getEtherAddress(); - return addr != Eaddr; } checkTransaction(transaction: Deferrable): Deferrable { @@ -124,168 +140,124 @@ export class Wallet extends EthersWallet { return tx; } - _convertTxFromRLP(transaction: Deferrable | string): any { - if (typeof transaction === "string") { - if (HexStr.isHex(transaction)) { - return this.decodeTxFromRLP(transaction); - } else { - throw new Error("String type input has to be RLP encoded Hex string."); - } - } else { - return transaction; - } - } - async populateTransaction(transaction: Deferrable): Promise { - let tx: TransactionRequest = this._convertTxFromRLP(transaction); - tx = await resolveProperties(tx); + const tx = await getTransactionRequest(transaction); + // Not a Klaytn TxType; fallback to ethers.Wallet if (!KlaytnTxFactory.has(tx.type)) { return super.populateTransaction(tx); } - // Klaytn AccountKey is not matched with pubKey of the privateKey - if (!(tx.nonce) && !!(this.klaytn_address)) { - if (this.provider instanceof EthersJsonRpcProvider) { - const result = await this.provider.getTransactionCount(this.klaytn_address); - tx.nonce = result; - } else { - throw new Error("Klaytn transaction can only be populated from a Klaytn JSON-RPC server"); - } - } - - if (!(tx.gasPrice)) { - if (this.provider instanceof EthersJsonRpcProvider) { - const result = await this.provider.send("klay_gasPrice", []); - tx.gasPrice = result; - } else { - throw new Error("Klaytn transaction can only be populated from a Klaytn JSON-RPC server"); - } + // If the account address is decoupled from private key, + // the ethers.Wallet.populateTransaction() may fill the nonce of the wrong address. + if (!tx.nonce) { + tx.nonce = await this.provider.getTransactionCount(await this.getAddress()); } - if (!(tx.gasLimit) && !!(tx.to)) { - if (this.provider instanceof EthersJsonRpcProvider) { - const ttx = encodeTxForRPC(tx); - - const result = await this.provider.send("klay_estimateGas", [ttx]); - // For the problem that estimateGas does not exactly match, - // the code for adding some Gas must be processed in the wallet or Dapp. - // e.g. - // In ethers, no special logic to modify Gas - // In Metamask, multiply 1.5 to Gas for ensuring that the estimated gas is sufficient - // https://github.com/MetaMask/metamask-extension/blob/9d38e537fca4a61643743f6bf3409f20189eb8bb/ui/ducks/send/helpers.js#L115 - tx.gasLimit = Math.ceil(result * 2.5); - } else { - throw new Error("Klaytn transaction can only be populated from a Klaytn JSON-RPC server"); - } + // Sometimes estimateGas underestimates the required gas limit. + // Therefore adding some buffer to the RPC result. + // Other cases: + // - ethers.js uses estimateGas result as-is. + // - Metamask multiplies by 1 or 1.5 depending on chainId + // (https://github.com/MetaMask/metamask-extension/blob/v11.3.0/ui/ducks/send/helpers.js#L126) + // TODO: To minimize buffer, add constant intrinsic gas overhead instead of multiplier. + if (!tx.gasLimit) { + const bufferMultiplier = 2.5; + const gasLimit = await this.provider.estimateGas(tx); + tx.gasLimit = Math.ceil(gasLimit.toNumber() * bufferMultiplier); } + // Leave rest of the fields to ethers const savedFields = saveCustomFields(tx); - tx = await super.populateTransaction(tx); - restoreCustomFields(tx, savedFields); + const populatedTx = await super.populateTransaction(tx); + restoreCustomFields(populatedTx, savedFields); - return tx; + return populatedTx; } - // TODO: refactor like below - // async rpc_estimateGas(tx: TransactionRequest): Promise { - // let allowExtra = { - - // } - // let rpcTx = JsonRpcProvider.hexlifyTransaction(tx, allowExtra); - - // if (this.provider instanceof JsonRpcProvider ) { - - // } - // return 0; - // } - - decodeTxFromRLP(str :string): any { - return objectFromRLP(str); + // @deprecated in favor of parseTransaction + decodeTxFromRLP(rlp :string): any { + return parseTransaction(rlp); } + // Sign as a sender + // tx.sigs += Sign(tx.sigRLP(), wallet.privateKey) + // return tx.txHashRLP() or tx.senderTxHashRLP(); async signTransaction(transaction: Deferrable): Promise { - let tx: TransactionRequest = this._convertTxFromRLP(transaction); - tx = await resolveProperties(tx); + const tx = await getTransactionRequest(transaction); + // Not a Klaytn TxType; fallback to ethers.Wallet if (!KlaytnTxFactory.has(tx.type)) { return super.signTransaction(tx); } - const ttx = KlaytnTxFactory.fromObject(tx); - const sigHash = keccak256(ttx.sigRLP()); - const sig = this._signingKey().signDigest(sigHash); + const klaytnTx = KlaytnTxFactory.fromObject(tx); - if (tx.chainId) { // EIP-155 - sig.v = sig.recoveryParam + tx.chainId * 2 + 35; - } - ttx.addSenderSig(sig); + const sigHash = keccak256(klaytnTx.sigRLP()); + const sig = this._eip155sign(sigHash, tx.chainId); + klaytnTx.addSenderSig(sig); - if (ttx.hasFeePayer()) { - return ttx.senderTxHashRLP(); + if (isFeePayerSigTxType(klaytnTx.type)) { + return klaytnTx.senderTxHashRLP(); + } else { + return klaytnTx.txHashRLP(); } - return ttx.txHashRLP(); } + // Sign as a fee payer + // tx.feepayerSigs += Sign(tx.sigFeePayerRLP(), wallet.privateKey) + // return tx.txHashRLP(); async signTransactionAsFeePayer(transaction: Deferrable): Promise { - const tx: TransactionRequest = this._convertTxFromRLP(transaction); + const tx = await getTransactionRequest(transaction); - // @ts-ignore : chainId can be omitted from RLP encoded format - if (!tx.chainId) { - // @ts-ignore - tx.chainId = this.getChainId(); - } - const rtx: TransactionRequest = await resolveProperties(tx); - - // @ts-ignore : we have to add feePayer property - if (!rtx.feePayer) { - // @ts-ignore : we have to add feePayer property - rtx.feePayer = await this.getAddress(); + // Not a Klaytn TxType; not supported + if (!KlaytnTxFactory.has(tx.type)) { + throw new Error(`feePayer signature not supported for tx type ${tx.type}`); } - const ttx = KlaytnTxFactory.fromObject(rtx); - if (!ttx.hasFeePayer()) { - throw new Error("This transaction can not be signed as FeePayer"); + // Automatically populate 'feePayer' field, just like how 'from' field is populated. + // @ts-ignore: feePayer field does not exist in ethers.TransactionRequest type + tx.feePayer ??= await this.getAddress(); + const klaytnTx = KlaytnTxFactory.fromObject(tx); + if (!isFeePayerSigTxType(klaytnTx.type)) { + klaytnTx.throwTypeError("feePayer signature not supported"); } - const sigFeePayerHash = keccak256(ttx.sigFeePayerRLP()); - const sig = this._signingKey().signDigest(sigFeePayerHash); - - // @ts-ignore : we have to add feePayer property - if (tx.chainId) { // EIP-155 - // @ts-ignore : we have to add feePayer property - sig.v = sig.recoveryParam + tx.chainId * 2 + 35; - } - ttx.addFeePayerSig(sig); + const sigFeePayerHash = keccak256(klaytnTx.sigFeePayerRLP()); + const sig = this._eip155sign(sigFeePayerHash, tx.chainId); + klaytnTx.addFeePayerSig(sig); - return ttx.txHashRLP(); + return klaytnTx.txHashRLP(); } async sendTransaction(transaction: Deferrable): Promise { this._checkProvider("sendTransaction"); - const tx: TransactionRequest = this._convertTxFromRLP(transaction); - const ptx = await this.populateTransaction(tx); - const signedTx = await this.signTransaction(ptx); + const populatedTx = await this.populateTransaction(transaction); + const signedTx = await this.signTransaction(populatedTx); - if (!KlaytnTxFactory.has(ptx.type)) { + if (!KlaytnTxFactory.has(populatedTx.type)) { return await this.provider.sendTransaction(signedTx); + } else { + return await this._sendRawTransaction(signedTx); } - - return this._sendRawTransaction(signedTx); } - async sendTransactionAsFeePayer(transaction: Deferrable | string): Promise { + async sendTransactionAsFeePayer(transaction: Deferrable): Promise { this._checkProvider("sendTransactionAsFeePayer"); - const tx: TransactionRequest = this._convertTxFromRLP(transaction); - const ptx = await this.populateTransaction(tx); + const populatedTx = await this.populateTransaction(transaction); + const signedTx = await this.signTransactionAsFeePayer(populatedTx); - // @ts-ignore : we have to add feePayer property - ptx.feePayer = await this.getAddress(); - const signedTx = await this.signTransactionAsFeePayer(ptx); + return await this._sendRawTransaction(signedTx); + } - return this._sendRawTransaction(signedTx); + _eip155sign(digest: string, chainId?: number) { + const sig = this._signingKey().signDigest(digest); + if (chainId) { + sig.v = sig.recoveryParam + chainId * 2 + 35; + } + return sig; } async _sendRawTransaction(signedTx: string): Promise { From 5f29abebd33cacbc2a6d4affa6e6b29b080e50e4 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 18:48:42 +0900 Subject: [PATCH 08/69] ethers: Remove verifyMessage --- ethers-ext/src/signer.ts | 95 ---------------------------------------- 1 file changed, 95 deletions(-) diff --git a/ethers-ext/src/signer.ts b/ethers-ext/src/signer.ts index aa762914b..998f9c137 100644 --- a/ethers-ext/src/signer.ts +++ b/ethers-ext/src/signer.ts @@ -281,98 +281,3 @@ export class Wallet extends EthersWallet { } } } - -export async function verifyMessageAsKlaytnAccountKey(provider: Provider, address: string, message: Bytes | string, signature: any): Promise { - if (provider instanceof EthersJsonRpcProvider) { - const klaytn_accountKey = await provider.send("klay_getAccountKey", [address, "latest"]); - - if (klaytn_accountKey.keyType == 1) { - // AccountKeyLegacy - return verifyMessageAsAccountKeyLegacy(provider, address, message, signature); - } else if (klaytn_accountKey.keyType == 2) { - // AccountKeyPublic - return verifyMessageAsAccountKeyPublic(provider, klaytn_accountKey, message, signature); - } else if (klaytn_accountKey.keyType == 4) { - // AccountKeyWeightedMultiSig - return verifyMessageAsAccountKeyWeightedMultiSig(provider, klaytn_accountKey, message, signature); - } else if (klaytn_accountKey.keyType == 5) { - // AccountKeyRoleBased - const roleTransactionKey = klaytn_accountKey.key[0]; - - if (roleTransactionKey.keyType == 2) { - return verifyMessageAsAccountKeyPublic(provider, roleTransactionKey, message, signature); - } else if (roleTransactionKey.keyType == 4) { - return verifyMessageAsAccountKeyWeightedMultiSig(provider, roleTransactionKey, message, signature); - } - } - } else { - throw new Error("Klaytn typed transaction can only be broadcasted to a Klaytn JSON-RPC server"); - } - - return false; -} - -function verifyMessageAsAccountKeyLegacy(provider: Provider, address: string, message: Bytes | string, signature: any): boolean { - if (Array.isArray(signature) && !signature[0]) { - throw new Error("Needs a signature as a parameter like [sig] or sig"); - } else if (Array.isArray(signature) && !!signature[0]) { - signature = signature[0]; - } - - const actual_signer_addr = recoverAddress(hashMessage(message), signature); - - if (actual_signer_addr == ethers.utils.getAddress(address)) { - return true; - } - return false; -} - -function verifyMessageAsAccountKeyPublic(provider: Provider, klaytn_accountKey: any, message: Bytes | string, signature: any): boolean { - if (Array.isArray(signature) && !signature[0]) { - throw new Error("Needs a signature as a parameter like [sig] or sig"); - } else if (Array.isArray(signature) && !!signature[0]) { - signature = signature[0]; - } - - const actual_signer_addr = recoverAddress(hashMessage(message), signature); - - const x = String(klaytn_accountKey.key.x).substring(2); - const y = String(klaytn_accountKey.key.y).substring(2); - const klaytn_addr = computeAddress(HexStr.concat("0x04" + x + y)); - - if (actual_signer_addr === klaytn_addr) { - return true; - } - return false; -} - -function verifyMessageAsAccountKeyWeightedMultiSig(provider: Provider, klaytn_accountKey: any, message: Bytes | string, signature: any): boolean { - if (!Array.isArray(signature)) { - throw new Error("This account needs multi-signature [ sig1, sig2 ... sigN ]"); - } - - const threshold = klaytn_accountKey.key.threshold; - let current_threshold = 0; - - for (let i = 0; i < klaytn_accountKey.key.keys.length; i++) { - const weight = klaytn_accountKey.key.keys[i].weight; - const x = String(klaytn_accountKey.key.keys[i].key.x).substring(2); - const y = String(klaytn_accountKey.key.keys[i].key.y).substring(2); - const oneOfAddress = computeAddress(HexStr.concat("0x04" + x + y)); - - for (let j = 0; j < signature.length; j++) { - const actual_signer_addr = recoverAddress(hashMessage(message), signature[j]); - - if (oneOfAddress === actual_signer_addr) { - current_threshold += weight; - if (threshold <= current_threshold) { - return true; - } else { - break; - } - } - } // for j - } // for i - - return false; -} From ca744b4204726ae223c8157ff1a46f0916a75954 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 18:51:33 +0900 Subject: [PATCH 09/69] ethers: Delete core component --- ethers-ext/src/core/accountKey.ts | 33 -- ethers-ext/src/core/field.ts | 381 ------------- ethers-ext/src/core/index.ts | 79 --- ethers-ext/src/core/klaytn_accountKeys.ts | 82 --- ethers-ext/src/core/klaytn_tx.ts | 147 ----- ethers-ext/src/core/klaytn_tx_basic.ts | 319 ----------- .../src/core/klaytn_tx_feeDelegation.ts | 520 ----------------- .../core/klaytn_tx_partialFeeDelegation.ts | 527 ------------------ ethers-ext/src/core/sig.ts | 57 -- ethers-ext/src/core/util.ts | 220 -------- ethers-ext/test/core/klaytn_tx.spec.ts | 111 ---- ethers-ext/test/core/sig.spec.ts | 30 - 12 files changed, 2506 deletions(-) delete mode 100644 ethers-ext/src/core/accountKey.ts delete mode 100644 ethers-ext/src/core/field.ts delete mode 100644 ethers-ext/src/core/index.ts delete mode 100644 ethers-ext/src/core/klaytn_accountKeys.ts delete mode 100644 ethers-ext/src/core/klaytn_tx.ts delete mode 100644 ethers-ext/src/core/klaytn_tx_basic.ts delete mode 100644 ethers-ext/src/core/klaytn_tx_feeDelegation.ts delete mode 100644 ethers-ext/src/core/klaytn_tx_partialFeeDelegation.ts delete mode 100644 ethers-ext/src/core/sig.ts delete mode 100644 ethers-ext/src/core/util.ts delete mode 100644 ethers-ext/test/core/klaytn_tx.spec.ts delete mode 100644 ethers-ext/test/core/sig.spec.ts diff --git a/ethers-ext/src/core/accountKey.ts b/ethers-ext/src/core/accountKey.ts deleted file mode 100644 index 8440b4ebb..000000000 --- a/ethers-ext/src/core/accountKey.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { FieldType, FieldSet, FieldSetFactory } from "./field"; - -export abstract class AccountKey extends FieldSet { - // ////////////////////////////////////////////////////////// - // Child classes MUST override below properties and methods - - // RLP encoding to be used in AccountUpdate transactions. - abstract toRLP(): string; - - // End override - // ////////////////////////////////////////////////////////// -} - -const requiredFields = ["type"]; -export const AccountKeyFactory = new FieldSetFactory( - requiredFields, -); - - -// Accepted types: TypedAccountKey, string, plain object, serialized bytes -export const FieldTypeAccountKey = new class implements FieldType { - canonicalize(value: AccountKey | string | any): string { - if (value instanceof AccountKey) { - return value.toRLP(); - } else if (typeof(value) == "string") { - return value; - } else { - return AccountKeyFactory.fromObject(value).toRLP(); - } - } - - emptyValue(): string { return ""; } -}; \ No newline at end of file diff --git a/ethers-ext/src/core/field.ts b/ethers-ext/src/core/field.ts deleted file mode 100644 index dd69bda05..000000000 --- a/ethers-ext/src/core/field.ts +++ /dev/null @@ -1,381 +0,0 @@ -import { getAddress } from "@ethersproject/address"; -import { BigNumber } from "@ethersproject/bignumber"; -import _ from "lodash"; - -import { SignatureLike, SignatureTuple, getSignatureTuple } from "./sig"; -import { HexStr, RLP } from "./util"; - -export class FieldError extends Error { - constructor(ty: FieldType, name: string, value: any) { - const message = `Cannot assign value '${value}' to field '${name}' of type '${ty.constructor.name}'`; - super(message); - this.name = "FieldError"; - } -} - -export interface FieldType { - // convert into the canonical form. - canonicalize(value: any): any; - // default empty value in canonical form. - emptyValue(): any; -} - -export interface FieldTypes { - [name: string]: FieldType; -} - -export interface Fields { - [name: string]: any; -} - -// Accepted types: hex string of an address -// Canonical type: hex string of checksumed address -export const FieldTypeAddress = new class implements FieldType { - canonicalize(value: any): string { - if (value === "0x") { - return "0x0000000000000000000000000000000000000000"; - } - return getAddress(value); - } - - emptyValue(): string { return "0x"; } -}; - -// Accepted types: hex string, byte array -// Canonical type: hex string -export const FieldTypeBytes = new class implements FieldType { - canonicalize(value: any): string { return HexStr.from(value); } - emptyValue(): string { return "0x"; } -}; - -export class FieldTypeBytesFixedLen implements FieldType { - length: number; - constructor(length: number) { - this.length = length; - } - - canonicalize(value: any): string { - if (!HexStr.isHex(value, this.length)) { - throw new Error(`Value is not ${this.length} bytes`); - } - return HexStr.from(value); - } - - emptyValue(): string { return "0x00"; } -} - -// Accepted types: hex-encoded string -// Canonical type: hex-encoded string -export const FieldTypeCompressedPubKey = new FieldTypeBytesFixedLen(33); - -// WeightedMultiSigKeys is canonicalized like follow. -// e.g. -// [ -// "03", // threshold -// [ -// // [ weight, key ] list for multi-sig -// [ -// "01", -// "02c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e" -// ], -// [ -// "01", -// "0212d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfb" -// ], -// [ -// "01", -// "02ea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cd" -// ], -// [ -// "01", -// "038551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6" -// ] -// ] -// ] -export const FieldTypeWeightedMultiSigKeys = new class implements FieldType { - canonicalize(value: [ number, [[number, string]] ]): any[] { - const ret = [], keys = []; - - if (value.length != 2 && value[1].length < 2) { - throw new Error("Threshold and Keys format is wrong for MultiSig"); - } - ret.push(HexStr.fromNumber(value[0])); - - for (let i = 0; i < value[1].length; i++) { - if (value[1][i][0] == undefined || value[1][i][1] == undefined) { - throw new Error("Weight and Key format is wrong for MultiSig"); - } - const key = []; - key.push(HexStr.fromNumber(value[1][i][0])); - key.push(value[1][i][1]); - keys.push(key); - } - - ret.push(keys); - return ret; - } - - emptyValue(): string { return "0x"; } -}; - -// RoleBasedKeys is canonicalized like follow. -// e.g. -// [ -// // RoleTransaction -// "02a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d", -// -// // RoleAccountUpdate -// [ -// "02", -// [ -// [ -// "01", -// "03e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d" -// ], -// [ -// "01", -// "0336f6355f5b532c3c1606f18fa2be7a16ae200c5159c8031dd25bfa389a4c9c06" -// ] -// ] -// ], -// -// // RoleFeePayer -// "02a102c8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447" -// ] -// -> -// [ -// "02a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d", -// "04f84b02f848e301a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512de301a10336f6355f5b532c3c1606f18fa2be7a16ae200c5159c8031dd25bfa389a4c9c06", -// "02a102c8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447" -// ] -export const FieldTypeRoleBasedKeys = new class implements FieldType { - canonicalize(value: [ any, any, any ]): string[] { - if (value.length != 3) { - throw new Error("RoleBasedKey format is wrong"); - } - - const ret = []; - for (let i = 0; i < value.length; i++) { - if (typeof value[i] === "string") { - // AccountKeyNil '0x80', AccountKeyPublic '0x02', AccountKeyWeightedMultiSig '0x04' - if (!(value[i] == "0x80" || value[i].startsWith("0x02") || value[i].startsWith("0x04"))) { - throw new Error(`'${value[i]}' is wrong string format for role-based key`); - } - ret.push(value[i]); - } else if (Array.isArray(value[i])) { - ret.push(HexStr.concat("0x04", RLP.encode(FieldTypeWeightedMultiSigKeys.canonicalize(value[i])))); - } else if (typeof value[i] === "object") { - if (value[i].type == undefined || HexStr.fromNumber(value[i].type) != "0x02" - || value[i].key == undefined || String(value[i].key).length != 68) { - throw new Error(`'${value[i]}' is wrong object format for role-based key`); - } - ret.push(HexStr.concat("0x02", RLP.encode(value[i].key))); - } else { - throw new Error(`'${value[i]}' is wrong format for role-based key`); - } - } - return ret; - } - - emptyValue(): string { return "0x"; } -}; - -export class FieldTypeNumberBits implements FieldType { - maxBits: number; - maxBN: BigNumber; - constructor(maxBits?: number) { - if (!maxBits) { - maxBits = 256; - } - this.maxBits = maxBits; - this.maxBN = BigNumber.from(2).pow(maxBits); - } - - canonicalize(value: any): string { - if (value === "0x") { - value = 0; - } - const bn = BigNumber.from(value); - - if (bn.gte(this.maxBN)) { - throw new Error(`Number exceeds ${this.maxBits} bits`); - } - - if (bn.isZero()) { - return "0x"; - } - return bn.toHexString(); - } - - emptyValue(): string { return "0x"; } -} - -// Accepted types: JS number, JS bigint, BigNumber class, hex-encoded string -// Canonical type: hex string -export const FieldTypeUint8 = new FieldTypeNumberBits(8); -export const FieldTypeUint32 = new FieldTypeNumberBits(32); -export const FieldTypeUint64 = new FieldTypeNumberBits(64); -export const FieldTypeUint256 = new FieldTypeNumberBits(256); - -// Accepted types: [v,r,s] tuple, {v,r,s} object, serialized bytes -// Canonical type: [v,r,s] tuple -export const FieldTypeSignatureTuples = new class implements FieldType { - canonicalize(value: SignatureLike[]): SignatureTuple[] { - return _.map(value, getSignatureTuple); - } - - emptyValue(): SignatureTuple[] { return []; } -}; - -export const FieldTypeBool = new class implements FieldType { - canonicalize(value: any): string { - if (value === "0x01" || value === "0x") { - return value; - } - return value ? "0x01" : "0x"; - } - - emptyValue(): string { return "0x"; } -}; -export abstract class FieldSet { - // ////////////////////////////////////////////////////////// - // Child classes MUST override below properties and methods - - // An 1-byte type enum - public static type: number; - - // Human readable name of the type. Appears in error messages. - public static typeName: string; - - // Fields declaration - public static fieldTypes: FieldTypes; - - // End override - // ////////////////////////////////////////////////////////// - - // shortcuts for this._static.*. - public readonly type: number = 0; - public readonly typeName: string = ""; - public readonly fieldTypes: FieldTypes = {}; - - // Fields in their canonical forms. - protected fields: Fields = {}; - - constructor() { - this.type = this._static.type; - this.typeName = this._static.typeName; - this.fieldTypes = this._static.fieldTypes; - } - - // A workaround to read child class's static members. - private get _static(): typeof FieldSet { - return this.constructor as typeof FieldSet; - } - - // Fields accessors - - public setFields(obj: Fields): void { - this.fields = {}; - _.forOwn(this.fieldTypes, (fieldType, name) => { - if (obj[name] === undefined) { - this.fields[name] = null; - } else { - this.fields[name] = fieldType.canonicalize(obj[name]); - } - }); - } - - public setFieldsFromArray(names: string[], array: any[]): void { - this.fields = {}; - for (let i = 0; i < array.length; i++) { - const name = names[i]; - const fieldType = this.fieldTypes[name]; - if (!fieldType) { - throw new Error(`Unknown field '${name}' for '${this.typeName}' (type ${this.type})`); - } - this.fields[name] = fieldType.canonicalize(array[i]); - } - } - - public getField(name: string): any { - const value = this.fields[name]; - if (value == null) { - throw new Error(`Missing field '${name}' for '${this.typeName}' (type ${this.type})`); - } - return value; - } - - public getFields(names: string[]): any[] { - return _.map(names, (name) => this.getField(name)); - } - - public toObject(): Fields { - return this.fields; - } -} - -// Instantiable child class of TypedFields -export interface ConcreteFieldSet { - type: number; - fieldTypes: FieldTypes; - new (): T; -} - -export class FieldSetFactory { - private registry: { [type: number]: ConcreteFieldSet } = {}; - private requiredFields: string[]; - - constructor(requiredFields?: string[]) { - this.requiredFields = requiredFields || []; - } - - public add(cls: ConcreteFieldSet) { - const type = cls.type; - const fieldTypes = cls.fieldTypes; - - if (!type) { - throw new Error("Cannot register TypedFields: Missing type"); - } - if (this.registry[type]) { - throw new Error(`Cannot register TypedFields: type ${type} already registered`); - } - - if (!fieldTypes) { - throw new Error("Cannot register TypedFields: Missing fieldTypes"); - } - for (const name of this.requiredFields) { - if (!fieldTypes[name]) { - throw new Error(`Cannot register TypedFields: Missing required field '${name}'`); - } - } - - this.registry[type] = cls; - } - - public has(type?: any): boolean { - if (!!type && HexStr.isHex(type)) { - return !!type && !!this.registry[HexStr.toNumber(type)]; - } else { - return !!type && !!this.registry[type]; - } - } - - public lookup(type?: any): ConcreteFieldSet { - if (!type || !this.has(type)) { - throw new Error(`Unsupported type '${type}'`); - } - - if (HexStr.isHex(type)) { - return this.registry[HexStr.toNumber(type)]; - } - - return this.registry[type]; - } - - public fromObject(fields: Fields): T { - const ctor = this.lookup(fields?.type); - const instance = new ctor(); - instance.setFields(fields); - return instance; - } -} diff --git a/ethers-ext/src/core/index.ts b/ethers-ext/src/core/index.ts deleted file mode 100644 index f86446493..000000000 --- a/ethers-ext/src/core/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -export { KlaytnTx, KlaytnTxFactory, objectFromRLP } from "./klaytn_tx"; -export { AccountKey, AccountKeyFactory } from "./accountKey"; - -/* eslint-disable import/order */ -import { KlaytnTxFactory } from "./klaytn_tx"; - -// Basic TX -import { - TxTypeValueTransfer, - TxTypeValueTransferMemo, - TxTypeSmartContractDeploy, - TxTypeSmartContractExecution, - TxTypeAccountUpdate, - TxTypeCancel, - TxTypeChainDataAnchoring, -} from "./klaytn_tx_basic"; - -KlaytnTxFactory.add(TxTypeValueTransfer); -KlaytnTxFactory.add(TxTypeValueTransferMemo); -KlaytnTxFactory.add(TxTypeSmartContractDeploy); -KlaytnTxFactory.add(TxTypeSmartContractExecution); -KlaytnTxFactory.add(TxTypeAccountUpdate); -KlaytnTxFactory.add(TxTypeCancel); -KlaytnTxFactory.add(TxTypeChainDataAnchoring); - -// Fee Delegation TX -import { - TxTypeFeeDelegatedValueTransfer, - TxTypeFeeDelegatedValueTransferMemo, - TxTypeFeeDelegatedSmartContractDeploy, - TxTypeFeeDelegatedSmartContractExecution, - TxTypeFeeDelegatedAccountUpdate, - TxTypeFeeDelegatedCancel, - TxTypeFeeDelegatedChainDataAnchoring, -} from "./klaytn_tx_feeDelegation"; - -KlaytnTxFactory.add(TxTypeFeeDelegatedValueTransfer); -KlaytnTxFactory.add(TxTypeFeeDelegatedValueTransferMemo); -KlaytnTxFactory.add(TxTypeFeeDelegatedSmartContractDeploy); -KlaytnTxFactory.add(TxTypeFeeDelegatedSmartContractExecution); -KlaytnTxFactory.add(TxTypeFeeDelegatedAccountUpdate); -KlaytnTxFactory.add(TxTypeFeeDelegatedCancel); -KlaytnTxFactory.add(TxTypeFeeDelegatedChainDataAnchoring); - -// Partial Fee Delegation TX -import { - TxTypeFeeDelegatedValueTransferWithRatio, - TxTypeFeeDelegatedValueTransferMemoWithRatio, - TxTypeFeeDelegatedSmartContractDeployWithRatio, - TxTypeFeeDelegatedSmartContractExecutionWithRatio, - TxTypeFeeDelegatedAccountUpdateWithRatio, - TxTypeFeeDelegatedCancelWithRatio, - TxTypeFeeDelegatedChainDataAnchoringWithRatio, -} from "./klaytn_tx_partialFeeDelegation"; - -KlaytnTxFactory.add(TxTypeFeeDelegatedValueTransferWithRatio); -KlaytnTxFactory.add(TxTypeFeeDelegatedValueTransferMemoWithRatio); -KlaytnTxFactory.add(TxTypeFeeDelegatedSmartContractDeployWithRatio); -KlaytnTxFactory.add(TxTypeFeeDelegatedSmartContractExecutionWithRatio); -KlaytnTxFactory.add(TxTypeFeeDelegatedAccountUpdateWithRatio); -KlaytnTxFactory.add(TxTypeFeeDelegatedCancelWithRatio); -KlaytnTxFactory.add(TxTypeFeeDelegatedChainDataAnchoringWithRatio); - -// AccountKey -import { AccountKeyFactory } from "./accountKey"; - -import { - AccountKeyLegacy, - AccountKeyPublic, - AccountKeyFail, - AccountKeyWeightedMultiSig, - AccountKeyRoleBased, -} from "./klaytn_accountKeys"; - -AccountKeyFactory.add(AccountKeyLegacy); -AccountKeyFactory.add(AccountKeyPublic); -AccountKeyFactory.add(AccountKeyFail); -AccountKeyFactory.add(AccountKeyWeightedMultiSig); -AccountKeyFactory.add(AccountKeyRoleBased); diff --git a/ethers-ext/src/core/klaytn_accountKeys.ts b/ethers-ext/src/core/klaytn_accountKeys.ts deleted file mode 100644 index afb191827..000000000 --- a/ethers-ext/src/core/klaytn_accountKeys.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { AccountKey } from "./accountKey"; -import { FieldTypeUint8, FieldTypeCompressedPubKey, FieldTypeWeightedMultiSigKeys, FieldTypeRoleBasedKeys } from "./field"; -import { HexStr, RLP } from "./util"; - - -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeynil -export const AccountKeyNil = "0x80"; - -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy -export class AccountKeyLegacy extends AccountKey { - static type = 0x01; - static typeName = "AccountKeyLegacy"; - static fieldTypes = { - "type": FieldTypeUint8, - }; - - toRLP(): string { - return "0x01c0"; - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -export class AccountKeyPublic extends AccountKey { - static type = 0x02; - static typeName = "AccountKeyPublic"; - static fieldTypes = { - "type": FieldTypeUint8, - "key": FieldTypeCompressedPubKey, - }; - - // 0x02 + encode(CompressedPubKey) - toRLP(): string { - const inner = this.getField("key"); - return HexStr.concat("0x02", RLP.encode(inner)); - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyfail -export class AccountKeyFail extends AccountKey { - static type = 0x03; - static typeName = "AccountKeyFail"; - static fieldTypes = { - "type": FieldTypeUint8, - }; - - toRLP(): string { - return "0x03c0"; - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -export class AccountKeyWeightedMultiSig extends AccountKey { - static type = 0x04; - static typeName = "AccountKeyWeightedMultiSig"; - static fieldTypes = { - "type": FieldTypeUint8, - "keys": FieldTypeWeightedMultiSigKeys, - }; - - // 0x04 + encode([threshold, [[weight, CompressedPubKey1], [weight2, CompressedPubKey2]]]) - toRLP(): string { - const inner = this.getField("keys"); - return HexStr.concat("0x04", RLP.encode(inner)); - } -} - - -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased -export class AccountKeyRoleBased extends AccountKey { - static type = 0x05; - static typeName = "AccountKeyRoleBased"; - static fieldTypes = { - "type": FieldTypeUint8, - "keys": FieldTypeRoleBasedKeys, - }; - - // 0x05 + encode([key1, key2, key3]) - toRLP(): string { - const inner = this.getField("keys"); - return HexStr.concat("0x05", RLP.encode(inner)); - } -} \ No newline at end of file diff --git a/ethers-ext/src/core/klaytn_tx.ts b/ethers-ext/src/core/klaytn_tx.ts deleted file mode 100644 index 895c3dbd5..000000000 --- a/ethers-ext/src/core/klaytn_tx.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { TransactionRequest } from "@ethersproject/abstract-provider"; -import { BigNumber } from "ethers"; -import { hexValue, parseTransaction } from "ethers/lib/utils"; -import { accessListify } from "@ethersproject/transactions"; -import _ from "lodash"; - -import { FieldSet, FieldSetFactory } from "./field"; -import { SignatureLike, getSignatureTuple } from "./sig"; -import { HexStr } from "./util"; - -export abstract class KlaytnTx extends FieldSet { - // ////////////////////////////////////////////////////////// - // Child classes MUST override below properties and methods - - // RLP encoding for sender to sign. - abstract sigRLP(): string; - // RLP encoding for broadcasting. Includes all signatures. - abstract txHashRLP(): string; - // Set its own fields from an RLP encoded string. - abstract setFieldsFromRLP(rlp: string): void; - - // ////////////////////////////////////////////////////////// - // Child classes MAY override below methods - - // RLP encoding for fee payer to sign. - sigFeePayerRLP(): string { - throw new Error(`fee payer not supported in txtype ${this.type}`); - } - - // RLP encoding with sender signature. - senderTxHashRLP(): string { - return this.sigRLP(); - } - - // Add a signature - addSenderSig(sig: SignatureLike) { - if (!this.fieldTypes.txSignatures) { - throw new Error(`No 'txSignatures' field in txtype '${this.type}'`); - } - const tuple = getSignatureTuple(sig); - this.fields.txSignatures ||= []; - this.fields.txSignatures.push(tuple); - } - - // Add a signature as a feePayer - addFeePayerSig(sig: SignatureLike) { - if (!this.fieldTypes.feePayerSignatures) { - throw new Error(`No 'feePayerSignatures' field in txtype '${this.type}'`); - } - const tuple = getSignatureTuple(sig); - this.fields.feePayerSignatures ||= []; - this.fields.feePayerSignatures.push(tuple); - } - - public hasFeePayer(): boolean { - const feeDelegations: Array = [ - 0x09, 0x11, 0x21, 0x29, 0x31, 0x39, 0x49]; - const feeDelegationsAsFeePayer: Array = [ - 0x0a, 0x12, 0x22, 0x2a, 0x32, 0x3a, 0x4a]; - - const fp_type = typeof(this.type) == "string" ? HexStr.toNumber(this.type) : this.type; - - if (typeof(fp_type) == "number") { - return feeDelegations.includes(fp_type) || feeDelegationsAsFeePayer.includes(fp_type); - } else { - throw new Error("The type have to be a number"); - } - } - - // End override - // ////////////////////////////////////////////////////////// -} - -class _KlaytnTxFactory extends FieldSetFactory { - public fromRLP(value: string): any { - if (!HexStr.isHex(value)) { - throw new Error("Not an RLP encoded string"); - } - - const rlp = HexStr.from(value); - if (rlp.length < 4) { - throw new Error("RLP encoded string too short"); - } - - const type = HexStr.toNumber(rlp.substr(0, 4)); - if (!this.has(type)) { - return parseTransaction(value); - } else { - const ctor = this.lookup(type); - const instance = new ctor(); - instance.setFieldsFromRLP(rlp); - return instance; - } - } -} - -const requiredFields = ["type", "chainId", "txSignatures"]; -export const KlaytnTxFactory = new _KlaytnTxFactory( - requiredFields, -); - -export function objectFromRLP(value: string): any { - const tx = KlaytnTxFactory.fromRLP(value); - - if (tx instanceof KlaytnTx) { - return tx.toObject(); - } - - return tx; -} - -export function encodeTxForRPC(tx: TransactionRequest): any { - const formatted: any = {}; - - const numericFields = ["chainId", "gasLimit", "gasPrice", "type", "maxFeePerGas", "maxPriorityFeePerGas", "nonce", "value"]; - _.each(numericFields, (key) => { - if (!_.has(tx, key)) { - return; - } - - let value = (tx)[key]; - value = hexValue(BigNumber.from(value)); - - if (key == "gasLimit") { - formatted["gas"] = value; - } else { - formatted[key] = value; - } - }); - - const bytestrFields = ["from", "to", "data", "input"] - _.each(bytestrFields, (key) => { - if (!_.has(tx, key)) { - return; - } - - let value = (tx)[key]; - value = HexStr.from(value); - formatted[key] = value; - }); - - if (tx.accessList) { - formatted["accessList"] = accessListify(tx.accessList); - } - - return formatted; -} diff --git a/ethers-ext/src/core/klaytn_tx_basic.ts b/ethers-ext/src/core/klaytn_tx_basic.ts deleted file mode 100644 index 802b166d0..000000000 --- a/ethers-ext/src/core/klaytn_tx_basic.ts +++ /dev/null @@ -1,319 +0,0 @@ -import _ from "lodash"; - -import { FieldTypeAccountKey } from "./accountKey"; -import { - FieldTypeAddress, - FieldTypeSignatureTuples, - FieldTypeBool, - FieldTypeUint8, - FieldTypeUint64, - FieldTypeUint256, - FieldTypeBytes} from "./field"; -import { KlaytnTx } from "./klaytn_tx"; -import { RLP, HexStr } from "./util"; - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer -export class TxTypeValueTransfer extends KlaytnTx { - static type = 0x8; - static typeName = "TxTypeValueTransfer"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "txSignatures" - ], array); - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfermemo -export class TxTypeValueTransferMemo extends KlaytnTx { - static type = 0x10; - static typeName = "TxTypeValueTransferMemo"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures" - ], array); - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypesmartcontractdeploy -export class TxTypeSmartContractDeploy extends KlaytnTx { - static type = 0x28; - static typeName = "TxTypeSmartContractDeploy"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "humanReadable": FieldTypeBool, - "codeFormat": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat"]); - inner[4] = "0x"; - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat", "txSignatures"]); - // have to do someting in the future - inner[3] = "0x"; - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat", "txSignatures" - ], array); - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypesmartcontractexecution -export class TxTypeSmartContractExecution extends KlaytnTx { - static type = 0x30; - static typeName = "TxTypeSmartContractExecution"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures" - ], array); - } -} - - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypeaccountupdate -export class TxTypeAccountUpdate extends KlaytnTx { - static type = 0x20; - static typeName = "TxTypeAccountUpdate"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "key": FieldTypeAccountKey, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "key", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "txSignatures" - ], array); - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypecancel -export class TxTypeCancel extends KlaytnTx { - static type = 0x38; - static typeName = "TxTypeCancel"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "txSignatures" - ], array); - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypechaindataanchoring -export class TxTypeChainDataAnchoring extends KlaytnTx { - static type = 0x48; - static typeName = "TxTypeCancel"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, input, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "input", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "txSignatures" - ], array); - } -} \ No newline at end of file diff --git a/ethers-ext/src/core/klaytn_tx_feeDelegation.ts b/ethers-ext/src/core/klaytn_tx_feeDelegation.ts deleted file mode 100644 index b70b3c860..000000000 --- a/ethers-ext/src/core/klaytn_tx_feeDelegation.ts +++ /dev/null @@ -1,520 +0,0 @@ -import _ from "lodash"; - -import { FieldTypeAccountKey } from "./accountKey"; -import { - FieldTypeAddress, - FieldTypeSignatureTuples, - FieldTypeBool, - FieldTypeUint8, - FieldTypeUint64, - FieldTypeUint256, - FieldTypeBytes} from "./field"; -import { KlaytnTx } from "./klaytn_tx"; -import { RLP, HexStr } from "./util"; - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer -export class TxTypeFeeDelegatedValueTransfer extends KlaytnTx { - static type = 0x9; - static typeName = "TxTypeFeeDelegatedValueTransfer"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([ encode([type, nonce, gasPrice, gas, to, value, from]), feePayer, chainid, 0, 0 ]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 8) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "txSignatures" - ], array); - } else if (array.length == 10) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo -export class TxTypeFeeDelegatedValueTransferMemo extends KlaytnTx { - static type = 0x11; - static typeName = "TxTypeFeeDelegatedValueTransferMemo"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 9) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures" - ], array); - } else if (array.length == 11) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractdeploy -export class TxTypeFeeDelegatedSmartContractDeploy extends KlaytnTx { - static type = 0x29; - static typeName = "TxTypeFeeDelegatedSmartContractDeploy"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "humanReadable": FieldTypeBool, - "codeFormat": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat"]); - // have to do someting in the future - inner[4] = "0x"; - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat"]); - // have to do someting in the future - inner[4] = "0x"; - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat", "txSignatures"]); - // have to do someting in the future - inner[3] = "0x"; - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, codeFormat, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat", "txSignatures", "feePayer", "feePayerSignatures"]); - // have to do someting in the future - inner[3] = "0x"; - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 11) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat", "txSignatures" - ], array); - } else if (array.length == 13) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "codeFormat", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractexecution -export class TxTypeFeeDelegatedSmartContractExecution extends KlaytnTx { - static type = 0x31; - static typeName = "TxTypeFeeDelegatedSmartContractExecution"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 9) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures" - ], array); - } else if (array.length == 11) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate -export class TxTypeFeeDelegatedAccountUpdate extends KlaytnTx { - static type = 0x21; - static typeName = "TxTypeFeeDelegatedAccountUpdate"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "key": FieldTypeAccountKey, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "key", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "key", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 7) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "txSignatures" - ], array); - } else if (array.length == 9) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedcancel -export class TxTypeFeeDelegatedCancel extends KlaytnTx { - static type = 0x39; - static typeName = "TxTypeFeeDelegatedCancel"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 6) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "txSignatures" - ], array); - } else if (array.length == 8) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedchaindataanchoring -export class TxTypeFeeDelegatedChainDataAnchoring extends KlaytnTx { - static type = 0x49; - static typeName = "TxTypeFeeDelegatedChainDataAnchoring"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "input", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "input", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 7) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "txSignatures" - ], array); - } else if (array.length == 9) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} \ No newline at end of file diff --git a/ethers-ext/src/core/klaytn_tx_partialFeeDelegation.ts b/ethers-ext/src/core/klaytn_tx_partialFeeDelegation.ts deleted file mode 100644 index 198c771bb..000000000 --- a/ethers-ext/src/core/klaytn_tx_partialFeeDelegation.ts +++ /dev/null @@ -1,527 +0,0 @@ -import _ from "lodash"; - -import { FieldTypeAccountKey } from "./accountKey"; -import { - FieldTypeAddress, - FieldTypeSignatureTuples, - FieldTypeBool, - FieldTypeUint8, - FieldTypeUint64, - FieldTypeUint256, - FieldTypeBytes} from "./field"; -import { KlaytnTx } from "./klaytn_tx"; -import { RLP, HexStr } from "./util"; - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio -export class TxTypeFeeDelegatedValueTransferWithRatio extends KlaytnTx { - static type = 0x0a; - static typeName = "TxTypeFeeDelegatedValueTransferWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "feeRatio": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, feeRatio]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([ encode([type, nonce, gasPrice, gas, to, value, from, feeRatio]), feePayer, chainid, 0, 0 ]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, feeRatio, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "feeRatio", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, feeRatio, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 9) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "feeRatio", "txSignatures" - ], array); - } else if (array.length == 11) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransfermemowithratio -export class TxTypeFeeDelegatedValueTransferMemoWithRatio extends KlaytnTx { - static type = 0x12; - static typeName = "TxTypeFeeDelegatedValueTransferMemoWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "feeRatio": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 10) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures" - ], array); - } else if (array.length == 12) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedsmartcontractdeploywithratio -export class TxTypeFeeDelegatedSmartContractDeployWithRatio extends KlaytnTx { - static type = 0x2a; - static typeName = "TxTypeFeeDelegatedSmartContractDeployWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "humanReadable": FieldTypeBool, - "feeRatio": FieldTypeUint8, - "codeFormat": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "feeRatio", "codeFormat"]); - // have to do someting in the future - inner[4] = "0x"; - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "feeRatio", "codeFormat"]); - // have to do someting in the future - inner[4] = "0x"; - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "feeRatio", "codeFormat", "txSignatures"]); - // have to do someting in the future - inner[3] = "0x"; - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, humanReadable, feeRatio, codeFormat, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "feeRatio", "codeFormat", "txSignatures", "feePayer", "feePayerSignatures"]); - // have to do someting in the future - inner[3] = "0x"; - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 12) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "feeRatio", "codeFormat", "txSignatures" - ], array); - } else if (array.length == 14) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "humanReadable", "feeRatio", "codeFormat", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedsmartcontractexecutionwithratio -export class TxTypeFeeDelegatedSmartContractExecutionWithRatio extends KlaytnTx { - static type = 0x32; - static typeName = "TxTypeFeeDelegatedSmartContractExecutionWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "to": FieldTypeAddress, - "value": FieldTypeUint256, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "feeRatio": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, to, value, from, input, feeRatio]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, to, value, from, input, feeRatio, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 10) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures" - ], array); - } else if (array.length == 12) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "to", "value", "from", "input", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedaccountupdatewithratio -export class TxTypeFeeDelegatedAccountUpdateWithRatio extends KlaytnTx { - static type = 0x22; - static typeName = "TxTypeFeeDelegatedAccountUpdateWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "key": FieldTypeAccountKey, - "feeRatio": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "key", "feeRatio", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, rlpEncodedKey, feeRatio, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "key", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 8) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "feeRatio", "txSignatures" - ], array); - } else if (array.length == 10) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "key", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedcancelwithratio -export class TxTypeFeeDelegatedCancelWithRatio extends KlaytnTx { - static type = 0x3a; - static typeName = "TxTypeFeeDelegatedCancelWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "feeRatio": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, feeRatio]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, feeRatio]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, feeRatio, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "feeRatio", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, feeRatio, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 7) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "feeRatio", "txSignatures" - ], array); - } else if (array.length == 9) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} - -// https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedchaindataanchoringwithratio -export class TxTypeFeeDelegatedChainDataAnchoringWithRatio extends KlaytnTx { - static type = 0x4a; - static typeName = "TxTypeFeeDelegatedChainDataAnchoringWithRatio"; - static fieldTypes = { - "type": FieldTypeUint8, - "nonce": FieldTypeUint64, - "gasPrice": FieldTypeUint256, - "gasLimit": FieldTypeUint64, - "from": FieldTypeAddress, - "input": FieldTypeBytes, - "feeRatio": FieldTypeUint8, - "chainId": FieldTypeUint64, - "txSignatures": FieldTypeSignatureTuples, - "feePayer": FieldTypeAddress, - "feePayerSignatures": FieldTypeSignatureTuples, - }; - - sigRLP(): string { - // SigRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData, feeRatio]), chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("chainId"), "0x", "0x"]); - } - - sigFeePayerRLP(): string { - // SigFeePayerRLP = encode([encode([type, nonce, gasPrice, gas, from, anchoredData, feeRatio]), feePayer, chainid, 0, 0]) - const inner = this.getFields([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "feeRatio"]); - return RLP.encode([ - RLP.encode(inner), this.getField("feePayer"), this.getField("chainId"), "0x", "0x"]); - } - - senderTxHashRLP(): string { - // SenderTxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, feeRatio, txSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "input", "feeRatio", "txSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - txHashRLP(): string { - // TxHashRLP = type + encode([nonce, gasPrice, gas, from, anchoredData, feeRatio, txSignatures, feePayer, feePayerSignatures]) - const inner = this.getFields([ - "nonce", "gasPrice", "gasLimit", "from", "input", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures"]); - return HexStr.concat( - this.getField("type"), RLP.encode(inner)); - } - - setFieldsFromRLP(rlp: string): void { - // Strip type byte - const inner_rlp = "0x" + String(rlp).substring(4); - const array = _.concat([this.type], RLP.decode(inner_rlp)); - - if (array.length == 8) { - // from SenderTxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "feeRatio", "txSignatures" - ], array); - } else if (array.length == 10) { - // from TxHashRLP - this.setFieldsFromArray([ - "type", "nonce", "gasPrice", "gasLimit", "from", "input", "feeRatio", "txSignatures", "feePayer", "feePayerSignatures" - ], array); - } else { - throw new Error("Wrongly encoded RLP string"); - } - } -} \ No newline at end of file diff --git a/ethers-ext/src/core/sig.ts b/ethers-ext/src/core/sig.ts deleted file mode 100644 index 6eb50a4e1..000000000 --- a/ethers-ext/src/core/sig.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { splitSignature } from "@ethersproject/bytes"; -import _ from "lodash"; - -import { HexStr } from "./util"; - -// List of signature tuples used in Klaytn transactions. -// All elements must be string for convenient RLP encoding. -// [ [v1,r1,s1], [v2,r2,s2] ]; -export type SignatureTuple = [string, string, string]; - -// Commonly used signature object. -export interface SignatureObject { - r: string; - s: string; - v?: number; - recoveryParam?: number; -} - -// All kinds of ECDSA signatures returned from various libraries. -export type SignatureLike = - SignatureTuple | - SignatureObject | - string; - -// If the sig is an array, the first element 'v' must be one of: -// - pre-EIP-155 v: {27, 28} -// - EIP-155 v: {27, 28} + chainId*8 + 2 -// -// If the sig is in object form, it must have one of: -// - sig.recoveryParam: {0, 1} -// - sig.v -// - pre-EIP-155 v: {27, 28} -// - EIP-155 v: {27, 28} + chainId*8 + 2 -// -// If the sig is bytes, it must be 64 or 65 bytes. -// -// Returns a [v,r,s] tuple composed of only strings. For example, [ -// "0x1b", -// "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", -// "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", -// ] -export function getSignatureTuple(sig: SignatureLike): SignatureTuple { - // For array, pass through splitSignature() for sanity check - if (_.isArray(sig) && sig.length == 3) { - const numV = HexStr.toNumber(sig[0]); - sig = { v: numV, r: sig[1], s: sig[2] }; - } - const split = splitSignature(sig); - - // R and S must not have leading zeros - // c.f. https://github.com/ethers-io/ethers.js/blob/v5/packages/transactions/src.ts/index.ts#L298 - return [ - HexStr.fromNumber(split.v), - HexStr.stripZeros(split.r), - HexStr.stripZeros(split.s), - ]; -} \ No newline at end of file diff --git a/ethers-ext/src/core/util.ts b/ethers-ext/src/core/util.ts deleted file mode 100644 index cc4b38a09..000000000 --- a/ethers-ext/src/core/util.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { BigNumber, BigNumberish } from "@ethersproject/bignumber"; -import * as bytes from "@ethersproject/bytes"; -import * as rlp from "@ethersproject/rlp"; -import { FixedNumber, ethers } from "ethers"; -import { computeAddress } from "ethers/lib/utils"; - -export const RLP = { - encode: rlp.encode, - decode: rlp.decode, -}; - -export const HexStr = { - toNumber(value: string): number { - return BigNumber.from(value).toNumber(); - }, - fromNumber(value: BigNumberish): string { - return BigNumber.from(value).toHexString(); - }, - from(value: any): string { - return bytes.hexlify(value); - }, - concat(...items: string[]): string { - return bytes.hexlify(bytes.concat(items)); - }, - isHex(value: any, length?: number): boolean { - return bytes.isHexString(value, length); - }, - isSameAddress(a:string, b:string): boolean { - const A = ethers.utils.getAddress(a); - const B = ethers.utils.getAddress(b); - return A == B; - }, - isSamePrivKey(a:string, b:string): boolean { - const A = computeAddress(a); - const B = computeAddress(b); - return this.isSameAddress(A, B); - }, - stripZeros(value: any): string { - return bytes.hexlify(bytes.stripZeros(value)); - }, - zeroPad(value:string, length:number): string { - return ethers.utils.hexZeroPad(value, length); - } -}; - -// Klaytn Type Enumeration -export enum TxType { - // Basic - ValueTransfer = 0x08, - ValueTransferMemo = 0x10, - AccountUpdate = 0x20, - SmartContractDeploy = 0x28, - SmartContractExecution = 0x30, - Cancel = 0x38, - - // Fee Delegation - FeeDelegatedValueTransfer = 0x09, - FeeDelegatedValueTransferMemo = 0x11, - FeeDelegatedAccountUpdate = 0x21, - FeeDelegatedSmartContractDeploy = 0x29, - FeeDelegatedSmartContractExecution = 0x31, - FeeDelegatedCancel = 0x39, - - // Partial Fee Delegation - FeeDelegatedValueTransferWithRatio = 0x0a, - FeeDelegatedValueTransferMemoWithRatio = 0x12, - FeeDelegatedAccountUpdateWithRatio = 0x22, - FeeDelegatedSmartContractDeployWithRatio = 0x2a, - FeeDelegatedSmartContractExecutionWithRatio = 0x32, - FeeDelegatedCancelWithRatio = 0x3a, -} - -export enum AccountKeyType { - // Account Key Type - Legacy = 0x01, - Public = 0x02, - Fail = 0x03, - WeightedMultiSig = 0x04, - RoleBased = 0x05 -} - -// For Klay unit -// https://docs.klaytn.foundation/content/klaytn/design/klaytn-native-coin-klay -// https://docs.ethers.org/v5/api/utils/display-logic/#display-logic--units -// https://github.com/ethers-io/ethers.js/blob/main/src.ts/utils/units.ts - -const KlayUnit = [ - { unit: "peb", pebFactor: 0 }, - { unit: "kpeb", pebFactor: 3 }, - { unit: "Mpeb", pebFactor: 6 }, - { unit: "Gpeb", pebFactor: 9 }, - { unit: "ston", pebFactor: 9 }, - { unit: "uKLAY", pebFactor: 12 }, - { unit: "mKLAY", pebFactor: 15 }, - { unit: "KLAY", pebFactor: 18 }, - { unit: "kKLAY", pebFactor: 21 }, - { unit: "MKLAY", pebFactor: 24 }, - { unit: "GKLAY", pebFactor: 27 }, - { unit: "TKLAY", pebFactor: 30 }, -]; - -function isValidUnit(unit: string): boolean { - for (let i = 0; i < KlayUnit.length; i++) { - if (KlayUnit[i].unit.toLowerCase() === unit.toLowerCase()) { - return true; - } - } - return false; -} - -function getFactor(unit: string): number { - for (let i = 0; i < KlayUnit.length; i++) { - if (KlayUnit[i].unit.toLowerCase() === unit.toLowerCase()) { - if (unit.toLowerCase() == "mklay" && unit.charAt(0) == "m") { - return 15; // milli KLAY - } else if (unit.toLowerCase() == "mklay" && unit.charAt(0) == "M") { - return 24; // Mega KLAY - } else { - return KlayUnit[i].pebFactor; - } - } - } - assertArgument(false, "invalid unit", "unit", unit); - return 0; -} - -type Numeric = number | bigint; - -/** -* Converts %%value%% into a //decimal string//, assuming %%unit%% decimal -* places. The %%unit%% may be the number of decimal places or the name of -* a unit (e.g. ``"gpeb"`` for 9 decimal places). -* -*/ -export function formatKlaytnUnits(value: BigNumberish, unit?: string | Numeric): string { - let decimals = 18; - if (typeof(unit) === "string") { - assertArgument(isValidUnit(unit) == true, "invalid unit", "unit", unit); - decimals = getFactor(unit); - } else if (unit != null) { - decimals = getNumber(unit, "unit"); - } - - // @ts-ignore - return FixedNumber.fromValue(BigNumber.from(value), decimals, { decimals, width: 512 }).toString(); -} - -/** -* Converts the //decimal string// %%value%% to a BigInt, assuming -* %%unit%% decimal places. Original Ethers function returns FixedNumber.value, -* but we changed to return BigNumber. The %%unit%% may the number of decimal places -* or the name of a unit (e.g. ``"gpeb"`` for 9 decimal places). -*/ -export function parseKlaytnUnits(value: string, unit?: string | Numeric): bigint { - assertArgument(typeof(value) === "string", "value must be a string", "value", value); - - let decimals = 18; - if (typeof(unit) === "string") { - assertArgument(isValidUnit(unit) == true, "invalid unit", "unit", unit); - decimals = getFactor(unit); - } else if (unit != null) { - decimals = getNumber(unit, "unit"); - } - - - // https://github.com/ethers-io/ethers.js/blob/3c17cf56b5164236108269ac1e36d66e2843cd1e/src.ts/utils/units.ts#L75 - // @ts-ignore - return BigNumber.from(FixedNumber.fromString(value, { decimals, width: 512 })); -} - -/** -* Converts %%value%% into a //decimal string// using 18 decimal places. -*/ -export function formatKlay(peb: BigNumberish): string { - return formatKlaytnUnits(peb, 18); -} - -/** -* Converts the //decimal string// %%ether%% to a BigInt, using 18 -* decimal places. -*/ -export function parseKlay(klay: string): bigint { - return parseKlaytnUnits(klay, 18); -} - -function assertArgument(check: boolean, message: string, code: string, info: any) { - if (check == false) { - throw new Error("message: " + message + ", code: " + code + ", info: " + info); - } -} - -// IEEE 754 support 53-bits of mantissa -const maxValue = 0x1fffffffffffff; - -/** - * Gets a //number// from %%value%%. If it is an invalid value for - * a //number//, then an ArgumentError will be thrown for %%name%%. - */ -export function getNumber(value: BigNumberish, name?: string): any { - switch (typeof(value)) { - case "bigint": - assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value); - return Number(value); - case "number": - assertArgument(Number.isInteger(value), "underflow", name || "value", value); - assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value); - return value; - case "string": - try { - if (value === "") { throw new Error("empty string"); } - return getNumber(BigInt(value), name); - } catch (e: any) { - assertArgument(false, `invalid numeric string: ${ e.message }`, name || "value", value); - return null; - } - } - assertArgument(false, "invalid numeric value", name || "value", value); - return null; -} - diff --git a/ethers-ext/test/core/klaytn_tx.spec.ts b/ethers-ext/test/core/klaytn_tx.spec.ts deleted file mode 100644 index af6186e17..000000000 --- a/ethers-ext/test/core/klaytn_tx.spec.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { assert } from "chai"; -import { TransactionRequest } from "@ethersproject/abstract-provider"; - -import { KlaytnTxFactory } from "../../src/core"; -import { encodeTxForRPC } from "../../src/core/klaytn_tx"; - -// Non-canonical types, which are common user-supplied values. -const nonce = 1234; -const gasPrice = 25e9; -const gasLimit = 30000; -const value = 1e12; -const chainId = 31337; -const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; -const to = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; -const txSignatures = [[ - "0x1b", - "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", - "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", -]]; -const feePayer = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; -const feePayerSignatures = [[ - "0x1b", - "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", - "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", -]]; - -interface txTestCase { - name: string; - obj: any; - sigRLP: string; - txRLP: string; - sigFeePayerRLP?: string; - senderTxHashRLP?: string; -} - -const txTestCases: txTestCase[] = [ - { - name: "TxTypeValueTransfer", - obj: { type: 0x08, nonce, gasPrice, gasLimit, to, value, from, chainId, txSignatures }, - sigRLP: "0xf846b83ff83d088204d28505d21dba008275309470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266827a698080", - txRLP: "0x08f8838204d28505d21dba008275309470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f845f8431ba066809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99a075c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", - }, - { - name: "TxTypeFeeDelegatedValueTransfer", - obj: { type: 0x09, nonce, gasPrice, gasLimit, to, value, from, chainId, txSignatures, feePayer, feePayerSignatures }, - sigRLP: "0xf846b83ff83d098204d28505d21dba008275309470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266827a698080", - txRLP: "0x09f8df8204d28505d21dba008275309470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f845f8431ba066809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99a075c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508943c44cdddb6a900fa2b585dd299e03d12fa4293bcf845f8431ba066809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99a075c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", - sigFeePayerRLP: "0xf85bb83ff83d098204d28505d21dba008275309470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266943c44cdddb6a900fa2b585dd299e03d12fa4293bc827a698080", - senderTxHashRLP: "0x09f8838204d28505d21dba008275309470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f845f8431ba066809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99a075c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", - } -]; - -describe("TypedTxFactory", () => { - // Generate mocha tests from test cases - for (const tc of txTestCases) { - it(tc.name, () => { - let tx = KlaytnTxFactory.fromObject(tc.obj); - assert.equal(tx.typeName, tc.name); - - // RLP encoding - assert.equal(tx.sigRLP(), tc.sigRLP); - assert.equal(tx.txHashRLP(), tc.txRLP); - if (tc.sigFeePayerRLP) { - assert.equal(tx.sigFeePayerRLP(), tc.sigFeePayerRLP); - } - if (tc.senderTxHashRLP) { - assert.equal(tx.senderTxHashRLP(), tc.senderTxHashRLP); - } - - // RLP decoding - tx = KlaytnTxFactory.fromRLP(tc.txRLP); - assert.equal(tx.typeName, tc.name); - assert.equal(tx.txHashRLP(), tc.txRLP); - }); - } -}); - -describe("encodeTxForRPC", () => { - it("success", () => { - let tx: TransactionRequest = { - chainId: 42, - gasLimit: 0x1111, - gasPrice: 0x222, - type: 2, - maxFeePerGas: 0x33, - maxPriorityFeePerGas: 0x4, - nonce: 0, - value: 0, - - from: "0x00000000000000000000000000000000000000aa", - to: "0x00000000000000000000000000000000000000bb", - data: "0x", - }; - - let formatted = encodeTxForRPC(tx); - assert.deepEqual(formatted, { - chainId: '0x2a', - gas: '0x1111', - gasPrice: '0x222', - type: '0x2', - maxFeePerGas: '0x33', - maxPriorityFeePerGas: '0x4', - nonce: '0x0', - value: '0x0', - - from: '0x00000000000000000000000000000000000000aa', - to: '0x00000000000000000000000000000000000000bb', - data: '0x', - }); - }); -}); diff --git a/ethers-ext/test/core/sig.spec.ts b/ethers-ext/test/core/sig.spec.ts deleted file mode 100644 index 30d130664..000000000 --- a/ethers-ext/test/core/sig.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { assert } from "chai"; - -import { getSignatureTuple } from "../../src/core/sig"; - -describe("getSignatureTuple", () => { - it("success", () => { - const vNum = 27; - const vHex = "0x1b"; - const rHex = "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99"; - const sHex = "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508"; - const canonical = [vHex, rHex, sHex]; - - const testcases = [ - // tuple - [vHex, rHex, sHex], - - // object - { v: vNum, r: rHex, s: sHex }, - { recoveryParam: 0, r: rHex, s: sHex }, - - // compact - ("0x" + rHex.substr(2) + sHex.substr(2)), - ("0x" + rHex.substr(2) + sHex.substr(2) + vHex.substr(2)), - ]; - - for (const tc of testcases) { - let tuple = getSignatureTuple(tc as any); - } - }); -}); From 100db2088960f72e30d3dfbfb7fa623882033025 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 19:02:36 +0900 Subject: [PATCH 10/69] ethers: Do not include test to dist --- ethers-ext/package.json | 3 ++- ethers-ext/tsconfig.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ethers-ext/package.json b/ethers-ext/package.json index a7843fae1..a1363d65e 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -1,7 +1,8 @@ { "name": "@klaytn/ethers-ext", "version": "0.9.5-beta", - "main": "dist/src/index.js", + "main": "dist/index.js", + "types": "dist/index.d.ts", "files": [ "./dist", "./src" diff --git a/ethers-ext/tsconfig.json b/ethers-ext/tsconfig.json index 3febbc51c..e31a2b94d 100644 --- a/ethers-ext/tsconfig.json +++ b/ethers-ext/tsconfig.json @@ -12,5 +12,5 @@ "esModuleInterop": true }, "exclude": ["dist", "example", "node_modules"], - "include": ["./test", "./src"] + "include": ["./src"] } From 9cc5b3720d5dc6b0322f2c8238d7f7f1196f397d Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 19:05:05 +0900 Subject: [PATCH 11/69] ethers: Bump deps @klaytn/web3rpc to 0.9.5 --- ethers-ext/package-lock.json | 8 ++++---- ethers-ext/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index a48aed3e2..72593dc40 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@klaytn/js-ext-core": "^0.9.6-beta", - "@klaytn/web3rpc": "^0.9.0", + "@klaytn/web3rpc": "^0.9.5", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", "lodash": "^4.17.21", @@ -1406,9 +1406,9 @@ } }, "node_modules/@klaytn/web3rpc": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.0.tgz", - "integrity": "sha512-sMyEkkEwmIMzd/1ixDlP0nrWIxVn+LHVgVMZ+yANswEtk6cgtpBscJdLsYwFNnGCeJ0vsHwvz1s9D4ZX/NT4gg==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.5.tgz", + "integrity": "sha512-yobaynvozIPRKH5XPtlNKAp4sqds2uPCHDxR0ym1gKst8R/P0gphtXEsWCA6taaHSUQynyB4qCQkIdWE2XLnlg==", "dependencies": { "@babel/cli": "^7.0.0", "superagent": "^5.3.0" diff --git a/ethers-ext/package.json b/ethers-ext/package.json index a1363d65e..646dcc6ab 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@klaytn/js-ext-core": "^0.9.6-beta", - "@klaytn/web3rpc": "^0.9.0", + "@klaytn/web3rpc": "^0.9.5", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", "lodash": "^4.17.21", From 4fac3f102d3c12c55b5a90c80af11814d5fdeedc Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 2 Nov 2023 19:20:33 +0900 Subject: [PATCH 12/69] ethers: Replace example AccountKeyLegacy_01 --- .../example/accountKey/AccountKeyLegacy_01.js | 47 +++++++++++++++++++ .../AccountKeyLegacy_01_ValueTransfer.js | 30 ------------ .../AccountKeyLegacy_02_ValueTransfer.js | 38 --------------- .../AccountKeyLegacy_03_signVerify.js | 33 ------------- ethers-ext/package-lock.json | 32 ++++++++++++- ethers-ext/package.json | 1 + 6 files changed, 79 insertions(+), 102 deletions(-) create mode 100644 ethers-ext/example/accountKey/AccountKeyLegacy_01.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyLegacy_02_ValueTransfer.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyLegacy_03_signVerify.js diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy_01.js b/ethers-ext/example/accountKey/AccountKeyLegacy_01.js new file mode 100644 index 000000000..d0e4b6f17 --- /dev/null +++ b/ethers-ext/example/accountKey/AccountKeyLegacy_01.js @@ -0,0 +1,47 @@ +// AccountKeyLegacy +// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy + +const { Wallet } = require("@klaytn/ethers-ext"); +const { ethers } = require("ethers"); + +const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; + +const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); +const wallet = new Wallet(senderPriv, provider); + +// Send transaction from an AccountKeyLegacy account +async function sendTx() { + let tx = { + from: senderAddr, + to: recieverAddr, + value: 0, + }; + + let sentTx = await wallet.sendTransaction(tx); + console.log("sentTx", sentTx); + + let rc = await sentTx.wait(); + console.log("receipt", rc); +} + +// Verify a message signed by an AccountKeyLegacy account +async function recoverMsg() { + const msg = "hello"; + const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); + const sig = await wallet.signMessage(msg); + console.log({ senderAddr, msg, msghex, sig }); + + const addr1 = ethers.utils.verifyMessage(msg, sig); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + + const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); +} + +async function main() { + await sendTx(); + await recoverMsg(); +} +main().catch(console.error); \ No newline at end of file diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js b/ethers-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js deleted file mode 100644 index 2214475fd..000000000 --- a/ethers-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js +++ /dev/null @@ -1,30 +0,0 @@ -const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyPublic Step 01 - value transfer -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy -// - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); - - let tx = { - to: recieverAddr, - value: parseKlay("1"), - from: senderAddr, - }; - - let sentTx = await wallet.sendTransaction(tx); - console.log("sentTx", sentTx); - - let rc = await sentTx.wait(); - console.log("receipt", rc); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy_02_ValueTransfer.js b/ethers-ext/example/accountKey/AccountKeyLegacy_02_ValueTransfer.js deleted file mode 100644 index 854db6373..000000000 --- a/ethers-ext/example/accountKey/AccountKeyLegacy_02_ValueTransfer.js +++ /dev/null @@ -1,38 +0,0 @@ -const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyPublic Step 02 - value transfer -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy -// - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); - - let tx = { - to: recieverAddr, - value: parseKlay("1"), - from: senderAddr, - }; - - const ptx = await wallet.populateTransaction(tx); - console.log("ptx", ptx); - const signTx = await wallet.signTransaction(ptx); - console.log("signTx", signTx); - - const objTx = wallet.decodeTxFromRLP(signTx); - console.log(objTx); - - const txhash = await provider.send("eth_sendRawTransaction", [signTx]); - console.log("txhash", txhash); - - const rc = await provider.waitForTransaction(txhash); - console.log("receipt", rc); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy_03_signVerify.js b/ethers-ext/example/accountKey/AccountKeyLegacy_03_signVerify.js deleted file mode 100644 index 2d931a915..000000000 --- a/ethers-ext/example/accountKey/AccountKeyLegacy_03_signVerify.js +++ /dev/null @@ -1,33 +0,0 @@ -const { Wallet, verifyMessageAsKlaytnAccountKey } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyLegacy Step 03 - sign verification -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy -// - -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const wallet = new Wallet(senderPriv, provider); - - const message = "Hello World"; - const signature = await wallet.signMessage(message); - - // 1. you can use ethers library in case of AccountKeyLegacy - const digest = ethers.utils.hashMessage(message); - const actualSignerAddr = ethers.utils.recoverAddress(digest, signature); - console.log("actual signer addr: ", actualSignerAddr); - console.log("sender addr: ", senderAddr); - console.log("verification result:", - ethers.utils.getAddress(actualSignerAddr) == ethers.utils.getAddress(senderAddr)); - - // 2. you can use Klaytn ethers-ext library - // const result = await verifyMessageAsKlaytnAccountKey(provider, senderAddr, message, signature); - // console.log( "verification result:", result); -} - -main(); diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index 72593dc40..39b3d690f 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -17,6 +17,7 @@ "uuid": "^9.0.1" }, "devDependencies": { + "@klaytn/ethers-ext": "^0.9.5-beta", "@types/aes-js": "^3.1.1", "@types/bn.js": "^5.1.1", "@types/chai": "^4.3.4", @@ -1390,6 +1391,36 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@klaytn/ethers-ext": { + "version": "0.9.5-beta", + "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.5-beta.tgz", + "integrity": "sha512-NW/7XBZxmMYArg9UbVi3CYGHUTDzTh94WtmpRPNI16V0HLC28jtbSz8xHLMrJC2Yl4G3Juy+DAz/PZjspuekRw==", + "dev": true, + "dependencies": { + "@klaytn/ethers-ext": "^0.9.3-beta", + "@klaytn/web3rpc": "^0.9.0", + "bn.js": "^5.2.1", + "eth-lib": "^0.1.29", + "lodash": "^4.17.21", + "uuid": "^9.0.1" + }, + "peerDependencies": { + "ethers": "^5.7.2" + } + }, + "node_modules/@klaytn/ethers-ext/node_modules/@klaytn/ethers-ext": { + "version": "0.9.3-beta", + "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.3-beta.tgz", + "integrity": "sha512-As3iP/KhxG6+EVbnEln4QtF5A/M5HI7uGFzbFXFSQCd4LpQlLovQcI31fjaD9tgCw4DA4agAqHNcnBPBnX6j6A==", + "dev": true, + "dependencies": { + "@klaytn/web3rpc": "^0.9.0", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "ethers": "^5.7.2" + } + }, "node_modules/@klaytn/js-ext-core": { "version": "0.9.6-beta", "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.6-beta.tgz", @@ -3632,7 +3663,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ diff --git a/ethers-ext/package.json b/ethers-ext/package.json index 646dcc6ab..b7c3b221a 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -21,6 +21,7 @@ "ethers": "^5.7.2" }, "devDependencies": { + "@klaytn/ethers-ext": "^0.9.5-beta", "@types/aes-js": "^3.1.1", "@types/bn.js": "^5.1.1", "@types/chai": "^4.3.4", From 8229b108b6c361a3ed13eec4aa016730e2f362cb Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Fri, 3 Nov 2023 19:03:16 +0900 Subject: [PATCH 13/69] Try recoverFromTransaction with Legacy account --- .../example/accountKey/AccountKeyLegacy_01.js | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy_01.js b/ethers-ext/example/accountKey/AccountKeyLegacy_01.js index d0e4b6f17..3e3fd9bf5 100644 --- a/ethers-ext/example/accountKey/AccountKeyLegacy_01.js +++ b/ethers-ext/example/accountKey/AccountKeyLegacy_01.js @@ -1,6 +1,8 @@ // AccountKeyLegacy // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy +const { sign } = require("crypto"); + const { Wallet } = require("@klaytn/ethers-ext"); const { ethers } = require("ethers"); @@ -26,8 +28,23 @@ async function sendTx() { console.log("receipt", rc); } +// Verify a transaction signed by an AccountKeyLegacy account +async function verifyTx() { + let tx = { + from: senderAddr, + to: recieverAddr, + value: 0, + }; + + let signedTx = await wallet.signTransaction(tx); + console.log("signedTx", signedTx); + + const addr1 = await provider.send("klay_recoverFromTransaction", [signedTx, "latest"]); + console.log("recoveredAddr rpc", addr1, addr1.toLowerCase() === senderAddr); +} + // Verify a message signed by an AccountKeyLegacy account -async function recoverMsg() { +async function verifyMsg() { const msg = "hello"; const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); const sig = await wallet.signMessage(msg); @@ -42,6 +59,7 @@ async function recoverMsg() { async function main() { await sendTx(); - await recoverMsg(); + await verifyTx(); + await verifyMsg(); } main().catch(console.error); \ No newline at end of file From f59a97d30035287dc09b4c31aaa32db7148eecd2 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 10 Nov 2023 10:52:30 +0900 Subject: [PATCH 14/69] Update AccountKey examples by using js-ext-core --- ...untKeyLegacy_01.js => AccountKeyLegacy.js} | 0 .../example/accountKey/AccountKeyPublic.js | 72 ++++++++++++ .../AccountKeyPublic_01_accountUpdate.js | 37 ------ .../AccountKeyPublic_02_valueTransfer.js | 32 ------ .../AccountKeyPublic_03_valueTransfer.js | 39 ------- .../AccountKeyPublic_04_signVerify.js | 25 ---- .../example/accountKey/AccountKeyRoleBased.js | 100 ++++++++++++++++ .../AccountKeyRoleBased_01_accountUpdate.js | 66 ----------- .../AccountKeyRoleBased_02_valueTransfer.js | 45 -------- .../AccountKeyRoleBased_03_signVerify.js | 28 ----- .../accountKey/AccountKeyWeightedMultiSig.js | 108 ++++++++++++++++++ ...untKeyWeightedMultiSig_01_accountUpdate.js | 51 --------- ...untKeyWeightedMultiSig_02_valueTransfer.js | 50 -------- ...ccountKeyWeightedMultiSig_03_signVerify.js | 38 ------ 14 files changed, 280 insertions(+), 411 deletions(-) rename ethers-ext/example/accountKey/{AccountKeyLegacy_01.js => AccountKeyLegacy.js} (100%) create mode 100644 ethers-ext/example/accountKey/AccountKeyPublic.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyPublic_03_valueTransfer.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyPublic_04_signVerify.js create mode 100644 ethers-ext/example/accountKey/AccountKeyRoleBased.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyRoleBased_03_signVerify.js create mode 100644 ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js delete mode 100644 ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_03_signVerify.js diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy_01.js b/ethers-ext/example/accountKey/AccountKeyLegacy.js similarity index 100% rename from ethers-ext/example/accountKey/AccountKeyLegacy_01.js rename to ethers-ext/example/accountKey/AccountKeyLegacy.js diff --git a/ethers-ext/example/accountKey/AccountKeyPublic.js b/ethers-ext/example/accountKey/AccountKeyPublic.js new file mode 100644 index 000000000..2139c21a1 --- /dev/null +++ b/ethers-ext/example/accountKey/AccountKeyPublic.js @@ -0,0 +1,72 @@ +// AccountKeyPublic Step 01 - account update +// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic + +const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet } = require("@klaytn/ethers-ext"); +const { ethers } = require("ethers"); + +const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; + +const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); +const wallet = new Wallet(senderAddr, senderPriv, provider); +const wallet2 = new Wallet(senderAddr, senderNewPriv, provider); + +// Update Account +async function updateAccount() { + let senderNewPub = new ethers.utils.SigningKey(senderNewPriv).compressedPublicKey; + + let tx = { + type: TxType.AccountUpdate, + from: senderAddr, + key: { + type: AccountKeyType.Public, + key: senderNewPub, + } + }; + + let sentTx = await wallet.sendTransaction(tx); + console.log("updateAccount", sentTx); + + let rc = await sentTx.wait(); + console.log("receipt", rc); +} + +// Send transaction from an AccountKeyLegacy account +async function sendTx() { + let tx = { + type: TxType.ValueTransfer, + from: senderAddr, + to: recieverAddr, + value: parseKlay("0.01"), + }; + + let sentTx = await wallet2.sendTransaction(tx); + console.log("sentTx", sentTx); + + let rc = await sentTx.wait(); + console.log("receipt", rc); +} + +// Verify a message signed by an AccountKeyLegacy account +async function recoverMsg() { + const msg = "hello"; + const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); + const sig = await wallet2.signMessage(msg); + console.log({ senderAddr, msg, msghex, sig }); + + const addr1 = ethers.utils.verifyMessage(msg, sig); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + + const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); +} + +async function main() { + await updateAccount(); + await sendTx(); + await recoverMsg(); +} +main().catch(console.error); \ No newline at end of file diff --git a/ethers-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js b/ethers-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js deleted file mode 100644 index 991491cb8..000000000 --- a/ethers-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js +++ /dev/null @@ -1,37 +0,0 @@ -const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyPublic Step 01 - account update -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -// - -// create a new account for testing -// https://baobab.wallet.klaytn.foundation/ -const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; -const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); - - let senderNewPub = new ethers.utils.SigningKey(senderNewPriv).compressedPublicKey; - - let tx = { - type: TxType.AccountUpdate, - from: senderAddr, - key: { - type: AccountKeyType.Public, - key: senderNewPub, - } - }; - - let sentTx = await wallet.sendTransaction(tx); - console.log("sentTx", sentTx); - - let rc = await sentTx.wait(); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js b/ethers-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js deleted file mode 100644 index 3f58538a8..000000000 --- a/ethers-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js +++ /dev/null @@ -1,32 +0,0 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyPublic Step 02 - value transfer -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -// - -// the same address of sender in AccountKeyPublic_01_accountUpdate.js -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderAddr, senderNewPriv, provider); - - let new_tx = { - type: TxType.ValueTransfer, - to: recieverAddr, - value: parseKlay("1"), - from: senderAddr, - }; - - let sentTx = await wallet.sendTransaction(new_tx); - console.log("sentTx", sentTx); - - let rc = await sentTx.wait(); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyPublic_03_valueTransfer.js b/ethers-ext/example/accountKey/AccountKeyPublic_03_valueTransfer.js deleted file mode 100644 index e0b6b5dc2..000000000 --- a/ethers-ext/example/accountKey/AccountKeyPublic_03_valueTransfer.js +++ /dev/null @@ -1,39 +0,0 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyPublic Step 03 - value transfer -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -// - -// the same address of sender in AccountKeyPublic_01_accountUpdate.js -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderAddr, senderNewPriv, provider); - - let tx = { - type: TxType.ValueTransfer, - to: recieverAddr, - value: parseKlay("1"), - from: senderAddr, - }; - - const ptx = await wallet.populateTransaction(tx); - const signTx = await wallet.signTransaction(ptx); - console.log("signTx", signTx); - - const objTx = wallet.decodeTxFromRLP(signTx); - console.log(objTx); - - const txhash = await provider.send("klay_sendRawTransaction", [signTx]); - console.log("txhash", txhash); - - const rc = await provider.waitForTransaction(txhash); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyPublic_04_signVerify.js b/ethers-ext/example/accountKey/AccountKeyPublic_04_signVerify.js deleted file mode 100644 index 0a3222dbf..000000000 --- a/ethers-ext/example/accountKey/AccountKeyPublic_04_signVerify.js +++ /dev/null @@ -1,25 +0,0 @@ -const { Wallet, verifyMessageAsKlaytnAccountKey } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyPublic Step 04 - sign verification -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -// - -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - -// the same address of sender in AccountKeyPublic_01_accountUpdate.js -const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const wallet = new Wallet(senderAddr, senderNewPriv, provider); - - const message = "Hello World"; - const signature = await wallet.signMessage(message); - - const result = await verifyMessageAsKlaytnAccountKey(provider, senderAddr, message, signature); - console.log("verification result:", result); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased.js b/ethers-ext/example/accountKey/AccountKeyRoleBased.js new file mode 100644 index 000000000..764499d6b --- /dev/null +++ b/ethers-ext/example/accountKey/AccountKeyRoleBased.js @@ -0,0 +1,100 @@ +// AccountKeyRoleBased Step 01 - account update +// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +const { ethers } = require("ethers"); + +const senderAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; +// const senderPriv = "0x9ba8cb8f60044058a9e6f815c5c42d3a216f47044c61a1750b6d29ddc7f34bda"; +const senderRoleTransactionPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; +const senderRoleAccountUpdatePriv = "0x9ba8cb8f60044058a9e6f815c5c42d3a216f47044c61a1750b6d29ddc7f34bda"; +const senderRoleFeePayerPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; + +const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); +const wallet = new Wallet(senderAddr, senderRoleAccountUpdatePriv, provider); +const wallet2 = new Wallet(senderAddr, senderRoleTransactionPriv, provider); + +// Update Account +async function updateAccount() { + let pub1 = new ethers.utils.SigningKey(senderRoleTransactionPriv).compressedPublicKey; + let pub2 = new ethers.utils.SigningKey(senderRoleAccountUpdatePriv).compressedPublicKey; + let pub3 = new ethers.utils.SigningKey(senderRoleFeePayerPriv).compressedPublicKey; + + console.log("1", pub1); + console.log("2", pub2); + console.log("3", pub3); + + let tx = { + type: TxType.AccountUpdate, + from: senderAddr, + gasLimit: 1000000, + key: { + type: AccountKeyType.RoleBased, + keys: [ + // RoleTransaction + { + type: AccountKeyType.Public, + key: pub1, + }, + + // RoleAccountUpdate + { + type: AccountKeyType.Public, + key: pub2, + }, + + // RoleFeePayer + { + type: AccountKeyType.Public, + key: pub3, + } + ] + } + }; + + let sentTx = await wallet.sendTransaction(tx); + console.log("updateAccount", sentTx); + + let rc = await sentTx.wait(); + console.log("receipt", rc); +} + +// Send transaction from an AccountKeyLegacy account +async function sendTx() { + let tx = { + type: TxType.ValueTransfer, + from: senderAddr, + to: recieverAddr, + value: parseKlay("0.01"), + gasLimit: 100000, + }; + + let sentTx = await wallet2.sendTransaction(tx); + console.log("sentTx", sentTx); + + let rc = await sentTx.wait(); + console.log("receipt", rc); +} + +// Verify a message signed by an AccountKeyLegacy account +async function recoverMsg() { + const msg = "hello"; + const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); + const sig = await wallet2.signMessage(msg); + console.log({ senderAddr, msg, msghex, sig }); + + const addr1 = ethers.utils.verifyMessage(msg, sig); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + + const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); +} + +async function main() { + await updateAccount(); + await sendTx(); + await recoverMsg(); +} +main().catch(console.error); \ No newline at end of file diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js b/ethers-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js deleted file mode 100644 index 6fb180c6e..000000000 --- a/ethers-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js +++ /dev/null @@ -1,66 +0,0 @@ -const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyRoleBased Step 01 - account update -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased -// -// gasLimit: Must be large enough -// -// create a new account for testing -// https://baobab.wallet.klaytn.foundation/ -// -const senderAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; -const senderPriv = "0x9ba8cb8f60044058a9e6f815c5c42d3a216f47044c61a1750b6d29ddc7f34bda"; -const senderRoleTransactionPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; -const senderRoleAccountUpdatePriv = "0x9ba8cb8f60044058a9e6f815c5c42d3a216f47044c61a1750b6d29ddc7f34bda"; -const senderRoleFeePayerPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); - - let pub1 = new ethers.utils.SigningKey(senderRoleTransactionPriv).compressedPublicKey; - let pub2 = new ethers.utils.SigningKey(senderRoleAccountUpdatePriv).compressedPublicKey; - let pub3 = new ethers.utils.SigningKey(senderRoleFeePayerPriv).compressedPublicKey; - - console.log("1", pub1); - console.log("2", pub2); - console.log("3", pub3); - - let tx = { - type: TxType.AccountUpdate, - from: senderAddr, - gasLimit: 1000000, - key: { - type: AccountKeyType.RoleBased, - keys: [ - // RoleTransaction - { - type: AccountKeyType.Public, - key: pub1, - }, - - // RoleAccountUpdate - { - type: AccountKeyType.Public, - key: pub2, - }, - - // RoleFeePayer - { - type: AccountKeyType.Public, - key: pub3, - } - ] - } - }; - - let sentTx = await wallet.sendTransaction(tx); - console.log("sentTx", sentTx); - - let rc = await sentTx.wait(); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js b/ethers-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js deleted file mode 100644 index 86f98c87e..000000000 --- a/ethers-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js +++ /dev/null @@ -1,45 +0,0 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyRoleBased Step 02 - value transfer -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased -// -// gasLimit: Must be large enough -// - -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - -// the same address of sender in AccountKeyRoleBased_01_accountUpdate.js -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const senderAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; -const senderRoleTransactionPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; - -async function main() { - let tx = { - type: TxType.ValueTransfer, - gasLimit: 100000, - to: recieverAddr, - value: parseKlay("1"), - from: senderAddr, - }; - - const wallet = new Wallet(senderAddr, senderRoleTransactionPriv, provider); - let ptx = await wallet.populateTransaction(tx); - console.log(ptx); - - const txHashRLP = await wallet.signTransaction(ptx); - console.log("TxHashRLP", txHashRLP); - - let decodedTx = wallet.decodeTxFromRLP(txHashRLP); - console.log(decodedTx); - - // send - const txhash = await provider.send("klay_sendRawTransaction", [txHashRLP]); - console.log("txhash", txhash); - - const rc = await provider.waitForTransaction(txhash); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased_03_signVerify.js b/ethers-ext/example/accountKey/AccountKeyRoleBased_03_signVerify.js deleted file mode 100644 index 996add086..000000000 --- a/ethers-ext/example/accountKey/AccountKeyRoleBased_03_signVerify.js +++ /dev/null @@ -1,28 +0,0 @@ -const { Wallet, verifyMessageAsKlaytnAccountKey } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyRoleBased Step 03 - sign verification -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased -// -// gasLimit: Must be large enough -// - -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - -// the same address of sender in AccountKeyRoleBased_01_accountUpdate.js -const senderAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; -const senderRoleTransactionPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; - -async function main() { - const message = "Hello World"; - - const wallet = new Wallet(senderRoleTransactionPriv, provider); - const signature = await wallet.signMessage(message); - const signatures = [signature]; - - const result = await verifyMessageAsKlaytnAccountKey(provider, senderAddr, message, signatures); - console.log("verification result:", result); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js new file mode 100644 index 000000000..7e6d99e92 --- /dev/null +++ b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js @@ -0,0 +1,108 @@ +// AccountKeyWeightedMultiSig Step 01 - account update +// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +const { ethers } = require("ethers"); + +const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; +// const senderPriv = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; +const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; +const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; +const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; + +const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); +const wallet = new Wallet(senderAddr, senderNewPriv1, provider); +const wallet2 = new Wallet(senderAddr, senderNewPriv2, provider); +const wallet3 = new Wallet(senderAddr, senderNewPriv3, provider); + +// Update Account +async function updateAccount() { + let senderNewPub1 = new ethers.utils.SigningKey(senderNewPriv1).compressedPublicKey; + let senderNewPub2 = new ethers.utils.SigningKey(senderNewPriv2).compressedPublicKey; + let senderNewPub3 = new ethers.utils.SigningKey(senderNewPriv3).compressedPublicKey; + + let tx = { + type: TxType.AccountUpdate, + from: senderAddr, + gasLimit: 1000000, + key: { + type: AccountKeyType.WeightedMultiSig, + keys: [ + 2, // threshold + [ + [1, senderNewPub1], + [1, senderNewPub2], + [1, senderNewPub3] + ] + ] + } + }; + + // sign 1 + let ptx = await wallet.populateTransaction(tx); + const txHashRLP = await wallet.signTransaction(ptx); + console.log("TxHashRLP", txHashRLP); + + // sign 2 + let ptx2 = await wallet2.populateTransaction(txHashRLP); + const txHashRLP2 = await wallet2.signTransaction(ptx2); + console.log("TxHashRLP2", txHashRLP2); + + // sign 3 & send + const res = await wallet3.sendTransaction(txHashRLP2); + console.log("updateAccount", res); + + let rc = await res.wait(); + console.log("receipt", rc); +} + +// Send transaction from an AccountKeyLegacy account +async function sendTx() { + let tx = { + type: TxType.ValueTransfer, + from: senderAddr, + to: recieverAddr, + value: parseKlay("0.01"), + gasLimit: 100000, + }; + + // sign 1 + let ptx = await wallet.populateTransaction(tx); + const txHashRLP = await wallet.signTransaction(ptx); + console.log("TxHashRLP", txHashRLP); + + // sign 2 + let ptx2 = await wallet2.populateTransaction(txHashRLP); + const txHashRLP2 = await wallet2.signTransaction(ptx2); + console.log("TxHashRLP2", txHashRLP2); + + // sign 3 & send + const res = await wallet3.sendTransaction(txHashRLP2); + console.log("transaction", res); + + const rc = await res.wait(); + console.log("receipt", rc); +} + +// Verify a message signed by an AccountKeyLegacy account +async function recoverMsg() { + const msg = "hello"; + const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); + const sig = await wallet2.signMessage(msg); + console.log({ senderAddr, msg, msghex, sig }); + + const addr1 = ethers.utils.verifyMessage(msg, sig); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + + const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); +} + +async function main() { + await updateAccount(); + await sendTx(); + await recoverMsg(); +} +main().catch(console.error); \ No newline at end of file diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js deleted file mode 100644 index a68b85707..000000000 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js +++ /dev/null @@ -1,51 +0,0 @@ -const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyWeightedMultiSig Step 01 - account update -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -// -// gasLimit: Must be large enough -// -// create a new account for testing -// https://baobab.wallet.klaytn.foundation/ -// -const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; -const senderPriv = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; -const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; -const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); - - let senderNewPub1 = new ethers.utils.SigningKey(senderNewPriv1).compressedPublicKey; - let senderNewPub2 = new ethers.utils.SigningKey(senderNewPriv2).compressedPublicKey; - let senderNewPub3 = new ethers.utils.SigningKey(senderNewPriv3).compressedPublicKey; - - let tx = { - type: TxType.AccountUpdate, - from: senderAddr, - gasLimit: 100000, - key: { - type: AccountKeyType.WeightedMultiSig, - keys: [ - 2, // threshold - [ - [1, senderNewPub1], - [1, senderNewPub2], - [1, senderNewPub3] - ] - ] - } - }; - - let sentTx = await wallet.sendTransaction(tx); - console.log("sentTx", sentTx); - - let rc = await sentTx.wait(); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js deleted file mode 100644 index fe8c053da..000000000 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js +++ /dev/null @@ -1,50 +0,0 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyWeightedMultiSig Step 02 - value transfer -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -// -// gasLimit: Must be large enough -// - -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - -// the same address of sender in AccountKeyWeightedMultiSig_01_accountUpdate.js -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; -const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; -const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; - -async function main() { - let tx = { - type: TxType.ValueTransfer, - gasLimit: 100000, - to: recieverAddr, - value: parseKlay("1"), - from: senderAddr, - }; - - // sign 1 - const wallet = new Wallet(senderAddr, senderNewPriv1, provider); - let ptx = await wallet.populateTransaction(tx); - const txHashRLP = await wallet.signTransaction(ptx); - console.log("TxHashRLP", txHashRLP); - - // sign 2 - const wallet2 = new Wallet(senderAddr, senderNewPriv2, provider); - let ptx2 = await wallet2.populateTransaction(txHashRLP); - const txHashRLP2 = await wallet2.signTransaction(ptx2); - console.log("TxHashRLP2", txHashRLP2); - - // sign 3 & send - const wallet3 = new Wallet(senderAddr, senderNewPriv3, provider); - const res = await wallet3.sendTransaction(txHashRLP2); - console.log("transaction", res); - - const rc = await res.wait(); - console.log("receipt", rc); -} - -main(); diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_03_signVerify.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_03_signVerify.js deleted file mode 100644 index b7321f990..000000000 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig_03_signVerify.js +++ /dev/null @@ -1,38 +0,0 @@ -const { Wallet, verifyMessageAsKlaytnAccountKey } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// -// AccountKeyWeightedMultiSig Step 03 - sign verification -// https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -// -// gasLimit: Must be large enough -// - -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - -// the same address of sender in AccountKeyWeightedMultiSig_01_accountUpdate.js -const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; -const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; -const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - - -async function main() { - const message = "Hello World"; - - const wallet = new Wallet(senderNewPriv1, provider); - const signature = await wallet.signMessage(message); - console.log(signature); - - const wallet2 = new Wallet(senderNewPriv2, provider); - const signature2 = await wallet2.signMessage(message); - console.log(signature2); - - const signatures = [ - signature, - signature2, - ]; - const result = await verifyMessageAsKlaytnAccountKey(provider, senderAddr, message, signatures); - console.log("verification result:", result); -} - -main(); From b965526c01686c6d9bee7b1ff16cf651eb0ba63b Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 10 Nov 2023 15:14:06 +0900 Subject: [PATCH 15/69] Update key format and address from recoverMessage --- .../example/accountKey/AccountKeyPublic.js | 4 +-- .../example/accountKey/AccountKeyRoleBased.js | 8 ++--- .../accountKey/AccountKeyWeightedMultiSig.js | 30 ++++++++++++------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/ethers-ext/example/accountKey/AccountKeyPublic.js b/ethers-ext/example/accountKey/AccountKeyPublic.js index 2139c21a1..b7002b71c 100644 --- a/ethers-ext/example/accountKey/AccountKeyPublic.js +++ b/ethers-ext/example/accountKey/AccountKeyPublic.js @@ -58,10 +58,10 @@ async function recoverMsg() { console.log({ senderAddr, msg, msghex, sig }); const addr1 = ethers.utils.verifyMessage(msg, sig); - console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === wallet2.address.toLowerCase()); const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); - console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === wallet2.address.toLowerCase()); } async function main() { diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased.js b/ethers-ext/example/accountKey/AccountKeyRoleBased.js index 764499d6b..db023e61e 100644 --- a/ethers-ext/example/accountKey/AccountKeyRoleBased.js +++ b/ethers-ext/example/accountKey/AccountKeyRoleBased.js @@ -22,10 +22,6 @@ async function updateAccount() { let pub2 = new ethers.utils.SigningKey(senderRoleAccountUpdatePriv).compressedPublicKey; let pub3 = new ethers.utils.SigningKey(senderRoleFeePayerPriv).compressedPublicKey; - console.log("1", pub1); - console.log("2", pub2); - console.log("3", pub3); - let tx = { type: TxType.AccountUpdate, from: senderAddr, @@ -86,10 +82,10 @@ async function recoverMsg() { console.log({ senderAddr, msg, msghex, sig }); const addr1 = ethers.utils.verifyMessage(msg, sig); - console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === wallet2.address.toLowerCase()); const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); - console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === wallet2.address.toLowerCase()); } async function main() { diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js index 7e6d99e92..edb92aa7c 100644 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js +++ b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js @@ -1,10 +1,13 @@ // AccountKeyWeightedMultiSig Step 01 - account update // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +// const { Wallet } = require("@klaytn/ethers-ext"); +// const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); const { ethers } = require("ethers"); +const { Wallet } = require("../../../ethers-ext/dist"); +const { TxType, AccountKeyType, parseKlay } = require("../../../js-ext-core/dist"); + const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; // const senderPriv = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; @@ -29,13 +32,20 @@ async function updateAccount() { gasLimit: 1000000, key: { type: AccountKeyType.WeightedMultiSig, + threshold: 2, keys: [ - 2, // threshold - [ - [1, senderNewPub1], - [1, senderNewPub2], - [1, senderNewPub3] - ] + { + "weight": 1, + "key": senderNewPub1 + }, + { + "weight": 1, + "key": senderNewPub2 + }, + { + "weight": 1, + "key": senderNewPub3 + } ] } }; @@ -94,10 +104,10 @@ async function recoverMsg() { console.log({ senderAddr, msg, msghex, sig }); const addr1 = ethers.utils.verifyMessage(msg, sig); - console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === senderAddr); + console.log("recoveredAddr lib", addr1, addr1.toLowerCase() === wallet2.address.toLowerCase()); const addr2 = await provider.send("klay_recoverFromMessage", [senderAddr, msghex, sig, "latest"]); - console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === senderAddr); + console.log("recoveredAddr rpc", addr2, addr2.toLowerCase() === wallet2.address.toLowerCase()); } async function main() { From f56b7a9abc6815f09148dfeeb0e669a15a7d5244 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 10 Nov 2023 16:41:03 +0900 Subject: [PATCH 16/69] Fix keys format --- .../accountKey/AccountKeyWeightedMultiSig.js | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js index edb92aa7c..6b5ee9fdc 100644 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js +++ b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js @@ -1,13 +1,10 @@ // AccountKeyWeightedMultiSig Step 01 - account update // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -// const { Wallet } = require("@klaytn/ethers-ext"); -// const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); const { ethers } = require("ethers"); -const { Wallet } = require("../../../ethers-ext/dist"); -const { TxType, AccountKeyType, parseKlay } = require("../../../js-ext-core/dist"); - const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; // const senderPriv = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; @@ -34,18 +31,9 @@ async function updateAccount() { type: AccountKeyType.WeightedMultiSig, threshold: 2, keys: [ - { - "weight": 1, - "key": senderNewPub1 - }, - { - "weight": 1, - "key": senderNewPub2 - }, - { - "weight": 1, - "key": senderNewPub3 - } + [1, senderNewPub1], + [1, senderNewPub2], + [1, senderNewPub3] ] } }; From bb5406a79dc40ec49ef70835bae96c62fc4ac73b Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 10 Nov 2023 18:27:20 +0900 Subject: [PATCH 17/69] Test js-ext-core with basic type transactions --- .../Basic_08_TxTypeValueTransfer.js | 12 +++++----- .../Basic_10_TxTypeValueTransferMemo.js | 11 +++++----- .../Basic_20_TxTypeAccountUpdate.js | 19 +++++++--------- .../Basic_28_TxTypeSmartContractDeploy.js | 10 ++++----- .../Basic_30_TxTypeSmartContractExecution.js | 22 ++++++++++--------- .../transactions/Basic_38_TxTypeCancel.js | 20 ++++++++--------- 6 files changed, 46 insertions(+), 48 deletions(-) diff --git a/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index 209845834..3bdf74117 100644 --- a/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -1,10 +1,10 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); + const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -16,7 +16,7 @@ async function main() { let tx = { type: TxType.ValueTransfer, to: recieverAddr, - value: parseKlay("1"), + value: parseKlay("0.01"), from: senderAddr, }; diff --git a/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js b/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js index 915bb2f62..495f5c6f0 100644 --- a/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js +++ b/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js @@ -1,10 +1,9 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfermemo -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; @@ -17,7 +16,7 @@ async function main() { let tx = { type: TxType.ValueTransferMemo, to: recieverAddr, - value: parseKlay("1"), + value: parseKlay("0.01"), from: senderAddr, input: "0x1234567890", }; diff --git a/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js b/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js index 2e6a2f04d..f3bf78477 100644 --- a/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js +++ b/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js @@ -1,30 +1,27 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeAccountUpdate // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypeaccountupdate // -// from: address of sender to be updated // key: Refer Klaytn account key // https://docs.klaytn.foundation/content/klaytn/design/accounts#account-key -// -// create new account for testing -// https://baobab.wallet.klaytn.foundation/ +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, AccountKeyType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); + +// create new account for testing in https://baobab.wallet.klaytn.foundation/ const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; async function main() { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); + const wallet = new Wallet(senderAddr, senderPriv, provider); let tx = { type: TxType.AccountUpdate, from: senderAddr, key: { - type: 0x02, + type: AccountKeyType.Public, key: ethers.utils.computePublicKey(senderNewPriv, true), } }; diff --git a/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js b/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js index 97c18628f..d9edfe32c 100644 --- a/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js +++ b/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js @@ -1,7 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeSmartContractDeploy // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypesmartcontractdeploy // @@ -10,7 +6,10 @@ const ethers = require("ethers"); // input: SmartContract binary, // humanReadable: Must be false, // codeFormat: Must be 0x00 -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -27,6 +26,7 @@ async function main() { input: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e0f4e7861cb6d7acf0f61d34896310975b57b5bc109681dbbfb2e548ef7546b364736f6c63430008120033", humanReadable: false, codeFormat: 0x00, + gasLimit: 100000, }; const sentTx = await wallet.sendTransaction(tx); diff --git a/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js b/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js index ccde286b4..dc0283c85 100644 --- a/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js +++ b/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js @@ -1,11 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const contractAddr = "0xD7fA6634bDDe0B2A9d491388e2fdeD0fa25D2067"; - -// // TxTypeSmartContractExecution // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypesmartcontractexecution // @@ -24,7 +16,16 @@ const contractAddr = "0xD7fA6634bDDe0B2A9d491388e2fdeD0fa25D2067"; // const CONTRACT_ABI = ["function setNumber(uint256 newNumber) public", "function increment() public"]; // const iface = new ethers.utils.Interface( CONTRACT_ABI ); // const param = iface.encodeFunctionData("setNumber", [ "0x123" ]) -// + + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); + +const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const contractAddr = "0xD7fA6634bDDe0B2A9d491388e2fdeD0fa25D2067"; + async function main() { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const wallet = new Wallet(senderPriv, provider); @@ -36,10 +37,11 @@ async function main() { let tx = { type: TxType.SmartContractExecution, + from: senderAddr, to: contractAddr, value: 0, - from: senderAddr, input: param, + gasLimit: 100000, }; const sentTx = await wallet.sendTransaction(tx); diff --git a/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js b/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js index 6cec453b1..d51aa89b4 100644 --- a/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js +++ b/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js @@ -1,11 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - -// // TxTypeCancel // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypecancel // @@ -13,7 +5,15 @@ const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; // 2) send Cancel tx with the next nonce + 1 // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); + +const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; + async function main() { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const wallet = new Wallet(senderPriv, provider); @@ -24,7 +24,7 @@ async function main() { type: TxType.ValueTransfer, nonce: nextNonce + 1, to: recieverAddr, - value: 1e12, + value: parseKlay("0.01"), from: senderAddr, }; From 4e84bc3f02fed1820f4ce99e689852e2b6806932 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Tue, 14 Nov 2023 18:32:18 +0900 Subject: [PATCH 18/69] Test js-ext-core with other type transactions --- ...eDel_09_TxTypeFeeDelegatedValueTransfer.js | 22 ++++------- ...Del_09_TxTypeFeeDelegatedValueTransfer2.js | 19 ++++------ ..._11_TxTypeFeeDelegatedValueTransferMemo.js | 22 ++++------- ...eDel_21_TxTypeFeeDelegatedAccountUpdate.js | 33 +++++------------ ...9_TxTypeFeeDelegatedSmartContractDeploy.js | 20 ++++------ ...xTypeFeeDelegatedSmartContractExecution.js | 22 ++++------- .../FeeDel_39_TxTypeFeeDelegatedCancel.js | 12 +++--- ...xTypeFeeDelegatedValueTransferWithRatio.js | 22 ++++------- ...eFeeDelegatedValueTransferMemoWithRatio.js | 20 +++------- ...xTypeFeeDelegatedAccountUpdateWithRatio.js | 37 ++++++------------- ...eeDelegatedSmartContractDeployWithRatio.js | 20 ++++------ ...elegatedSmartContractExecutionWithRatio.js | 22 ++++------- ...el_3a_TxTypeFeeDelegatedCancelWithRatio.js | 11 +++--- 13 files changed, 96 insertions(+), 186 deletions(-) diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js index eee18e883..6b19f6252 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js @@ -1,10 +1,9 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -12,16 +11,15 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedValueTransfer, to: recieverAddr, - value: parseKlay("1"), + value: parseKlay("0.01"), from: senderAddr, }; @@ -31,12 +29,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js index 4d9271325..da4466674 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js @@ -1,10 +1,9 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -12,16 +11,15 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedValueTransfer, to: recieverAddr, - value: parseKlay("1"), + value: parseKlay("0.01"), from: senderAddr, }; @@ -31,9 +29,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); console.log(tx); diff --git a/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js b/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js index 3587d8cce..9232f99f8 100644 --- a/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js +++ b/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js @@ -1,10 +1,9 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -12,16 +11,15 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedValueTransferMemo, to: recieverAddr, - value: parseKlay("1"), + value: parseKlay("0.01"), from: senderAddr, input: "0x1234567890", }; @@ -32,12 +30,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js b/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js index d95679dde..9fadb9223 100644 --- a/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js +++ b/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js @@ -1,35 +1,28 @@ -const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedAccountUpdate // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate -// -// create new account for testing -// https://baobab.wallet.klaytn.foundation/ -const senderAddr = "0x30908464d76604420162a6c880c0e1c7e641bad7"; -const senderPriv = "0x136cc0d035c2df0d37a954e2b89dff5d04ba0731fff501c7318c8220d6381a6a"; +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, AccountKeyType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); +// create new account for testing in https://baobab.wallet.klaytn.foundation/ +const senderAddr = "0x30908464d76604420162a6c880c0e1c7e641bad7"; +const senderPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; +const senderNewPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedAccountUpdate, from: senderAddr, key: { type: AccountKeyType.Public, - // private key 0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b - // pubkeyX 0xdbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8 - // pubkeyY 0x906d7170ba349c86879fb8006134cbf57bda9db9214a90b607b6b4ab57fc026e - // Compressed PublicKey "0x02dbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8", - key: ethers.utils.computePublicKey("0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b", true) + key: ethers.utils.computePublicKey(senderNewPriv, true) } }; @@ -39,12 +32,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js b/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js index fb1824590..869ae963d 100644 --- a/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js +++ b/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js @@ -1,6 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - // TxTypeFeeDelegatedSmartContractDeploy // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractdeploy // @@ -11,16 +8,19 @@ const ethers = require("ethers"); // codeFormat: Must be 0x00 // +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); + const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedSmartContractDeploy, @@ -30,19 +30,15 @@ async function main() { input: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e0f4e7861cb6d7acf0f61d34896310975b57b5bc109681dbbfb2e548ef7546b364736f6c63430008120033", humanReadable: false, codeFormat: 0x00, + gasLimit: 100000, }; + tx = await senderWallet.populateTransaction(tx); console.log(tx); const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js b/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js index 310b47bae..3c263d762 100644 --- a/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js +++ b/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js @@ -1,6 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - // TxTypeFeeDelegatedSmartContractExecution // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractexecution // @@ -19,18 +16,20 @@ const ethers = require("ethers"); // const CONTRACT_ABI = ["function setNumber(uint256 newNumber) public", "function increment() public"]; // const iface = new ethers.utils.Interface( CONTRACT_ABI ); // const param = iface.encodeFunctionData("setNumber", [ "0x123" ]) -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); const CONTRACT_ADDRESS = "0xcc18eC0261AADbe5fB5a7854449FC26b4F428653"; const CONTRACT_ABI = ["function setNumber(uint256 newNumber) public", "function increment() public"]; @@ -39,10 +38,11 @@ async function main() { let tx = { type: TxType.FeeDelegatedSmartContractExecution, + from: senderAddr, to: CONTRACT_ADDRESS, value: 0, - from: senderAddr, input: param, + gasLimit: 100000, }; tx = await senderWallet.populateTransaction(tx); @@ -51,12 +51,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js b/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js index fcd42aba4..06898314b 100644 --- a/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js +++ b/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js @@ -1,7 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedCancel // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedcancel // @@ -9,7 +5,10 @@ const ethers = require("ethers"); // 2) send Cancel tx with the next nonce + 1 // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,7 +18,6 @@ const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function senderSign(nextNonce) { const senderWallet = new Wallet(senderPriv, provider); @@ -57,7 +55,7 @@ async function main() { type: TxType.ValueTransfer, nonce: nextNonce + 1, to: recieverAddr, - value: 1e12, + value: parseKlay("0.01"), from: senderAddr, }; diff --git a/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js index bc7f0e40b..9d8f6eb8f 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js @@ -1,10 +1,9 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedValueTransferWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -12,16 +11,15 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedValueTransferWithRatio, to: recieverAddr, - value: parseKlay("1"), + value: parseKlay("0.01"), from: senderAddr, feeRatio: 40, }; @@ -32,12 +30,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js index 52e3a34be..f1368a9a1 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js @@ -1,12 +1,11 @@ -const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedValueTransferMemoWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransfermemowithratio // // nonce: In signTransactionAsFeePayer, must not be omitted, because feePayer's nonce is filled when populating -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -14,11 +13,10 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedValueTransferMemoWithRatio, @@ -35,12 +33,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js index f08decc09..c9a700b46 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js @@ -1,7 +1,3 @@ -const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedAccountUpdateWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedaccountupdatewithratio // @@ -15,37 +11,32 @@ const ethers = require("ethers"); // Learn how Klaytn Tx intrinsic gas are calculated - which is unlikely because there's no documentation for it. // You should see the source code for the info (e.g. VTwithMemo intrinsic gas is 21000 + len(memo)*100 ) // https://github.com/klaytn/klaytn/blob/dev/blockchain/types/tx_internal_data_value_transfer_memo.go#L239 -// -// create new account for testing -// https://baobab.wallet.klaytn.foundation/ -const senderPriv = "0x78197af8e2293de5357a91d5d7b6e4224168668180704cc1c7150669d7190fbc"; -const senderAddr = "0x0adc9d67eef6d0f02e17543386be40ed451f7667"; +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, AccountKeyType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); +// create new account for testing in https://baobab.wallet.klaytn.foundation/ +const senderAddr = "0x0adc9d67eef6d0f02e17543386be40ed451f7667"; +const senderPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; +const senderNewPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedAccountUpdateWithRatio, - // gasLimit was 56000 - // https://baobab.scope.klaytn.com/tx/0x2a9fc23547e58f67d83263e509e0dc987ada346521a95d8f48de4e023796dede?tabId=accountKeyInfo - gasLimit: 60000, from: senderAddr, key: { type: AccountKeyType.Public, - // private key 0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b - // pubkeyX 0xdbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8 - // pubkeyY 0x906d7170ba349c86879fb8006134cbf57bda9db9214a90b607b6b4ab57fc026e - // Compressed PublicKey "0x02dbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8", - key: ethers.utils.computePublicKey("0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b", true) + key: ethers.utils.computePublicKey(senderNewPriv, true) }, feeRatio: 40, + gasLimit: 60000, }; tx = await senderWallet.populateTransaction(tx); @@ -54,12 +45,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js index 0de158d79..cdac1beec 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js @@ -1,6 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - // TxTypeFeeDelegatedSmartContractDeployWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedsmartcontractdeploywithratio // @@ -9,18 +6,20 @@ const ethers = require("ethers"); // input: SmartContract binary, // humanReadable: Must be false, // codeFormat: Must be 0x00 -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedSmartContractDeployWithRatio, @@ -32,18 +31,13 @@ async function main() { feeRatio: 30, codeFormat: 0x00, }; + tx = await senderWallet.populateTransaction(tx); console.log(tx); const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js index 0b9f785c7..027f1137f 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js @@ -1,6 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - // TxTypeFeeDelegatedSmartContractExecutionWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedsmartcontractexecutionwithratio // @@ -19,18 +16,20 @@ const ethers = require("ethers"); // const CONTRACT_ABI = ["function setNumber(uint256 newNumber) public", "function increment() public"]; // const iface = new ethers.utils.Interface( CONTRACT_ABI ); // const param = iface.encodeFunctionData("setNumber", [ "0x123" ]) -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - async function main() { - // sender + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); + const feePayerWallet = new Wallet(feePayerPriv, provider); const CONTRACT_ADDRESS = "0xcc18eC0261AADbe5fB5a7854449FC26b4F428653"; const CONTRACT_ABI = ["function setNumber(uint256 newNumber) public", "function increment() public"]; @@ -39,10 +38,11 @@ async function main() { let tx = { type: TxType.FeeDelegatedSmartContractExecutionWithRatio, + from: senderAddr, to: CONTRACT_ADDRESS, value: 0, - from: senderAddr, input: param, + gasLimit: 100000, feeRatio: 30, }; @@ -52,12 +52,6 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); - // fee payer - const feePayerWallet = new Wallet(feePayerPriv, provider); - - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); - console.log(tx); - const sentTx = await feePayerWallet.sendTransactionAsFeePayer(senderTxHashRLP); console.log("sentTx", sentTx); diff --git a/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js index 867db34a9..51a26c5c8 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js @@ -1,7 +1,3 @@ -const { Wallet, TxType } = require("@klaytn/ethers-ext"); -const ethers = require("ethers"); - -// // TxTypeFeeDelegatedCancelWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedcancelwithratio // @@ -9,7 +5,10 @@ const ethers = require("ethers"); // 2) send Cancel tx with the next nonce + 1 // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -// + +const { Wallet } = require("@klaytn/ethers-ext"); +const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -57,7 +56,7 @@ async function main() { type: TxType.ValueTransfer, nonce: nextNonce + 1, to: recieverAddr, - value: 1e12, + value: parseKlay("0.01"), from: senderAddr, }; From c838d84901273b099bbccf0171481324adb74cbe Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Wed, 15 Nov 2023 17:56:29 +0900 Subject: [PATCH 19/69] Test and debug with js-ext-core 0.9.7 --- .../transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js | 2 +- ...PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js b/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js index 9fadb9223..db9dc92eb 100644 --- a/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js +++ b/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js @@ -14,7 +14,7 @@ const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16f async function main() { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const senderWallet = new Wallet(senderPriv, provider); + const senderWallet = new Wallet(senderAddr, senderPriv, provider); const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { diff --git a/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js index c9a700b46..6f73d79af 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js @@ -25,7 +25,7 @@ const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16f async function main() { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const senderWallet = new Wallet(senderPriv, provider); + const senderWallet = new Wallet(senderAddr, senderPriv, provider); const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { From 513a0b69c815b9d7dc9be2431e79ddcc215c78f5 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 13:37:53 +0900 Subject: [PATCH 20/69] ethers: Bump deps --- ethers-ext/package-lock.json | 340 +++++++++++++++++++++++++++++++++-- ethers-ext/package.json | 8 +- 2 files changed, 334 insertions(+), 14 deletions(-) diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index 39b3d690f..dfeb83ead 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -9,8 +9,8 @@ "version": "0.9.5-beta", "license": "MIT", "dependencies": { - "@klaytn/js-ext-core": "^0.9.6-beta", - "@klaytn/web3rpc": "^0.9.5", + "@klaytn/js-ext-core": "^0.9.7-beta", + "@klaytn/web3rpc": "^0.9.7-beta", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", "lodash": "^4.17.21", @@ -496,6 +496,14 @@ "node": ">=6.9.0" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -508,6 +516,16 @@ "node": ">=12" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1422,9 +1440,9 @@ } }, "node_modules/@klaytn/js-ext-core": { - "version": "0.9.6-beta", - "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.6-beta.tgz", - "integrity": "sha512-t4rYzZ0SOOqFoyhkvgYPG16Yb54zzsa/3IrIfrm40OMWwaVuCdje6rUoPAcQryoGviBZel8B04o/2l17Bm4c0Q==", + "version": "0.9.7-beta", + "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.7-beta.tgz", + "integrity": "sha512-dgoO8zPuPA3LQRdUic9VW2c1UIjRpnP8BbKxEWjmrjmZ6GF0rYCqIu1onV7qvq0O8dDCKg7/bGDC4rpBnhFlxQ==", "dependencies": { "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", @@ -1432,14 +1450,15 @@ "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ethersproject/units": "^5.7.0", + "build": "^0.1.4", "elliptic": "^6.5.4", "lodash": "^4.17.21" } }, "node_modules/@klaytn/web3rpc": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.5.tgz", - "integrity": "sha512-yobaynvozIPRKH5XPtlNKAp4sqds2uPCHDxR0ym1gKst8R/P0gphtXEsWCA6taaHSUQynyB4qCQkIdWE2XLnlg==", + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.7.tgz", + "integrity": "sha512-D/ZTjaQY6oF65DNJu8evaOLPoCioCDiy9uqkIPOi1gwLmYNEMqFhy9NbtPPjkXFyKfj1fAHzgByyrWmNd7GyBA==", "dependencies": { "@babel/cli": "^7.0.0", "superagent": "^5.3.0" @@ -1576,6 +1595,11 @@ "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@types/uuid": { "version": "9.0.6", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz", @@ -2120,6 +2144,11 @@ "node": "*" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -2307,6 +2336,26 @@ "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" }, + "node_modules/build": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", + "integrity": "sha512-KwbDJ/zrsU8KZRRMfoURG14cKIAStUlS8D5jBDvtrZbwO5FEkYqc3oB8HIhRiyD64A48w1lc+sOmQ+mmBw5U/Q==", + "dependencies": { + "cssmin": "0.3.x", + "jsmin": "1.x", + "jxLoader": "*", + "moo-server": "*", + "promised-io": "*", + "timespan": "2.x", + "uglify-js": "1.x", + "walker": "1.x", + "winston": "*", + "wrench": "1.3.x" + }, + "engines": { + "node": ">v0.4.12" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2478,6 +2527,15 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2493,8 +2551,38 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } }, "node_modules/combined-stream": { "version": "1.0.8", @@ -2604,6 +2692,14 @@ "node": ">= 8" } }, + "node_modules/cssmin": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", + "integrity": "sha512-bynxGIAJ8ybrnFobjsQotIjA8HFDDgPwbeUWNXXXfR+B4f9kkxdcUyagJoQCSUOfMV+ZZ6bMn8bvbozlCzUGwQ==", + "bin": { + "cssmin": "bin/cssmin" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2809,6 +2905,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -3496,6 +3597,11 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3594,6 +3700,11 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -3663,6 +3774,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -4151,6 +4263,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4347,6 +4464,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -4478,6 +4606,17 @@ "node": ">=4" } }, + "node_modules/jsmin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", + "integrity": "sha512-OPuL5X/bFKgVdMvEIX3hnpx3jbVpFCrEM8pKPXjFkZUqg521r41ijdyTz7vACOhW6o1neVlcLyd+wkbK5fNHRg==", + "bin": { + "jsmin": "bin/jsmin" + }, + "engines": { + "node": ">=0.1.93" + } + }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -4525,6 +4664,33 @@ "node": ">=0.6.0" } }, + "node_modules/jxLoader": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", + "integrity": "sha512-ClEvAj3K68y8uKhub3RgTmcRPo5DfIWvtxqrKQdDPyZ1UVHIIKvVvjrAsJFSVL5wjv0rt5iH9SMCZ0XRKNzeUA==", + "dependencies": { + "js-yaml": "0.3.x", + "moo-server": "1.3.x", + "promised-io": "*", + "walker": "1.x" + }, + "engines": { + "node": ">v0.4.10" + } + }, + "node_modules/jxLoader/node_modules/js-yaml": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", + "integrity": "sha512-/7PsVDNP2tVe2Z1cF9kTEkjamIwz4aooDpRKmN1+g/9eePCgcxsv4QDvEbxO0EH+gdDD7MLyDoR6BASo3hH51g==", + "engines": { + "node": "> 0.4.11" + } + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4580,6 +4746,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", @@ -4624,6 +4806,14 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4793,6 +4983,14 @@ "node": ">=0.3.1" } }, + "node_modules/moo-server": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", + "integrity": "sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==", + "engines": { + "node": ">v0.4.10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4937,6 +5135,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5112,6 +5318,11 @@ "node": ">= 0.6.0" } }, + "node_modules/promised-io": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.6.tgz", + "integrity": "sha512-bNwZusuNIW4m0SPR8jooSyndD35ggirHlxVl/UhIaZD/F0OBv9ebfc6tNmbpZts3QXHggkjIBH8lvtnzhtcz0A==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -5452,6 +5663,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -5624,6 +5843,14 @@ "simple-concat": "^1.0.0" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -5656,6 +5883,14 @@ "node": ">=0.10.0" } }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -5851,6 +6086,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5865,6 +6105,19 @@ "node": ">=0.10.0" } }, + "node_modules/timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha512-0Jq9+58T2wbOyLth0EU+AUb6JMGCLaTWIykJFa7hyAybjVH9gpVMTfUAwo5fWAvtFt2Tjh/Elg8JtgNpnMnM8g==", + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -5906,6 +6159,14 @@ "node": ">=0.8" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", @@ -6124,6 +6385,14 @@ "node": ">=12.20" } }, + "node_modules/uglify-js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", + "integrity": "sha512-YPX1DjKtom8l9XslmPFQnqWzTBkvI4N0pbkzLuPZZ4QTyig0uQqvZz9NgUdfEV+qccJzi7fVcGWdESvRIjWptQ==", + "bin": { + "uglifyjs": "bin/uglifyjs" + } + }, "node_modules/ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -6247,6 +6516,14 @@ "extsprintf": "^1.2.0" } }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6297,6 +6574,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/winston": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", + "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", + "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -6325,6 +6636,15 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/wrench": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", + "integrity": "sha512-srTJQmLTP5YtW+F5zDuqjMEZqLLr/eJOZfDI5ibfPfRMeDh3oBUefAscuH0q5wBKE339ptH/S/0D18ZkfOfmKQ==", + "deprecated": "wrench.js is deprecated! You should check out fs-extra (https://github.com/jprichardson/node-fs-extra) for any operations you were using wrench for. Thanks for all the usage over the years.", + "engines": { + "node": ">=0.1.97" + } + }, "node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", diff --git a/ethers-ext/package.json b/ethers-ext/package.json index b7c3b221a..cce82671e 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -1,6 +1,6 @@ { "name": "@klaytn/ethers-ext", - "version": "0.9.5-beta", + "version": "0.9.7-beta", "main": "dist/index.js", "types": "dist/index.d.ts", "files": [ @@ -21,7 +21,7 @@ "ethers": "^5.7.2" }, "devDependencies": { - "@klaytn/ethers-ext": "^0.9.5-beta", + "@klaytn/ethers-ext": "^0.9.7-beta", "@types/aes-js": "^3.1.1", "@types/bn.js": "^5.1.1", "@types/chai": "^4.3.4", @@ -39,8 +39,8 @@ "typescript": "^5.0.4" }, "dependencies": { - "@klaytn/js-ext-core": "^0.9.6-beta", - "@klaytn/web3rpc": "^0.9.5", + "@klaytn/js-ext-core": "^0.9.7-beta", + "@klaytn/web3rpc": "^0.9.7", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", "lodash": "^4.17.21", From 9abdcd1a3c4a00c1c63df48681e544fc15bcf2b7 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 13:43:27 +0900 Subject: [PATCH 21/69] ethers: Cleanup example --- .../example/accountKey/AccountKeyLegacy.js | 20 +--------------- .../example/accountKey/AccountKeyPublic.js | 7 ++---- .../example/accountKey/AccountKeyRoleBased.js | 7 ++---- .../accountKey/AccountKeyWeightedMultiSig.js | 23 ++++++++----------- 4 files changed, 15 insertions(+), 42 deletions(-) diff --git a/ethers-ext/example/accountKey/AccountKeyLegacy.js b/ethers-ext/example/accountKey/AccountKeyLegacy.js index 3e3fd9bf5..fef19080f 100644 --- a/ethers-ext/example/accountKey/AccountKeyLegacy.js +++ b/ethers-ext/example/accountKey/AccountKeyLegacy.js @@ -13,7 +13,6 @@ const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const wallet = new Wallet(senderPriv, provider); -// Send transaction from an AccountKeyLegacy account async function sendTx() { let tx = { from: senderAddr, @@ -28,22 +27,6 @@ async function sendTx() { console.log("receipt", rc); } -// Verify a transaction signed by an AccountKeyLegacy account -async function verifyTx() { - let tx = { - from: senderAddr, - to: recieverAddr, - value: 0, - }; - - let signedTx = await wallet.signTransaction(tx); - console.log("signedTx", signedTx); - - const addr1 = await provider.send("klay_recoverFromTransaction", [signedTx, "latest"]); - console.log("recoveredAddr rpc", addr1, addr1.toLowerCase() === senderAddr); -} - -// Verify a message signed by an AccountKeyLegacy account async function verifyMsg() { const msg = "hello"; const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); @@ -59,7 +42,6 @@ async function verifyMsg() { async function main() { await sendTx(); - await verifyTx(); await verifyMsg(); } -main().catch(console.error); \ No newline at end of file +main().catch(console.error); diff --git a/ethers-ext/example/accountKey/AccountKeyPublic.js b/ethers-ext/example/accountKey/AccountKeyPublic.js index b7002b71c..f2c4d7d64 100644 --- a/ethers-ext/example/accountKey/AccountKeyPublic.js +++ b/ethers-ext/example/accountKey/AccountKeyPublic.js @@ -1,4 +1,4 @@ -// AccountKeyPublic Step 01 - account update +// AccountKeyPublic // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); @@ -14,7 +14,6 @@ const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab. const wallet = new Wallet(senderAddr, senderPriv, provider); const wallet2 = new Wallet(senderAddr, senderNewPriv, provider); -// Update Account async function updateAccount() { let senderNewPub = new ethers.utils.SigningKey(senderNewPriv).compressedPublicKey; @@ -34,7 +33,6 @@ async function updateAccount() { console.log("receipt", rc); } -// Send transaction from an AccountKeyLegacy account async function sendTx() { let tx = { type: TxType.ValueTransfer, @@ -50,7 +48,6 @@ async function sendTx() { console.log("receipt", rc); } -// Verify a message signed by an AccountKeyLegacy account async function recoverMsg() { const msg = "hello"; const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); @@ -69,4 +66,4 @@ async function main() { await sendTx(); await recoverMsg(); } -main().catch(console.error); \ No newline at end of file +main().catch(console.error); diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased.js b/ethers-ext/example/accountKey/AccountKeyRoleBased.js index db023e61e..0c306208d 100644 --- a/ethers-ext/example/accountKey/AccountKeyRoleBased.js +++ b/ethers-ext/example/accountKey/AccountKeyRoleBased.js @@ -1,4 +1,4 @@ -// AccountKeyRoleBased Step 01 - account update +// AccountKeyRoleBased // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased const { Wallet } = require("@klaytn/ethers-ext"); @@ -16,7 +16,6 @@ const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab. const wallet = new Wallet(senderAddr, senderRoleAccountUpdatePriv, provider); const wallet2 = new Wallet(senderAddr, senderRoleTransactionPriv, provider); -// Update Account async function updateAccount() { let pub1 = new ethers.utils.SigningKey(senderRoleTransactionPriv).compressedPublicKey; let pub2 = new ethers.utils.SigningKey(senderRoleAccountUpdatePriv).compressedPublicKey; @@ -57,7 +56,6 @@ async function updateAccount() { console.log("receipt", rc); } -// Send transaction from an AccountKeyLegacy account async function sendTx() { let tx = { type: TxType.ValueTransfer, @@ -74,7 +72,6 @@ async function sendTx() { console.log("receipt", rc); } -// Verify a message signed by an AccountKeyLegacy account async function recoverMsg() { const msg = "hello"; const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); @@ -93,4 +90,4 @@ async function main() { await sendTx(); await recoverMsg(); } -main().catch(console.error); \ No newline at end of file +main().catch(console.error); diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js index 6b5ee9fdc..8d12cb772 100644 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js +++ b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js @@ -1,4 +1,4 @@ -// AccountKeyWeightedMultiSig Step 01 - account update +// AccountKeyWeightedMultiSig // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig const { Wallet } = require("@klaytn/ethers-ext"); @@ -17,7 +17,6 @@ const wallet = new Wallet(senderAddr, senderNewPriv1, provider); const wallet2 = new Wallet(senderAddr, senderNewPriv2, provider); const wallet3 = new Wallet(senderAddr, senderNewPriv3, provider); -// Update Account async function updateAccount() { let senderNewPub1 = new ethers.utils.SigningKey(senderNewPriv1).compressedPublicKey; let senderNewPub2 = new ethers.utils.SigningKey(senderNewPriv2).compressedPublicKey; @@ -39,12 +38,12 @@ async function updateAccount() { }; // sign 1 - let ptx = await wallet.populateTransaction(tx); - const txHashRLP = await wallet.signTransaction(ptx); - console.log("TxHashRLP", txHashRLP); + let ptx1 = await wallet.populateTransaction(tx); + const txHashRLP1 = await wallet.signTransaction(ptx1); + console.log("TxHashRLP1", txHashRLP1); // sign 2 - let ptx2 = await wallet2.populateTransaction(txHashRLP); + let ptx2 = await wallet2.populateTransaction(txHashRLP1); const txHashRLP2 = await wallet2.signTransaction(ptx2); console.log("TxHashRLP2", txHashRLP2); @@ -56,7 +55,6 @@ async function updateAccount() { console.log("receipt", rc); } -// Send transaction from an AccountKeyLegacy account async function sendTx() { let tx = { type: TxType.ValueTransfer, @@ -67,12 +65,12 @@ async function sendTx() { }; // sign 1 - let ptx = await wallet.populateTransaction(tx); - const txHashRLP = await wallet.signTransaction(ptx); - console.log("TxHashRLP", txHashRLP); + let ptx1 = await wallet.populateTransaction(tx); + const txHashRLP1 = await wallet.signTransaction(ptx1); + console.log("TxHashRLP1", txHashRLP1); // sign 2 - let ptx2 = await wallet2.populateTransaction(txHashRLP); + let ptx2 = await wallet2.populateTransaction(txHashRLP1); const txHashRLP2 = await wallet2.signTransaction(ptx2); console.log("TxHashRLP2", txHashRLP2); @@ -84,7 +82,6 @@ async function sendTx() { console.log("receipt", rc); } -// Verify a message signed by an AccountKeyLegacy account async function recoverMsg() { const msg = "hello"; const msghex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(msg)); @@ -103,4 +100,4 @@ async function main() { await sendTx(); await recoverMsg(); } -main().catch(console.error); \ No newline at end of file +main().catch(console.error); From 800c2ae149758fa874dcba627b4a1f8a0c4da8ba Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 15:38:35 +0900 Subject: [PATCH 22/69] ethers: Bump deps --- ethers-ext/package-lock.json | 22 +++++++++++----------- ethers-ext/package.json | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index dfeb83ead..c5cc998a1 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -1,29 +1,29 @@ { "name": "@klaytn/ethers-ext", - "version": "0.9.5-beta", + "version": "0.9.7-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@klaytn/ethers-ext", - "version": "0.9.5-beta", + "version": "0.9.7-beta", "license": "MIT", "dependencies": { "@klaytn/js-ext-core": "^0.9.7-beta", - "@klaytn/web3rpc": "^0.9.7-beta", + "@klaytn/web3rpc": "^0.9.7", "bn.js": "^5.2.1", "eth-lib": "^0.1.29", "lodash": "^4.17.21", "uuid": "^9.0.1" }, "devDependencies": { - "@klaytn/ethers-ext": "^0.9.5-beta", + "@klaytn/ethers-ext": "^0.9.7-beta", "@types/aes-js": "^3.1.1", "@types/bn.js": "^5.1.1", "@types/chai": "^4.3.4", "@types/chai-as-promised": "^7.1.5", "@types/lodash": "^4.14.192", - "@types/mocha": "^10.0.1", + "@types/mocha": "^10.0.4", "@types/uuid": "^9.0.3", "@typescript-eslint/eslint-plugin": "^6.1.0", "chai": "^4.3.7", @@ -1410,9 +1410,9 @@ } }, "node_modules/@klaytn/ethers-ext": { - "version": "0.9.5-beta", - "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.5-beta.tgz", - "integrity": "sha512-NW/7XBZxmMYArg9UbVi3CYGHUTDzTh94WtmpRPNI16V0HLC28jtbSz8xHLMrJC2Yl4G3Juy+DAz/PZjspuekRw==", + "version": "0.9.7-beta", + "resolved": "https://registry.npmjs.org/@klaytn/ethers-ext/-/ethers-ext-0.9.7-beta.tgz", + "integrity": "sha512-qZ2cjmw0VX1eNfPeaZbEJz1fLeICeKhKIAUINz3xJqAiMd4jSYrHv4VEoNZ1iz08DJI15vVsHMXWmByTsotzXg==", "dev": true, "dependencies": { "@klaytn/ethers-ext": "^0.9.3-beta", @@ -1578,9 +1578,9 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.4.tgz", + "integrity": "sha512-xKU7bUjiFTIttpWaIZ9qvgg+22O1nmbA+HRxdlR+u6TWsGfmFdXrheJoK4fFxrHNVIOBDvDNKZG+LYBpMHpX3w==", "dev": true }, "node_modules/@types/node": { diff --git a/ethers-ext/package.json b/ethers-ext/package.json index cce82671e..b95069a20 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -27,7 +27,7 @@ "@types/chai": "^4.3.4", "@types/chai-as-promised": "^7.1.5", "@types/lodash": "^4.14.192", - "@types/mocha": "^10.0.1", + "@types/mocha": "^10.0.4", "@types/uuid": "^9.0.3", "@typescript-eslint/eslint-plugin": "^6.1.0", "chai": "^4.3.7", From f8ed493ac3596ebd817e1e27291163f70c5f9df7 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 15:40:58 +0900 Subject: [PATCH 23/69] ethers: Fix tests --- ethers-ext/src/signer.ts | 65 ++++++++++++++---- ethers-ext/test/signer.spec.ts | 121 ++++++++++++++++++++++++--------- 2 files changed, 141 insertions(+), 45 deletions(-) diff --git a/ethers-ext/src/signer.ts b/ethers-ext/src/signer.ts index 998f9c137..9b7cc320f 100644 --- a/ethers-ext/src/signer.ts +++ b/ethers-ext/src/signer.ts @@ -4,8 +4,8 @@ import { JsonRpcProvider as EthersJsonRpcProvider } from "@ethersproject/provide import { Wallet as EthersWallet } from "@ethersproject/wallet"; import { poll } from "@ethersproject/web"; import { KlaytnTxFactory, HexStr, isFeePayerSigTxType, parseTransaction } from "@klaytn/js-ext-core"; -import { ethers } from "ethers"; -import { Bytes, BytesLike, Deferrable, ProgressCallback, SigningKey, computeAddress, hashMessage, keccak256, recoverAddress, resolveProperties } from "ethers/lib/utils"; +import { BigNumber } from "ethers"; +import { Bytes, BytesLike, Deferrable, Logger, ProgressCallback, SigningKey, computeAddress, keccak256, resolveProperties } from "ethers/lib/utils"; import _ from "lodash"; import { decryptKeystoreList, decryptKeystoreListSync } from "./keystore"; @@ -22,7 +22,8 @@ function saveCustomFields(tx: Deferrable): any { // Save fields that are not allowed in ethers.js const savedFields: any = {}; for (const key in tx) { - if (ethersAllowedTransactionKeys.indexOf(key) === -1) { + // 'from' may not be corresponded to the public key of the private key in a decoupled account. + if (ethersAllowedTransactionKeys.indexOf(key) === -1 || key == "from") { savedFields[key] = _.get(tx, key); _.unset(tx, key); } @@ -40,11 +41,6 @@ function saveCustomFields(tx: Deferrable): any { tx.type = 0; } - // 'from' may not be corresponded to the public key of the private key in Klaytn account - // So 'from' field also has to be saved - savedFields["from"] = tx.from; - _.unset(tx, "from"); - return savedFields; } @@ -112,7 +108,7 @@ export class Wallet extends EthersWallet { getAddress(legacy?: boolean): Promise { if (legacy || !this.klaytnAddr) { - return super.getAddress(); + return Promise.resolve(computeAddress(this.publicKey)); } else { return Promise.resolve(this.klaytnAddr); } @@ -131,12 +127,25 @@ export class Wallet extends EthersWallet { } } + // Fill legacy address for Ethereum TxTypes, and (possibly) decoupled address for Klaytn TxTypes. checkTransaction(transaction: Deferrable): Deferrable { const tx = _.clone(transaction); - const savedFields = saveCustomFields(tx); - transaction = super.checkTransaction(tx); - restoreCustomFields(tx, savedFields); + const legacy = !KlaytnTxFactory.has(tx.type); + const expectedFrom = this.getAddress(legacy); + if (!tx.from) { + tx.from = expectedFrom; + } else { + tx.from = Promise.all([ + Promise.resolve(tx.from), + expectedFrom, + ]).then(([from, expectedFrom]) => { + if (from?.toLowerCase() != expectedFrom?.toLowerCase()) { + throw new Error(`from address mismatch tx=${JSON.stringify(transaction)} addr=${expectedFrom}`); + } + return from; + }); + } return tx; } @@ -148,10 +157,15 @@ export class Wallet extends EthersWallet { return super.populateTransaction(tx); } + // Fill 'from' field. + if (!tx.from) { + tx.from = await this.getAddress(); + } + // If the account address is decoupled from private key, // the ethers.Wallet.populateTransaction() may fill the nonce of the wrong address. if (!tx.nonce) { - tx.nonce = await this.provider.getTransactionCount(await this.getAddress()); + tx.nonce = await this.provider.getTransactionCount(tx.from); } // Sometimes estimateGas underestimates the required gas limit. @@ -191,6 +205,9 @@ export class Wallet extends EthersWallet { return super.signTransaction(tx); } + // Because RLP-encoded tx may not contain chainId, fill up here. + tx.chainId ??= await this._chainIdFromTx(tx); + const klaytnTx = KlaytnTxFactory.fromObject(tx); const sigHash = keccak256(klaytnTx.sigRLP()); @@ -215,9 +232,13 @@ export class Wallet extends EthersWallet { throw new Error(`feePayer signature not supported for tx type ${tx.type}`); } + // Because RLP-encoded tx may not contain chainId, fill up here. + tx.chainId ??= await this._chainIdFromTx(tx); + // Automatically populate 'feePayer' field, just like how 'from' field is populated. // @ts-ignore: feePayer field does not exist in ethers.TransactionRequest type tx.feePayer ??= await this.getAddress(); + const klaytnTx = KlaytnTxFactory.fromObject(tx); if (!isFeePayerSigTxType(klaytnTx.type)) { klaytnTx.throwTypeError("feePayer signature not supported"); @@ -260,6 +281,24 @@ export class Wallet extends EthersWallet { return sig; } + // Extract chainId from tx signatures. + // If no signatures, query provider. + async _chainIdFromTx(tx: any): Promise { + function extractFromSig(field: any[]): number | undefined { + if (_.isArray(field) && field.length > 0 && + _.isArray(field[0]) && field[0].length == 3) { + const v = BigNumber.from(field[0][0]).toNumber(); + return (v - 35) / 2; + } + return undefined; + } + + return ( + extractFromSig(tx.txSignatures) ?? + extractFromSig(tx.feePayerSignatures) ?? + this.getChainId()); + } + async _sendRawTransaction(signedTx: string): Promise { if (!(this.provider instanceof EthersJsonRpcProvider)) { throw new Error("Klaytn typed transaction can only be broadcasted to a Klaytn JSON-RPC server"); diff --git a/ethers-ext/test/signer.spec.ts b/ethers-ext/test/signer.spec.ts index a8780e309..764acd6cb 100644 --- a/ethers-ext/test/signer.spec.ts +++ b/ethers-ext/test/signer.spec.ts @@ -1,28 +1,35 @@ -import chai from "chai"; +import { keccak256 } from "@ethersproject/keccak256"; +import { parseTransaction } from "@klaytn/js-ext-core"; +import chai, { assert, expect } from "chai"; import chaiAsPromised from "chai-as-promised"; -import { BigNumber, Wallet as EthersWallet } from "ethers"; +import { Wallet as EthersWallet } from "ethers"; import _ from "lodash"; +import { describe, it } from "mocha"; import { Wallet as KlaytnWallet } from "../src"; import { MockEthersProvider, MockKlaytnProvider } from "./mock_provider"; +chai.use(chaiAsPromised); + +// Dummy values. const url = "https://public-en-baobab.klaytn.net"; const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; - const value = 0; const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const to = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; const feePayer = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; const decoupledAddr = "0x90F79bf6EB2c4f870365E785982E1f101E93b906"; const otherAddr = "0x15d34aaf54267db7d7c367839aaf71a00a2c6a65"; - +const nonce = 2; +const gasPrice = 25e9; +const gasLimit = 50000; +const chainId = 1001; +const txHashRLP = "0x08f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a0f3d0cd43661cabf53425535817c5058c27781f478cb5459874feaa462ed3a29aa06748abe186269ff10b8100a4b7d7fea274b53ea2905acbf498dc8b5ab1bf4fbc"; +const senderTxHashRLP = "0x09f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"; +const txSignatures = [["0x25", "0x9f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956", "0x6bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"]]; const block = JSON.parse('{"difficulty":"0x1","extraData":"0x","gasLimit":"0xe8d4a50fff","gasUsed":"0x0","hash":"0xe6a28d57db4dec9eacad5e6ce3d90fef900ab65760c579c46567b4bbb3803bc2","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x571e53df607be97431a5bbefca1dffe5aef56f4d","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","number":"0x12d687","parentHash":"0x720ed13d78e8b0f2c20f4129b9b69dcbad49eebecfc2bb22e792be5ea28ecbfc","receiptsRoot":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x33b","stateRoot":"0xd3db6e4adfc526b5028764512e338d0ff3d8bc76e02593a763ac747ed8a22112","timestamp":"0x5d261b95","totalDifficulty":"0x12d688","transactions":[],"transactionsRoot":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","uncles":[]}'); -const txhash = "0x35f47ecde5f7a450f8210809fb03fad28c3c7f52ddb5038dd494011e5eeec3a2"; - -const assert = chai.assert; -const expect = chai.expect; -chai.use(chaiAsPromised); +const txJson = JSON.parse('{"blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2","blockNumber":"0x5daf3b","hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b","from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d","gas":"0xc350","gasPrice":"0x4a817c800","input":"0x68656c6c6f21","nonce":"0x15","r":"0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea","s":"0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c","to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb","transactionIndex":"0x41","type":"0x0","v":"0x25","value":"0xf3dbb76162000"}'); describe("Wallet", () => { let EP: MockEthersProvider; @@ -42,13 +49,17 @@ describe("Wallet", () => { // Stuff dummy values to mock providers for (let P of [EP, KP]) { P.mock_override("eth_chainId", () => "0x3e9"); + P.mock_override("eth_blockNumber", () => "0x12d687"); P.mock_override("eth_gasPrice", () => "0xba43b7400"); P.mock_override("eth_getTransactionCount", () => "0x1234"); P.mock_override("eth_getBlockByNumber", () => block); P.mock_override("eth_estimateGas", () => "0x5208"); P.mock_override("eth_sendRawTransaction", (params: any[]) => { sentRawTx = params[0]; - return txhash; + return keccak256(sentRawTx); + }); + P.mock_override("eth_getTransactionByHash", () => { + return txJson; }); } for (let P of [KP]) { @@ -56,7 +67,7 @@ describe("Wallet", () => { P.mock_override("klay_estimateGas", () => "0x5208"); P.mock_override("klay_sendRawTransaction", (params: any[]) => { sentRawTx = params[0]; - return txhash; + return keccak256(sentRawTx); }); } }); @@ -67,9 +78,10 @@ describe("Wallet", () => { // - If from field exists, reject if different from getAddress() // - Original tx object remain untouched describe("checkTransaction", () => { - async function testOK(W: EthersWallet, tx: any) { + async function testOK(W: EthersWallet, tx: any, expectedFrom?: any) { let res = W.checkTransaction(tx); - assert.equal(await res.from, await W.getAddress()); + expectedFrom ??= await W.getAddress(); + assert.equal(await res.from, expectedFrom); } async function testErr(W: EthersWallet, tx: any, err: string) { let trigger = async () => { @@ -80,25 +92,23 @@ describe("Wallet", () => { expect(trigger()).to.be.rejectedWith(err); } - it("fill missing from field", async () => { - return; // TODO: Enable after fixing checkTransaction - for (let W of [EW, KW, KWD]) { - await testOK(W, { type: 0, to, value }); + it("fill missing 'from' field", async () => { + for (let W of [EW, KW]) { + // Ethereum TxType always filled with legacy address + await testOK(W, { type: 0, to, value }, from); } for (let W of [KW, KWD]) { await testOK(W, { type: 9, to, feePayer, value }); } }); - it("check given from field", async () => { + it("preserve existing 'from' field", async () => { for (let W of [EW, KW, KWD]) { - let addr = await W.getAddress(); - await testOK(W, { type: 0, from: addr, to, value }); + // Ethereum TxType always filled with legacy address + await testOK(W, { type: 0, from, to, value }, from); } for (let W of [KW, KWD]) { - let addr = await W.getAddress(); - await testOK(W, { type: 9, from: addr, to, feePayer, value }); + await testOK(W, { type: 9, from: (await W.getAddress()), to, feePayer, value }); } - for (let W of [EW, KW, KWD]) { await testErr(W, { type: 0, from: otherAddr, to, value }, "from address mismatch"); } @@ -115,7 +125,7 @@ describe("Wallet", () => { describe("populateTransaction", () => { async function testOK(W: EthersWallet, tx: any) { let res = await W.populateTransaction(tx); - // assert.isDefined(res.from); // TODO: enable after fixing checkTransaction + assert.isDefined(res.from); assert.isDefined(res.nonce); assert.isDefined(res.gasPrice); assert.isDefined(res.gasLimit); @@ -131,27 +141,74 @@ describe("Wallet", () => { }); }); - // TODO: signTransaction sign transactions under various settings + // signTransaction sign transactions under various settings // - Accepts both object and RLP-encoded string // - signTransaction and signTransactionAsFeePayer - // - For Klaytn tx types, Appends existing signature describe("signTransaction", () => { async function testOK(W: EthersWallet, tx: any) { + let res = await W.signTransaction(tx); + assert.typeOf(res, "string"); } - async function testOKAsFeePayer(W: EthersWallet, tx: any) { + async function testOK_AsFeePayer(W: KlaytnWallet, tx: any) { + let res = await W.signTransactionAsFeePayer(tx); + assert.typeOf(res, "string"); } - it("sign object", async () => {}); - it("sign string", async () => {}); - it("signatures appended", async () => {}); + it("as sender", async () => { + for (let W of [EW, KW, KWD]) { + await testOK(W, { type: 0, to, value, nonce, gasPrice, gasLimit }); + } + for (let W of [KW, KWD]) { + await testOK(W, { type: 9, from: (await W.getAddress()), to, feePayer, value, nonce, gasPrice, gasLimit, chainId }); + } + for (let W of [KW, KWD]) { + await testOK(W, txHashRLP); + } + }); + it("as fee payer", async () => { + for (let W of [KW, KWD]) { + await testOK_AsFeePayer(W, { type: 9, from: (await W.getAddress()), to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }); + } + for (let W of [KW, KWD]) { + await testOK_AsFeePayer(W, senderTxHashRLP); + } + }); }); - // TODO: sendTransaction can send transactions + // sendTransaction send transactions // - Accepts both object and RLP-encoded string // - sendTransaction and sendTransactionAsFeePayer // - populateTransaction before signing - // - For Klaytn tx types, Appends existing signature describe("sendTransaction", () => { + async function testOK(W: EthersWallet, tx: any) { + let res = await W.sendTransaction(tx); + assert.isDefined(res); + assert.isDefined(res.hash); + assert.isDefined(res.wait); + } + async function testOK_AsFeePayer(W: KlaytnWallet, tx: any) { + let res = await W.sendTransactionAsFeePayer(tx); + assert.isDefined(res); + assert.isDefined(res.hash); + assert.isDefined(res.wait); + } + + it("as sender", async () => { + for (let W of [KWD]) { + await testOK(W, { type: 0, to, value }); + } + for (let W of [KW, KWD]) { + // await testOK(W, { type: 9, to, feePayer, value }); + } + }); + it("as fee payer", async () => { + for (let W of [KW, KWD]) { + await testOK_AsFeePayer(W, { type: 9, to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }); + } + for (let W of [KW, KWD]) { + await testOK_AsFeePayer(W, senderTxHashRLP); + } + }); }); }); From 5df1f6c39534d4f58cc4a8935562bcbd0f47a941 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 15:43:47 +0900 Subject: [PATCH 24/69] ethers: Remove signRecover in favor of accountKey examples --- .../signRecover/1_tx_signRecover_legacy.js | 45 ---------------- .../signRecover/2_tx_signRecover_pubkey.js | 31 ----------- .../signRecover/3_tx_signRecover_multisig.js | 52 ------------------- .../signRecover/4_tx_signRecover_rolebased.js | 37 ------------- .../signRecover/5_msg_signRecover_legacy.js | 20 ------- .../signRecover/6_msg_signRecover_pubkey.js | 23 -------- .../signRecover/7_msg_signRecover_multisig.js | 25 --------- .../8_msg_signRecover_rolebased.js | 25 --------- 8 files changed, 258 deletions(-) delete mode 100644 ethers-ext/example/signRecover/1_tx_signRecover_legacy.js delete mode 100644 ethers-ext/example/signRecover/2_tx_signRecover_pubkey.js delete mode 100644 ethers-ext/example/signRecover/3_tx_signRecover_multisig.js delete mode 100644 ethers-ext/example/signRecover/4_tx_signRecover_rolebased.js delete mode 100644 ethers-ext/example/signRecover/5_msg_signRecover_legacy.js delete mode 100644 ethers-ext/example/signRecover/6_msg_signRecover_pubkey.js delete mode 100644 ethers-ext/example/signRecover/7_msg_signRecover_multisig.js delete mode 100644 ethers-ext/example/signRecover/8_msg_signRecover_rolebased.js diff --git a/ethers-ext/example/signRecover/1_tx_signRecover_legacy.js b/ethers-ext/example/signRecover/1_tx_signRecover_legacy.js deleted file mode 100644 index fbf931478..000000000 --- a/ethers-ext/example/signRecover/1_tx_signRecover_legacy.js +++ /dev/null @@ -1,45 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet, parseKlay } = require("../../dist/src"); - -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderPriv, provider); - - const receiverAddr = wallet.address; - const senderAddr = wallet.address; - - let tx = { - from: senderAddr, - to: receiverAddr, - value: parseKlay("1"), - }; - - // sign - const popedTx = await wallet.populateTransaction(tx); - const txHashRLP = await wallet.signTransaction(popedTx); - let txObj = ethers.utils.parseTransaction(txHashRLP); - console.log(txHashRLP); - console.log(txObj); - - // verify - const rawTx = ethers.utils.serializeTransaction(popedTx); - const msgHash = ethers.utils.keccak256(rawTx); - const msgBytes = ethers.utils.arrayify(msgHash); - - const expandedSig = { - r: txObj.r, - s: txObj.s, - recoveryParam: 0, - v: txObj.v - }; - const signature = ethers.utils.joinSignature(expandedSig); - - const recoverAddr = ethers.utils.recoverAddress(msgBytes, signature); - console.log("\nsender", senderAddr, "\nrecovered", recoverAddr); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/2_tx_signRecover_pubkey.js b/ethers-ext/example/signRecover/2_tx_signRecover_pubkey.js deleted file mode 100644 index 4e5d2f7f5..000000000 --- a/ethers-ext/example/signRecover/2_tx_signRecover_pubkey.js +++ /dev/null @@ -1,31 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet, parseKlay, TxType } = require("../../dist/src"); - -const receiverAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(senderAddr, senderPriv, provider); - - let tx = { - type: TxType.ValueTransfer, - from: senderAddr, - to: receiverAddr, - value: parseKlay("1"), - }; - - tx = await wallet.populateTransaction(tx); - const senderTxHashRLP = await wallet.signTransaction(tx); - - console.log(senderTxHashRLP); - console.log(wallet.decodeTxFromRLP(senderTxHashRLP)); - - const recoverAddr = await provider.send("klay_recoverFromTransaction", [senderTxHashRLP, "latest"]); - console.log("\nsender", senderAddr, "\nrecovered", recoverAddr); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/3_tx_signRecover_multisig.js b/ethers-ext/example/signRecover/3_tx_signRecover_multisig.js deleted file mode 100644 index bd2cdab2e..000000000 --- a/ethers-ext/example/signRecover/3_tx_signRecover_multisig.js +++ /dev/null @@ -1,52 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet, parseKlay, TxType } = require("../../dist/src"); - - -const receiverAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; -const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - - let user1 = new Wallet( - "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e", - "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a", - provider - ); - let user2 = new Wallet( - "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e", - "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8", - provider - ); - let user3 = new Wallet( - "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e", - "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac", - provider - ); - - let tx = { - type: TxType.ValueTransfer, - from: senderAddr, - to: receiverAddr, - value: parseKlay("1"), - }; - - tx = await user1.populateTransaction(tx); - const senderTxHashRLP = await user1.signTransaction(tx); - - const tx2 = await user2.populateTransaction(user2.decodeTxFromRLP(senderTxHashRLP)); - const senderTxHashRLP2 = await user2.signTransaction(tx2); - - const tx3 = await user3.populateTransaction(user3.decodeTxFromRLP(senderTxHashRLP2)); - const senderTxHashRLP3 = await user3.signTransaction(tx3); - - console.log(senderTxHashRLP3); - console.log(user1.decodeTxFromRLP(senderTxHashRLP3)); - - const recoverAddr = await provider.send("klay_recoverFromTransaction", [senderTxHashRLP3, "latest"]); - console.log("\nsender", senderAddr, "\nrecovered", recoverAddr); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/4_tx_signRecover_rolebased.js b/ethers-ext/example/signRecover/4_tx_signRecover_rolebased.js deleted file mode 100644 index 5a68ea6ed..000000000 --- a/ethers-ext/example/signRecover/4_tx_signRecover_rolebased.js +++ /dev/null @@ -1,37 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet, parseKlay, TxType } = require("../../dist/src"); - - -const receiverAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; -const senderAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; - - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - - let user = new Wallet( - "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea", - "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac", - provider - ); - - let tx = { - type: TxType.ValueTransfer, - from: senderAddr, - to: receiverAddr, - value: parseKlay("1"), - }; - - tx = await user.populateTransaction(tx); - const senderTxHashRLP = await user.signTransaction(tx); - - console.log(senderTxHashRLP); - console.log(user.decodeTxFromRLP(senderTxHashRLP)); - - const recoverAddr = await provider.send("klay_recoverFromTransaction", [senderTxHashRLP, "latest"]); - console.log("\nsender", senderAddr, "\nrecovered", recoverAddr); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/5_msg_signRecover_legacy.js b/ethers-ext/example/signRecover/5_msg_signRecover_legacy.js deleted file mode 100644 index c09a80f93..000000000 --- a/ethers-ext/example/signRecover/5_msg_signRecover_legacy.js +++ /dev/null @@ -1,20 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet} = require("../../dist/src"); - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet("0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8", provider); - - const address = wallet.address; - let msg = "I♥KLAYTN"; - let msgHash = ethers.utils.hashMessage(msg); - let msgHashBytes = ethers.utils.arrayify(msgHash); - const signature = await wallet.signMessage(msgHashBytes); - - const recoverAddr = await provider.send("klay_recoverFromMessage", [address, msgHash, signature, "latest"]); - console.log("\nsender", address, "\nrecovered", recoverAddr); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/6_msg_signRecover_pubkey.js b/ethers-ext/example/signRecover/6_msg_signRecover_pubkey.js deleted file mode 100644 index 827032a65..000000000 --- a/ethers-ext/example/signRecover/6_msg_signRecover_pubkey.js +++ /dev/null @@ -1,23 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet} = require("../../dist/src"); - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet( - "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b", - "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8", - provider); - - const address = wallet.address; - let msg = "I♥KLAYTN"; - let msgHash = ethers.utils.hashMessage(msg); - let msgHashBytes = ethers.utils.arrayify(msgHash); - const signature = await wallet.signMessage(msgHashBytes); - - const recoverAddr = await provider.send("klay_recoverFromMessage", [address, msgHash, signature, "latest"]); - console.log("\nsender", address, "\nrecovered", recoverAddr); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/7_msg_signRecover_multisig.js b/ethers-ext/example/signRecover/7_msg_signRecover_multisig.js deleted file mode 100644 index feb8a9d24..000000000 --- a/ethers-ext/example/signRecover/7_msg_signRecover_multisig.js +++ /dev/null @@ -1,25 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet} = require("../../dist/src"); - -// multisig account address -const address = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; -// a member private key of multisig account -const priv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(address, priv, provider); - - let msg = "I♥KLAYTN"; - let msgHash = ethers.utils.hashMessage(msg); - let msgHashBytes = ethers.utils.arrayify(msgHash); - const signature = await wallet.signMessage(msgHashBytes); - - const recoverAddr = await provider.send("klay_recoverFromMessage", [address, msgHash, signature, "latest"]); - console.log("\nsender", address, "\nrecovered", recoverAddr); - console.log("private key's legacy type address", await wallet.getEtherAddress()); -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/signRecover/8_msg_signRecover_rolebased.js b/ethers-ext/example/signRecover/8_msg_signRecover_rolebased.js deleted file mode 100644 index 6e1691191..000000000 --- a/ethers-ext/example/signRecover/8_msg_signRecover_rolebased.js +++ /dev/null @@ -1,25 +0,0 @@ -const ethers = require("ethers"); - -// const { Wallet, parseKlay } = require("@klaytn/ethers-ext"); -const { Wallet} = require("../../dist/src"); - -// role-based account address -const address = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; -// transaction role key of role-based account -const priv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; - -async function main() { - const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const wallet = new Wallet(address, priv, provider); - - let msg = "I♥KLAYTN"; - let msgHash = ethers.utils.hashMessage(msg); - let msgHashBytes = ethers.utils.arrayify(msgHash); - const signature = await wallet.signMessage(msgHashBytes); - - const recoverAddr = await provider.send("klay_recoverFromMessage", [address, msgHash, signature, "latest"]); - console.log("\nsender", address, "\nrecovered", recoverAddr); - console.log("private key's legacy type address", await wallet.getEtherAddress()); -} - -main(); \ No newline at end of file From 1ab68804b87f3830d7319ea83efe9cbaaa7cc2c0 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 13 Nov 2023 15:37:51 +0900 Subject: [PATCH 25/69] web3js: Add deps @klaytn/js-ext-core --- web3js-ext/package-lock.json | 152 +++++++++++++++++------------------ web3js-ext/package.json | 3 +- 2 files changed, 76 insertions(+), 79 deletions(-) diff --git a/web3js-ext/package-lock.json b/web3js-ext/package-lock.json index 5796f4e90..c541e0bb2 100644 --- a/web3js-ext/package-lock.json +++ b/web3js-ext/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@klaytn/ethers-ext": "^0.9.3-beta", + "@klaytn/js-ext-core": "^0.9.6-beta", "@klaytn/web3rpc": "^0.9.0", "ethereum-cryptography": "^2.1.2", "lodash": "^4.17.21" @@ -89,12 +90,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "peer": true, "dependencies": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" }, "engines": { @@ -141,12 +142,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", "peer": true, "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.3", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -172,22 +173,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "peer": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -270,9 +271,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "peer": true, "engines": { "node": ">=6.9.0" @@ -302,12 +303,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "peer": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -316,9 +317,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", - "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", + "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", "peer": true, "bin": { "parser": "bin/babel-parser.js" @@ -328,33 +329,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "peer": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", "peer": true, "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.11", - "@babel/types": "^7.22.11", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -363,13 +364,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", + "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -570,7 +571,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/bytes": "^5.7.0", @@ -632,7 +632,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0", @@ -653,7 +652,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/logger": "^5.7.0" } @@ -672,7 +670,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0" } @@ -807,7 +804,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "js-sha3": "0.8.0" @@ -826,8 +822,7 @@ "type": "individual", "url": "https://www.buymeacoffee.com/ricmoo" } - ], - "peer": true + ] }, "node_modules/@ethersproject/networks": { "version": "5.7.1", @@ -882,7 +877,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/logger": "^5.7.0" } @@ -980,7 +974,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0" @@ -1021,7 +1014,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/logger": "^5.7.0", @@ -1090,7 +1082,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", @@ -1117,7 +1108,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/constants": "^5.7.0", @@ -1293,6 +1283,21 @@ "ethers": "^5.7.2" } }, + "node_modules/@klaytn/js-ext-core": { + "version": "0.9.6-beta", + "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.6-beta.tgz", + "integrity": "sha512-t4rYzZ0SOOqFoyhkvgYPG16Yb54zzsa/3IrIfrm40OMWwaVuCdje6rUoPAcQryoGviBZel8B04o/2l17Bm4c0Q==", + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/units": "^5.7.0", + "elliptic": "^6.5.4", + "lodash": "^4.17.21" + } + }, "node_modules/@klaytn/web3rpc": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@klaytn/web3rpc/-/web3rpc-0.9.0.tgz", @@ -2042,8 +2047,7 @@ "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "peer": true + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -2069,8 +2073,7 @@ "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "peer": true + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -2462,7 +2465,6 @@ "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "peer": true, "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -2476,8 +2478,7 @@ "node_modules/elliptic/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "peer": true + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -3224,9 +3225,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -3444,7 +3445,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "peer": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -3463,7 +3463,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "peer": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -3859,8 +3858,7 @@ "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "peer": true + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -4163,14 +4161,12 @@ "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "peer": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "peer": true + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" }, "node_modules/minimatch": { "version": "3.1.2", @@ -5949,9 +5945,9 @@ } }, "node_modules/zod": { - "version": "3.22.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", - "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==", + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/web3js-ext/package.json b/web3js-ext/package.json index 37053788e..cd0929a69 100644 --- a/web3js-ext/package.json +++ b/web3js-ext/package.json @@ -35,8 +35,9 @@ }, "dependencies": { "@klaytn/ethers-ext": "^0.9.3-beta", + "@klaytn/js-ext-core": "^0.9.6-beta", "@klaytn/web3rpc": "^0.9.0", "ethereum-cryptography": "^2.1.2", "lodash": "^4.17.21" } -} \ No newline at end of file +} From 547deb888a5ee90c9b17e7a801067db477291640 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 16:32:13 +0900 Subject: [PATCH 26/69] web3js: Bump tsconfig --- web3js-ext/tsconfig.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web3js-ext/tsconfig.json b/web3js-ext/tsconfig.json index f89fdc9d4..e31a2b94d 100644 --- a/web3js-ext/tsconfig.json +++ b/web3js-ext/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { "target": "ES2017", - "module": "commonjs", + "module": "nodenext", + "moduleResolution": "nodenext", "declaration": true, "declarationMap": true, "sourceMap": true, @@ -11,5 +12,5 @@ "esModuleInterop": true }, "exclude": ["dist", "example", "node_modules"], - "include": ["./test", "./src"] + "include": ["./src"] } From b56b4f61cc9c64f1c52f92bc03a4629b38b8afa1 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 17:44:21 +0900 Subject: [PATCH 27/69] jscore: Remove unused deps --- js-ext-core/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/js-ext-core/package.json b/js-ext-core/package.json index eef7f80fd..2b9072090 100644 --- a/js-ext-core/package.json +++ b/js-ext-core/package.json @@ -50,7 +50,6 @@ "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ethersproject/units": "^5.7.0", - "build": "^0.1.4", "elliptic": "^6.5.4", "lodash": "^4.17.21" } From 96f0d029818db4a69f3f48cf940e0dc9b81d7a5a Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Mon, 20 Nov 2023 17:44:27 +0900 Subject: [PATCH 28/69] ethers: Remove unused deps --- ethers-ext/package-lock.json | 230 +++++++++++++++++++++++++---------- ethers-ext/package.json | 8 +- 2 files changed, 165 insertions(+), 73 deletions(-) diff --git a/ethers-ext/package-lock.json b/ethers-ext/package-lock.json index c5cc998a1..78e8a19d8 100644 --- a/ethers-ext/package-lock.json +++ b/ethers-ext/package-lock.json @@ -11,20 +11,14 @@ "dependencies": { "@klaytn/js-ext-core": "^0.9.7-beta", "@klaytn/web3rpc": "^0.9.7", - "bn.js": "^5.2.1", - "eth-lib": "^0.1.29", - "lodash": "^4.17.21", - "uuid": "^9.0.1" + "lodash": "^4.17.21" }, "devDependencies": { "@klaytn/ethers-ext": "^0.9.7-beta", - "@types/aes-js": "^3.1.1", - "@types/bn.js": "^5.1.1", "@types/chai": "^4.3.4", "@types/chai-as-promised": "^7.1.5", "@types/lodash": "^4.14.192", "@types/mocha": "^10.0.4", - "@types/uuid": "^9.0.3", "@typescript-eslint/eslint-plugin": "^6.1.0", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", @@ -1529,21 +1523,6 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, - "node_modules/@types/aes-js": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/aes-js/-/aes-js-3.1.3.tgz", - "integrity": "sha512-VqCfy688tI0TTIhJyd785KJqgfE1J+8bfXrzi+mV+jBPyEv5iqUkj6gLgvjJdX5EuJwtYvZ4elsF4b+fJjw8MQ==", - "dev": true - }, - "node_modules/@types/bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", @@ -1587,7 +1566,8 @@ "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@types/semver": { "version": "7.5.0", @@ -1600,12 +1580,6 @@ "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" }, - "node_modules/@types/uuid": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz", - "integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==", - "dev": true - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz", @@ -1900,6 +1874,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -1948,6 +1923,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2033,7 +2009,8 @@ "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true }, "node_modules/array-includes": { "version": "3.1.6", @@ -2123,6 +2100,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -2131,6 +2109,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, "engines": { "node": ">=0.8" } @@ -2152,7 +2131,8 @@ "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true }, "node_modules/asynckit": { "version": "0.4.0", @@ -2175,6 +2155,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, "engines": { "node": "*" } @@ -2182,7 +2163,8 @@ "node_modules/aws4": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true }, "node_modules/balanced-match": { "version": "1.0.2", @@ -2193,6 +2175,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -2221,6 +2204,7 @@ "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -2244,6 +2228,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { "ms": "2.0.0" } @@ -2251,12 +2236,14 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/body-parser/node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -2334,7 +2321,8 @@ "node_modules/buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "dev": true }, "node_modules/build": { "version": "0.1.4", @@ -2360,6 +2348,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -2420,7 +2409,8 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true }, "node_modules/chai": { "version": "4.3.7", @@ -2617,6 +2607,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, "dependencies": { "safe-buffer": "5.2.1" }, @@ -2628,6 +2619,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -2641,6 +2633,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -2648,7 +2641,8 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true }, "node_modules/cookiejar": { "version": "2.1.4", @@ -2658,12 +2652,14 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, "dependencies": { "object-assign": "^4", "vary": "^1" @@ -2704,6 +2700,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -2748,6 +2745,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, "engines": { "node": ">=0.10" } @@ -2756,6 +2754,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, "dependencies": { "mimic-response": "^1.0.0" }, @@ -2809,6 +2808,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -2817,6 +2817,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -2858,12 +2859,14 @@ "node_modules/dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -2872,7 +2875,8 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true }, "node_modules/electron-to-chromium": { "version": "1.4.468", @@ -2914,6 +2918,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -3022,7 +3027,8 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -3348,6 +3354,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -3356,6 +3363,7 @@ "version": "0.1.29", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, "dependencies": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -3368,17 +3376,20 @@ "node_modules/eth-lib/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, "node_modules/eth-lib/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/eth-lib/node_modules/ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, "dependencies": { "async-limiter": "~1.0.0", "safe-buffer": "~5.1.0", @@ -3437,6 +3448,7 @@ "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -3478,6 +3490,7 @@ "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -3501,6 +3514,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { "ms": "2.0.0" } @@ -3508,12 +3522,14 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/express/node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -3528,6 +3544,7 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -3541,12 +3558,14 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, "engines": [ "node >=0.6.0" ] @@ -3554,7 +3573,8 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-glob": { "version": "3.3.1", @@ -3575,7 +3595,8 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -3630,6 +3651,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -3647,6 +3669,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { "ms": "2.0.0" } @@ -3654,7 +3677,8 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/find-up": { "version": "5.0.0", @@ -3718,6 +3742,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, "engines": { "node": "*" } @@ -3748,6 +3773,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -3756,6 +3782,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -3877,6 +3904,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -3936,6 +3964,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, "dependencies": { "min-document": "^2.19.0", "process": "^0.11.10" @@ -4016,6 +4045,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, "engines": { "node": ">=4" } @@ -4025,6 +4055,7 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", + "dev": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -4143,6 +4174,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -4158,6 +4190,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -4172,6 +4205,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -4245,6 +4279,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, "engines": { "node": ">= 0.10" } @@ -4368,7 +4403,8 @@ "node_modules/is-function": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true }, "node_modules/is-glob": { "version": "4.0.3", @@ -4523,7 +4559,8 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", @@ -4564,7 +4601,8 @@ "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true }, "node_modules/js-sha3": { "version": "0.8.0", @@ -4592,7 +4630,8 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true }, "node_modules/jsesc": { "version": "2.5.2", @@ -4620,12 +4659,14 @@ "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -4636,7 +4677,8 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true }, "node_modules/json5": { "version": "2.2.3", @@ -4654,6 +4696,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -4818,6 +4861,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -4825,7 +4869,8 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", @@ -4891,6 +4936,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, "engines": { "node": ">=4" } @@ -4899,6 +4945,7 @@ "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dev": true, "dependencies": { "dom-walk": "^0.1.0" } @@ -4999,7 +5046,8 @@ "node_modules/nano-json-stream-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==" + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.3", @@ -5029,6 +5077,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -5052,6 +5101,7 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, "engines": { "node": "*" } @@ -5060,6 +5110,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -5120,6 +5171,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, "dependencies": { "ee-first": "1.1.1" }, @@ -5205,12 +5257,14 @@ "node_modules/parse-headers": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", + "dev": true }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -5250,7 +5304,8 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", @@ -5273,7 +5328,8 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true }, "node_modules/picocolors": { "version": "1.0.0", @@ -5314,6 +5370,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, "engines": { "node": ">= 0.6.0" } @@ -5327,6 +5384,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -5338,12 +5396,14 @@ "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, "engines": { "node": ">=6" } @@ -5366,6 +5426,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, "dependencies": { "decode-uri-component": "^0.2.0", "object-assign": "^4.1.0", @@ -5408,6 +5469,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -5416,6 +5478,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -5473,6 +5536,7 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -5503,6 +5567,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -5516,6 +5581,7 @@ "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, "engines": { "node": ">=0.6" } @@ -5525,6 +5591,7 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, "bin": { "uuid": "bin/uuid" } @@ -5674,7 +5741,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "node_modules/scrypt-js": { "version": "3.0.1", @@ -5694,6 +5762,7 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -5717,6 +5786,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { "ms": "2.0.0" } @@ -5724,12 +5794,14 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, "bin": { "mime": "cli.js" }, @@ -5750,6 +5822,7 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -5764,6 +5837,7 @@ "version": "0.1.12", "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, "dependencies": { "body-parser": "^1.16.0", "cors": "^2.8.1", @@ -5778,7 +5852,8 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true }, "node_modules/shebang-command": { "version": "2.0.0", @@ -5818,6 +5893,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, "funding": [ { "type": "github", @@ -5837,6 +5913,7 @@ "version": "2.8.2", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, "dependencies": { "decompress-response": "^3.3.0", "once": "^1.3.1", @@ -5863,6 +5940,7 @@ "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -5895,6 +5973,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -5903,6 +5982,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6101,6 +6181,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6143,6 +6224,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, "engines": { "node": ">=0.6" } @@ -6151,6 +6233,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -6250,6 +6333,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -6260,7 +6344,8 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true }, "node_modules/type-check": { "version": "0.4.0", @@ -6299,6 +6384,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -6396,7 +6482,8 @@ "node_modules/ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true }, "node_modules/unbox-primitive": { "version": "1.0.2", @@ -6417,6 +6504,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -6455,6 +6543,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -6462,7 +6551,8 @@ "node_modules/url-set-query": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==" + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", + "dev": true }, "node_modules/util-deprecate": { "version": "1.0.2", @@ -6473,6 +6563,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, "engines": { "node": ">= 0.4.0" } @@ -6481,6 +6572,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -6499,6 +6591,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, "engines": { "node": ">= 0.8" } @@ -6507,6 +6600,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, "engines": [ "node >=0.6.0" ], @@ -6670,6 +6764,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dev": true, "dependencies": { "global": "~4.4.0", "is-function": "^1.0.1", @@ -6681,6 +6776,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, "dependencies": { "buffer-to-arraybuffer": "^0.0.5", "object-assign": "^4.1.1", @@ -6695,6 +6791,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, "dependencies": { "xhr-request": "^1.1.0" } @@ -6703,6 +6800,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, "engines": { "node": ">=0.4" } diff --git a/ethers-ext/package.json b/ethers-ext/package.json index b95069a20..96478cd0f 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -22,13 +22,10 @@ }, "devDependencies": { "@klaytn/ethers-ext": "^0.9.7-beta", - "@types/aes-js": "^3.1.1", - "@types/bn.js": "^5.1.1", "@types/chai": "^4.3.4", "@types/chai-as-promised": "^7.1.5", "@types/lodash": "^4.14.192", "@types/mocha": "^10.0.4", - "@types/uuid": "^9.0.3", "@typescript-eslint/eslint-plugin": "^6.1.0", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", @@ -41,9 +38,6 @@ "dependencies": { "@klaytn/js-ext-core": "^0.9.7-beta", "@klaytn/web3rpc": "^0.9.7", - "bn.js": "^5.2.1", - "eth-lib": "^0.1.29", - "lodash": "^4.17.21", - "uuid": "^9.0.1" + "lodash": "^4.17.21" } } From 7f6337139c7f72279f5a78184d49c1ac22e377ad Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Thu, 23 Nov 2023 19:46:13 +0900 Subject: [PATCH 29/69] Import path for js-ext-core --- web3js-ext/src/web3/account.ts | 11 ++++------- web3js-ext/src/web3/klaytn_tx.ts | 2 +- web3js-ext/src/web3/send_transaction.ts | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/web3js-ext/src/web3/account.ts b/web3js-ext/src/web3/account.ts index c42bb47b6..98edb05c4 100644 --- a/web3js-ext/src/web3/account.ts +++ b/web3js-ext/src/web3/account.ts @@ -21,10 +21,7 @@ import { TransactionSigningError, UndefinedRawTransactionError } from 'web3-erro import { prepareTransaction } from "./klaytn_tx"; -// TODO: Change the path after web3-core deployed -const { objectFromRLP } = require("../../../../ethers-ext/dist/src"); - -import { KlaytnTxFactory} from "@klaytn/ethers-ext"; +import { KlaytnTxFactory } from "@klaytn/js-ext-core"; export const signTransactionAsFeePayer = async ( transaction: TypedTransaction, @@ -79,7 +76,7 @@ export const recoverTransactionWithKlaytnTx = (rawTransaction: HexString): Addre let tx; if ( KlaytnTxFactory.has(data[0]) ) { - tx = objectFromRLP(rawTransaction); + tx = KlaytnTxFactory.fromRLP(rawTransaction).toObject(); if ( !tx.from ) { throw new Error('tx.from is not a property.'); @@ -102,7 +99,7 @@ export const initAccountsForContext = (context: Web3Context) => if (typeof transaction === "string") { if (isHex(transaction)) { - tx = objectFromRLP(transaction); + tx = KlaytnTxFactory.fromRLP(transaction).toObject(); } else { throw new Error("String type input has to be RLP encoded Hex string."); } @@ -121,7 +118,7 @@ export const initAccountsForContext = (context: Web3Context) => if (typeof transaction === "string") { if (isHex(transaction)) { - tx = objectFromRLP(transaction); + tx = KlaytnTxFactory.fromRLP(transaction).toObject(); } else { throw new Error("String type input has to be RLP encoded Hex string."); } diff --git a/web3js-ext/src/web3/klaytn_tx.ts b/web3js-ext/src/web3/klaytn_tx.ts index e8455d7ca..7286dc77a 100644 --- a/web3js-ext/src/web3/klaytn_tx.ts +++ b/web3js-ext/src/web3/klaytn_tx.ts @@ -11,7 +11,7 @@ import * as ethereumCryptography from 'ethereum-cryptography/secp256k1.js'; export const secp256k1 = ethereumCryptography.secp256k1 ?? ethereumCryptography; -import { KlaytnTxFactory, TxType } from "@klaytn/ethers-ext"; +import { KlaytnTxFactory, TxType } from "@klaytn/js-ext-core"; export interface KlaytnTxData extends TxData { from?: string, chainId?: bigint, diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index a2143419e..35f9c1650 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -22,7 +22,7 @@ import { import { isAbiErrorFragment, decodeContractErrorData } from "web3-eth-abi"; import _ from "lodash"; -import { KlaytnTxFactory } from "@klaytn/ethers-ext"; +import { KlaytnTxFactory } from "@klaytn/js-ext-core"; import { saveCustomFields } from "./klaytn_tx"; From d6593f45a9feecbdf19231701525e531a2c09e83 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 24 Nov 2023 11:29:41 +0900 Subject: [PATCH 30/69] Format like encodeTxForRPC --- web3js-ext/src/web3/send_transaction.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index 35f9c1650..f0d69626f 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -22,7 +22,7 @@ import { import { isAbiErrorFragment, decodeContractErrorData } from "web3-eth-abi"; import _ from "lodash"; -import { KlaytnTxFactory } from "@klaytn/js-ext-core"; +import { KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; import { saveCustomFields } from "./klaytn_tx"; @@ -54,16 +54,8 @@ export function klay_sendSignedTransaction< } // Parse the signed KlaytnTx - // TODO: make something like encodeTxForRPC const unSerializedTransaction = KlaytnTxFactory.fromRLP(signedTransactionFormattedHex).toObject(); - const unSerializedTransactionForCall = _.clone(unSerializedTransaction); - saveCustomFields(unSerializedTransactionForCall); - if (unSerializedTransactionForCall.value == "0x") { - unSerializedTransactionForCall.value = "0x0"; - } - if (unSerializedTransactionForCall.nonce == "0x") { - unSerializedTransactionForCall.nonce = "0x0"; - } + const unSerializedTransactionForCall = getRpcTxObject(unSerializedTransaction); // Because modifying the rpc name to "klay_sendRawTransaction" is not trivial, // we resort to reimplement the whole logic. From a4752c8eaad184a3c195804c11b5c2c519f13821 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 24 Nov 2023 15:49:51 +0900 Subject: [PATCH 31/69] Delete old API --- web3js-ext/src/web3/klaytn_tx.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web3js-ext/src/web3/klaytn_tx.ts b/web3js-ext/src/web3/klaytn_tx.ts index 7286dc77a..01d081f0e 100644 --- a/web3js-ext/src/web3/klaytn_tx.ts +++ b/web3js-ext/src/web3/klaytn_tx.ts @@ -11,7 +11,7 @@ import * as ethereumCryptography from 'ethereum-cryptography/secp256k1.js'; export const secp256k1 = ethereumCryptography.secp256k1 ?? ethereumCryptography; -import { KlaytnTxFactory, TxType } from "@klaytn/js-ext-core"; +import { KlaytnTxFactory, TxType, isFeePayerSigTxType } from "@klaytn/js-ext-core"; export interface KlaytnTxData extends TxData { from?: string, chainId?: bigint, @@ -284,7 +284,7 @@ export class KlaytnTx extends LegacyTransaction { let tx = this.klaytnTxData; - if (tx.hasFeePayer()) { + if (isFeePayerSigTxType(tx.type)) { return hexToBytes(tx.senderTxHashRLP()); } return hexToBytes(tx.txHashRLP()); From 06c06bd1788f300650a75be0703469f0963cf929 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 24 Nov 2023 15:52:29 +0900 Subject: [PATCH 32/69] Export js-ext-core-util --- .../transactions/Basic_08_TxTypeValueTransfer.js | 11 ++++------- web3js-ext/src/web3/index.ts | 2 ++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index 568fab42f..e9539ba01 100644 --- a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -1,12 +1,9 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, parseKlay } = require("@klaytn/ethers-ext"); - -// // TxTypeValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType } = require( "@klaytn/web3js-ext"); + const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/src/web3/index.ts b/web3js-ext/src/web3/index.ts index 65cd9dd96..27693aa44 100644 --- a/web3js-ext/src/web3/index.ts +++ b/web3js-ext/src/web3/index.ts @@ -1,2 +1,4 @@ +export * from "@klaytn/js-ext-core/util"; + export { KlaytnWeb3 } from "./web3"; export { KlaytnTx } from "./klaytn_tx"; \ No newline at end of file From 04672850f93576ce521d5bf7221bb7ace5a24b82 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 24 Nov 2023 16:47:35 +0900 Subject: [PATCH 33/69] Test utility function for unit converting --- .../example/transactions/Basic_08_TxTypeValueTransfer.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index e9539ba01..331dc81ab 100644 --- a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType } = require( "@klaytn/web3js-ext"); +const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; @@ -17,8 +17,7 @@ async function main() { let tx = { type: TxType.ValueTransfer, to: recieverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb("0.01"), from: senderAddr, gas: 21000, gasPrice: 25e9, From 222356b32b890421af1603c805a68ee1e21e2427 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Fri, 24 Nov 2023 17:28:46 +0900 Subject: [PATCH 34/69] Update module path --- ethers-ext/example/accountKey/AccountKeyPublic.js | 3 +-- ethers-ext/example/accountKey/AccountKeyRoleBased.js | 3 +-- ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js | 3 +-- .../example/transactions/Basic_08_TxTypeValueTransfer.js | 3 +-- .../example/transactions/Basic_10_TxTypeValueTransferMemo.js | 3 +-- .../example/transactions/Basic_20_TxTypeAccountUpdate.js | 3 +-- .../example/transactions/Basic_28_TxTypeSmartContractDeploy.js | 3 +-- .../transactions/Basic_30_TxTypeSmartContractExecution.js | 3 +-- ethers-ext/example/transactions/Basic_38_TxTypeCancel.js | 3 +-- .../transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js | 3 +-- .../transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js | 3 +-- .../FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js | 3 +-- .../transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js | 3 +-- .../FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js | 3 +-- .../FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js | 3 +-- .../example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js | 3 +-- ...artialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js | 3 +-- ...alFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js | 3 +-- ...artialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js | 3 +-- ...FeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js | 3 +-- ...Del_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js | 3 +-- .../PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js | 3 +-- 22 files changed, 22 insertions(+), 44 deletions(-) diff --git a/ethers-ext/example/accountKey/AccountKeyPublic.js b/ethers-ext/example/accountKey/AccountKeyPublic.js index f2c4d7d64..d4ef5fd9c 100644 --- a/ethers-ext/example/accountKey/AccountKeyPublic.js +++ b/ethers-ext/example/accountKey/AccountKeyPublic.js @@ -1,8 +1,7 @@ // AccountKeyPublic // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); -const { Wallet } = require("@klaytn/ethers-ext"); +const { Wallet, TxType, AccountKeyType, parseKlay } = require("@klaytn/ethers-ext"); const { ethers } = require("ethers"); const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; diff --git a/ethers-ext/example/accountKey/AccountKeyRoleBased.js b/ethers-ext/example/accountKey/AccountKeyRoleBased.js index 0c306208d..4193b1d9c 100644 --- a/ethers-ext/example/accountKey/AccountKeyRoleBased.js +++ b/ethers-ext/example/accountKey/AccountKeyRoleBased.js @@ -1,8 +1,7 @@ // AccountKeyRoleBased // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, AccountKeyType, parseKlay } = require("@klaytn/ethers-ext"); const { ethers } = require("ethers"); const senderAddr = "0x5bd2fb3c21564c023a4a735935a2b7a238c4ccea"; diff --git a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js index 8d12cb772..da2d90537 100644 --- a/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js +++ b/ethers-ext/example/accountKey/AccountKeyWeightedMultiSig.js @@ -1,8 +1,7 @@ // AccountKeyWeightedMultiSig // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, AccountKeyType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, AccountKeyType, parseKlay } = require("@klaytn/ethers-ext"); const { ethers } = require("ethers"); const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e"; diff --git a/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index 3bdf74117..9def9d7a4 100644 --- a/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/ethers-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -1,8 +1,7 @@ // TxTypeValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; diff --git a/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js b/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js index 495f5c6f0..6a9d744d3 100644 --- a/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js +++ b/ethers-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js @@ -1,8 +1,7 @@ // TxTypeValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfermemo -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; diff --git a/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js b/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js index f3bf78477..86ceae979 100644 --- a/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js +++ b/ethers-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js @@ -4,8 +4,7 @@ // key: Refer Klaytn account key // https://docs.klaytn.foundation/content/klaytn/design/accounts#account-key -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, AccountKeyType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); // create new account for testing in https://baobab.wallet.klaytn.foundation/ diff --git a/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js b/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js index d9edfe32c..9cb9b18c6 100644 --- a/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js +++ b/ethers-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js @@ -7,8 +7,7 @@ // humanReadable: Must be false, // codeFormat: Must be 0x00 -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js b/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js index dc0283c85..b9111d87e 100644 --- a/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js +++ b/ethers-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js @@ -18,8 +18,7 @@ // const param = iface.encodeFunctionData("setNumber", [ "0x123" ]) -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js b/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js index d51aa89b4..ecdb5451e 100644 --- a/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js +++ b/ethers-ext/example/transactions/Basic_38_TxTypeCancel.js @@ -6,8 +6,7 @@ // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js index 6b19f6252..a1b002c85 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js @@ -1,8 +1,7 @@ // TxTypeFeeDelegatedValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js index da4466674..ca0d54de2 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js @@ -1,8 +1,7 @@ // TxTypeFeeDelegatedValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js b/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js index 9232f99f8..479d6aaef 100644 --- a/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js +++ b/ethers-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js @@ -1,8 +1,7 @@ // TxTypeFeeDelegatedValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js b/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js index db9dc92eb..6e6a40072 100644 --- a/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js +++ b/ethers-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js @@ -1,8 +1,7 @@ // TxTypeFeeDelegatedAccountUpdate // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, AccountKeyType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); // create new account for testing in https://baobab.wallet.klaytn.foundation/ diff --git a/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js b/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js index 869ae963d..f67bb9e8c 100644 --- a/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js +++ b/ethers-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js @@ -8,8 +8,7 @@ // codeFormat: Must be 0x00 // -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js b/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js index 3c263d762..9732d4d2a 100644 --- a/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js +++ b/ethers-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js @@ -17,8 +17,7 @@ // const iface = new ethers.utils.Interface( CONTRACT_ABI ); // const param = iface.encodeFunctionData("setNumber", [ "0x123" ]) -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js b/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js index 06898314b..439f6c5f3 100644 --- a/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js +++ b/ethers-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js @@ -6,8 +6,7 @@ // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js index 9d8f6eb8f..6e7d1accc 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js @@ -1,8 +1,7 @@ // TxTypeFeeDelegatedValueTransferWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js index f1368a9a1..618a3c021 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js @@ -3,8 +3,7 @@ // // nonce: In signTransactionAsFeePayer, must not be omitted, because feePayer's nonce is filled when populating -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js index 6f73d79af..989ea8d4a 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js @@ -12,8 +12,7 @@ // You should see the source code for the info (e.g. VTwithMemo intrinsic gas is 21000 + len(memo)*100 ) // https://github.com/klaytn/klaytn/blob/dev/blockchain/types/tx_internal_data_value_transfer_memo.go#L239 -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, AccountKeyType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, AccountKeyType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); // create new account for testing in https://baobab.wallet.klaytn.foundation/ diff --git a/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js index cdac1beec..f071bb715 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js @@ -7,8 +7,7 @@ // humanReadable: Must be false, // codeFormat: Must be 0x00 -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js index 027f1137f..42583bcec 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js @@ -17,8 +17,7 @@ // const iface = new ethers.utils.Interface( CONTRACT_ABI ); // const param = iface.encodeFunctionData("setNumber", [ "0x123" ]) -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType } = require("@klaytn/js-ext-core"); +const { Wallet, TxType } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js b/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js index 51a26c5c8..747f2c155 100644 --- a/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js +++ b/ethers-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js @@ -6,8 +6,7 @@ // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -const { Wallet } = require("@klaytn/ethers-ext"); -const { TxType, parseKlay } = require("@klaytn/js-ext-core"); +const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; From 6bf74ff2793a85df8c06a3b53963c66a8b0b447f Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 12:05:09 +0900 Subject: [PATCH 35/69] Debug type error in toPeb --- js-ext-core/src/util/units.ts | 11 ++++++++--- .../transactions/Basic_08_TxTypeValueTransfer.js | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/js-ext-core/src/util/units.ts b/js-ext-core/src/util/units.ts index 1c83cf51b..d27553a8f 100644 --- a/js-ext-core/src/util/units.ts +++ b/js-ext-core/src/util/units.ts @@ -91,6 +91,11 @@ export function parseKlay(klay: string): BigNumber { export const formatUnits = formatKlayUnits; export const parseUnits = parseKlayUnits; -// Alias to web3js-like names -export const fromPeb = formatKlay; // Equivalent to web3.utils.fromWei -export const toPeb = parseKlay; // Equivalent to web3.utils.toWei + +// Equivalent to web3.utils.fromWei +export const fromPeb = formatKlay; + +// Equivalent to web3.utils.toWei +export function toPeb(value: string, unitName?: string | BigNumberish): string { + return parseKlayUnits(value, unitName).toString(); +} \ No newline at end of file diff --git a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index 331dc81ab..63a5a73f9 100644 --- a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -2,7 +2,8 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); +const { KlaytnWeb3, TxType } = require("../../dist/web3"); +const { toPeb } = require("../../../js-ext-core/dist/util"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; From c42dd6f79b5772c254217b2240c09ca30407260e Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 12:31:25 +0900 Subject: [PATCH 36/69] Resolve package dependency --- js-ext-core/src/util/units.ts | 4 +++- .../Basic_08_TxTypeValueTransfer.js | 3 +-- .../Basic_10_TxTypeValueTransferMemo.js | 13 ++++--------- .../Basic_20_TxTypeAccountUpdate.js | 17 ++++++----------- web3js-ext/src/web3/index.ts | 3 ++- web3js-ext/src/web3/utils.ts | 12 ++++++++++++ 6 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 web3js-ext/src/web3/utils.ts diff --git a/js-ext-core/src/util/units.ts b/js-ext-core/src/util/units.ts index d27553a8f..6c24f81dc 100644 --- a/js-ext-core/src/util/units.ts +++ b/js-ext-core/src/util/units.ts @@ -93,7 +93,9 @@ export const parseUnits = parseKlayUnits; // Equivalent to web3.utils.fromWei -export const fromPeb = formatKlay; +export function fromPeb(number: any, unitName?: string | BigNumberish): string { + return formatKlayUnits(number, unitName); +} // Equivalent to web3.utils.toWei export function toPeb(value: string, unitName?: string | BigNumberish): string { diff --git a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index 63a5a73f9..331dc81ab 100644 --- a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -2,8 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType } = require("../../dist/web3"); -const { toPeb } = require("../../../js-ext-core/dist/util"); +const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js b/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js index 58b330235..f5d4ef348 100644 --- a/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js +++ b/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js @@ -1,12 +1,8 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, parseKlay } = require("@klaytn/ethers-ext"); - -// // TxTypeValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfermemo -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; @@ -21,8 +17,7 @@ async function main() { let tx = { type: TxType.ValueTransferMemo, to: recieverAddr, - value: 1e9, - // value: parseKlay("1"), // TODO: add type conversion function + value: toPeb("0.01"), from: senderAddr, input: "0x1234567890", }; diff --git a/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js b/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js index 945e5758b..14ff3daca 100644 --- a/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js +++ b/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js @@ -1,23 +1,18 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType } = require("@klaytn/ethers-ext"); - -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") - -// // TxTypeAccountUpdate // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypeaccountupdate // // from: address of sender to be updated // key: Refer Klaytn account key // https://docs.klaytn.foundation/content/klaytn/design/accounts#account-key -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require("../../dist/web3"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create new account for testing // https://baobab.wallet.klaytn.foundation/ -const senderAddr = "0x7532967dda17c5e367c7a5c5dcb56ef6ed299e20"; -const senderPriv = "0x4ef44daeb7941877bebc7b97c023e1e51b5593ee1fbc4a232387774603173b86"; +const senderAddr = "0xe15cd70a41dfb05e7214004d7d054801b2a2f06b"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; async function main() { diff --git a/web3js-ext/src/web3/index.ts b/web3js-ext/src/web3/index.ts index 27693aa44..3a5b2a871 100644 --- a/web3js-ext/src/web3/index.ts +++ b/web3js-ext/src/web3/index.ts @@ -1,4 +1,5 @@ export * from "@klaytn/js-ext-core/util"; export { KlaytnWeb3 } from "./web3"; -export { KlaytnTx } from "./klaytn_tx"; \ No newline at end of file +export { KlaytnTx } from "./klaytn_tx"; +export { fromPeb, toPeb } from "./utils"; \ No newline at end of file diff --git a/web3js-ext/src/web3/utils.ts b/web3js-ext/src/web3/utils.ts new file mode 100644 index 000000000..09e546b31 --- /dev/null +++ b/web3js-ext/src/web3/utils.ts @@ -0,0 +1,12 @@ +import { parseKlayUnits, formatKlayUnits } from "@klaytn/js-ext-core"; +import { toWei, fromWei, toBigInt } from "web3-utils"; + +// Equivalent to web3.utils.fromWei +export function fromPeb(number: any, unitName?: string): string { + return formatKlayUnits(number, unitName); +} + +// Equivalent to web3.utils.toWei +export function toPeb(value: string, unitName?: string): string { + return parseKlayUnits(value, unitName).toString(); +} \ No newline at end of file From 439fcb670d1624290c320f3e218f4e538ff5c14d Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 16:34:11 +0900 Subject: [PATCH 37/69] Add rpc exception log --- js-ext-core/src/util/rpc.ts | 13 ++++++++++++- .../Basic_28_TxTypeSmartContractDeploy.js | 11 +++-------- web3js-ext/src/web3/send_transaction.ts | 7 +++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/js-ext-core/src/util/rpc.ts b/js-ext-core/src/util/rpc.ts index 83953f291..d13ca79e4 100644 --- a/js-ext-core/src/util/rpc.ts +++ b/js-ext-core/src/util/rpc.ts @@ -9,11 +9,18 @@ const bytestrFields = ["from", "to", "data", "input"]; // Normalize Tx object to suitable for JSON-RPCs such as eth_call and eth_estimateGas. export function getRpcTxObject(tx: any): any { const formatted: any = {}; + let value : string; _.each(numericFields, (key) => { if (!_.has(tx, key)) { return; } - const value = hexValue(BigNumber.from(tx[key])); + if (tx[key] == "0x"){ + formatted[key] = hexValue("0x"); + } + else { + value = hexValue(BigNumber.from(tx[key])); + } + if (key == "gasLimit") { formatted["gas"] = value; } else { @@ -26,6 +33,10 @@ export function getRpcTxObject(tx: any): any { const value = hexlify(tx[key]); formatted[key] = value; + + if ((key === "to" || key === "from") && tx[key] === "0x") { + formatted[key] = "0x0000000000000000000000000000000000000000"; + } }); if (tx.accessList) { diff --git a/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js b/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js index 3bc647642..6b2195ce1 100644 --- a/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js +++ b/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js @@ -1,10 +1,3 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType } = require("@klaytn/ethers-ext"); - - -// // TxTypeSmartContractDeploy // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypesmartcontractdeploy // @@ -13,7 +6,9 @@ const { TxType } = require("@klaytn/ethers-ext"); // input: SmartContract binary, // humanReadable: Must be false, // codeFormat: Must be 0x00 -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index f0d69626f..4f0b8a40a 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -55,6 +55,13 @@ export function klay_sendSignedTransaction< // Parse the signed KlaytnTx const unSerializedTransaction = KlaytnTxFactory.fromRLP(signedTransactionFormattedHex).toObject(); + console.log(unSerializedTransaction); + + // hot fix + // TODO : the code below will be deleted after deploying same logic in js-ext-core + if (unSerializedTransaction.value == "0x") unSerializedTransaction.value = 0; + if (unSerializedTransaction.to == "0x") unSerializedTransaction.to = "0x0000000000000000000000000000000000000000" + const unSerializedTransactionForCall = getRpcTxObject(unSerializedTransaction); // Because modifying the rpc name to "klay_sendRawTransaction" is not trivial, From c913b0455b954d9053cbc62dbe02f48de436d7d2 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 17:20:39 +0900 Subject: [PATCH 38/69] Test basic transaction types --- .../Basic_30_TxTypeSmartContractExecution.js | 19 ++++++++----------- .../transactions/Basic_38_TxTypeCancel.js | 19 ++++++++----------- web3js-ext/src/web3/send_transaction.ts | 1 - 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js b/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js index 7a83a15dd..118bd4e6e 100644 --- a/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js +++ b/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js @@ -1,20 +1,17 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType } = require("@klaytn/ethers-ext"); - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const contractAddr = "0xD7fA6634bDDe0B2A9d491388e2fdeD0fa25D2067"; - -// // TxTypeSmartContractExecution // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypesmartcontractexecution // // to : deployed contract address // value: Must be 0, if not payable // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); + +const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const contractAddr = "0xD7fA6634bDDe0B2A9d491388e2fdeD0fa25D2067"; + async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); diff --git a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js index 30619087f..d78a1288b 100644 --- a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js +++ b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js @@ -1,13 +1,3 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType } = require("@klaytn/ethers-ext"); - -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - -// // TxTypeCancel // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypecancel // @@ -15,7 +5,14 @@ const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; // 2) send Cancel tx with the next nonce + 1 // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); + +const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; + async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index 4f0b8a40a..2757baf37 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -55,7 +55,6 @@ export function klay_sendSignedTransaction< // Parse the signed KlaytnTx const unSerializedTransaction = KlaytnTxFactory.fromRLP(signedTransactionFormattedHex).toObject(); - console.log(unSerializedTransaction); // hot fix // TODO : the code below will be deleted after deploying same logic in js-ext-core From a8c8644d2f33972c7acc2e32edfaa922e272ee0d Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 17:37:13 +0900 Subject: [PATCH 39/69] Test FeeDelegation types --- ...eDel_09_TxTypeFeeDelegatedValueTransfer.js | 19 +++++-------- ..._11_TxTypeFeeDelegatedValueTransferMemo.js | 27 +++++++------------ web3js-ext/src/web3/index.ts | 4 ++- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js b/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js index b57046e9c..97047baa4 100644 --- a/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js +++ b/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js @@ -1,12 +1,8 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -// // TxTypeFeeDelegatedValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -14,7 +10,6 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -22,11 +17,9 @@ async function main() { let tx = { type: TxType.FeeDelegatedValueTransfer, to: recieverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb("0.01"), from: senderAddr, gas: 300000, - gasPrice: 100e9, }; // sender @@ -34,7 +27,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -42,7 +35,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js index fd767b69e..6697a5f07 100644 --- a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js +++ b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js @@ -1,12 +1,8 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -// // TxTypeFeeDelegatedValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -14,8 +10,6 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -23,12 +17,11 @@ async function main() { let tx = { type: TxType.FeeDelegatedValueTransferMemo, to: recieverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb("0.01"), from: senderAddr, input: "0x1234567890", - gas: 300000, // intrinsic gas too low - gasPrice: 100e9, + gas: 100000000, // intrinsic gas too low + gasPrice: 25e9, }; // sender @@ -36,16 +29,16 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); - // console.log(tx); + tx = parseTransaction(senderTx.rawTransaction); + console.log(tx); // fee payer const feePayer = web3.eth.accounts.privateKeyToAccount(feePayerPriv, provider); let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); - // console.log(tx); + tx = parseTransaction(signResult.rawTransaction); + console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); let txhash = sendResult.transactionHash; diff --git a/web3js-ext/src/web3/index.ts b/web3js-ext/src/web3/index.ts index 3a5b2a871..cc2d66782 100644 --- a/web3js-ext/src/web3/index.ts +++ b/web3js-ext/src/web3/index.ts @@ -1,4 +1,6 @@ -export * from "@klaytn/js-ext-core/util"; +export * from "../../../js-ext-core/dist"; +// export * from "@klaytn/js-ext-core/tx"; +// export * from "@klaytn/js-ext-core/util"; export { KlaytnWeb3 } from "./web3"; export { KlaytnTx } from "./klaytn_tx"; From a1bd374d3ba08c67bda4450eb67c981f8f51656d Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 19:36:05 +0900 Subject: [PATCH 40/69] Test more FeeDelegation types --- ..._11_TxTypeFeeDelegatedValueTransferMemo.js | 10 +- ...eDel_21_TxTypeFeeDelegatedAccountUpdate.js | 27 +- ...9_TxTypeFeeDelegatedSmartContractDeploy.js | 14 +- ...xTypeFeeDelegatedSmartContractExecution.js | 14 +- .../FeeDel_39_TxTypeFeeDelegatedCancel.js | 11 +- web3js-ext/package-lock.json | 319 +++++++++++++++++- web3js-ext/package.json | 2 +- 7 files changed, 341 insertions(+), 56 deletions(-) diff --git a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js index 6697a5f07..d54ee0711 100644 --- a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js +++ b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js @@ -20,7 +20,7 @@ async function main() { value: toPeb("0.01"), from: senderAddr, input: "0x1234567890", - gas: 100000000, // intrinsic gas too low + gas: 250000, // intrinsic gas too low gasPrice: 25e9, }; @@ -29,16 +29,16 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - tx = parseTransaction(senderTx.rawTransaction); - console.log(tx); + // tx = parseTransaction(senderTx.rawTransaction); + // console.log(tx); // fee payer const feePayer = web3.eth.accounts.privateKeyToAccount(feePayerPriv, provider); let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - tx = parseTransaction(signResult.rawTransaction); - console.log(tx); + // tx = parseTransaction(signResult.rawTransaction); + // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); let txhash = sendResult.transactionHash; diff --git a/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js b/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js index f1a824de6..c3d90dab0 100644 --- a/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js +++ b/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js @@ -1,24 +1,17 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") - -// // TxTypeFeeDelegatedAccountUpdate // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate -// -// create new account for testing -// https://baobab.wallet.klaytn.foundation/ -const senderAddr = "0x9b0d00d5ffcc2024f1816feb99522d8c0e519170"; -const senderPriv = "0xc7fd5cceea90867c80193d9cfbd2b8b5dc0f4b794c5dd2413d569e332b0ae4c7"; -const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require("../../dist/web3"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") + +// create new account for testing in https://baobab.wallet.klaytn.foundation/ +const senderAddr = "0x30908464d76604420162a6c880c0e1c7e641bad7"; +const senderPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; +const senderNewPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -40,7 +33,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -48,7 +41,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js b/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js index 033a312ac..0d8708da7 100644 --- a/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js +++ b/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js @@ -1,8 +1,3 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - // TxTypeFeeDelegatedSmartContractDeploy // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractdeploy // @@ -11,14 +6,15 @@ const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); // input: SmartContract binary, // humanReadable: Must be false, // codeFormat: Must be 0x00 -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -40,7 +36,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -48,7 +44,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js b/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js index 01baaaf4e..6798e8fba 100644 --- a/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js +++ b/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js @@ -1,15 +1,12 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - // TxTypeFeeDelegatedSmartContractExecution // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedsmartcontractexecution // // to : deployed contract address // value: Must be 0, if not payable // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -17,7 +14,6 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const contractAddr = "0xD7fA6634bDDe0B2A9d491388e2fdeD0fa25D2067"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -63,7 +59,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -71,7 +67,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js index 8c349a3de..3fa34ec38 100644 --- a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js +++ b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js @@ -1,9 +1,3 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType } = require("@klaytn/ethers-ext"); - -// // TxTypeFeeDelegatedCancel // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedcancel // @@ -11,7 +5,9 @@ const { TxType } = require("@klaytn/ethers-ext"); // 2) send Cancel tx with the next nonce + 1 // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,7 +15,6 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); diff --git a/web3js-ext/package-lock.json b/web3js-ext/package-lock.json index c541e0bb2..922c063f8 100644 --- a/web3js-ext/package-lock.json +++ b/web3js-ext/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@klaytn/ethers-ext": "^0.9.3-beta", - "@klaytn/js-ext-core": "^0.9.6-beta", + "@klaytn/js-ext-core": "^0.9.7-beta", "@klaytn/web3rpc": "^0.9.0", "ethereum-cryptography": "^2.1.2", "lodash": "^4.17.21" @@ -377,6 +377,14 @@ "node": ">=6.9.0" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -399,6 +407,16 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1284,9 +1302,9 @@ } }, "node_modules/@klaytn/js-ext-core": { - "version": "0.9.6-beta", - "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.6-beta.tgz", - "integrity": "sha512-t4rYzZ0SOOqFoyhkvgYPG16Yb54zzsa/3IrIfrm40OMWwaVuCdje6rUoPAcQryoGviBZel8B04o/2l17Bm4c0Q==", + "version": "0.9.7-beta", + "resolved": "https://registry.npmjs.org/@klaytn/js-ext-core/-/js-ext-core-0.9.7-beta.tgz", + "integrity": "sha512-dgoO8zPuPA3LQRdUic9VW2c1UIjRpnP8BbKxEWjmrjmZ6GF0rYCqIu1onV7qvq0O8dDCKg7/bGDC4rpBnhFlxQ==", "dependencies": { "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", @@ -1294,6 +1312,7 @@ "@ethersproject/rlp": "^5.7.0", "@ethersproject/transactions": "^5.7.0", "@ethersproject/units": "^5.7.0", + "build": "^0.1.4", "elliptic": "^6.5.4", "lodash": "^4.17.21" } @@ -1478,6 +1497,11 @@ "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -2008,6 +2032,11 @@ "node": "*" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2113,6 +2142,26 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/build": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", + "integrity": "sha512-KwbDJ/zrsU8KZRRMfoURG14cKIAStUlS8D5jBDvtrZbwO5FEkYqc3oB8HIhRiyD64A48w1lc+sOmQ+mmBw5U/Q==", + "dependencies": { + "cssmin": "0.3.x", + "jsmin": "1.x", + "jxLoader": "*", + "moo-server": "*", + "promised-io": "*", + "timespan": "2.x", + "uglify-js": "1.x", + "walker": "1.x", + "winston": "*", + "wrench": "1.3.x" + }, + "engines": { + "node": ">v0.4.12" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2257,11 +2306,19 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -2269,8 +2326,25 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "peer": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } }, "node_modules/combined-stream": { "version": "1.0.8", @@ -2352,6 +2426,14 @@ "node": ">= 8" } }, + "node_modules/cssmin": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", + "integrity": "sha512-bynxGIAJ8ybrnFobjsQotIjA8HFDDgPwbeUWNXXXfR+B4f9kkxdcUyagJoQCSUOfMV+ZZ6bMn8bvbozlCzUGwQ==", + "bin": { + "cssmin": "bin/cssmin" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2486,6 +2568,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/es-abstract": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", @@ -3051,6 +3138,11 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3120,6 +3212,11 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -3561,6 +3658,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -3766,6 +3868,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -3890,6 +4003,17 @@ "node": ">=4" } }, + "node_modules/jsmin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", + "integrity": "sha512-OPuL5X/bFKgVdMvEIX3hnpx3jbVpFCrEM8pKPXjFkZUqg521r41ijdyTz7vACOhW6o1neVlcLyd+wkbK5fNHRg==", + "bin": { + "jsmin": "bin/jsmin" + }, + "engines": { + "node": ">=0.1.93" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -3920,6 +4044,28 @@ "node": ">=6" } }, + "node_modules/jxLoader": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", + "integrity": "sha512-ClEvAj3K68y8uKhub3RgTmcRPo5DfIWvtxqrKQdDPyZ1UVHIIKvVvjrAsJFSVL5wjv0rt5iH9SMCZ0XRKNzeUA==", + "dependencies": { + "js-yaml": "0.3.x", + "moo-server": "1.3.x", + "promised-io": "*", + "walker": "1.x" + }, + "engines": { + "node": ">v0.4.10" + } + }, + "node_modules/jxLoader/node_modules/js-yaml": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", + "integrity": "sha512-/7PsVDNP2tVe2Z1cF9kTEkjamIwz4aooDpRKmN1+g/9eePCgcxsv4QDvEbxO0EH+gdDD7MLyDoR6BASo3hH51g==", + "engines": { + "node": "> 0.4.11" + } + }, "node_modules/keyv": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", @@ -3929,6 +4075,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4054,6 +4205,22 @@ "node": ">=8" } }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", @@ -4098,6 +4265,14 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4323,6 +4498,14 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/moo-server": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", + "integrity": "sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==", + "engines": { + "node": ">v0.4.10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4470,6 +4653,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -4614,6 +4805,11 @@ "node": ">= 0.8.0" } }, + "node_modules/promised-io": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.6.tgz", + "integrity": "sha512-bNwZusuNIW4m0SPR8jooSyndD35ggirHlxVl/UhIaZD/F0OBv9ebfc6tNmbpZts3QXHggkjIBH8lvtnzhtcz0A==" + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -4842,6 +5038,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", @@ -4905,6 +5109,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -4913,6 +5125,14 @@ "node": ">=6" } }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -5089,12 +5309,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha512-0Jq9+58T2wbOyLth0EU+AUb6JMGCLaTWIykJFa7hyAybjVH9gpVMTfUAwo5fWAvtFt2Tjh/Elg8JtgNpnMnM8g==", + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -5122,6 +5360,14 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "peer": true }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", @@ -5321,6 +5567,14 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", + "integrity": "sha512-YPX1DjKtom8l9XslmPFQnqWzTBkvI4N0pbkzLuPZZ4QTyig0uQqvZz9NgUdfEV+qccJzi7fVcGWdESvRIjWptQ==", + "bin": { + "uglifyjs": "bin/uglifyjs" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -5399,6 +5653,14 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/web3": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/web3/-/web3-4.1.1.tgz", @@ -5784,6 +6046,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/winston": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", + "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", + "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -5845,6 +6141,15 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/wrench": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", + "integrity": "sha512-srTJQmLTP5YtW+F5zDuqjMEZqLLr/eJOZfDI5ibfPfRMeDh3oBUefAscuH0q5wBKE339ptH/S/0D18ZkfOfmKQ==", + "deprecated": "wrench.js is deprecated! You should check out fs-extra (https://github.com/jprichardson/node-fs-extra) for any operations you were using wrench for. Thanks for all the usage over the years.", + "engines": { + "node": ">=0.1.97" + } + }, "node_modules/ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", diff --git a/web3js-ext/package.json b/web3js-ext/package.json index cd0929a69..ec35df809 100644 --- a/web3js-ext/package.json +++ b/web3js-ext/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@klaytn/ethers-ext": "^0.9.3-beta", - "@klaytn/js-ext-core": "^0.9.6-beta", + "@klaytn/js-ext-core": "^0.9.7-beta", "@klaytn/web3rpc": "^0.9.0", "ethereum-cryptography": "^2.1.2", "lodash": "^4.17.21" From 3657c6cb004b60a2a51214adae7f7ef19a6b9a16 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 19:49:12 +0900 Subject: [PATCH 41/69] Test partial FeeDelegation types --- ...a_TxTypeFeeDelegatedValueTransferWithRatio.js | 14 ++++---------- ...TypeFeeDelegatedValueTransferMemoWithRatio.js | 12 ++++-------- ...2_TxTypeFeeDelegatedAccountUpdateWithRatio.js | 16 ++++++---------- ...peFeeDelegatedSmartContractDeployWithRatio.js | 10 +++------- ...eeDelegatedSmartContractExecutionWithRatio.js | 8 +++----- ...eeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js | 6 +----- 6 files changed, 21 insertions(+), 45 deletions(-) diff --git a/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js index e760da7c2..511f9e6d0 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js @@ -1,12 +1,8 @@ -// // TxTypeFeeDelegatedValueTransferWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio -// const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -14,7 +10,6 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -22,8 +17,7 @@ async function main() { let tx = { type: TxType.FeeDelegatedValueTransferWithRatio, to: recieverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb("0.01"), from: senderAddr, gas: 300000, gasPrice: 100e9, @@ -35,7 +29,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -43,7 +37,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js index 30af9db82..f7a691f9a 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js @@ -3,12 +3,9 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransfermemowithratio // // nonce: In signTransactionAsFeePayer, must not be omitted, because feePayer's nonce is filled when populating -// const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -24,8 +21,7 @@ async function main() { let tx = { type: TxType.FeeDelegatedValueTransferMemoWithRatio, to: recieverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb("0.01"), from: senderAddr, input: "0x1234567890", gas: 300000, @@ -38,7 +34,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -46,7 +42,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js index 2abf1f1df..e8c975f34 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js @@ -12,23 +12,19 @@ // Learn how Klaytn Tx intrinsic gas are calculated - which is unlikely because there's no documentation for it. // You should see the source code for the info (e.g. VTwithMemo intrinsic gas is 21000 + len(memo)*100 ) // https://github.com/klaytn/klaytn/blob/dev/blockchain/types/tx_internal_data_value_transfer_memo.go#L239 -// const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); +const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require( "../../dist/web3"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") - // create new account for testing // https://baobab.wallet.klaytn.foundation/ -const senderAddr = "0xd34c89278e763b8ea7663db2df199984d6b3ae55"; -const senderPriv = "0xdde24aa1236ff2304171c46376f6b6b4d82c9aa97a4406c4be9c95014a02b9ee"; -const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; +const senderAddr = "0x30908464d76604420162a6c880c0e1c7e641bad7"; +const senderPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; +const senderNewPriv = "0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -53,7 +49,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -61,7 +57,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js index b012d78e5..126a88065 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js @@ -6,19 +6,15 @@ // input: SmartContract binary, // humanReadable: Must be false, // codeFormat: Must be 0x00 -// const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - +const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); @@ -41,7 +37,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -49,7 +45,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js index 1876b09f7..eb6d2a9e1 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js @@ -7,9 +7,7 @@ // const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); -const { TxType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - +const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -63,7 +61,7 @@ async function main() { let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log(senderTx); - // tx = objectFromRLP(senderTx.rawTransaction); + // tx = parseTransaction(senderTx.rawTransaction); // console.log(tx); // fee payer @@ -71,7 +69,7 @@ async function main() { let signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log(signResult); - // tx = objectFromRLP(signResult.rawTransaction); + // tx = parseTransaction(signResult.rawTransaction); // console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js index b54e30473..df00b6066 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js @@ -6,12 +6,9 @@ // 2) send Cancel tx with the next nonce + 1 // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -// const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); -const { TxType } = require("@klaytn/ethers-ext"); - +const { KlaytnWeb3, TxType } = require( "../../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,7 +16,6 @@ const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; - async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); From 66550324e739b200e4bafacfb7d804fc9b707fde Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Mon, 27 Nov 2023 21:50:19 +0900 Subject: [PATCH 42/69] Test AccountKey types --- .../AccountKeyLegacy_01_ValueTransfer.js | 17 ++++------- .../AccountKeyPublic_01_accountUpdate.js | 16 ++++------ .../AccountKeyPublic_02_valueTransfer.js | 13 +++----- .../AccountKeyRoleBased_01_accountUpdate.js | 17 ++++------- .../AccountKeyRoleBased_02_valueTransfer.js | 14 +++------ ...untKeyWeightedMultiSig_01_accountUpdate.js | 30 +++++++------------ ...untKeyWeightedMultiSig_02_valueTransfer.js | 24 +++++++-------- 7 files changed, 46 insertions(+), 85 deletions(-) diff --git a/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js b/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js index 9aa4a6882..5335742ea 100644 --- a/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js @@ -1,15 +1,11 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -// // AccountKeyPublic Step 01 - value transfer // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy -// -const senderAddr = "0xfb60ded0ae96fe04eed6450aead860aa9d57128e"; -const senderPriv = "0x59f9dd78ae367feb962874345d95f7a0642920059453e74cd707bf1f4fc59e01"; +const { Web3 } = require("web3"); +const { KlaytnWeb3, toPeb } = require( "../../dist/web3"); + +const senderAddr = "0x24e8efd18d65bcb6b3ba15a4698c0b0d69d13ff7"; +const senderPriv = "0x4a72b3d09c3d5e28e8652e0111f9c4ce252e8299aad95bb219a38eb0a3f4da49"; const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; async function main() { @@ -18,8 +14,7 @@ async function main() { let tx = { to: receiverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb('0.01', 'KLAY'), from: senderAddr, }; diff --git a/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js index 8052c42a8..bd1f920bc 100644 --- a/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js @@ -1,20 +1,14 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") - -// // AccountKeyPublic Step 01 - account update // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require( "../../dist/web3"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing // https://baobab.wallet.klaytn.foundation/ - const senderAddr = "0xfb60ded0ae96fe04eed6450aead860aa9d57128e"; -const senderPriv = "0x59f9dd78ae367feb962874345d95f7a0642920059453e74cd707bf1f4fc59e01"; +const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const senderNewPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; async function main() { diff --git a/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js index f047908d9..c971d9e58 100644 --- a/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js @@ -1,12 +1,8 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -// // AccountKeyPublic Step 02 - value transfer // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb } = require( "../../dist/web3"); // the same address of sender in AccountKeyPublic_01_accountUpdate.js const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; @@ -20,8 +16,7 @@ async function main() { let tx = { type: TxType.ValueTransfer, to: receiverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb('0.01', 'KLAY'), from: senderAddr, }; diff --git a/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js index 3a93bedda..ece92b6db 100644 --- a/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js @@ -1,21 +1,16 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") - -// // AccountKeyRoleBased Step 01 - account update // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased // // gasLimit: Must be large enough -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require( "../../dist/web3"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") + // create a new account for testing // https://baobab.wallet.klaytn.foundation/ -// const senderAddr = "0x334b4d3c775c45c59de54e9f0408cba25a1aece7"; -const senderPriv = "0x3e1a2e2adf17eeee71a65bb112f0a4685bdf2bb24dc01c0927de0cc40506253d"; +const senderPriv = "0x9ba8cb8f60044058a9e6f815c5c42d3a216f47044c61a1750b6d29ddc7f34bda"; const senderRoleTransactionPriv = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; const senderRoleAccountUpdatePriv = "0x9ba8cb8f60044058a9e6f815c5c42d3a216f47044c61a1750b6d29ddc7f34bda"; const senderRoleFeePayerPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js index 8be3026df..a20708299 100644 --- a/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js @@ -1,14 +1,10 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -// // AccountKeyRoleBased Step 02 - value transfer // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyrolebased // // gasLimit: Must be large enough -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb } = require( "../../dist/web3"); // the same address of sender in AccountKeyRoleBased_01_accountUpdate.js const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; @@ -23,8 +19,7 @@ async function main() { type: TxType.ValueTransfer, gasLimit: 100000, to: receiverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb('1', 'KLAY'), from: senderAddr, }; @@ -32,7 +27,6 @@ async function main() { let signTx = await web3.eth.accounts.signTransaction(tx, account.privateKey); console.log(signTx); - let sendResult = await web3.eth.sendSignedTransaction(signTx.rawTransaction); console.log( sendResult ); diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js index 8387a2f51..49ca69342 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js @@ -1,21 +1,16 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") - -// // AccountKeyWeightedMultiSig Step 01 - account update // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig // // gasLimit: Must be large enough -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require( "../../dist/web3"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") + // create a new account for testing // https://baobab.wallet.klaytn.foundation/ -// -const senderAddr = "0x55815c94c0c375e11a535096f8067c0418a93b48"; -const senderPriv = "0x7394141c6fa82980656212a8d15f120e8f1ac81e6705a49864e86f6c507f239e"; +const senderAddr = "0x2bf611d14d330fd3688d10f2201321eacc8aa2ce"; +const senderPriv = "0x31fadf868e68fd2e3f7a1c528023c9a86a45db850e9d6b82c1a82d4c75b469d1"; const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; @@ -34,19 +29,16 @@ async function main() { gasLimit: 100000, key: { type: AccountKeyType.WeightedMultiSig, + threshold: 2, keys: [ - 2, // threshold - [ - [1, senderNewPub1], - [1, senderNewPub2], - [1, senderNewPub3] - ] + [1, senderNewPub1], + [1, senderNewPub2], + [1, senderNewPub3] ] } }; const senderAccount = web3.eth.accounts.privateKeyToAccount(senderPriv); - const senderTx = await web3.eth.accounts.signTransaction(tx, senderAccount.privateKey); console.log(senderTx); diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js index 0337d809f..0456a2db0 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js @@ -1,18 +1,15 @@ -const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../../dist/src"); - -const { TxType, AccountKeyType, objectFromRLP } = require("../../../ethers-ext/dist/src"); - -// // AccountKeyWeightedMultiSig Step 02 - value transfer // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeyweightedmultisig // // gasLimit: Must be large enough -// + +const { Web3 } = require("web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // the same address of sender in AccountKeyWeightedMultiSig_01_accountUpdate.js -const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -const senderAddr = "0x55815c94c0c375e11a535096f8067c0418a93b48"; +const senderAddr = "0x2bf611d14d330fd3688d10f2201321eacc8aa2ce"; +const senderPriv = "0x31fadf868e68fd2e3f7a1c528023c9a86a45db850e9d6b82c1a82d4c75b469d1"; const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; @@ -25,8 +22,7 @@ async function main() { type: TxType.ValueTransfer, gasLimit: 100000, to: receiverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb('1', 'KLAY'), from: senderAddr, }; @@ -34,21 +30,21 @@ async function main() { const account = web3.eth.accounts.privateKeyToAccount(senderNewPriv1); let signTx = await web3.eth.accounts.signTransaction(tx, account.privateKey); - // tx = objectFromRLP(signTx.rawTransaction); + // tx = parseTransaction(signTx.rawTransaction); // console.log(tx); // sign 2 const account2 = web3.eth.accounts.privateKeyToAccount(senderNewPriv2, provider); let signTx2 = await web3.eth.accounts.signTransaction(signTx.rawTransaction, account2.privateKey); - // tx = objectFromRLP(signTx2.rawTransaction); + // tx = parseTransaction(signTx2.rawTransaction); // console.log(tx); // sign 3 const account3 = web3.eth.accounts.privateKeyToAccount(senderNewPriv3, provider); let signTx3 = await web3.eth.accounts.signTransaction(signTx2.rawTransaction, account3.privateKey); - tx = objectFromRLP(signTx3.rawTransaction); + tx = parseTransaction(signTx3.rawTransaction); console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signTx3.rawTransaction); From dc59b009f91245e159983a3be7e6bc742885b1e6 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Tue, 28 Nov 2023 15:57:51 +0900 Subject: [PATCH 43/69] Add WeightedMultiSig cononicalizing logic --- web3js-ext/src/web3/send_transaction.ts | 54 ++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index 2757baf37..5e844a59f 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -22,9 +22,12 @@ import { import { isAbiErrorFragment, decodeContractErrorData } from "web3-eth-abi"; import _ from "lodash"; -import { KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; +import { HexStr, KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; import { saveCustomFields } from "./klaytn_tx"; +import { TxType } from "@klaytn/ethers-ext"; +import { AccountKey } from "@klaytn/ethers-ext/dist/src/core"; +import { AccountKeyType } from "."; // Platform-independent NodeJS timeout types type TimeoutT = ReturnType; @@ -58,8 +61,55 @@ export function klay_sendSignedTransaction< // hot fix // TODO : the code below will be deleted after deploying same logic in js-ext-core + if (unSerializedTransaction.nonce == "0x") unSerializedTransaction.nonce = 0; if (unSerializedTransaction.value == "0x") unSerializedTransaction.value = 0; - if (unSerializedTransaction.to == "0x") unSerializedTransaction.to = "0x0000000000000000000000000000000000000000" + if (unSerializedTransaction.to == "0x") unSerializedTransaction.to = "0x0000000000000000000000000000000000000000"; + // if (unSerializedTransaction.key && unSerializedTransaction.key.type == AccountKeyType.WeightedMultiSig) { + // // WeightedMultiSigKeys is canonicalized like follow. + // // e.g. + // // [ + // // "03", // threshold + // // [ + // // // [ weight, key ] list for multi-sig + // // [ + // // "01", + // // "02c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e" + // // ], + // // [ + // // "01", + // // "0212d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfb" + // // ], + // // [ + // // "01", + // // "02ea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cd" + // // ], + // // [ + // // "01", + // // "038551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6" + // // ] + // // ] + // // ] + // const value = unSerializedTransaction.key; + // const ret = [], keys = []; + + // if (value.type != AccountKeyType.WeightedMultiSig && value.keys.length < 2) { + // throw new Error("Threshold and Keys format is wrong for MultiSig"); + // } + // ret.push(HexStr.fromNumber(value.threshold)); + + // for (let i = 0; i < value.keys.length; i++) { + // if (value.keys[i][0] == undefined || value.keys[i][1] == undefined) { + // throw new Error("Weight and Key format is wrong for MultiSig"); + // } + // const key = []; + // key.push(HexStr.fromNumber(value.keys[i][0])); + // key.push(value.keys[i][1]); + // keys.push(key); + // } + // ret.push(keys); + + // unSerializedTransaction.key = ret; + // } const unSerializedTransactionForCall = getRpcTxObject(unSerializedTransaction); From 25467716bd57dfea67ac6b7ccb880b607763a1be Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Tue, 28 Nov 2023 15:59:11 +0900 Subject: [PATCH 44/69] Add hot fix for nonce exception --- web3js-ext/src/web3/send_transaction.ts | 48 +------------------------ 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index 5e844a59f..d233cdedb 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -22,7 +22,7 @@ import { import { isAbiErrorFragment, decodeContractErrorData } from "web3-eth-abi"; import _ from "lodash"; -import { HexStr, KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; +import { KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; import { saveCustomFields } from "./klaytn_tx"; import { TxType } from "@klaytn/ethers-ext"; @@ -64,52 +64,6 @@ export function klay_sendSignedTransaction< if (unSerializedTransaction.nonce == "0x") unSerializedTransaction.nonce = 0; if (unSerializedTransaction.value == "0x") unSerializedTransaction.value = 0; if (unSerializedTransaction.to == "0x") unSerializedTransaction.to = "0x0000000000000000000000000000000000000000"; - // if (unSerializedTransaction.key && unSerializedTransaction.key.type == AccountKeyType.WeightedMultiSig) { - // // WeightedMultiSigKeys is canonicalized like follow. - // // e.g. - // // [ - // // "03", // threshold - // // [ - // // // [ weight, key ] list for multi-sig - // // [ - // // "01", - // // "02c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e" - // // ], - // // [ - // // "01", - // // "0212d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfb" - // // ], - // // [ - // // "01", - // // "02ea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cd" - // // ], - // // [ - // // "01", - // // "038551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6" - // // ] - // // ] - // // ] - // const value = unSerializedTransaction.key; - // const ret = [], keys = []; - - // if (value.type != AccountKeyType.WeightedMultiSig && value.keys.length < 2) { - // throw new Error("Threshold and Keys format is wrong for MultiSig"); - // } - // ret.push(HexStr.fromNumber(value.threshold)); - - // for (let i = 0; i < value.keys.length; i++) { - // if (value.keys[i][0] == undefined || value.keys[i][1] == undefined) { - // throw new Error("Weight and Key format is wrong for MultiSig"); - // } - // const key = []; - // key.push(HexStr.fromNumber(value.keys[i][0])); - // key.push(value.keys[i][1]); - // keys.push(key); - // } - // ret.push(keys); - - // unSerializedTransaction.key = ret; - // } const unSerializedTransactionForCall = getRpcTxObject(unSerializedTransaction); From 241e029080ef366a9101aa5e1a7ebc781b80f968 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Tue, 28 Nov 2023 16:18:12 +0900 Subject: [PATCH 45/69] Update package path --- web3js-ext/example/create.js | 3 +-- web3js-ext/example/privateKeyToAccount.js | 7 ++----- web3js-ext/example/recoverTransaction.js | 2 +- web3js-ext/example/valueTransfer.js | 7 ++++--- web3js-ext/example/wallet.js | 2 +- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/web3js-ext/example/create.js b/web3js-ext/example/create.js index 6db0cff31..1f64cde80 100644 --- a/web3js-ext/example/create.js +++ b/web3js-ext/example/create.js @@ -1,6 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/src"); - +const { KlaytnWeb3 } = require( "../dist/web3"); async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); diff --git a/web3js-ext/example/privateKeyToAccount.js b/web3js-ext/example/privateKeyToAccount.js index 4745f4426..3b9959091 100644 --- a/web3js-ext/example/privateKeyToAccount.js +++ b/web3js-ext/example/privateKeyToAccount.js @@ -1,7 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/src"); -const { TxType, parseKlay } = require("@klaytn/ethers-ext"); - +const { KlaytnWeb3, TxType, toPeb} = require( "../dist/web3"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; @@ -15,8 +13,7 @@ async function main() { { type: TxType.ValueTransfer, to: recieverAddr, - value: 1e9, - // value: convertToPeb('1', 'KLAY'), + value: toPeb('0.01', 'KLAY'), from: senderAddr, gas: 21000, gasPrice: 25e9, diff --git a/web3js-ext/example/recoverTransaction.js b/web3js-ext/example/recoverTransaction.js index 59076bd53..17066fec5 100644 --- a/web3js-ext/example/recoverTransaction.js +++ b/web3js-ext/example/recoverTransaction.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/src"); +const { KlaytnWeb3 } = require( "../dist/web3"); async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); diff --git a/web3js-ext/example/valueTransfer.js b/web3js-ext/example/valueTransfer.js index 0be0dc96f..a048d8956 100644 --- a/web3js-ext/example/valueTransfer.js +++ b/web3js-ext/example/valueTransfer.js @@ -1,10 +1,11 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/src"); +const { KlaytnWeb3 } = require( "../dist/web3"); const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; const addr = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const to = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8"; -const url = "http://localhost:8545"; +// const url = "http://localhost:8545"; +const url = "https://public-en-baobab.klaytn.net"; const contractAddr = "0x5FbDB2315678afecb367f032d93F642f64180aa3"; const data_increment = "0xd09de08a"; // Counter.sol:increment() @@ -33,7 +34,7 @@ async function main() { to: contractAddr, value: 0, nonce: await web3.eth.getTransactionCount(addr), - gas: 100_000, + gas: 100000, gasPrice: 25e9, data: data_increment, data: "0xdeadbeef", // trigger error diff --git a/web3js-ext/example/wallet.js b/web3js-ext/example/wallet.js index b5546b773..00f2a18f8 100644 --- a/web3js-ext/example/wallet.js +++ b/web3js-ext/example/wallet.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/src"); +const { KlaytnWeb3 } = require( "../dist/web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; From 0a25693511d7f97618da1eaa8bee74b5bc3b78aa Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Wed, 29 Nov 2023 15:09:03 +0900 Subject: [PATCH 46/69] Change path --- .../example/accountKey/AccountKeyLegacy_01_ValueTransfer.js | 2 +- .../example/accountKey/AccountKeyPublic_01_accountUpdate.js | 2 +- .../example/accountKey/AccountKeyPublic_02_valueTransfer.js | 2 +- .../example/accountKey/AccountKeyRoleBased_01_accountUpdate.js | 2 +- .../example/accountKey/AccountKeyRoleBased_02_valueTransfer.js | 2 +- .../accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js | 2 +- .../accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js | 2 +- web3js-ext/example/create.js | 2 +- web3js-ext/example/privateKeyToAccount.js | 2 +- web3js-ext/example/recoverTransaction.js | 2 +- web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js | 2 +- .../example/transactions/Basic_10_TxTypeValueTransferMemo.js | 2 +- web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js | 2 +- .../example/transactions/Basic_28_TxTypeSmartContractDeploy.js | 2 +- .../transactions/Basic_30_TxTypeSmartContractExecution.js | 2 +- web3js-ext/example/transactions/Basic_38_TxTypeCancel.js | 2 +- .../transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js | 2 +- .../FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js | 2 +- .../transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js | 2 +- .../FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js | 2 +- .../FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js | 2 +- .../example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js | 2 +- ...PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js | 2 +- ...ialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js | 2 +- ...PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js | 2 +- ...lFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js | 2 +- ...eDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js | 2 +- .../PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js | 2 +- web3js-ext/example/valueTransfer.js | 2 +- web3js-ext/example/wallet.js | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js b/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js index 5335742ea..f6c6fbd4d 100644 --- a/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy const { Web3 } = require("web3"); -const { KlaytnWeb3, toPeb } = require( "../../dist/web3"); +const { KlaytnWeb3, toPeb } = require( "@klaytn/web3js-ext"); const senderAddr = "0x24e8efd18d65bcb6b3ba15a4698c0b0d69d13ff7"; const senderPriv = "0x4a72b3d09c3d5e28e8652e0111f9c4ce252e8299aad95bb219a38eb0a3f4da49"; diff --git a/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js index bd1f920bc..e4f98d7b4 100644 --- a/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require( "@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing diff --git a/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js index c971d9e58..a17337c49 100644 --- a/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb } = require( "@klaytn/web3js-ext"); // the same address of sender in AccountKeyPublic_01_accountUpdate.js const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; diff --git a/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js index ece92b6db..ba64f740a 100644 --- a/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js @@ -4,7 +4,7 @@ // gasLimit: Must be large enough const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require( "@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing diff --git a/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js index a20708299..b03819bd4 100644 --- a/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js @@ -4,7 +4,7 @@ // gasLimit: Must be large enough const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb } = require( "@klaytn/web3js-ext"); // the same address of sender in AccountKeyRoleBased_01_accountUpdate.js const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js index 49ca69342..8e7a07740 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js @@ -4,7 +4,7 @@ // gasLimit: Must be large enough const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require( "@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js index 0456a2db0..c1b1c8489 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js @@ -4,7 +4,7 @@ // gasLimit: Must be large enough const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // the same address of sender in AccountKeyWeightedMultiSig_01_accountUpdate.js diff --git a/web3js-ext/example/create.js b/web3js-ext/example/create.js index 1f64cde80..2c800df4e 100644 --- a/web3js-ext/example/create.js +++ b/web3js-ext/example/create.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/web3"); +const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); diff --git a/web3js-ext/example/privateKeyToAccount.js b/web3js-ext/example/privateKeyToAccount.js index 3b9959091..7c60d0b1c 100644 --- a/web3js-ext/example/privateKeyToAccount.js +++ b/web3js-ext/example/privateKeyToAccount.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb} = require( "../dist/web3"); +const { KlaytnWeb3, TxType, toPeb} = require( "@klaytn/web3js-ext"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/web3js-ext/example/recoverTransaction.js b/web3js-ext/example/recoverTransaction.js index 17066fec5..5a5f3357e 100644 --- a/web3js-ext/example/recoverTransaction.js +++ b/web3js-ext/example/recoverTransaction.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/web3"); +const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); diff --git a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index 331dc81ab..ec37efe97 100644 --- a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js b/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js index f5d4ef348..f1400edb9 100644 --- a/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js +++ b/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfermemo const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js b/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js index 14ff3daca..da681219d 100644 --- a/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js +++ b/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js @@ -6,7 +6,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/accounts#account-key const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require("../../dist/web3"); +const { KlaytnWeb3, TxType, AccountKeyType } = require("@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create new account for testing diff --git a/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js b/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js index 6b2195ce1..3c48b8063 100644 --- a/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js +++ b/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js @@ -8,7 +8,7 @@ // codeFormat: Must be 0x00 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js b/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js index 118bd4e6e..e12669499 100644 --- a/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js +++ b/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js @@ -6,7 +6,7 @@ // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js index d78a1288b..c18108e38 100644 --- a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js +++ b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js @@ -7,7 +7,7 @@ // then you can see Cancel tx with the next nonce + 1 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require("../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js b/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js index 97047baa4..bb311a8c8 100644 --- a/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js +++ b/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js index d54ee0711..b16082275 100644 --- a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js +++ b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js b/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js index c3d90dab0..f7141cb2d 100644 --- a/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js +++ b/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require("../../dist/web3"); +const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require("@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create new account for testing in https://baobab.wallet.klaytn.foundation/ diff --git a/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js b/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js index 0d8708da7..01fc9d828 100644 --- a/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js +++ b/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js @@ -8,7 +8,7 @@ // codeFormat: Must be 0x00 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js b/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js index 6798e8fba..a9b06eb4c 100644 --- a/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js +++ b/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js @@ -6,7 +6,7 @@ // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js index 3fa34ec38..38ee38098 100644 --- a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js +++ b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js @@ -7,7 +7,7 @@ // then you can see Cancel tx with the next nonce + 1 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js index 511f9e6d0..35789e985 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js @@ -2,7 +2,7 @@ // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js index f7a691f9a..5341bb9f5 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js @@ -5,7 +5,7 @@ // nonce: In signTransactionAsFeePayer, must not be omitted, because feePayer's nonce is filled when populating const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js index e8c975f34..63f0e03f7 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js @@ -14,7 +14,7 @@ // https://github.com/klaytn/klaytn/blob/dev/blockchain/types/tx_internal_data_value_transfer_memo.go#L239 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require( "@klaytn/web3js-ext"); const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create new account for testing diff --git a/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js index 126a88065..57c1ad3d0 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js @@ -8,7 +8,7 @@ // codeFormat: Must be 0x00 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js index eb6d2a9e1..e00987593 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js @@ -7,7 +7,7 @@ // const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js index df00b6066..65d454190 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js @@ -8,7 +8,7 @@ // then you can see Cancel tx with the next nonce + 1 const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType } = require( "../../dist/web3"); +const { KlaytnWeb3, TxType } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/valueTransfer.js b/web3js-ext/example/valueTransfer.js index a048d8956..28e751162 100644 --- a/web3js-ext/example/valueTransfer.js +++ b/web3js-ext/example/valueTransfer.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/web3"); +const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; const addr = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; diff --git a/web3js-ext/example/wallet.js b/web3js-ext/example/wallet.js index 00f2a18f8..70a95817e 100644 --- a/web3js-ext/example/wallet.js +++ b/web3js-ext/example/wallet.js @@ -1,5 +1,5 @@ const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "../dist/web3"); +const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; From df93f0d6527347386d710ccc6ac292a8b07281a4 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Wed, 29 Nov 2023 15:21:59 +0900 Subject: [PATCH 47/69] Update rpc.ts --- js-ext-core/src/util/rpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js-ext-core/src/util/rpc.ts b/js-ext-core/src/util/rpc.ts index d13ca79e4..cc54b6aa3 100644 --- a/js-ext-core/src/util/rpc.ts +++ b/js-ext-core/src/util/rpc.ts @@ -15,7 +15,7 @@ export function getRpcTxObject(tx: any): any { if (!_.has(tx, key)) { return; } if (tx[key] == "0x"){ - formatted[key] = hexValue("0x"); + value = hexValue("0x"); } else { value = hexValue(BigNumber.from(tx[key])); From 43dde680d95c3c5b4ac3b59e8e2cac66e84344f2 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 15:38:26 +0900 Subject: [PATCH 48/69] web3js: Add eslintrc --- web3js-ext/.eslintrc.js | 98 +++++++++++++++++++++++++++++++++++++++++ web3js-ext/.gitignore | 47 ++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 web3js-ext/.eslintrc.js create mode 100644 web3js-ext/.gitignore diff --git a/web3js-ext/.eslintrc.js b/web3js-ext/.eslintrc.js new file mode 100644 index 000000000..593d82b79 --- /dev/null +++ b/web3js-ext/.eslintrc.js @@ -0,0 +1,98 @@ +module.exports = { + "root": true, + + // rule presets and plugins + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/typescript", + ], + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + ], + "env": { + "es2022": true, + "browser": false, + "node": true, + "mocha": true + }, + + // custom rules + // see https://eslint.org/docs/latest/rules + "rules": { + // logic + "prefer-const": "warn", + "no-promise-executor-return": "warn", + "consistent-return": "warn", + "no-unneeded-ternary": "warn", + "yoda": "warn", + + "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/ban-ts-comment": "off", + + // imports + "import/order": ["warn", { + "alphabetize": { "order": "asc", "caseInsensitive": true }, + "pathGroups": [ + { "pattern": "@klaytn/**", "group": "external", "position": "after" }, + ], + "newlines-between": "always", + }], + "import/no-unresolved": [ + "error", // eslint-plugin-import cannot resolve subpaths https://github.com/firebase/firebase-admin-node/discussions/1359 + { ignore: ["^@klaytn/js-ext-core/util$"] } + ], + + // formatting + "curly": ["warn", "all"], + "brace-style": ["warn", "1tbs", { "allowSingleLine": true }], + "semi": "warn", + "no-extra-semi": "warn", + "quotes": ["warn", "double", { "avoidEscape": true }], + "comma-dangle": ["warn", "only-multiline"], + "arrow-parens": "warn", + "wrap-iife": "warn", + + // formatting about spaces + "max-len": ["off", 120], + "indent": ["warn", 2], + "linebreak-style": ["warn", "unix"], + + "no-trailing-spaces": "warn", + "no-multiple-empty-lines": "warn", + "no-multi-spaces": "warn", + "padded-blocks": ["warn", "never", { "allowSingleLineBlocks": true }], + "lines-between-class-members": ["warn", "always", { "exceptAfterSingleLine": true }], + + "space-before-blocks": ["warn", "always"], + "space-before-function-paren": ["warn", { "named": "never", "anonymous": "always", "asyncArrow": "always" }], + "space-in-parens": ["warn", "never"], + "space-infix-ops": "warn", + "spaced-comment": "warn", + "no-whitespace-before-property": "warn", + + "array-bracket-spacing": "warn", + "arrow-spacing": "warn", + "block-spacing": "warn", + "comma-spacing": "warn", + "key-spacing": ["warn", { "mode": "minimum" }], + "keyword-spacing": "warn", + "semi-spacing": "warn", + }, + "overrides": [ + { // examples and tests use relaxed rules + "files": ["example/**/*", "test/**/*"], + "rules": { + // examples may use require() because they are JS + "@typescript-eslint/no-var-requires": "off", + // give some flexibility adding and deleting variables + "@typescript-eslint/no-unused-vars": "off", + "prefer-const": "off", + } + }, + ] +}; diff --git a/web3js-ext/.gitignore b/web3js-ext/.gitignore new file mode 100644 index 000000000..55a69a562 --- /dev/null +++ b/web3js-ext/.gitignore @@ -0,0 +1,47 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz +*.swp + +pids +logs +results +tmp + +# Build +public/css/main.css + +# Coverage reports +coverage + +# API keys and secrets +.env +example/privateKey +example/feePayerPrivateKey + +# Dependency directory +node_modules +bower_components + +# Editors +.idea +*.iml + +# OS metadata +.DS_Store +Thumbs.db + +# Ignore built ts files +dist/**/* + +# ignore yarn.lock +yarn.lock + +# eslint +.eslintcache + From 3b58faa494f77070b726e4f29a60f2a10fdbce0c Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 15:40:36 +0900 Subject: [PATCH 49/69] web3js: Lint auto-fix --- .../AccountKeyLegacy_01_ValueTransfer.js | 4 +- .../AccountKeyPublic_01_accountUpdate.js | 6 +- .../AccountKeyPublic_02_valueTransfer.js | 6 +- .../AccountKeyRoleBased_01_accountUpdate.js | 10 +- .../AccountKeyRoleBased_02_valueTransfer.js | 6 +- ...untKeyWeightedMultiSig_01_accountUpdate.js | 12 +- ...untKeyWeightedMultiSig_02_valueTransfer.js | 8 +- web3js-ext/example/create.js | 2 +- web3js-ext/example/privateKeyToAccount.js | 8 +- web3js-ext/example/recoverTransaction.js | 10 +- .../Basic_08_TxTypeValueTransfer.js | 2 +- .../Basic_10_TxTypeValueTransferMemo.js | 2 +- .../Basic_20_TxTypeAccountUpdate.js | 6 +- .../Basic_28_TxTypeSmartContractDeploy.js | 2 +- .../Basic_30_TxTypeSmartContractExecution.js | 24 +- .../transactions/Basic_38_TxTypeCancel.js | 16 +- ...eDel_09_TxTypeFeeDelegatedValueTransfer.js | 4 +- ..._11_TxTypeFeeDelegatedValueTransferMemo.js | 6 +- ...eDel_21_TxTypeFeeDelegatedAccountUpdate.js | 6 +- ...9_TxTypeFeeDelegatedSmartContractDeploy.js | 6 +- ...xTypeFeeDelegatedSmartContractExecution.js | 28 +- .../FeeDel_39_TxTypeFeeDelegatedCancel.js | 8 +- ...xTypeFeeDelegatedValueTransferWithRatio.js | 6 +- ...eFeeDelegatedValueTransferMemoWithRatio.js | 6 +- ...xTypeFeeDelegatedAccountUpdateWithRatio.js | 10 +- ...eeDelegatedSmartContractDeployWithRatio.js | 8 +- ...elegatedSmartContractExecutionWithRatio.js | 28 +- ...el_3a_TxTypeFeeDelegatedCancelWithRatio.js | 8 +- web3js-ext/example/valueTransfer.js | 6 +- web3js-ext/example/wallet.js | 10 +- web3js-ext/src/web3/account.ts | 325 +++++++++--------- web3js-ext/src/web3/klaytn_tx.ts | 72 ++-- web3js-ext/src/web3/send_transaction.ts | 186 +++++----- web3js-ext/src/web3/utils.ts | 6 +- web3js-ext/src/web3/web3.ts | 19 +- 35 files changed, 433 insertions(+), 439 deletions(-) diff --git a/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js b/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js index f6c6fbd4d..bc549c92d 100644 --- a/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyLegacy_01_ValueTransfer.js @@ -1,8 +1,8 @@ // AccountKeyPublic Step 01 - value transfer // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeylegacy +const { KlaytnWeb3, toPeb } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, toPeb } = require( "@klaytn/web3js-ext"); const senderAddr = "0x24e8efd18d65bcb6b3ba15a4698c0b0d69d13ff7"; const senderPriv = "0x4a72b3d09c3d5e28e8652e0111f9c4ce252e8299aad95bb219a38eb0a3f4da49"; @@ -14,7 +14,7 @@ async function main() { let tx = { to: receiverAddr, - value: toPeb('0.01', 'KLAY'), + value: toPeb("0.01", "KLAY"), from: senderAddr, }; diff --git a/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js index e4f98d7b4..d7665307c 100644 --- a/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyPublic_01_accountUpdate.js @@ -1,9 +1,9 @@ // AccountKeyPublic Step 01 - account update // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic +const { KlaytnWeb3, TxType, AccountKeyType } = require("@klaytn/web3js-ext"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require( "@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing // https://baobab.wallet.klaytn.foundation/ @@ -15,7 +15,7 @@ async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); - let senderNewPub = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv), true)).toString('hex'); + let senderNewPub = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv), true)).toString("hex"); let tx = { type: TxType.AccountUpdate, diff --git a/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js index a17337c49..ec1224834 100644 --- a/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyPublic_02_valueTransfer.js @@ -1,8 +1,8 @@ // AccountKeyPublic Step 02 - value transfer // https://docs.klaytn.foundation/content/klaytn/design/accounts#accountkeypublic +const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require( "@klaytn/web3js-ext"); // the same address of sender in AccountKeyPublic_01_accountUpdate.js const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; @@ -16,7 +16,7 @@ async function main() { let tx = { type: TxType.ValueTransfer, to: receiverAddr, - value: toPeb('0.01', 'KLAY'), + value: toPeb("0.01", "KLAY"), from: senderAddr, }; @@ -26,7 +26,7 @@ async function main() { let sendResult = await web3.eth.sendSignedTransaction(signTx.rawTransaction); - console.log( sendResult ); + console.log(sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); console.log({ receipt }); diff --git a/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js index ba64f740a..08e06ff96 100644 --- a/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyRoleBased_01_accountUpdate.js @@ -3,9 +3,9 @@ // // gasLimit: Must be large enough +const { KlaytnWeb3, TxType, AccountKeyType } = require("@klaytn/web3js-ext"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require( "@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing // https://baobab.wallet.klaytn.foundation/ @@ -19,9 +19,9 @@ async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); - const pub1 = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderRoleTransactionPriv), true)).toString('hex'); - const pub2 = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderRoleAccountUpdatePriv), true)).toString('hex'); - const pub3 = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderRoleFeePayerPriv), true)).toString('hex'); + const pub1 = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderRoleTransactionPriv), true)).toString("hex"); + const pub2 = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderRoleAccountUpdatePriv), true)).toString("hex"); + const pub3 = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderRoleFeePayerPriv), true)).toString("hex"); console.log("1", pub1); console.log("2", pub2); diff --git a/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js index b03819bd4..381ac5a82 100644 --- a/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyRoleBased_02_valueTransfer.js @@ -3,8 +3,8 @@ // // gasLimit: Must be large enough +const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb } = require( "@klaytn/web3js-ext"); // the same address of sender in AccountKeyRoleBased_01_accountUpdate.js const receiverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; @@ -19,7 +19,7 @@ async function main() { type: TxType.ValueTransfer, gasLimit: 100000, to: receiverAddr, - value: toPeb('1', 'KLAY'), + value: toPeb("1", "KLAY"), from: senderAddr, }; @@ -28,7 +28,7 @@ async function main() { console.log(signTx); let sendResult = await web3.eth.sendSignedTransaction(signTx.rawTransaction); - console.log( sendResult ); + console.log(sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); console.log({ receipt }); diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js index 8e7a07740..b36a1f69a 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_01_accountUpdate.js @@ -3,9 +3,9 @@ // // gasLimit: Must be large enough +const { KlaytnWeb3, TxType, AccountKeyType } = require("@klaytn/web3js-ext"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType } = require( "@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create a new account for testing // https://baobab.wallet.klaytn.foundation/ @@ -19,10 +19,10 @@ async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); - const senderNewPub1 = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv1), true)).toString('hex'); - const senderNewPub2 = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv2), true)).toString('hex'); - const senderNewPub3 = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv3), true)).toString('hex'); - + const senderNewPub1 = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv1), true)).toString("hex"); + const senderNewPub2 = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv2), true)).toString("hex"); + const senderNewPub3 = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv3), true)).toString("hex"); + let tx = { type: TxType.AccountUpdate, from: senderAddr, diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js index c1b1c8489..cf42a1766 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js @@ -3,9 +3,9 @@ // // gasLimit: Must be large enough +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require("@klaytn/web3js-ext"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // the same address of sender in AccountKeyWeightedMultiSig_01_accountUpdate.js const senderAddr = "0x2bf611d14d330fd3688d10f2201321eacc8aa2ce"; @@ -22,7 +22,7 @@ async function main() { type: TxType.ValueTransfer, gasLimit: 100000, to: receiverAddr, - value: toPeb('1', 'KLAY'), + value: toPeb("1", "KLAY"), from: senderAddr, }; @@ -48,7 +48,7 @@ async function main() { console.log(tx); let sendResult = await web3.eth.sendSignedTransaction(signTx3.rawTransaction); - console.log( sendResult ); + console.log(sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); console.log({ receipt }); diff --git a/web3js-ext/example/create.js b/web3js-ext/example/create.js index 2c800df4e..75154f913 100644 --- a/web3js-ext/example/create.js +++ b/web3js-ext/example/create.js @@ -1,5 +1,5 @@ +const { KlaytnWeb3 } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); diff --git a/web3js-ext/example/privateKeyToAccount.js b/web3js-ext/example/privateKeyToAccount.js index 7c60d0b1c..a8f5e77b2 100644 --- a/web3js-ext/example/privateKeyToAccount.js +++ b/web3js-ext/example/privateKeyToAccount.js @@ -1,5 +1,5 @@ +const { KlaytnWeb3, TxType, toPeb} = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb} = require( "@klaytn/web3js-ext"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; @@ -9,16 +9,16 @@ async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); let web3 = new KlaytnWeb3(provider); - let signResult = await web3.eth.accounts.privateKeyToAccount(senderPriv).signTransaction( + let signResult = await web3.eth.accounts.privateKeyToAccount(senderPriv).signTransaction( { type: TxType.ValueTransfer, to: recieverAddr, - value: toPeb('0.01', 'KLAY'), + value: toPeb("0.01", "KLAY"), from: senderAddr, gas: 21000, gasPrice: 25e9, } - ); + ); console.log({ signResult }); let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); diff --git a/web3js-ext/example/recoverTransaction.js b/web3js-ext/example/recoverTransaction.js index 5a5f3357e..8fb672580 100644 --- a/web3js-ext/example/recoverTransaction.js +++ b/web3js-ext/example/recoverTransaction.js @@ -1,18 +1,18 @@ +const { KlaytnWeb3 } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); let web3 = new KlaytnWeb3(provider); - // ethereum's rawTransaction - let rawTransaction = '0xf869808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a0c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895a0727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68'; + // ethereum's rawTransaction + let rawTransaction = "0xf869808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a0c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895a0727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68"; let address = await web3.eth.accounts.recoverTransaction(rawTransaction); console.log("\nsender", "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23"); console.log("recovered", address); - // Klaytn's rawTransaction - rawTransaction = '0x08f88482020b8505d21dba0082520894a2a8854b1802d8cd5de631e690817c253d6a9153843b9aca0094a2a8854b1802d8cd5de631e690817c253d6a9153f847f8458207f6a00739be424c6074a17b38badc0a10ca30e50a3b56dce73ecf60cec1dbb48ebde5a0039d8ce12722feb26fe784932e2b4100982232d81efd1960dc846d6c6c49efdb'; + // Klaytn's rawTransaction + rawTransaction = "0x08f88482020b8505d21dba0082520894a2a8854b1802d8cd5de631e690817c253d6a9153843b9aca0094a2a8854b1802d8cd5de631e690817c253d6a9153f847f8458207f6a00739be424c6074a17b38badc0a10ca30e50a3b56dce73ecf60cec1dbb48ebde5a0039d8ce12722feb26fe784932e2b4100982232d81efd1960dc846d6c6c49efdb"; address = await web3.eth.accounts.recoverTransaction(rawTransaction); console.log("\nsender", "0xA2a8854b1802D8Cd5De631E690817c253d6a9153"); console.log("recovered", address); diff --git a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js index ec37efe97..bdd77cbba 100644 --- a/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js +++ b/web3js-ext/example/transactions/Basic_08_TxTypeValueTransfer.js @@ -1,8 +1,8 @@ // TxTypeValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfer -const { Web3 } = require("web3"); const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); +const { Web3 } = require("web3"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js b/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js index f1400edb9..57dfa5330 100644 --- a/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js +++ b/web3js-ext/example/transactions/Basic_10_TxTypeValueTransferMemo.js @@ -1,8 +1,8 @@ // TxTypeValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/basic#txtypevaluetransfermemo -const { Web3 } = require("web3"); const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); +const { Web3 } = require("web3"); const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; diff --git a/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js b/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js index da681219d..25e5561ca 100644 --- a/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js +++ b/web3js-ext/example/transactions/Basic_20_TxTypeAccountUpdate.js @@ -5,9 +5,9 @@ // key: Refer Klaytn account key // https://docs.klaytn.foundation/content/klaytn/design/accounts#account-key -const { Web3 } = require("web3"); const { KlaytnWeb3, TxType, AccountKeyType } = require("@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); +const { Web3 } = require("web3"); // create new account for testing // https://baobab.wallet.klaytn.foundation/ @@ -19,7 +19,7 @@ async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); - const publicKey = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv), true)).toString('hex') + const publicKey = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv), true)).toString("hex"); console.log(publicKey); let tx = { diff --git a/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js b/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js index 3c48b8063..40a4da383 100644 --- a/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js +++ b/web3js-ext/example/transactions/Basic_28_TxTypeSmartContractDeploy.js @@ -7,8 +7,8 @@ // humanReadable: Must be false, // codeFormat: Must be 0x00 +const { KlaytnWeb3, TxType } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; diff --git a/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js b/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js index e12669499..4e24aa7fd 100644 --- a/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js +++ b/web3js-ext/example/transactions/Basic_30_TxTypeSmartContractExecution.js @@ -5,8 +5,8 @@ // value: Must be 0, if not payable // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi -const { Web3 } = require("web3"); const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); +const { Web3 } = require("web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,30 +19,30 @@ async function main() { const sender = web3.eth.accounts.privateKeyToAccount(senderPriv); const CONTRACT_ADDRESS = contractAddr; - const CONTRACT_ABI = [ + const CONTRACT_ABI = [ { "inputs": [ - { - "internalType": "uint256", - "name": "newNumber", - "type": "uint256" - } + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256" + } ], "name": "setNumber", "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { + }, + { "inputs": [], "name": "increment", "outputs": [], "stateMutability": "nonpayable", "type": "function" - } - ]; + } + ]; const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS); - const param = contract.methods.setNumber(0x123).encodeABI(); + const param = contract.methods.setNumber(0x123).encodeABI(); let tx = { type: TxType.SmartContractExecution, diff --git a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js index c18108e38..c12da1d91 100644 --- a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js +++ b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js @@ -6,8 +6,8 @@ // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 -const { Web3 } = require("web3"); const { KlaytnWeb3, TxType, toPeb } = require("@klaytn/web3js-ext"); +const { Web3 } = require("web3"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -30,9 +30,9 @@ async function main() { }; let signResult = await web3.eth.accounts.signTransaction(tx, sender.privateKey); - web3.eth.sendSignedTransaction(signResult.rawTransaction); - // TODO: .on function not working - //.on("receipt", (receipt) => console.log("tx next + 1", receipt)); + web3.eth.sendSignedTransaction(signResult.rawTransaction); + // TODO: .on function not working + // .on("receipt", (receipt) => console.log("tx next + 1", receipt)); // 2) send Cancel tx with the next nonce+1 let txCancel = { @@ -42,9 +42,9 @@ async function main() { }; signResult = await web3.eth.accounts.signTransaction(txCancel, sender.privateKey); - web3.eth.sendSignedTransaction(signResult.rawTransaction) - // TODO: .on function not working - //.on("receipt", (receipt) => console.log("tx next + 1 cancel", receipt)); + web3.eth.sendSignedTransaction(signResult.rawTransaction); + // TODO: .on function not working + // .on("receipt", (receipt) => console.log("tx next + 1 cancel", receipt)); // 3) send ValueTransfer tx with the next nonce tx.nonce = nextNonce; @@ -55,7 +55,7 @@ async function main() { console.log("sendResult", sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); - console.log( receipt ); + console.log(receipt); } main(); diff --git a/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js b/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js index bb311a8c8..ae8d16e24 100644 --- a/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js +++ b/web3js-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer.js @@ -1,8 +1,8 @@ // TxTypeFeeDelegatedValueTransfer // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfer +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,7 +19,7 @@ async function main() { to: recieverAddr, value: toPeb("0.01"), from: senderAddr, - gas: 300000, + gas: 300000, }; // sender diff --git a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js index b16082275..f85c7a661 100644 --- a/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js +++ b/web3js-ext/example/transactions/FeeDel_11_TxTypeFeeDelegatedValueTransferMemo.js @@ -1,8 +1,8 @@ // TxTypeFeeDelegatedValueTransferMemo // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedvaluetransfermemo +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -20,8 +20,8 @@ async function main() { value: toPeb("0.01"), from: senderAddr, input: "0x1234567890", - gas: 250000, // intrinsic gas too low - gasPrice: 25e9, + gas: 250000, // intrinsic gas too low + gasPrice: 25e9, }; // sender diff --git a/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js b/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js index f7141cb2d..1b2b2f468 100644 --- a/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js +++ b/web3js-ext/example/transactions/FeeDel_21_TxTypeFeeDelegatedAccountUpdate.js @@ -1,9 +1,9 @@ // TxTypeFeeDelegatedAccountUpdate // https://docs.klaytn.foundation/content/klaytn/design/transactions/fee-delegation#txtypefeedelegatedaccountupdate -const { Web3 } = require("web3"); const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require("@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); +const { Web3 } = require("web3"); // create new account for testing in https://baobab.wallet.klaytn.foundation/ const senderAddr = "0x30908464d76604420162a6c880c0e1c7e641bad7"; @@ -16,7 +16,7 @@ async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); - const publicKey = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv), true)).toString('hex') + const publicKey = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv), true)).toString("hex"); console.log(publicKey); let tx = { diff --git a/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js b/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js index 01fc9d828..658b7f73e 100644 --- a/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js +++ b/web3js-ext/example/transactions/FeeDel_29_TxTypeFeeDelegatedSmartContractDeploy.js @@ -7,8 +7,8 @@ // humanReadable: Must be false, // codeFormat: Must be 0x00 +const { KlaytnWeb3, TxType, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -27,8 +27,8 @@ async function main() { input: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e0f4e7861cb6d7acf0f61d34896310975b57b5bc109681dbbfb2e548ef7546b364736f6c63430008120033", humanReadable: false, codeFormat: 0x00, - gas: 400000, // intrinsic gas too low - gasPrice: 100e9, + gas: 400000, // intrinsic gas too low + gasPrice: 100e9, }; // sender diff --git a/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js b/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js index a9b06eb4c..9891faa24 100644 --- a/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js +++ b/web3js-ext/example/transactions/FeeDel_31_TxTypeFeeDelegatedSmartContractExecution.js @@ -5,8 +5,8 @@ // value: Must be 0, if not payable // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi +const { KlaytnWeb3, TxType, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,30 +19,30 @@ async function main() { const web3 = new KlaytnWeb3(provider); const CONTRACT_ADDRESS = contractAddr; - const CONTRACT_ABI = [ + const CONTRACT_ABI = [ { "inputs": [ - { - "internalType": "uint256", - "name": "newNumber", - "type": "uint256" - } + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256" + } ], "name": "setNumber", "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { + }, + { "inputs": [], "name": "increment", "outputs": [], "stateMutability": "nonpayable", "type": "function" - } - ]; + } + ]; const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS); - const param = contract.methods.setNumber(0x123).encodeABI(); + const param = contract.methods.setNumber(0x123).encodeABI(); let tx = { type: TxType.FeeDelegatedSmartContractExecution, @@ -50,8 +50,8 @@ async function main() { value: 0, from: senderAddr, input: param, - gas: 400000, // intrinsic gas too low - gasPrice: 100e9, + gas: 400000, // intrinsic gas too low + gasPrice: 100e9, }; // sender diff --git a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js index 38ee38098..3a1424c50 100644 --- a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js +++ b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js @@ -6,8 +6,8 @@ // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 +const { KlaytnWeb3, TxType, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -31,7 +31,7 @@ async function main() { to: recieverAddr, value: 1e12, from: senderAddr, - gas: 300000, // intrinsic gas too low + gas: 300000, // intrinsic gas too low gasPrice: 100e9, }; @@ -48,7 +48,7 @@ async function main() { type: TxType.FeeDelegatedCancel, nonce: nextNonce + 1n, from: senderAddr, - gas: 300000, // intrinsic gas too low + gas: 300000, // intrinsic gas too low gasPrice: 100e9, }; @@ -73,7 +73,7 @@ async function main() { console.log("sendResult", sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); - console.log( receipt ); + console.log(receipt); } main(); diff --git a/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js index 35789e985..22979d2a0 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_0a_TxTypeFeeDelegatedValueTransferWithRatio.js @@ -1,8 +1,8 @@ // TxTypeFeeDelegatedValueTransferWithRatio // https://docs.klaytn.foundation/content/klaytn/design/transactions/partial-fee-delegation#txtypefeedelegatedvaluetransferwithratio +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -19,8 +19,8 @@ async function main() { to: recieverAddr, value: toPeb("0.01"), from: senderAddr, - gas: 300000, - gasPrice: 100e9, + gas: 300000, + gasPrice: 100e9, feeRatio: 40, }; diff --git a/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js index 5341bb9f5..3123cc194 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_12_TxTypeFeeDelegatedValueTransferMemoWithRatio.js @@ -4,8 +4,8 @@ // // nonce: In signTransactionAsFeePayer, must not be omitted, because feePayer's nonce is filled when populating +const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -24,8 +24,8 @@ async function main() { value: toPeb("0.01"), from: senderAddr, input: "0x1234567890", - gas: 300000, - gasPrice: 100e9, + gas: 300000, + gasPrice: 100e9, feeRatio: 30, }; diff --git a/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js index 63f0e03f7..9c2850d89 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_22_TxTypeFeeDelegatedAccountUpdateWithRatio.js @@ -13,9 +13,9 @@ // You should see the source code for the info (e.g. VTwithMemo intrinsic gas is 21000 + len(memo)*100 ) // https://github.com/klaytn/klaytn/blob/dev/blockchain/types/tx_internal_data_value_transfer_memo.go#L239 +const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require("@klaytn/web3js-ext"); +const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, AccountKeyType, parseTransaction } = require( "@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js") // create new account for testing // https://baobab.wallet.klaytn.foundation/ @@ -29,7 +29,7 @@ async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); - const publicKey = "0x" + Buffer.from(secp256k1.getPublicKey( BigInt(senderNewPriv), true)).toString('hex') + const publicKey = "0x" + Buffer.from(secp256k1.getPublicKey(BigInt(senderNewPriv), true)).toString("hex"); console.log(publicKey); let tx = { @@ -38,9 +38,9 @@ async function main() { key: { type: AccountKeyType.Public, key: publicKey - }, + }, feeRatio: 40, - gas: 300000, // intrinsic gas too low + gas: 300000, // intrinsic gas too low gasPrice: 100e9, }; diff --git a/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js index 57c1ad3d0..1ba79b09b 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_2a_TxTypeFeeDelegatedSmartContractDeployWithRatio.js @@ -7,8 +7,8 @@ // humanReadable: Must be false, // codeFormat: Must be 0x00 +const { KlaytnWeb3, TxType, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -27,11 +27,11 @@ async function main() { input: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e0f4e7861cb6d7acf0f61d34896310975b57b5bc109681dbbfb2e548ef7546b364736f6c63430008120033", humanReadable: false, codeFormat: 0x00, - gas: 400000, // intrinsic gas too low - gasPrice: 100e9, + gas: 400000, // intrinsic gas too low + gasPrice: 100e9, feeRatio: 30, }; - + // sender const sender = web3.eth.accounts.privateKeyToAccount(senderPriv); let senderTx = await web3.eth.accounts.signTransaction(tx, sender.privateKey); diff --git a/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js index e00987593..67622d9df 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_32_TxTypeFeeDelegatedSmartContractExecutionWithRatio.js @@ -6,42 +6,42 @@ // input: Refer https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi // +const { KlaytnWeb3, TxType, parseTransaction } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType, parseTransaction } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const contractAddr = '0xdd43ebd381060a31ca2827311835649e9819439b'; +const contractAddr = "0xdd43ebd381060a31ca2827311835649e9819439b"; async function main() { const provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); const web3 = new KlaytnWeb3(provider); const CONTRACT_ADDRESS = contractAddr; - const CONTRACT_ABI = [ + const CONTRACT_ABI = [ { "inputs": [ - { - "internalType": "uint256", - "name": "newNumber", - "type": "uint256" - } + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256" + } ], "name": "setNumber", "outputs": [], "stateMutability": "nonpayable", "type": "function" - }, - { + }, + { "inputs": [], "name": "increment", "outputs": [], "stateMutability": "nonpayable", "type": "function" - } - ]; + } + ]; const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS); const param = contract.methods.setNumber(0x123).encodeABI(); @@ -51,8 +51,8 @@ async function main() { value: 0, from: senderAddr, input: param, - gas: 400000, // intrinsic gas too low - gasPrice: 100e9, + gas: 400000, // intrinsic gas too low + gasPrice: 100e9, feeRatio: 30, }; diff --git a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js index 65d454190..17e2c3d52 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js @@ -7,8 +7,8 @@ // 3) send ValueTransfer tx with the next nonce // then you can see Cancel tx with the next nonce + 1 +const { KlaytnWeb3, TxType } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3, TxType } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -32,7 +32,7 @@ async function main() { to: recieverAddr, value: 1e12, from: senderAddr, - gas: 300000, // intrinsic gas too low + gas: 300000, // intrinsic gas too low gasPrice: 100e9, feeRatio: 30, }; @@ -51,7 +51,7 @@ async function main() { type: TxType.FeeDelegatedCancelWithRatio, nonce: nextNonce + 1n, from: senderAddr, - gas: 300000, // intrinsic gas too low + gas: 300000, // intrinsic gas too low gasPrice: 100e9, feeRatio: 30, }; @@ -77,7 +77,7 @@ async function main() { console.log("sendResult", sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); - console.log( receipt ); + console.log(receipt); } main(); diff --git a/web3js-ext/example/valueTransfer.js b/web3js-ext/example/valueTransfer.js index 28e751162..93e9f138c 100644 --- a/web3js-ext/example/valueTransfer.js +++ b/web3js-ext/example/valueTransfer.js @@ -1,5 +1,5 @@ +const { KlaytnWeb3 } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; const addr = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; @@ -39,8 +39,8 @@ async function main() { data: data_increment, data: "0xdeadbeef", // trigger error type: 0x30, - } - //*/ + }; + //* / let signResult = await web3.eth.accounts.signTransaction(tx, sender.privateKey); console.log({ signResult }); diff --git a/web3js-ext/example/wallet.js b/web3js-ext/example/wallet.js index 70a95817e..3bb8b470f 100644 --- a/web3js-ext/example/wallet.js +++ b/web3js-ext/example/wallet.js @@ -1,5 +1,5 @@ +const { KlaytnWeb3 } = require("@klaytn/web3js-ext"); const { Web3 } = require("web3"); -const { KlaytnWeb3 } = require( "@klaytn/web3js-ext"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; @@ -8,17 +8,17 @@ async function main() { let provider = new Web3.providers.HttpProvider("https://public-en-baobab.klaytn.net"); let web3 = new KlaytnWeb3(provider); - let wallet = await web3.eth.accounts.wallet.create(2); + let wallet = await web3.eth.accounts.wallet.create(2); console.log(wallet); wallet = await web3.eth.accounts.wallet.add(senderPriv); - console.log(wallet); + console.log(wallet); wallet = await web3.eth.accounts.wallet.remove(senderAddr); - console.log(web3.eth.accounts.wallet); + console.log(web3.eth.accounts.wallet); wallet = await web3.eth.accounts.wallet.clear(); - console.log(wallet); + console.log(wallet); } main().catch(console.err); diff --git a/web3js-ext/src/web3/account.ts b/web3js-ext/src/web3/account.ts index 98edb05c4..bc32b3914 100644 --- a/web3js-ext/src/web3/account.ts +++ b/web3js-ext/src/web3/account.ts @@ -1,61 +1,60 @@ -import { Address, HexString, EthExecutionAPI, Bytes, Transaction, KeyStore, ETH_DATA_FORMAT } from 'web3-types'; -import { format, bytesToHex, hexToBytes, sha3Raw, toChecksumAddress, isHex } from 'web3-utils'; -import { Web3Context } from 'web3-core'; +import { KlaytnTxFactory } from "@klaytn/js-ext-core"; +import { Web3Context } from "web3-core"; +import { TransactionSigningError, UndefinedRawTransactionError } from "web3-errors"; import { - create, - decrypt, - encrypt, - hashMessage, - privateKeyToAddress, - privateKeyToAccount, - recover, - signTransaction, - sign, - Wallet, - TransactionFactory, - TypedTransaction, - SignTransactionResult, -} from 'web3-eth-accounts'; -import { isNullish } from 'web3-validator'; -import { TransactionSigningError, UndefinedRawTransactionError } from 'web3-errors'; + create, + decrypt, + encrypt, + hashMessage, + privateKeyToAddress, + privateKeyToAccount, + recover, + signTransaction, + sign, + Wallet, + TransactionFactory, + TypedTransaction, + SignTransactionResult, +} from "web3-eth-accounts"; +import { Address, HexString, EthExecutionAPI, Bytes, Transaction, KeyStore, ETH_DATA_FORMAT } from "web3-types"; +import { format, bytesToHex, hexToBytes, sha3Raw, toChecksumAddress, isHex } from "web3-utils"; +import { isNullish } from "web3-validator"; import { prepareTransaction } from "./klaytn_tx"; -import { KlaytnTxFactory } from "@klaytn/js-ext-core"; export const signTransactionAsFeePayer = async ( - transaction: TypedTransaction, - privateKey: HexString, - // To make it compatible with rest of the API, have to keep it async - // eslint-disable-next-line @typescript-eslint/require-await + transaction: TypedTransaction, + privateKey: HexString, + // To make it compatible with rest of the API, have to keep it async + // eslint-disable-next-line @typescript-eslint/require-await ): Promise => { - // @ts-ignore - const signedTx = transaction.signAsFeePayer(hexToBytes(privateKey)); - if (isNullish(signedTx.feePayer_v) || isNullish(signedTx.feePayer_r) || isNullish(signedTx.feePayer_s)) - throw new TransactionSigningError('Signer Error'); - - const validationErrors = signedTx.validate(true); - - if (validationErrors.length > 0) { - let errorString = 'Signer Error '; - for (const validationError of validationErrors) { - errorString += `${errorString} ${validationError}.`; - } - throw new TransactionSigningError(errorString); - } - - // @ts-ignore - const rawTx = bytesToHex(signedTx.serializeAsFeePayer()); - const txHash = sha3Raw(rawTx); // using keccak in web3-utils.sha3Raw instead of SHA3 (NIST Standard) as both are different - - return { - messageHash: bytesToHex(signedTx.getMessageToSignAsFeePayer(true)), - v: `0x${signedTx.feePayer_v.toString(16)}`, - r: `0x${signedTx.feePayer_r.toString(16).padStart(64, '0')}`, - s: `0x${signedTx.feePayer_s.toString(16).padStart(64, '0')}`, - rawTransaction: rawTx, - transactionHash: bytesToHex(txHash), - }; + // @ts-ignore + const signedTx = transaction.signAsFeePayer(hexToBytes(privateKey)); + if (isNullish(signedTx.feePayer_v) || isNullish(signedTx.feePayer_r) || isNullish(signedTx.feePayer_s)) { throw new TransactionSigningError("Signer Error"); } + + const validationErrors = signedTx.validate(true); + + if (validationErrors.length > 0) { + let errorString = "Signer Error "; + for (const validationError of validationErrors) { + errorString += `${errorString} ${validationError}.`; + } + throw new TransactionSigningError(errorString); + } + + // @ts-ignore + const rawTx = bytesToHex(signedTx.serializeAsFeePayer()); + const txHash = sha3Raw(rawTx); // using keccak in web3-utils.sha3Raw instead of SHA3 (NIST Standard) as both are different + + return { + messageHash: bytesToHex(signedTx.getMessageToSignAsFeePayer(true)), + v: `0x${signedTx.feePayer_v.toString(16)}`, + r: `0x${signedTx.feePayer_r.toString(16).padStart(64, "0")}`, + s: `0x${signedTx.feePayer_s.toString(16).padStart(64, "0")}`, + rawTransaction: rawTx, + transactionHash: bytesToHex(txHash), + }; }; @@ -70,123 +69,123 @@ export const signTransactionAsFeePayer = async ( * ``` */ export const recoverTransactionWithKlaytnTx = (rawTransaction: HexString): Address => { - if (isNullish(rawTransaction)) throw new UndefinedRawTransactionError(); - - const data = hexToBytes(rawTransaction); - let tx; - - if ( KlaytnTxFactory.has(data[0]) ) { - tx = KlaytnTxFactory.fromRLP(rawTransaction).toObject(); - - if ( !tx.from ) { - throw new Error('tx.from is not a property.'); - } else if ( typeof tx.from == "string") { - return toChecksumAddress(tx.from); - } else { - throw new Error('tx.from is not a string type.'); - } - } - - tx = TransactionFactory.fromSerializedData(data); - return toChecksumAddress(tx.getSenderAddress().toString()); + if (isNullish(rawTransaction)) { throw new UndefinedRawTransactionError(); } + + const data = hexToBytes(rawTransaction); + let tx; + + if (KlaytnTxFactory.has(data[0])) { + tx = KlaytnTxFactory.fromRLP(rawTransaction).toObject(); + + if (!tx.from) { + throw new Error("tx.from is not a property."); + } else if (typeof tx.from == "string") { + return toChecksumAddress(tx.from); + } else { + throw new Error("tx.from is not a string type."); + } + } + + tx = TransactionFactory.fromSerializedData(data); + return toChecksumAddress(tx.getSenderAddress().toString()); }; // We overrided web3/src/accounts.ts:initAccountsForContext // Below methods are bound to the context 'web3'. export const initAccountsForContext = (context: Web3Context) => { - const signTransactionWithContext = async (transaction: Transaction, privateKey: Bytes) => { - let tx; - - if (typeof transaction === "string") { - if (isHex(transaction)) { + const signTransactionWithContext = async (transaction: Transaction, privateKey: Bytes) => { + let tx; + + if (typeof transaction === "string") { + if (isHex(transaction)) { tx = KlaytnTxFactory.fromRLP(transaction).toObject(); - } else { + } else { throw new Error("String type input has to be RLP encoded Hex string."); - } - } else { - tx = transaction; - } - - let ttx = await prepareTransaction(tx, context, privateKey); - let priv = bytesToHex(privateKey); - return signTransaction(ttx, priv); - }; - - // New added function for Klaytn - const signTransactionAsFeePayerWithContext = async (transaction: any, privateKey: Bytes): Promise => { - let tx; - - if (typeof transaction === "string") { - if (isHex(transaction)) { - tx = KlaytnTxFactory.fromRLP(transaction).toObject(); - } else { - throw new Error("String type input has to be RLP encoded Hex string."); - } - } else { - tx = transaction; - } - - if (!tx.feePayer) { - tx.feePayer = privateKeyToAddress(privateKey); - } - - let ftx = await prepareTransaction(tx, context, privateKey); - let priv = bytesToHex(privateKey); - return signTransactionAsFeePayer(ftx, priv); - }; - - const privateKeyToAccountWithContext = (privateKey: Uint8Array | string) => { - const account = privateKeyToAccount(privateKey); - - return { - ...account, - signTransaction: async (transaction: Transaction) => - signTransactionWithContext(transaction, account.privateKey), - }; - }; - - // TODO : we will support KeyStore V4. - const decryptWithContext = async ( - keystore: KeyStore | string, - password: string, - options?: Record, - ) => { - const account = await decrypt(keystore, password, (options?.nonStrict as boolean) ?? true); - - return { - ...account, - signTransaction: async (transaction: Transaction) => - signTransactionWithContext(transaction, account.privateKey), - }; - }; - - const createWithContext = () => { - const account = create(); - - return { - ...account, - signTransaction: async (transaction: Transaction) => - signTransactionWithContext(transaction, account.privateKey), - }; - }; - - const wallet = new Wallet({ - create: createWithContext, - privateKeyToAccount: privateKeyToAccountWithContext, - decrypt: decryptWithContext, - }); - - return { - signTransaction: signTransactionWithContext, - signTransactionAsFeePayer: signTransactionAsFeePayerWithContext, - create: createWithContext, - privateKeyToAccount: privateKeyToAccountWithContext, - decrypt: decryptWithContext, - recoverTransaction: recoverTransactionWithKlaytnTx, - hashMessage, - sign, - recover, - encrypt, - wallet, - }; + } + } else { + tx = transaction; + } + + const ttx = await prepareTransaction(tx, context, privateKey); + const priv = bytesToHex(privateKey); + return signTransaction(ttx, priv); + }; + + // New added function for Klaytn + const signTransactionAsFeePayerWithContext = async (transaction: any, privateKey: Bytes): Promise => { + let tx; + + if (typeof transaction === "string") { + if (isHex(transaction)) { + tx = KlaytnTxFactory.fromRLP(transaction).toObject(); + } else { + throw new Error("String type input has to be RLP encoded Hex string."); + } + } else { + tx = transaction; + } + + if (!tx.feePayer) { + tx.feePayer = privateKeyToAddress(privateKey); + } + + const ftx = await prepareTransaction(tx, context, privateKey); + const priv = bytesToHex(privateKey); + return signTransactionAsFeePayer(ftx, priv); + }; + + const privateKeyToAccountWithContext = (privateKey: Uint8Array | string) => { + const account = privateKeyToAccount(privateKey); + + return { + ...account, + signTransaction: async (transaction: Transaction) => + signTransactionWithContext(transaction, account.privateKey), + }; + }; + + // TODO : we will support KeyStore V4. + const decryptWithContext = async ( + keystore: KeyStore | string, + password: string, + options?: Record, + ) => { + const account = await decrypt(keystore, password, (options?.nonStrict as boolean) ?? true); + + return { + ...account, + signTransaction: async (transaction: Transaction) => + signTransactionWithContext(transaction, account.privateKey), + }; + }; + + const createWithContext = () => { + const account = create(); + + return { + ...account, + signTransaction: async (transaction: Transaction) => + signTransactionWithContext(transaction, account.privateKey), + }; + }; + + const wallet = new Wallet({ + create: createWithContext, + privateKeyToAccount: privateKeyToAccountWithContext, + decrypt: decryptWithContext, + }); + + return { + signTransaction: signTransactionWithContext, + signTransactionAsFeePayer: signTransactionAsFeePayerWithContext, + create: createWithContext, + privateKeyToAccount: privateKeyToAccountWithContext, + decrypt: decryptWithContext, + recoverTransaction: recoverTransactionWithKlaytnTx, + hashMessage, + sign, + recover, + encrypt, + wallet, + }; }; \ No newline at end of file diff --git a/web3js-ext/src/web3/klaytn_tx.ts b/web3js-ext/src/web3/klaytn_tx.ts index 01d081f0e..de163fecf 100644 --- a/web3js-ext/src/web3/klaytn_tx.ts +++ b/web3js-ext/src/web3/klaytn_tx.ts @@ -1,13 +1,13 @@ -import { Transaction as LegacyTransaction, TypedTransaction, TxData, TxOptions, ECDSASignature } from "web3-eth-accounts"; -import { bytesToHex, hexToBytes, toHex, toNumber, numberToHex, toBigInt } from "web3-utils"; -import { keccak256 } from 'ethereum-cryptography/keccak.js'; -import { RLP } from '@ethereumjs/rlp'; -import { Bytes, Numbers, Transaction as TransactionFields, Uint, Web3Context } from "web3"; +import { RLP } from "@ethereumjs/rlp"; +import { keccak256 } from "ethereum-cryptography/keccak.js"; +import * as ethereumCryptography from "ethereum-cryptography/secp256k1.js"; import _ from "lodash"; +import { Bytes, Numbers, Transaction as TransactionFields, Uint, Web3Context } from "web3"; import { prepareTransactionForSigning } from "web3-eth"; +import { Transaction as LegacyTransaction, TypedTransaction, TxData, TxOptions, ECDSASignature } from "web3-eth-accounts"; +import { bytesToHex, hexToBytes, toHex, toNumber, numberToHex, toBigInt } from "web3-utils"; // eslint-disable-next-line import/extensions -import * as ethereumCryptography from 'ethereum-cryptography/secp256k1.js'; export const secp256k1 = ethereumCryptography.secp256k1 ?? ethereumCryptography; @@ -28,8 +28,8 @@ export interface KlaytnTxData extends TxData { // See web3-types/src/eth_types.ts:TransactionBase and its child interfaces const web3jsAllowedTransactionKeys = [ "value", "accessList", "common", "gas", "gasPrice", "type", "maxFeePerGas", - "maxPriorityFeePerGas", "data", "input", "nonce", "chain", "hardfork", - "chainId", "networkId", "gasLimit", "yParity", "v", "r", "s", + "maxPriorityFeePerGas", "data", "input", "nonce", "chain", "hardfork", + "chainId", "networkId", "gasLimit", "yParity", "v", "r", "s", "from", "to", ]; @@ -60,11 +60,10 @@ export function saveCustomFields(tx: any): any { export async function prepareTransaction( transaction: TransactionFields, context: Web3Context, - privateKey: Bytes): Promise -{ + privateKey: Bytes): Promise { if (KlaytnTxFactory.has(transaction.type)) { transaction = _.clone(transaction); - let savedFields = saveCustomFields(transaction); + const savedFields = saveCustomFields(transaction); // prepareTransactionForSigning expects ANY value (not undefined) // because otherwise eth_estimateGas will fail with an RPC error '"0x"..*hexutil.Big'. @@ -72,10 +71,10 @@ export async function prepareTransaction( // Therefore we fill with zero value if not defined. transaction.value ??= 0; - let tx = await prepareTransactionForSigning( + const tx = await prepareTransactionForSigning( transaction, context, privateKey, true, true); - let txData = { ...tx, ...savedFields }; + const txData = { ...tx, ...savedFields }; // Below fields might be // (1) not specified at the first place, @@ -84,7 +83,7 @@ export async function prepareTransaction( txData.from ??= transaction.from; txData.chainId ??= tx.common.chainId(); - let txOptions = (tx as any).txOptions; + const txOptions = (tx as any).txOptions; return new KlaytnTx(txData, txOptions); } else { @@ -102,7 +101,6 @@ export async function prepareTransaction( // - _processSignature // - serialize export class KlaytnTx extends LegacyTransaction { - // BaseTransaction._type is always 0. KlaytnTx._klaytnType is nonzero. private readonly _klaytnType: number; public readonly from?: string; @@ -152,7 +150,7 @@ export class KlaytnTx extends LegacyTransaction { this.feePayerSignatures = txData.feePayerSignatures; this.feeRatio = txData.feeRatio; - let klaytnTxObject = { + const klaytnTxObject = { // Convert to type understood by CoreKlaytnTx. // TODO: add more fields for other TxTypes type: toHex(this.type || 0), @@ -165,17 +163,17 @@ export class KlaytnTx extends LegacyTransaction { data: bytesToHex(this.data), input: bytesToHex(this.data), chainId: this.chainId ? toHex(this.chainId) : undefined, - humanReadable: false, + humanReadable: false, codeFormat: 0x00, key: this.key, feePayer: this.feePayer, txSignatures: this.txSignatures, feePayerSignatures: this.feePayerSignatures, - feeRatio: this.feeRatio, - }; + feeRatio: this.feeRatio, + }; - if ( txData.type == TxType.SmartContractDeploy || - txData.type == TxType.FeeDelegatedSmartContractDeploy || + if (txData.type == TxType.SmartContractDeploy || + txData.type == TxType.FeeDelegatedSmartContractDeploy || txData.type == TxType.FeeDelegatedSmartContractDeployWithRatio) { klaytnTxObject.to = "0x0000000000000000000000000000000000000000"; } @@ -183,7 +181,7 @@ export class KlaytnTx extends LegacyTransaction { // A readonly CoreKlaytnTx object this.klaytnTxData = KlaytnTxFactory.fromObject(klaytnTxObject); - if (this.v && this.r && this. s) { + if (this.v && this.r && this.s) { this.klaytnTxData.addSenderSig([ Number(this.v), numberToHex(this.r), @@ -233,23 +231,23 @@ export class KlaytnTx extends LegacyTransaction { } public signAsFeePayer(privateKey: Uint8Array): KlaytnTx { - if (privateKey.length !== 32) { - const msg = this._errorMsg('Private key must be 32 bytes in length.'); - throw new Error(msg); - } + if (privateKey.length !== 32) { + const msg = this._errorMsg("Private key must be 32 bytes in length."); + throw new Error(msg); + } - const msgHash = this.getMessageToSignAsFeePayer(true); + const msgHash = this.getMessageToSignAsFeePayer(true); const signature = secp256k1.sign(msgHash, privateKey); - const signatureBytes = signature.toCompactRawBytes(); + const signatureBytes = signature.toCompactRawBytes(); - const r = signatureBytes.subarray(0, 32); - const s = signatureBytes.subarray(32, 64); - const v = BigInt(signature.recovery! + 27); + const r = signatureBytes.subarray(0, 32); + const s = signatureBytes.subarray(32, 64); + const v = BigInt(signature.recovery! + 27); - const tx = this._processSignatureAsFeePayer(v, r, s); + const tx = this._processSignatureAsFeePayer(v, r, s); - return tx; - } + return tx; + } // Returns a new KlaytnTx by adding the signature protected _processSignature(v: bigint, r: Uint8Array, s: Uint8Array): KlaytnTx { @@ -281,8 +279,7 @@ export class KlaytnTx extends LegacyTransaction { // Returns the raw transaction public serialize(): Uint8Array { - - let tx = this.klaytnTxData; + const tx = this.klaytnTxData; if (isFeePayerSigTxType(tx.type)) { return hexToBytes(tx.senderTxHashRLP()); @@ -292,8 +289,7 @@ export class KlaytnTx extends LegacyTransaction { // Returns the raw transaction public serializeAsFeePayer(): Uint8Array { - - let tx = this.klaytnTxData; + const tx = this.klaytnTxData; return hexToBytes(tx.txHashRLP()); } diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index d233cdedb..1f4c193b9 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -1,14 +1,8 @@ +import { TxType } from "@klaytn/ethers-ext"; +import { AccountKey } from "@klaytn/ethers-ext/dist/src/core"; +import { KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; +import _ from "lodash"; import { Web3Context, Web3PromiEvent } from "web3-core"; -import { - Bytes, DataFormat, FormatType, TransactionCall, TransactionReceipt, - EthExecutionAPI, ETH_DATA_FORMAT, DEFAULT_RETURN_FORMAT, ContractAbi, AbiErrorFragment -} from "web3-types"; -import { format, toHex, rejectIfTimeout, pollTillDefined } from "web3-utils"; -import { - SendSignedTransactionOptions, SendSignedTransactionEvents, sendSignedTransaction, - transactionReceiptSchema, getTransactionReceipt, call, - RevertReason, RevertReasonWithCustomError -} from "web3-eth"; import { ContractExecutionError, InvalidResponseError, @@ -18,15 +12,23 @@ import { TransactionSendTimeoutError, TransactionPollingTimeoutError, Eip838ExecutionError, -} from 'web3-errors'; +} from "web3-errors"; +import { + SendSignedTransactionOptions, SendSignedTransactionEvents, sendSignedTransaction, + transactionReceiptSchema, getTransactionReceipt, call, + RevertReason, RevertReasonWithCustomError +} from "web3-eth"; import { isAbiErrorFragment, decodeContractErrorData } from "web3-eth-abi"; -import _ from "lodash"; +import { + Bytes, DataFormat, FormatType, TransactionCall, TransactionReceipt, + EthExecutionAPI, ETH_DATA_FORMAT, DEFAULT_RETURN_FORMAT, ContractAbi, AbiErrorFragment +} from "web3-types"; +import { format, toHex, rejectIfTimeout, pollTillDefined } from "web3-utils"; -import { KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; import { saveCustomFields } from "./klaytn_tx"; -import { TxType } from "@klaytn/ethers-ext"; -import { AccountKey } from "@klaytn/ethers-ext/dist/src/core"; + + import { AccountKeyType } from "."; // Platform-independent NodeJS timeout types @@ -44,10 +46,9 @@ export function klay_sendSignedTransaction< returnFormat: ReturnFormat, options: SendSignedTransactionOptions = { checkRevertBeforeSending: true }, ): Web3PromiEvent> { - // Short circuit if the transaction is an Ethereum transaction const signedTransactionFormattedHex = format( - { format: 'bytes' }, + { format: "bytes" }, signedTransaction, ETH_DATA_FORMAT, ); @@ -59,11 +60,11 @@ export function klay_sendSignedTransaction< // Parse the signed KlaytnTx const unSerializedTransaction = KlaytnTxFactory.fromRLP(signedTransactionFormattedHex).toObject(); - // hot fix + // hot fix // TODO : the code below will be deleted after deploying same logic in js-ext-core - if (unSerializedTransaction.nonce == "0x") unSerializedTransaction.nonce = 0; - if (unSerializedTransaction.value == "0x") unSerializedTransaction.value = 0; - if (unSerializedTransaction.to == "0x") unSerializedTransaction.to = "0x0000000000000000000000000000000000000000"; + if (unSerializedTransaction.nonce == "0x") { unSerializedTransaction.nonce = 0; } + if (unSerializedTransaction.value == "0x") { unSerializedTransaction.value = 0; } + if (unSerializedTransaction.to == "0x") { unSerializedTransaction.to = "0x0000000000000000000000000000000000000000"; } const unSerializedTransactionForCall = getRpcTxObject(unSerializedTransaction); @@ -89,21 +90,21 @@ export function klay_sendSignedTransaction< reason, ); - if (promiEvent.listenerCount('error') > 0) { - promiEvent.emit('error', error); + if (promiEvent.listenerCount("error") > 0) { + promiEvent.emit("error", error); } return error; } } return null; - } + }; const doSend = async ( promiEvent: Web3PromiEvent>, ) => { - if (promiEvent.listenerCount('sending') > 0) { - promiEvent.emit('sending', signedTransactionFormattedHex); + if (promiEvent.listenerCount("sending") > 0) { + promiEvent.emit("sending", signedTransactionFormattedHex); } const transactionHash = await trySendTransaction( @@ -111,20 +112,20 @@ export function klay_sendSignedTransaction< signedTransactionFormattedHex ); const transactionHashFormatted = format( - { format: 'bytes32' }, + { format: "bytes32" }, transactionHash as Bytes, returnFormat ); - if (promiEvent.listenerCount('sent') > 0) { - promiEvent.emit('sent', signedTransactionFormattedHex); + if (promiEvent.listenerCount("sent") > 0) { + promiEvent.emit("sent", signedTransactionFormattedHex); } - if (promiEvent.listenerCount('transactionHash') > 0) { - promiEvent.emit('transactionHash', transactionHashFormatted); + if (promiEvent.listenerCount("transactionHash") > 0) { + promiEvent.emit("transactionHash", transactionHashFormatted); } return transactionHash; - } + }; const doWait = async ( promiEvent: Web3PromiEvent>, @@ -136,24 +137,24 @@ export function klay_sendSignedTransaction< web3Context, transactionHash, returnFormat, - ) + ); const transactionReceiptFormatted = format( transactionReceiptSchema, transactionReceipt, returnFormat, ); - if (promiEvent.listenerCount('receipt') > 0) { - promiEvent.emit('receipt', transactionReceiptFormatted); + if (promiEvent.listenerCount("receipt") > 0) { + promiEvent.emit("receipt", transactionReceiptFormatted); } - if (promiEvent.listenerCount('confirmation') > 0) { + if (promiEvent.listenerCount("confirmation") > 0) { // Klaytn transactions are immediately confirmed. - promiEvent.emit('confirmation', { - confirmations: format({ format: 'uint' }, 1 as number, returnFormat), + promiEvent.emit("confirmation", { + confirmations: format({ format: "uint" }, 1 as number, returnFormat), receipt: transactionReceiptFormatted, latestBlockHash: format( - { format: 'bytes32' }, + { format: "bytes32" }, transactionReceipt.blockHash as Bytes, returnFormat, ), @@ -175,16 +176,15 @@ export function klay_sendSignedTransaction< options?.contractAbi, ); - if (promiEvent.listenerCount('error') > 0) { - promiEvent.emit('error', error); + if (promiEvent.listenerCount("error") > 0) { + promiEvent.emit("error", error); } reject(error); } else { resolve(transactionReceiptFormatted as unknown as ResolveType); } - - } + }; const doError = async ( promiEvent: Web3PromiEvent>, @@ -209,13 +209,13 @@ export function klay_sendSignedTransaction< _error instanceof TransactionRevertWithCustomError || _error instanceof TransactionRevertedWithoutReasonError || _error instanceof TransactionRevertInstructionError) && - promiEvent.listenerCount('error') > 0 + promiEvent.listenerCount("error") > 0 ) { - promiEvent.emit('error', _error); + promiEvent.emit("error", _error); } reject(_error); - } + }; const promiEvent = new Web3PromiEvent>( (resolve, reject) => { @@ -226,14 +226,14 @@ export function klay_sendSignedTransaction< if (checkError) { reject(checkError); return; - } + } const transactionHash = await doSend(promiEvent); await doWait(promiEvent, resolve, reject, transactionHash); } catch (error) { await doError(promiEvent, reject, error); } - })() + })(); }); }); return promiEvent; @@ -267,7 +267,7 @@ export async function trySendTransaction( return await Promise.race([ sendRpc(), rejectOnSendTimeout, - ]) + ]); } finally { clearTimeout(sendTimeoutId as TimeoutT); } @@ -286,7 +286,7 @@ export async function waitForTransactionReceipt try { return getTransactionReceipt(web3Context, transactionHash, returnFormat); } catch (error) { - console.warn('An error happen while trying to get the transaction receipt', error); + console.warn("An error happen while trying to get the transaction receipt", error); return undefined; } }, pollingInterval); @@ -340,7 +340,7 @@ export async function getTransactionError( error = new TransactionRevertedWithoutReasonError< FormatType >(transactionReceiptFormatted); - } else if (typeof _reason === 'string') { + } else if (typeof _reason === "string") { error = new TransactionRevertInstructionError>( _reason, undefined, @@ -376,57 +376,57 @@ export async function getTransactionError( // See web3-eth/src/utils/get_revert_reason.ts export const parseTransactionError = (error: unknown, contractAbi?: ContractAbi) => { - if ( - error instanceof ContractExecutionError && + if ( + error instanceof ContractExecutionError && error.innerError instanceof Eip838ExecutionError - ) { - if (contractAbi !== undefined) { - const errorsAbi = contractAbi.filter(abi => - isAbiErrorFragment(abi), - ) as unknown as AbiErrorFragment[]; - decodeContractErrorData(errorsAbi, error.innerError); - - return { - reason: error.innerError.message, - signature: error.innerError.data?.slice(0, 10), - data: error.innerError.data?.substring(10), - customErrorName: error.innerError.errorName, - customErrorDecodedSignature: error.innerError.errorSignature, - customErrorArguments: error.innerError.errorArgs, - } as RevertReasonWithCustomError; - } - - return { - reason: error.innerError.message, - signature: error.innerError.data?.slice(0, 10), - data: error.innerError.data?.substring(10), - } as RevertReason; - } - - if ( - error instanceof InvalidResponseError && + ) { + if (contractAbi !== undefined) { + const errorsAbi = contractAbi.filter((abi) => + isAbiErrorFragment(abi), + ) as unknown as AbiErrorFragment[]; + decodeContractErrorData(errorsAbi, error.innerError); + + return { + reason: error.innerError.message, + signature: error.innerError.data?.slice(0, 10), + data: error.innerError.data?.substring(10), + customErrorName: error.innerError.errorName, + customErrorDecodedSignature: error.innerError.errorSignature, + customErrorArguments: error.innerError.errorArgs, + } as RevertReasonWithCustomError; + } + + return { + reason: error.innerError.message, + signature: error.innerError.data?.slice(0, 10), + data: error.innerError.data?.substring(10), + } as RevertReason; + } + + if ( + error instanceof InvalidResponseError && !Array.isArray(error.innerError) && error.innerError !== undefined - ) { - return error.innerError.message; - } + ) { + return error.innerError.message; + } - throw error; + throw error; }; // See web3-eth/src/utils/get_revert_reason.ts export async function getRevertReason< ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT, >( - web3Context: Web3Context, - transaction: TransactionCall, - contractAbi?: ContractAbi, - returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, + web3Context: Web3Context, + transaction: TransactionCall, + contractAbi?: ContractAbi, + returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, ): Promise { - try { - await call(web3Context, transaction, web3Context.defaultBlock, returnFormat); - return undefined; - } catch (error) { - return parseTransactionError(error, contractAbi); - } + try { + await call(web3Context, transaction, web3Context.defaultBlock, returnFormat); + return undefined; + } catch (error) { + return parseTransactionError(error, contractAbi); + } } diff --git a/web3js-ext/src/web3/utils.ts b/web3js-ext/src/web3/utils.ts index 09e546b31..985516ae9 100644 --- a/web3js-ext/src/web3/utils.ts +++ b/web3js-ext/src/web3/utils.ts @@ -3,10 +3,10 @@ import { toWei, fromWei, toBigInt } from "web3-utils"; // Equivalent to web3.utils.fromWei export function fromPeb(number: any, unitName?: string): string { - return formatKlayUnits(number, unitName); + return formatKlayUnits(number, unitName); } // Equivalent to web3.utils.toWei -export function toPeb(value: string, unitName?: string): string { - return parseKlayUnits(value, unitName).toString(); +export function toPeb(value: string, unitName?: string): string { + return parseKlayUnits(value, unitName).toString(); } \ No newline at end of file diff --git a/web3js-ext/src/web3/web3.ts b/web3js-ext/src/web3/web3.ts index d19080bde..90966a93a 100644 --- a/web3js-ext/src/web3/web3.ts +++ b/web3js-ext/src/web3/web3.ts @@ -1,10 +1,10 @@ +import _ from "lodash"; import Web3, {Bytes, Web3Context} from "web3"; -import { DataFormat, DEFAULT_RETURN_FORMAT } from "web3-types"; import { SendTransactionOptions } from "web3-eth"; -import _ from "lodash"; +import { DataFormat, DEFAULT_RETURN_FORMAT } from "web3-types"; -import { klay_sendSignedTransaction } from "./send_transaction"; import { initAccountsForContext } from "./account"; +import { klay_sendSignedTransaction } from "./send_transaction"; export class KlaytnWeb3 extends Web3 { constructor(provider: any) { @@ -26,9 +26,8 @@ export class KlaytnWeb3 extends Web3 { // except a few methods below which call klay_ RPCs despite its name 'web3.eth'. this.eth.getProtocolVersion = this.eth_getProtocolVersion(this); this.eth.sendSignedTransaction = this.eth_sendSignedTransaction(this); - - // TODO: Connect web3.klay, web3.net, etc from @klaytn/web3rpc + // TODO: Connect web3.klay, web3.net, etc from @klaytn/web3rpc } eth_getProtocolVersion(context: Web3Context): typeof this.eth.getProtocolVersion { @@ -38,8 +37,8 @@ export class KlaytnWeb3 extends Web3 { return context.requestManager.send({ method: "klay_protocolVersion", params: [], - }) - } + }); + }; } eth_sendSignedTransaction(context: Web3Context): typeof this.eth.sendSignedTransaction { @@ -49,8 +48,8 @@ export class KlaytnWeb3 extends Web3 { transaction: Bytes, returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, options?: SendTransactionOptions) => { - // TODO: use klay_sendRawTransaction - return klay_sendSignedTransaction(context, transaction, returnFormat, options) - } + // TODO: use klay_sendRawTransaction + return klay_sendSignedTransaction(context, transaction, returnFormat, options); + }; } } From 367052e8405881190ad345a82b0f7e3e71641fbc Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 15:46:06 +0900 Subject: [PATCH 50/69] web3js: Lint manual fix --- ...untKeyWeightedMultiSig_02_valueTransfer.js | 4 +- .../transactions/Basic_38_TxTypeCancel.js | 2 +- .../FeeDel_39_TxTypeFeeDelegatedCancel.js | 2 +- ...el_3a_TxTypeFeeDelegatedCancelWithRatio.js | 2 +- web3js-ext/example/valueTransfer.js | 55 ------------------- web3js-ext/src/web3/account.ts | 8 +-- web3js-ext/src/web3/index.ts | 10 ++-- web3js-ext/src/web3/send_transaction.ts | 10 +--- web3js-ext/src/web3/utils.ts | 1 - 9 files changed, 14 insertions(+), 80 deletions(-) delete mode 100644 web3js-ext/example/valueTransfer.js diff --git a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js index cf42a1766..501780975 100644 --- a/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js +++ b/web3js-ext/example/accountKey/AccountKeyWeightedMultiSig_02_valueTransfer.js @@ -4,12 +4,12 @@ // gasLimit: Must be large enough const { KlaytnWeb3, TxType, toPeb, parseTransaction } = require("@klaytn/web3js-ext"); -const { secp256k1 } = require("ethereum-cryptography/secp256k1.js"); const { Web3 } = require("web3"); // the same address of sender in AccountKeyWeightedMultiSig_01_accountUpdate.js const senderAddr = "0x2bf611d14d330fd3688d10f2201321eacc8aa2ce"; const senderPriv = "0x31fadf868e68fd2e3f7a1c528023c9a86a45db850e9d6b82c1a82d4c75b469d1"; +const receiverAddr = "0x2bf611d14d330fd3688d10f2201321eacc8aa2ce"; const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a"; const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac"; @@ -22,7 +22,7 @@ async function main() { type: TxType.ValueTransfer, gasLimit: 100000, to: receiverAddr, - value: toPeb("1", "KLAY"), + value: toPeb("0.01", "KLAY"), from: senderAddr, }; diff --git a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js index c12da1d91..8e540daa8 100644 --- a/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js +++ b/web3js-ext/example/transactions/Basic_38_TxTypeCancel.js @@ -50,7 +50,7 @@ async function main() { tx.nonce = nextNonce; signResult = await web3.eth.accounts.signTransaction(tx, sender.privateKey); - sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); + let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); console.log("sendResult", sendResult); diff --git a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js index 3a1424c50..3505e2d2f 100644 --- a/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js +++ b/web3js-ext/example/transactions/FeeDel_39_TxTypeFeeDelegatedCancel.js @@ -69,7 +69,7 @@ async function main() { // feePayer sign signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log({signResult}); - sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); + let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); console.log("sendResult", sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); diff --git a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js index 17e2c3d52..5603dc6d0 100644 --- a/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js +++ b/web3js-ext/example/transactions/PartialFeeDel_3a_TxTypeFeeDelegatedCancelWithRatio.js @@ -73,7 +73,7 @@ async function main() { // feePayer sign signResult = await web3.eth.accounts.signTransactionAsFeePayer(senderTx.rawTransaction, feePayer.privateKey); console.log({signResult}); - sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); + let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); console.log("sendResult", sendResult); let receipt = await web3.eth.getTransactionReceipt(sendResult.transactionHash); diff --git a/web3js-ext/example/valueTransfer.js b/web3js-ext/example/valueTransfer.js deleted file mode 100644 index 93e9f138c..000000000 --- a/web3js-ext/example/valueTransfer.js +++ /dev/null @@ -1,55 +0,0 @@ -const { KlaytnWeb3 } = require("@klaytn/web3js-ext"); -const { Web3 } = require("web3"); - -const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; -const addr = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; -const to = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8"; -// const url = "http://localhost:8545"; -const url = "https://public-en-baobab.klaytn.net"; -const contractAddr = "0x5FbDB2315678afecb367f032d93F642f64180aa3"; -const data_increment = "0xd09de08a"; // Counter.sol:increment() - -async function main() { - let provider = new Web3.providers.HttpProvider(url); - - // let web3 = new Web3(addr); - let web3 = new KlaytnWeb3(provider); - - let sender = web3.eth.accounts.privateKeyToAccount(priv); - console.log({ sender }); - - /* - let tx = { - from: sender.address, - to: to, - value: 1e9, - // nonce: await web3.eth.getTransactionCount(addr), - // gas: 21000, - // gasPrice: 25e9, - type: 0x08, - }; - /*/ - let tx = { - from: sender.address, - to: contractAddr, - value: 0, - nonce: await web3.eth.getTransactionCount(addr), - gas: 100000, - gasPrice: 25e9, - data: data_increment, - data: "0xdeadbeef", // trigger error - type: 0x30, - }; - //* / - - let signResult = await web3.eth.accounts.signTransaction(tx, sender.privateKey); - console.log({ signResult }); - - let sendResult = await web3.eth.sendSignedTransaction(signResult.rawTransaction); - let txhash = sendResult.transactionHash; - - let receipt = await web3.eth.getTransactionReceipt(txhash); - console.log({ receipt }); -} - -main().catch(console.err); diff --git a/web3js-ext/src/web3/account.ts b/web3js-ext/src/web3/account.ts index bc32b3914..aa04753ba 100644 --- a/web3js-ext/src/web3/account.ts +++ b/web3js-ext/src/web3/account.ts @@ -16,8 +16,8 @@ import { TypedTransaction, SignTransactionResult, } from "web3-eth-accounts"; -import { Address, HexString, EthExecutionAPI, Bytes, Transaction, KeyStore, ETH_DATA_FORMAT } from "web3-types"; -import { format, bytesToHex, hexToBytes, sha3Raw, toChecksumAddress, isHex } from "web3-utils"; +import { Address, HexString, EthExecutionAPI, Bytes, Transaction, KeyStore } from "web3-types"; +import { bytesToHex, hexToBytes, sha3Raw, toChecksumAddress, isHex } from "web3-utils"; import { isNullish } from "web3-validator"; import { prepareTransaction } from "./klaytn_tx"; @@ -98,9 +98,9 @@ export const initAccountsForContext = (context: Web3Context) => if (typeof transaction === "string") { if (isHex(transaction)) { - tx = KlaytnTxFactory.fromRLP(transaction).toObject(); + tx = KlaytnTxFactory.fromRLP(transaction).toObject(); } else { - throw new Error("String type input has to be RLP encoded Hex string."); + throw new Error("String type input has to be RLP encoded Hex string."); } } else { tx = transaction; diff --git a/web3js-ext/src/web3/index.ts b/web3js-ext/src/web3/index.ts index cc2d66782..8c7a8fd06 100644 --- a/web3js-ext/src/web3/index.ts +++ b/web3js-ext/src/web3/index.ts @@ -1,7 +1,5 @@ -export * from "../../../js-ext-core/dist"; -// export * from "@klaytn/js-ext-core/tx"; -// export * from "@klaytn/js-ext-core/util"; +export * from "@klaytn/js-ext-core/util"; -export { KlaytnWeb3 } from "./web3"; -export { KlaytnTx } from "./klaytn_tx"; -export { fromPeb, toPeb } from "./utils"; \ No newline at end of file +export * from "./web3"; +export * from "./klaytn_tx"; +export { fromPeb, toPeb } from "./utils"; // TODO: remove when js-ext-core toPeb is fixed \ No newline at end of file diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/web3/send_transaction.ts index 1f4c193b9..6c0d91a72 100644 --- a/web3js-ext/src/web3/send_transaction.ts +++ b/web3js-ext/src/web3/send_transaction.ts @@ -1,7 +1,4 @@ -import { TxType } from "@klaytn/ethers-ext"; -import { AccountKey } from "@klaytn/ethers-ext/dist/src/core"; import { KlaytnTxFactory, getRpcTxObject } from "@klaytn/js-ext-core"; -import _ from "lodash"; import { Web3Context, Web3PromiEvent } from "web3-core"; import { ContractExecutionError, @@ -23,14 +20,9 @@ import { Bytes, DataFormat, FormatType, TransactionCall, TransactionReceipt, EthExecutionAPI, ETH_DATA_FORMAT, DEFAULT_RETURN_FORMAT, ContractAbi, AbiErrorFragment } from "web3-types"; -import { format, toHex, rejectIfTimeout, pollTillDefined } from "web3-utils"; +import { format, rejectIfTimeout, pollTillDefined } from "web3-utils"; -import { saveCustomFields } from "./klaytn_tx"; - - -import { AccountKeyType } from "."; - // Platform-independent NodeJS timeout types type TimeoutT = ReturnType; diff --git a/web3js-ext/src/web3/utils.ts b/web3js-ext/src/web3/utils.ts index 985516ae9..34e12c228 100644 --- a/web3js-ext/src/web3/utils.ts +++ b/web3js-ext/src/web3/utils.ts @@ -1,5 +1,4 @@ import { parseKlayUnits, formatKlayUnits } from "@klaytn/js-ext-core"; -import { toWei, fromWei, toBigInt } from "web3-utils"; // Equivalent to web3.utils.fromWei export function fromPeb(number: any, unitName?: string): string { From cc9df4da85cd0baf17d184f0858ecec1183ccce2 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 15:48:23 +0900 Subject: [PATCH 51/69] web3js: Move files out of src/web3 --- web3js-ext/src/{web3 => }/account.ts | 0 web3js-ext/src/index.ts | 6 +++++- web3js-ext/src/{web3 => }/klaytn_tx.ts | 0 web3js-ext/src/{web3 => }/send_transaction.ts | 0 web3js-ext/src/{web3 => }/utils.ts | 0 web3js-ext/src/{web3 => }/web3.ts | 0 web3js-ext/src/web3/index.ts | 5 ----- web3js-ext/test/{web3 => }/sig.spec.ts | 2 +- web3js-ext/tsconfig.json | 2 +- 9 files changed, 7 insertions(+), 8 deletions(-) rename web3js-ext/src/{web3 => }/account.ts (100%) rename web3js-ext/src/{web3 => }/klaytn_tx.ts (100%) rename web3js-ext/src/{web3 => }/send_transaction.ts (100%) rename web3js-ext/src/{web3 => }/utils.ts (100%) rename web3js-ext/src/{web3 => }/web3.ts (100%) delete mode 100644 web3js-ext/src/web3/index.ts rename web3js-ext/test/{web3 => }/sig.spec.ts (87%) diff --git a/web3js-ext/src/web3/account.ts b/web3js-ext/src/account.ts similarity index 100% rename from web3js-ext/src/web3/account.ts rename to web3js-ext/src/account.ts diff --git a/web3js-ext/src/index.ts b/web3js-ext/src/index.ts index ba16a2b7f..8c7a8fd06 100644 --- a/web3js-ext/src/index.ts +++ b/web3js-ext/src/index.ts @@ -1 +1,5 @@ -export { KlaytnWeb3 } from "./web3"; +export * from "@klaytn/js-ext-core/util"; + +export * from "./web3"; +export * from "./klaytn_tx"; +export { fromPeb, toPeb } from "./utils"; // TODO: remove when js-ext-core toPeb is fixed \ No newline at end of file diff --git a/web3js-ext/src/web3/klaytn_tx.ts b/web3js-ext/src/klaytn_tx.ts similarity index 100% rename from web3js-ext/src/web3/klaytn_tx.ts rename to web3js-ext/src/klaytn_tx.ts diff --git a/web3js-ext/src/web3/send_transaction.ts b/web3js-ext/src/send_transaction.ts similarity index 100% rename from web3js-ext/src/web3/send_transaction.ts rename to web3js-ext/src/send_transaction.ts diff --git a/web3js-ext/src/web3/utils.ts b/web3js-ext/src/utils.ts similarity index 100% rename from web3js-ext/src/web3/utils.ts rename to web3js-ext/src/utils.ts diff --git a/web3js-ext/src/web3/web3.ts b/web3js-ext/src/web3.ts similarity index 100% rename from web3js-ext/src/web3/web3.ts rename to web3js-ext/src/web3.ts diff --git a/web3js-ext/src/web3/index.ts b/web3js-ext/src/web3/index.ts deleted file mode 100644 index 8c7a8fd06..000000000 --- a/web3js-ext/src/web3/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "@klaytn/js-ext-core/util"; - -export * from "./web3"; -export * from "./klaytn_tx"; -export { fromPeb, toPeb } from "./utils"; // TODO: remove when js-ext-core toPeb is fixed \ No newline at end of file diff --git a/web3js-ext/test/web3/sig.spec.ts b/web3js-ext/test/sig.spec.ts similarity index 87% rename from web3js-ext/test/web3/sig.spec.ts rename to web3js-ext/test/sig.spec.ts index 18f833a80..bc0c0395e 100644 --- a/web3js-ext/test/web3/sig.spec.ts +++ b/web3js-ext/test/sig.spec.ts @@ -1,7 +1,7 @@ import { assert } from "chai"; import Web3 from "web3"; -import { KlaytnWeb3 } from "../../src/web3"; +import { KlaytnWeb3 } from "../src/web3"; describe("KlaytnWeb3", () => { it("success", () => { diff --git a/web3js-ext/tsconfig.json b/web3js-ext/tsconfig.json index e31a2b94d..fe90847db 100644 --- a/web3js-ext/tsconfig.json +++ b/web3js-ext/tsconfig.json @@ -7,7 +7,7 @@ "declarationMap": true, "sourceMap": true, "outDir": "./dist", - "rootDirs": ["./src", "./test"], + "rootDir": "./src", "strict": true, "esModuleInterop": true }, From 0d0cbf6207296a6dde682300ff56be808c32a00a Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 15:53:51 +0900 Subject: [PATCH 52/69] web3js: Update deps --- web3js-ext/package-lock.json | 327 ++++++++++++++++++----------------- 1 file changed, 171 insertions(+), 156 deletions(-) diff --git a/web3js-ext/package-lock.json b/web3js-ext/package-lock.json index 922c063f8..15108cef1 100644 --- a/web3js-ext/package-lock.json +++ b/web3js-ext/package-lock.json @@ -30,7 +30,7 @@ "typescript": "^5.0.4" }, "peerDependencies": { - "web3": "^4.1.0" + "web3": "^4.2.3-dev.b3ccd5c.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -43,9 +43,9 @@ } }, "node_modules/@adraffy/ens-normalize": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.4.tgz", - "integrity": "sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", + "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", "peer": true }, "node_modules/@ampproject/remapping": { @@ -1800,6 +1800,21 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/abitype": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz", + "integrity": "sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==", + "peer": true, + "peerDependencies": { + "typescript": ">=4.9.4", + "zod": "^3 >=3.19.1" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -2404,9 +2419,9 @@ "dev": true }, "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "peer": true, "dependencies": { "node-fetch": "^2.6.12" @@ -5558,7 +5573,6 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5662,27 +5676,27 @@ } }, "node_modules/web3": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/web3/-/web3-4.1.1.tgz", - "integrity": "sha512-vnPll2G+ZNktSu7oJVjAW0QYuY0kPHLs8LQMifml4kTR+hqhiTmzMIzO8FqkcsESLEu6H9R7Acj6EgyeU1hruQ==", + "version": "4.2.3-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-4.2.3-dev.b3ccd5c.0.tgz", + "integrity": "sha512-yXdsfonGdpadaaQNqJywsDU4qoUS2hLUgd0XVk0kNKYsP0C3Yh8LSX5t/HiWCUqCLhRH36A1vVbWaY8W/BeR5w==", "peer": true, "dependencies": { - "web3-core": "^4.1.1", - "web3-errors": "^1.1.1", - "web3-eth": "^4.1.1", - "web3-eth-abi": "^4.1.1", - "web3-eth-accounts": "^4.0.5", - "web3-eth-contract": "^4.0.5", - "web3-eth-ens": "^4.0.5", - "web3-eth-iban": "^4.0.5", - "web3-eth-personal": "^4.0.5", - "web3-net": "^4.0.5", - "web3-providers-http": "^4.0.5", - "web3-providers-ws": "^4.0.5", - "web3-rpc-methods": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-abi": "4.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-accounts": "4.1.1-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-contract": "4.1.4-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-ens": "4.0.9-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-iban": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-personal": "4.0.9-dev.b3ccd5c.0+b3ccd5c", + "web3-net": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-providers-http": "4.1.1-dev.b3ccd5c.0+b3ccd5c", + "web3-providers-ws": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-rpc-methods": "1.1.4-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14.0.0", @@ -5690,34 +5704,35 @@ } }, "node_modules/web3-core": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.1.1.tgz", - "integrity": "sha512-wzS01bC+ihf5DJ6mz2fz4d5yxnPEM5AYQIRihO8kUt3dil+X4V07CHks23wLbb9yk8U9+3a1Iod207WGF872rA==", + "version": "4.3.2-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.3.2-dev.b3ccd5c.0.tgz", + "integrity": "sha512-9TmX0CFneaO2ZJGRZNvUbM7eajk4Yq0qYmlTsux2p/4eW/55ernRenoLJaFVSQCEEv7c1k/dZ8WYHglY+gOZsw==", "peer": true, "dependencies": { - "web3-errors": "^1.1.1", - "web3-eth-iban": "^4.0.5", - "web3-providers-http": "^4.0.5", - "web3-providers-ws": "^4.0.5", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-accounts": "4.1.1-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-iban": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-providers-http": "4.1.1-dev.b3ccd5c.0+b3ccd5c", + "web3-providers-ws": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", "npm": ">=6.12.0" }, "optionalDependencies": { - "web3-providers-ipc": "^4.0.5" + "web3-providers-ipc": "4.0.8-dev.b3ccd5c.0+b3ccd5c" } }, "node_modules/web3-errors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.1.1.tgz", - "integrity": "sha512-9IEhcympCJEK3Nmkz2oE/daKnOh+3CxHceuVWWRkHWKUfuIiJQgXAv9wRkPGk63JJTP/R9jtGmP+IbkScKoTBA==", + "version": "1.1.5-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.1.5-dev.b3ccd5c.0.tgz", + "integrity": "sha512-ywft7vpkFiLxz51o9s5j/Zn3uu+SJscfh9ICUEzQaAznrx9l5UpBcESggM2NsbwpBtXs2rDEsLXzuZPc5cEl4A==", "peer": true, "dependencies": { - "web3-types": "^1.1.1" + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5725,22 +5740,22 @@ } }, "node_modules/web3-eth": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.1.1.tgz", - "integrity": "sha512-0lftXINbeEOiYhHCWIKgeAOPnjoeHR8DTWLOjURDoz5CKbTj2wfcRQvuL6tUfvvVmrGWHEfIOncM30jhjlTxYQ==", + "version": "4.3.2-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.3.2-dev.b3ccd5c.0.tgz", + "integrity": "sha512-Qdcf6NWmQ6amqP1rFHvQqFScJiS9AYXWqb5lrzW/dTqEDNGgRZesSg60vYpFUcNBOh9vh/bFVRPlF2aamxDbMQ==", "peer": true, "dependencies": { "setimmediate": "^1.0.5", - "web3-core": "^4.1.1", - "web3-errors": "^1.1.1", - "web3-eth-abi": "^4.1.1", - "web3-eth-accounts": "^4.0.5", - "web3-net": "^4.0.5", - "web3-providers-ws": "^4.0.5", - "web3-rpc-methods": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-abi": "4.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-accounts": "4.1.1-dev.b3ccd5c.0+b3ccd5c", + "web3-net": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-providers-ws": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-rpc-methods": "1.1.4-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5748,16 +5763,16 @@ } }, "node_modules/web3-eth-abi": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.1.1.tgz", - "integrity": "sha512-dOLwJ7Ua98WMXuxk7anYfSIqkuCdUvrvU/Um/OWPb6Gw10QciKUWXMIiRobNpWkpS8R77nDtecmQQ1OnTnLaNA==", + "version": "4.1.5-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.1.5-dev.b3ccd5c.0.tgz", + "integrity": "sha512-97KEl5tQwUczUTRhXnnoJhy6POE+yz61LcBlh3BAQFr7nWJkfdCykVlJhWyVAfbID8H6agKb0mzECriX6MjvGQ==", "peer": true, "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5" + "abitype": "0.7.1", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5765,18 +5780,18 @@ } }, "node_modules/web3-eth-accounts": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.0.5.tgz", - "integrity": "sha512-cmaAH20zFe/7Xjga7EuRXL0UV4O894i6ElEXB9Cqd9fP/CBnhQYK/TYuU37xydHhs5WY+B0hKeaoTqxLaPWAYg==", + "version": "4.1.1-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.1.1-dev.b3ccd5c.0.tgz", + "integrity": "sha512-uT9Ww/TE/1xreW76/6Up6LS/hbUpeh4jO9WvL0Gw+dv/d1NCtRXcBQotZr7g7+YgIC6+1Jc/R2GNUZq7kr2A8A==", "peer": true, "dependencies": { "@ethereumjs/rlp": "^4.0.1", "crc-32": "^1.2.2", "ethereum-cryptography": "^2.0.0", - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5784,18 +5799,18 @@ } }, "node_modules/web3-eth-contract": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.0.5.tgz", - "integrity": "sha512-gS21liRDutWQX9i+Ru2Porzefx+7AumRvk+ZLR9wy8l9iLZxldvsvMdgbsyf9lA7UHOqPEhg/zoDyEc0N0hAVw==", + "version": "4.1.4-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.1.4-dev.b3ccd5c.0.tgz", + "integrity": "sha512-W6pwnRJ7giMpf9t5ThaxXc2I3XbYqQxm93b7vuxU7TGlVfcaeY7cuYxt+M3nkxVxuuPvmskx4NALPQs5gUK1qw==", "peer": true, "dependencies": { - "web3-core": "^4.1.1", - "web3-errors": "^1.1.1", - "web3-eth": "^4.1.1", - "web3-eth-abi": "^4.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-abi": "4.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5803,20 +5818,20 @@ } }, "node_modules/web3-eth-ens": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.0.5.tgz", - "integrity": "sha512-PBTCk7h3NlSKP9XWmUJbpTJfMK3IybMAjn+uKrvSbeP50/xaZ73s94nI0eaRmI2FxlSQwTsd7apxXzrE07iKJw==", + "version": "4.0.9-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.0.9-dev.b3ccd5c.0.tgz", + "integrity": "sha512-gkCXsF/rfLinKN8FICS+fdFfP0dBjNUAiKffV4J0spaFTUtBsanUMW+07ScvahoGHDNAl/JQi18pAg7B0hqT9g==", "peer": true, "dependencies": { "@adraffy/ens-normalize": "^1.8.8", - "web3-core": "^4.1.1", - "web3-errors": "^1.1.1", - "web3-eth": "^4.1.1", - "web3-eth-contract": "^4.0.5", - "web3-net": "^4.0.5", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-eth": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-eth-contract": "4.1.4-dev.b3ccd5c.0+b3ccd5c", + "web3-net": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5824,15 +5839,15 @@ } }, "node_modules/web3-eth-iban": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.5.tgz", - "integrity": "sha512-rAH4Dsk0G90W8UqQFomGNjLfxKhBJwkSnkjdG7TUCRhoFvqvrsW1YL+4a+UoODRyJ9BCdaRR71jrymmy4UTDHA==", + "version": "4.0.8-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.8-dev.b3ccd5c.0.tgz", + "integrity": "sha512-f4//9WMjfvtzjb382ycPh4y/jEZBzqpULCEH5d04LdLv2LHVZntVI4X7FAeunIYLiuwIzsPTZ6e5T75ss9uXyA==", "peer": true, "dependencies": { - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5840,17 +5855,17 @@ } }, "node_modules/web3-eth-personal": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.0.5.tgz", - "integrity": "sha512-cypChpAaljYtd1fOfjvhDvty7SBdUvwz5hSimwb+81IJ4MtWc7Jdbn1Ka/g0ZxwoAm46OmeV0yHef7+QyfbpsQ==", + "version": "4.0.9-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.0.9-dev.b3ccd5c.0.tgz", + "integrity": "sha512-0hHfkjCvl3M0i8P1FYWmRuEPqXPJ+7VoxwSuJNNSMAfO19WSllua5bZmVCN9dzp2CTsZDupfyeHyLVVLKlUTEQ==", "peer": true, "dependencies": { - "web3-core": "^4.1.1", - "web3-eth": "^4.1.1", - "web3-rpc-methods": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", - "web3-validator": "^2.0.1" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-eth": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-rpc-methods": "1.1.4-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5858,15 +5873,15 @@ } }, "node_modules/web3-net": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.0.5.tgz", - "integrity": "sha512-7Ir+Da5z3I3KxUn7nmg6NcXxWADYnQAkHX7Z4u4NE3yA+gNbiwPUjVpvSgzpNoDZj+EFovvP1AuOR5idHvyE0g==", + "version": "4.0.8-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.0.8-dev.b3ccd5c.0.tgz", + "integrity": "sha512-oMVjL1MkpcvmlMRTnzX23z0c58pBqn+CGyHhGsOEez2M1U/GSpg4+FKSEc2CWhvwe4f8/zUc5jVtAYYw0y9Zaw==", "peer": true, "dependencies": { - "web3-core": "^4.1.1", - "web3-rpc-methods": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-rpc-methods": "1.1.4-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5874,15 +5889,15 @@ } }, "node_modules/web3-providers-http": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.0.5.tgz", - "integrity": "sha512-JAY0GyLqRKbKw7m92EMg84otLU6N/NmYqepPid7B8XcPkGzhK6R/FsATyi+BGe2ecW9HRyCSz9SWllTjlKhRwQ==", + "version": "4.1.1-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.1.1-dev.b3ccd5c.0.tgz", + "integrity": "sha512-pNITBG9JtGbThC6PJ12WkrWi+xtr2079l1XQ3Z61cwotEMt3QLlrdFWoKOSAPlV2FHpB+f89RxMRf/tjyjYTBQ==", "peer": true, "dependencies": { - "cross-fetch": "^3.1.5", - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5" + "cross-fetch": "^4.0.0", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5890,15 +5905,15 @@ } }, "node_modules/web3-providers-ipc": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.5.tgz", - "integrity": "sha512-1mJWqBnKbQ6UGHVxuXDJRpw4NwkpJ7NabyF2XBmzctzFHKvzE0X1dAocy3tih49J38d0vKrmubTOqxxkMpq49Q==", + "version": "4.0.8-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.8-dev.b3ccd5c.0.tgz", + "integrity": "sha512-WAfwKKA/1goHOlKVc9qfp24j0O5U/EBoCHJnJjHRBIWBQNzG+Dx9Y3kSZFa5R7eiH5befz8Of/ILQma81EgWOg==", "optional": true, "peer": true, "dependencies": { - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5" + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5906,16 +5921,16 @@ } }, "node_modules/web3-providers-ws": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.5.tgz", - "integrity": "sha512-v9xE16Jjczy+7jMKY7rwTuXgwGK51NKvCGdFERPPcSNJCkS5YCBq9DpzJe8mcr5QhuhnTeGeQ7XmcjTzDRkwnQ==", + "version": "4.0.8-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.8-dev.b3ccd5c.0.tgz", + "integrity": "sha512-z2BoynQSmDg8OmFHMBlwJiTOwD5UzXs7Sp4P2j+uXfKT7k/1h9Zuw9P7H87lC2F2UM2X1/FJo47XqRMuHL7fKA==", "peer": true, "dependencies": { "@types/ws": "8.5.3", "isomorphic-ws": "^5.0.0", - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-utils": "^4.0.5", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-utils": "4.0.8-dev.b3ccd5c.0+b3ccd5c", "ws": "^8.8.1" }, "engines": { @@ -5924,14 +5939,14 @@ } }, "node_modules/web3-rpc-methods": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.1.1.tgz", - "integrity": "sha512-aAhm1eIKPWWBRf+BrYpKcvQX5qAg1LOU6NhriY0xpXJh01hbwkz0Q8rMJfCCjlGAElYHSp2K/odyAmyKRDr0LQ==", + "version": "1.1.4-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.1.4-dev.b3ccd5c.0.tgz", + "integrity": "sha512-Gh50qhoJjICm+QU4ww+fHTwoQip69HhS0nE5Xn4hLcaqjN6CfQyf96G9H7MXtplIK8S1GVl9WYU7X6b55Pb0xw==", "peer": true, "dependencies": { - "web3-core": "^4.1.1", - "web3-types": "^1.1.1", - "web3-validator": "^2.0.1" + "web3-core": "4.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5939,9 +5954,9 @@ } }, "node_modules/web3-types": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.1.1.tgz", - "integrity": "sha512-bXmIPJi/NPed43JBcya71gT+euZSMvfQx6NYv8G97PSNxR1HWwANYBKbamTZvzBbq10QCwQLh0hZw3tyOXuPFA==", + "version": "1.3.2-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.3.2-dev.b3ccd5c.0.tgz", + "integrity": "sha512-MnPKuvWEHf6XdF9ybE9vO2UEh2jysSJFAw1ET0JpIsplUKvembLp5Nx7XJZKSR0XZSNANqF+A3OmNBd4cYDTNA==", "peer": true, "engines": { "node": ">=14", @@ -5949,15 +5964,15 @@ } }, "node_modules/web3-utils": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.0.5.tgz", - "integrity": "sha512-43xIM7rr3htYNzliVQLpWLQmEf4XX8IXgjvqLcEuC/xje14O5UQM4kamRCtz8v3JZN3X6QTfsV6Zgby67mVmCg==", + "version": "4.0.8-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.0.8-dev.b3ccd5c.0.tgz", + "integrity": "sha512-ifbW0mJ+0mNbsag0UAZub9Eor74AjitOyDa+EyKwjS7XJ3O5TxsluoxsO5fGKjK9X/FxvWgs38TVMGk0zqS6dA==", "peer": true, "dependencies": { "ethereum-cryptography": "^2.0.0", - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", - "web3-validator": "^2.0.1" + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", + "web3-validator": "2.0.4-dev.b3ccd5c.0+b3ccd5c" }, "engines": { "node": ">=14", @@ -5965,15 +5980,15 @@ } }, "node_modules/web3-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.1.tgz", - "integrity": "sha512-RIdZCNhceBEOQpmzcEk6K3qqLHRfDIMkg2PJe7yllpuEc0fa0cmUZgGUl1FEnioc5Rx9GBEE8eTllaneIAiiQQ==", + "version": "2.0.4-dev.b3ccd5c.0", + "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.4-dev.b3ccd5c.0.tgz", + "integrity": "sha512-qBH35AzmOZYyYIptXxT/WOL/5oV2BBrE3vgxxXy09ZmhOlD8Zuky8+Eb7JdYOmGADAGwZ9Fg0ou6VFIrjO57xA==", "peer": true, "dependencies": { "ethereum-cryptography": "^2.0.0", "util": "^0.12.5", - "web3-errors": "^1.1.1", - "web3-types": "^1.1.1", + "web3-errors": "1.1.5-dev.b3ccd5c.0+b3ccd5c", + "web3-types": "1.3.2-dev.b3ccd5c.0+b3ccd5c", "zod": "^3.21.4" }, "engines": { @@ -6151,9 +6166,9 @@ } }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "peer": true, "engines": { "node": ">=10.0.0" From 0a7b07eaef9d09bc37a505a7176509469dcfa57a Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 16:02:53 +0900 Subject: [PATCH 53/69] web3js: Add util.spec.ts --- web3js-ext/test/util.spec.ts | 96 ++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 web3js-ext/test/util.spec.ts diff --git a/web3js-ext/test/util.spec.ts b/web3js-ext/test/util.spec.ts new file mode 100644 index 000000000..cb00e8bb4 --- /dev/null +++ b/web3js-ext/test/util.spec.ts @@ -0,0 +1,96 @@ +import { BigNumber } from "@ethersproject/bignumber"; +import { assert } from "chai"; +import { describe, it } from "mocha"; + +import { + TxType, isKlaytnTxType, isBasicTxType, isFeeDelegationTxType, isPartialFeeDelegationTxType, isFeePayerSigTxType, + AccountKeyType, isKlaytnAccountKeyType, isEmbeddableAccountKeyType, CodeFormatEVM, + RLP, HexStr, + getCompressedPublicKey, getSignatureTuple, + splitKeystoreKIP3, isKIP3Json, + asyncOpenApi, rpcSendFunction, + getRpcTxObject, + formatKlayUnits, formatKlay, parseKlayUnits, parseKlay, toPeb, fromPeb, +} from "../src"; + +// Test that js-ext-core utils are properly exported. +// Do not test the correctness. That is done in js-ext-core/test. +describe("utils", () => { + it("const", () => { + assert.equal(TxType.ValueTransfer, 8); + assert.equal(isKlaytnTxType(8), true); + assert.equal(isBasicTxType(9), false); + assert.equal(isFeeDelegationTxType(9), true); + assert.equal(isPartialFeeDelegationTxType(10), true); + assert.equal(isFeePayerSigTxType(9), true); + + assert.equal(AccountKeyType.Public, 2); + assert.equal(isKlaytnAccountKeyType(2), true); + assert.equal(isEmbeddableAccountKeyType(5), false); + + assert.equal(CodeFormatEVM, 0); + }); + + it("data", () => { + assert.equal(RLP.encode(["0x01", "0x02", "0x03"]), "0xc3010203"); + assert.equal(HexStr.from("0xabcd"), "0xabcd"); + }); + + it("ec", () => { + const uncompressed = "0x04c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e61a443ac3ffff164d1fb3617875f07641014cf17af6b7dc38e429fe838763712"; + const compressed = "0x02c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e"; + assert.equal(getCompressedPublicKey(uncompressed), compressed); + + const object = { v: 27, r: "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", s: "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508" }; + const tuple = ["0x1b", "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508"]; + assert.deepEqual(getSignatureTuple(object), tuple); + }); + + it("keystore", () => { + assert.isFalse(isKIP3Json("asdf")); + + const v4 = '{"address":"ec5eaa07b4d3cbafe7bf437a1ea9a898209f617c","keyring":[[{"cipher":"aes-128-ctr","ciphertext":"0a5aa3749b9e83c2a4238445aeb66f59355c0363a54c163e34e454f76e061e47","cipherparams":{"iv":"2a0b2e02a61e0f721bd800ea6e23a588"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"538ead57745bcd946b05fe294de08256628d9a0a393fd29ced933ba5fc045b07"},"mac":"30b5488bc97165bc7ecac8ff8dfec65a75a8ad206450aecff0ac2dfea6f79b08"}]],"id":"362c0766-f5e3-4b4d-af22-7e89d5fb613a","version":4}'; + const split = splitKeystoreKIP3(v4); + const v3 = JSON.parse(split[0]); + assert.equal(v3.version, 3); + }); + + it("openapi", async () => { + const send: rpcSendFunction = (_method: string, _params: any[]) => Promise.resolve("0x1234"); + + class MockKlayApi { + apiClient: any; + constructor(apiClient: any) { + this.apiClient = apiClient; + } + + blockNumber(_opts: any, callback: any) { + const bodyParams = { method: "klay_blockNumber", params: [] }; + this.apiClient.callApi("/", "POST", null, null, null, null, bodyParams, + [], ["application/json"], ["application/json"], {}, null, callback); + } + } + const KlayApi = MockKlayApi as any; + + const klay = asyncOpenApi(send, KlayApi); + const ret = await klay.blockNumber(); + assert.isTrue(HexStr.isHex(ret)); + }); + + it("rpc", () => { + const tx = { nonce: 0 }; + const formatted = { nonce: "0x0" }; + assert.deepEqual(getRpcTxObject(tx), formatted); + }); + + it("units", () => { + const peb = BigNumber.from("1000000000000000000"); + assert.equal(formatKlayUnits(peb, "ston"), "1000000000.0"); + assert.equal(formatKlay(peb), "1.0"); + assert.equal(fromPeb(peb), "1.0"); + + assert.equal(parseKlayUnits("25.0", "ston").toString(), "25000000000"); + assert.equal(parseKlay("123.456").toString(), "123456000000000000000"); + assert.equal(toPeb("123.456"), "123456000000000000000"); + }); +}); \ No newline at end of file From 353155dc12516c77f2f255a8d43583c020aee664 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Wed, 29 Nov 2023 19:44:16 +0900 Subject: [PATCH 54/69] Fix KlaytnWeb3.eth.accounts type --- ethers-ext/test/signer.spec.ts | 2 +- web3js-ext/src/rpc.ts | 32 +++++++ web3js-ext/src/type-extensions.ts | 89 +++++++++++++++++ web3js-ext/src/web3.ts | 125 ++++++++++++++++-------- web3js-ext/test/account.spec.ts | 153 ++++++++++++++++++++++++++++++ web3js-ext/test/mock_provider.ts | 46 +++++++++ 6 files changed, 406 insertions(+), 41 deletions(-) create mode 100644 web3js-ext/src/rpc.ts create mode 100644 web3js-ext/src/type-extensions.ts create mode 100644 web3js-ext/test/account.spec.ts create mode 100644 web3js-ext/test/mock_provider.ts diff --git a/ethers-ext/test/signer.spec.ts b/ethers-ext/test/signer.spec.ts index 764acd6cb..727df5809 100644 --- a/ethers-ext/test/signer.spec.ts +++ b/ethers-ext/test/signer.spec.ts @@ -198,7 +198,7 @@ describe("Wallet", () => { await testOK(W, { type: 0, to, value }); } for (let W of [KW, KWD]) { - // await testOK(W, { type: 9, to, feePayer, value }); + await testOK(W, { type: 9, to, feePayer, value }); } }); it("as fee payer", async () => { diff --git a/web3js-ext/src/rpc.ts b/web3js-ext/src/rpc.ts new file mode 100644 index 000000000..22f2cad61 --- /dev/null +++ b/web3js-ext/src/rpc.ts @@ -0,0 +1,32 @@ +import { Web3Context } from "web3-core"; +import { SendTransactionOptions } from "web3-eth"; +import { Bytes, DEFAULT_RETURN_FORMAT, DataFormat } from "web3-types"; + +import { klay_sendSignedTransaction } from "./send_transaction"; + +// Create a getProtocolVersion() function bound to given context +// Should replace web3.eth.getProtocolVersion(). +// Override it because eth_getProtocolVersion is not supported in Klaytn node. +export function bound_getProtocolVersion(context: Web3Context) { + // See web3-eth/src/web3_eth.ts:Web3Eth + // See web3-rpc-methods/src/eth_rpc_methods.ts + return async (): Promise => { + return context.requestManager.send({ + method: "klay_protocolVersion", + params: [], + }); + }; +} + +// Create a sendSignedTransaction() function bound to given context +// Should replace web3.eth.sendSignedTransaction(). +// Override it because eth_sendRawTransaction cannot accept Klaytn TxTypes. +export function bound_sendSignedTransaction(context: Web3Context) { + // See web3-eth/src/web3_eth.ts:Web3Eth + return async ( + transaction: Bytes, + returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, + options?: SendTransactionOptions) => { + return klay_sendSignedTransaction(context, transaction, returnFormat, options); + }; +} \ No newline at end of file diff --git a/web3js-ext/src/type-extensions.ts b/web3js-ext/src/type-extensions.ts new file mode 100644 index 000000000..611ee2ab5 --- /dev/null +++ b/web3js-ext/src/type-extensions.ts @@ -0,0 +1,89 @@ +import Eth from "web3-eth"; +import { + decodeLog, + decodeParameter, + decodeParameters, + encodeFunctionCall, + encodeFunctionSignature, + encodeParameter, + encodeParameters, +} from "web3-eth-abi"; +import { + encrypt, + hashMessage, + recover, + recoverTransaction, + sign, + signTransaction, + Wallet, + Web3Account, +} from "web3-eth-accounts"; +import { Contract } from "web3-eth-contract"; +import { ENS } from "web3-eth-ens"; +import { Iban } from "web3-eth-iban"; +import { Personal } from "web3-eth-personal"; +import { Net } from "web3-net"; +import { Bytes, Transaction } from "web3-types"; + +// Extended web3.eth type. +// Modified from web3/src/types.ts:Web3EthInterface +export interface ExtWeb3EthInterface extends Eth { + Contract: typeof Contract; + Iban: typeof Iban; + net: Net; + ens: ENS; + abi: { + encodeEventSignature: typeof encodeFunctionSignature; + encodeFunctionCall: typeof encodeFunctionCall; + encodeFunctionSignature: typeof encodeFunctionSignature; + encodeParameter: typeof encodeParameter; + encodeParameters: typeof encodeParameters; + decodeParameter: typeof decodeParameter; + decodeParameters: typeof decodeParameters; + decodeLog: typeof decodeLog; + }; + accounts: { + create: () => Web3Account; + privateKeyToAccount: (privateKey: Uint8Array | string) => Web3Account; + signTransaction: ( + transaction: Transaction, + privateKey: Bytes, + ) => ReturnType; + recoverTransaction: typeof recoverTransaction; + hashMessage: typeof hashMessage; + sign: typeof sign; + recover: typeof recover; + encrypt: typeof encrypt; + decrypt: ( + keystore: string, + password: string, + options?: Record, + ) => Promise; + wallet: Wallet; + + // Additional methods + signTransactionAsFeePayer: ( + transaction: Transaction, + privateKey: Bytes, + ) => ReturnType; + }; + personal: Personal; +} + +// Globally extend the Web3Account type +// which are returned by +// - web3.eth.accounts.privateKeyToAccount() +// - web3.eth.accounts.create() +// - web3.eth.accounts.decrypt() +declare module "web3-eth-accounts" { + interface Web3Account { + readonly signTransactionAsFeePayer: (tx: Transaction) => Promise<{ + readonly messageHash: string; + readonly r: string; + readonly s: string; + readonly v: string; + readonly rawTransaction: string; + readonly transactionHash: string; + }>; + } +} \ No newline at end of file diff --git a/web3js-ext/src/web3.ts b/web3js-ext/src/web3.ts index 90966a93a..2f09cab93 100644 --- a/web3js-ext/src/web3.ts +++ b/web3js-ext/src/web3.ts @@ -1,55 +1,100 @@ -import _ from "lodash"; -import Web3, {Bytes, Web3Context} from "web3"; -import { SendTransactionOptions } from "web3-eth"; -import { DataFormat, DEFAULT_RETURN_FORMAT } from "web3-types"; +import { Web3 } from "web3"; +import { + Web3Context, + Web3ContextInitOptions, + isSupportedProvider +} from "web3-core"; +import { RegisteredSubscription, SendTransactionOptions } from "web3-eth"; +import { + EthExecutionAPI, + SupportedProviders, + Bytes, + DEFAULT_RETURN_FORMAT, + DataFormat, +} from "web3-types"; +import * as utils from "web3-utils"; import { initAccountsForContext } from "./account"; +import { bound_getProtocolVersion, bound_sendSignedTransaction } from "./rpc"; import { klay_sendSignedTransaction } from "./send_transaction"; +import { ExtWeb3EthInterface } from "./type-extensions"; -export class KlaytnWeb3 extends Web3 { - constructor(provider: any) { - // TODO: Override default values to fit Klaytn network. - // transactionSendTimeout = 50*1000 - // The Web3 constructor. See web3/src/web3.ts - super(provider); +// Follow the Web3 class from the web3/src/web3.ts +// with slight difference in the web3.eth property. +export class KlaytnWeb3 + extends Web3Context { + // Static properties analogous to Web3 class + public static version = Web3.version; + public static utils = Web3.utils; + public static modules = Web3.modules; - // web3.eth.accounts methods are bound to 'this' object. - const accounts = initAccountsForContext(this); + // Properties analogous to Web3 class + public utils: typeof utils; + public eth: ExtWeb3EthInterface; + + // The inner Web3 instance that provides the base implementation. + // KlaytnWeb3 will delegate most of its methods to this instance. + private _web3: Web3; + + public constructor( + providerOrContext?: + | string + | SupportedProviders + | Web3ContextInitOptions, + ) { + // Call super() like original Web3.constructor() does + const contextInitOptions = getContextInitOptions(providerOrContext); + super(contextInitOptions); + + // Create inner Web3 object + this._web3 = new Web3(providerOrContext); + // Expose required properties from inner Web3 object + this.utils = this._web3.utils; + this.eth = this._web3.eth as ExtWeb3EthInterface; + + // Override web3.eth.accounts methods + const accounts = initAccountsForContext(this); this.eth.accounts = accounts; this._accountProvider = accounts; this._wallet = accounts.wallet; - // Override web3.eth RPC method wrappers. See web3-eth/src/web3_eth.ts:Web3Eth - // Note that web3.eth methods should simply call eth_ RPCs to Klaytn node, - // except a few methods below which call klay_ RPCs despite its name 'web3.eth'. - this.eth.getProtocolVersion = this.eth_getProtocolVersion(this); - this.eth.sendSignedTransaction = this.eth_sendSignedTransaction(this); - - // TODO: Connect web3.klay, web3.net, etc from @klaytn/web3rpc - } - - eth_getProtocolVersion(context: Web3Context): typeof this.eth.getProtocolVersion { + // Override web3.eth RPC method wrappers. // See web3-eth/src/web3_eth.ts:Web3Eth - // See web3-rpc-methods/src/eth_rpc_methods.ts - return async (): Promise => { - return context.requestManager.send({ - method: "klay_protocolVersion", - params: [], - }); - }; + // Note that most of the web3.eth methods should keep calling eth_ RPCs to Klaytn node, + // except below ones. + this.eth.getProtocolVersion = bound_getProtocolVersion(this._web3); + // TODO: fix typing + this.eth.sendSignedTransaction = bound_sendSignedTransaction(this._web3) as typeof this.eth.sendSignedTransaction; } +} - eth_sendSignedTransaction(context: Web3Context): typeof this.eth.sendSignedTransaction { - // See web3-eth/src/web3_eth.ts:Web3Eth - // @ts-ignore: TODO: fix typing - return async ( - transaction: Bytes, - returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, - options?: SendTransactionOptions) => { - // TODO: use klay_sendRawTransaction - return klay_sendSignedTransaction(context, transaction, returnFormat, options); - }; +// Parse providerOrContext into Web3ContextInitOptions. +// See web3/src/web3.ts:Web3 +function getContextInitOptions( + providerOrContext?: + | string + | SupportedProviders + | Web3ContextInitOptions, +) { + // Because console.warn will be printed in `this._web3 = new Web3(..)`, we omit here. + // if (...) { console.warn('NOTE: web3.js is running without provider...'); } + + let contextInitOptions: Web3ContextInitOptions = {}; + if ( + typeof providerOrContext === "string" || + isSupportedProvider(providerOrContext as SupportedProviders) + ) { + contextInitOptions.provider = providerOrContext as + | undefined + | string + | SupportedProviders; + } else if (providerOrContext) { + contextInitOptions = providerOrContext as Web3ContextInitOptions; + } else { + contextInitOptions = {}; } -} + + return contextInitOptions; +} \ No newline at end of file diff --git a/web3js-ext/test/account.spec.ts b/web3js-ext/test/account.spec.ts new file mode 100644 index 000000000..145c3f992 --- /dev/null +++ b/web3js-ext/test/account.spec.ts @@ -0,0 +1,153 @@ +import { assert } from "chai"; +import { describe, it } from "mocha"; +import { EthExecutionAPI, Web3, Web3BaseProvider } from "web3"; +import { toWei } from "web3-utils"; + +import { KlaytnWeb3 } from "../src"; + +import { MockProvider } from "./mock_provider"; + + +// Dummy values. + +/* eslint-disable quotes */ +const url = "https://public-en-baobab.klaytn.net"; +const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; +const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; +const to = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; +const feePayer = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; +const value = toWei("0.01", "ether"); +const nonce = 2; +const gasPrice = 25e9; +const gasLimit = 50000; +const chainId = 1001; +const senderTxHashRLP = "0x09f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"; +const txSignatures = [["0x25", "0x9f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956", "0x6bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"]]; +const keystore_v3 = `{"address":"3c44cdddb6a900fa2b585dd299e03d12fa4293bc","id":"3d73e4aa-2102-4203-8f90-2fb1b0690af7","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"c65d46f512e3e3c66729cdec6884123c"},"ciphertext":"32f222a3b6f454559331f04f0645b76733e924c770bfe311d6a80a11b952c97a","kdf":"scrypt","kdfparams":{"salt":"317e916c3caa8da89868c41300ec8e2eba88abc2474ee5f7954ba757e7c81caf","n":2,"dklen":32,"p":1,"r":8},"mac":"36ed4164aab7f139aa42990d11d7f790078f454b46a4d4d0b9ed718de2dd3e9a"},"x-ethers":{"client":"ethers.js","gethFilename":"UTC--2023-11-29T09-26-20.0Z--3c44cdddb6a900fa2b585dd299e03d12fa4293bc","mnemonicCounter":"6c3b6d22c9e7361b65043ef05430febd","mnemonicCiphertext":"63bd4059afc9294ae4e748cf5cee4b61","path":"m/44'/60'/0'/0/2","locale":"en","version":"0.1"}}`; +/* eslint-enable quotes */ + +function checkSignResult(signResult: any) { + assert.isDefined(signResult.messageHash); + assert.isDefined(signResult.v); + assert.isDefined(signResult.r); + assert.isDefined(signResult.s); + assert.isDefined(signResult.rawTransaction); + assert.isDefined(signResult.transactionHash); +} + +function checkAccountObject(account: any, klaytn: boolean) { + // TODO: check account.signTransaction accepts klaytn tx type + // TODO: check account.sign works + // TODO: check account.encrypt works + + assert.isDefined(account.address); + assert.isDefined(account.privateKey); + assert.isDefined(account.signTransaction); + assert.isDefined(account.sign); + assert.isDefined(account.encrypt); + if (klaytn) { + // assert.isDefined(account.signTransactionAsFeePayer); + } +} + +describe("accounts", () => { + let P: MockProvider; + let EW3: Web3; + let KW3: KlaytnWeb3; + + before(() => { + P = new MockProvider(url); + EW3 = new Web3(P); + KW3 = new KlaytnWeb3(P); + + // Stuff dummy values to the mock provider + P.mock_override("eth_getTransactionCount", () => "0x1234"); + P.mock_override("eth_chainId", () => "0x3e9"); + P.mock_override("net_version", () => "0x3e9"); + P.mock_override("eth_blockNumber", () => "0x12d687"); + P.mock_override("eth_gasPrice", () => "0xba43b7400"); + P.mock_override("eth_getTransactionCount", () => "0x1234"); + P.mock_override("eth_estimateGas", () => "0x5208"); + }); + + describe("privateKeyToAccount", () => { + it("account has all necessary fields", () => { + let account = EW3.eth.accounts.privateKeyToAccount(priv); + checkAccountObject(account, false); + + account = KW3.eth.accounts.privateKeyToAccount(priv); + checkAccountObject(account, true); + }); + it("address and private key are correct", () => { + const account = EW3.eth.accounts.privateKeyToAccount(priv); + assert.equal(account.address, from); + assert.equal(account.privateKey, priv); + }); + }); + + describe("create", () => { + it("account has all necessary fields", () => { + let account = EW3.eth.accounts.create(); + checkAccountObject(account, false); + + account = KW3.eth.accounts.create(); + checkAccountObject(account, true); + }); + }); + + describe("decrypt", () => { + it("account has all necessary fields", async () => { + let account = await EW3.eth.accounts.decrypt(keystore_v3, ""); + checkAccountObject(account, false); + + account = await KW3.eth.accounts.decrypt(keystore_v3, ""); + checkAccountObject(account, true); + }); + }); + + describe("signTransaction", () => { + const tx0 = { type: 0, from, to, value, gasPrice }; + const tx9 = { type: 9, from, to, value, gasPrice }; + + async function testOK_withAccount(W3: Web3, tx: any) { + const account = W3.eth.accounts.privateKeyToAccount(priv); + const signResult = await account.signTransaction(tx); + checkSignResult(signResult); + } + async function testOK_withWeb3(W3: Web3, tx: any) { + const signResult = await W3.eth.accounts.signTransaction(tx, priv); + checkSignResult(signResult); + } + + it("account.signTransaction", async () => { + for (const W3 of [EW3, KW3]) { + await testOK_withAccount(W3, tx0); + } + for (const W3 of [KW3]) { + await testOK_withAccount(W3, tx9); + } + }); + it("web3.eth.accounts.signTransaction", async () => { + for (const W3 of [EW3, KW3]) { + await testOK_withWeb3(W3, { type: 0, from, to, value, gasPrice }); + } + for (const W3 of [KW3]) { + await testOK_withWeb3(W3, { type: 9, from, to, value, gasPrice }); + } + }); + }); + + describe("signTransactionAsFeePayer", () => { + const tx9 = { type: 9, from, to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }; + + it("account.signTransactionAsFeePayer", async () => { + const account = EW3.eth.accounts.privateKeyToAccount(priv); + const signResult = await account.signTransactionAsFeePayer(tx9); + checkSignResult(signResult); + }); + it("web3.eth.accounts.signTransactionAsFeePayer", async () => { + const signResult = await KW3.eth.accounts.signTransactionAsFeePayer(tx9, priv); + checkSignResult(signResult); + }); + }); +}); \ No newline at end of file diff --git a/web3js-ext/test/mock_provider.ts b/web3js-ext/test/mock_provider.ts new file mode 100644 index 000000000..ff62f062c --- /dev/null +++ b/web3js-ext/test/mock_provider.ts @@ -0,0 +1,46 @@ +import { HttpProvider } from "web3-providers-http"; +import { + EthExecutionAPI, + JsonRpcResponseWithResult, + Web3APIMethod, + Web3APIPayload, + Web3APIReturnType, + Web3APISpec, +} from "web3-types"; + +type mockRpcHandler = + (params: Array) => (Promise | any); + +export class MockProvider extends HttpProvider { + overrides: { [method: string]: mockRpcHandler } = {}; + + mock_override(method: string, handler: mockRpcHandler) { + this.overrides[method] = handler; + } + + mock_reset() { + this.overrides = {}; + } + + public async request< + Method extends Web3APIMethod, + ResultType = Web3APIReturnType, + >( + payload: Web3APIPayload, + requestOptions?: RequestInit, + ): Promise> { + const method = payload.method; + const params = (payload.params as any[]) || []; + let handler = this.overrides[method]; + if (handler) { + return { + id: 1, + jsonrpc: "2.0", + result: await handler(params), + }; + } else { + console.log("mock fallback", method, params); + return super.request(payload, requestOptions); + } + } +} \ No newline at end of file From e23bb3812c2c89ce9b060d4d447a4bbddd306da5 Mon Sep 17 00:00:00 2001 From: Yunjong Jeong Date: Wed, 29 Nov 2023 23:06:41 +0900 Subject: [PATCH 55/69] web3js: Add accounts.create().signTransactionAsFeePayer --- web3js-ext/src/account.ts | 215 +++++++++++++++--------------- web3js-ext/src/rpc.ts | 4 +- web3js-ext/src/type-extensions.ts | 89 ------------- web3js-ext/src/types.ts | 118 ++++++++++++++++ web3js-ext/src/web3.ts | 24 ++-- web3js-ext/test/account.spec.ts | 7 +- 6 files changed, 239 insertions(+), 218 deletions(-) delete mode 100644 web3js-ext/src/type-extensions.ts create mode 100644 web3js-ext/src/types.ts diff --git a/web3js-ext/src/account.ts b/web3js-ext/src/account.ts index aa04753ba..0fd13e58a 100644 --- a/web3js-ext/src/account.ts +++ b/web3js-ext/src/account.ts @@ -1,7 +1,9 @@ import { KlaytnTxFactory } from "@klaytn/js-ext-core"; +import _ from "lodash"; import { Web3Context } from "web3-core"; import { TransactionSigningError, UndefinedRawTransactionError } from "web3-errors"; import { + Web3Account, create, decrypt, encrypt, @@ -11,6 +13,7 @@ import { recover, signTransaction, sign, + recoverTransaction, Wallet, TransactionFactory, TypedTransaction, @@ -21,14 +24,114 @@ import { bytesToHex, hexToBytes, sha3Raw, toChecksumAddress, isHex } from "web3- import { isNullish } from "web3-validator"; import { prepareTransaction } from "./klaytn_tx"; +import { KlaytnAccountsInterface, KlaytnWeb3Account } from "./types"; +export function context_accounts(context: Web3Context): KlaytnAccountsInterface { + const _signTransaction = context_signTransaction(context); + const _create = context_create(context); + const _privateKeyToAccount = context_privateKeyToAccount(context); + const _decrypt = context_decrypt(context); + + return { + recoverTransaction, + hashMessage, + sign, + recover, + encrypt, + + create: _create, + privateKeyToAccount: _privateKeyToAccount, + decrypt: _decrypt, + signTransaction: _signTransaction, + signTransactionAsFeePayer: _signTransaction, + + wallet: new Wallet({ + create: _create, + privateKeyToAccount: _privateKeyToAccount, + decrypt: _decrypt as any, // inevitable conflict due to signTransaction receiving string + }), + }; +} + +export function context_create(context: Web3Context) { + return function (): KlaytnWeb3Account { + const account = create(); + return wrapAccount(context, account); + }; +} + +export function context_privateKeyToAccount(context: Web3Context) { + return function (privateKey: Uint8Array | string): KlaytnWeb3Account { + const account = privateKeyToAccount(privateKey); + return wrapAccount(context, account); + }; +} + +export function context_decrypt(context: Web3Context) { + return async function ( + keystore: KeyStore | string, + password: string, + options?: Record, + ): Promise { + const account = await decrypt(keystore, password, (options?.nonStrict as boolean) ?? true); + return wrapAccount(context, account); + }; +} + +function wrapAccount(context: Web3Context, account: Web3Account): KlaytnWeb3Account { + const _signTransaction = context_signTransaction(context); + const _signTransactionAsFeePayer = context_signTransactionAsFeePayer(context); + + return { + ...account, + signTransaction: + (transaction: Transaction | string) => _signTransaction(transaction, account.privateKey), + signTransactionAsFeePayer: + (transaction: Transaction | string) => _signTransactionAsFeePayer(transaction, account.privateKey), + }; +} + +export function context_signTransaction(context: Web3Context) { + return async (transaction: Transaction | string, privateKey: Bytes) => { + const tx = resolveTransaction(transaction); + const priv = bytesToHex(privateKey); + + const preparedTx = await prepareTransaction(tx, context, privateKey); + return signTransaction(preparedTx, priv); + }; +} + +export function context_signTransactionAsFeePayer(context: Web3Context) { + // TODO + return async (transaction: Transaction | string, privateKey: Bytes) => { + const tx = resolveTransaction(transaction); + const priv = bytesToHex(privateKey); + + const preparedTx = await prepareTransaction(tx, context, privateKey); + return signTransaction(preparedTx, priv); + }; +} + +function resolveTransaction(transaction: Transaction | string): Transaction { + if (_.isString(transaction)) { + return KlaytnTxFactory.fromRLP(transaction).toObject(); + } else { + return transaction; + } +} + +// TODO: move to tx.ts export const signTransactionAsFeePayer = async ( transaction: TypedTransaction, privateKey: HexString, // To make it compatible with rest of the API, have to keep it async // eslint-disable-next-line @typescript-eslint/require-await ): Promise => { + if (!(transaction as any).feePayer) { + (transaction as any).feePayer = privateKeyToAddress(privateKey); + } + // @ts-ignore const signedTx = transaction.signAsFeePayer(hexToBytes(privateKey)); if (isNullish(signedTx.feePayer_v) || isNullish(signedTx.feePayer_r) || isNullish(signedTx.feePayer_s)) { throw new TransactionSigningError("Signer Error"); } @@ -57,17 +160,7 @@ export const signTransactionAsFeePayer = async ( }; }; - -/** - * Recovers the Ethereum address which was used to sign the given RLP encoded Ethereum & Klaytn transaction. - * - * @param rawTransaction - The hex string having RLP encoded transaction - * @returns The Ethereum address used to sign this transaction - * ```ts - * recoverTransaction('0xf869808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a0c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895a0727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68'); - * > "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23" - * ``` - */ +// TODO: move to tx.ts export const recoverTransactionWithKlaytnTx = (rawTransaction: HexString): Address => { if (isNullish(rawTransaction)) { throw new UndefinedRawTransactionError(); } @@ -88,104 +181,4 @@ export const recoverTransactionWithKlaytnTx = (rawTransaction: HexString): Addre tx = TransactionFactory.fromSerializedData(data); return toChecksumAddress(tx.getSenderAddress().toString()); -}; - -// We overrided web3/src/accounts.ts:initAccountsForContext -// Below methods are bound to the context 'web3'. -export const initAccountsForContext = (context: Web3Context) => { - const signTransactionWithContext = async (transaction: Transaction, privateKey: Bytes) => { - let tx; - - if (typeof transaction === "string") { - if (isHex(transaction)) { - tx = KlaytnTxFactory.fromRLP(transaction).toObject(); - } else { - throw new Error("String type input has to be RLP encoded Hex string."); - } - } else { - tx = transaction; - } - - const ttx = await prepareTransaction(tx, context, privateKey); - const priv = bytesToHex(privateKey); - return signTransaction(ttx, priv); - }; - - // New added function for Klaytn - const signTransactionAsFeePayerWithContext = async (transaction: any, privateKey: Bytes): Promise => { - let tx; - - if (typeof transaction === "string") { - if (isHex(transaction)) { - tx = KlaytnTxFactory.fromRLP(transaction).toObject(); - } else { - throw new Error("String type input has to be RLP encoded Hex string."); - } - } else { - tx = transaction; - } - - if (!tx.feePayer) { - tx.feePayer = privateKeyToAddress(privateKey); - } - - const ftx = await prepareTransaction(tx, context, privateKey); - const priv = bytesToHex(privateKey); - return signTransactionAsFeePayer(ftx, priv); - }; - - const privateKeyToAccountWithContext = (privateKey: Uint8Array | string) => { - const account = privateKeyToAccount(privateKey); - - return { - ...account, - signTransaction: async (transaction: Transaction) => - signTransactionWithContext(transaction, account.privateKey), - }; - }; - - // TODO : we will support KeyStore V4. - const decryptWithContext = async ( - keystore: KeyStore | string, - password: string, - options?: Record, - ) => { - const account = await decrypt(keystore, password, (options?.nonStrict as boolean) ?? true); - - return { - ...account, - signTransaction: async (transaction: Transaction) => - signTransactionWithContext(transaction, account.privateKey), - }; - }; - - const createWithContext = () => { - const account = create(); - - return { - ...account, - signTransaction: async (transaction: Transaction) => - signTransactionWithContext(transaction, account.privateKey), - }; - }; - - const wallet = new Wallet({ - create: createWithContext, - privateKeyToAccount: privateKeyToAccountWithContext, - decrypt: decryptWithContext, - }); - - return { - signTransaction: signTransactionWithContext, - signTransactionAsFeePayer: signTransactionAsFeePayerWithContext, - create: createWithContext, - privateKeyToAccount: privateKeyToAccountWithContext, - decrypt: decryptWithContext, - recoverTransaction: recoverTransactionWithKlaytnTx, - hashMessage, - sign, - recover, - encrypt, - wallet, - }; }; \ No newline at end of file diff --git a/web3js-ext/src/rpc.ts b/web3js-ext/src/rpc.ts index 22f2cad61..c0bcd09c8 100644 --- a/web3js-ext/src/rpc.ts +++ b/web3js-ext/src/rpc.ts @@ -7,7 +7,7 @@ import { klay_sendSignedTransaction } from "./send_transaction"; // Create a getProtocolVersion() function bound to given context // Should replace web3.eth.getProtocolVersion(). // Override it because eth_getProtocolVersion is not supported in Klaytn node. -export function bound_getProtocolVersion(context: Web3Context) { +export function context_getProtocolVersion(context: Web3Context) { // See web3-eth/src/web3_eth.ts:Web3Eth // See web3-rpc-methods/src/eth_rpc_methods.ts return async (): Promise => { @@ -21,7 +21,7 @@ export function bound_getProtocolVersion(context: Web3Context) { // Create a sendSignedTransaction() function bound to given context // Should replace web3.eth.sendSignedTransaction(). // Override it because eth_sendRawTransaction cannot accept Klaytn TxTypes. -export function bound_sendSignedTransaction(context: Web3Context) { +export function context_sendSignedTransaction(context: Web3Context) { // See web3-eth/src/web3_eth.ts:Web3Eth return async ( transaction: Bytes, diff --git a/web3js-ext/src/type-extensions.ts b/web3js-ext/src/type-extensions.ts deleted file mode 100644 index 611ee2ab5..000000000 --- a/web3js-ext/src/type-extensions.ts +++ /dev/null @@ -1,89 +0,0 @@ -import Eth from "web3-eth"; -import { - decodeLog, - decodeParameter, - decodeParameters, - encodeFunctionCall, - encodeFunctionSignature, - encodeParameter, - encodeParameters, -} from "web3-eth-abi"; -import { - encrypt, - hashMessage, - recover, - recoverTransaction, - sign, - signTransaction, - Wallet, - Web3Account, -} from "web3-eth-accounts"; -import { Contract } from "web3-eth-contract"; -import { ENS } from "web3-eth-ens"; -import { Iban } from "web3-eth-iban"; -import { Personal } from "web3-eth-personal"; -import { Net } from "web3-net"; -import { Bytes, Transaction } from "web3-types"; - -// Extended web3.eth type. -// Modified from web3/src/types.ts:Web3EthInterface -export interface ExtWeb3EthInterface extends Eth { - Contract: typeof Contract; - Iban: typeof Iban; - net: Net; - ens: ENS; - abi: { - encodeEventSignature: typeof encodeFunctionSignature; - encodeFunctionCall: typeof encodeFunctionCall; - encodeFunctionSignature: typeof encodeFunctionSignature; - encodeParameter: typeof encodeParameter; - encodeParameters: typeof encodeParameters; - decodeParameter: typeof decodeParameter; - decodeParameters: typeof decodeParameters; - decodeLog: typeof decodeLog; - }; - accounts: { - create: () => Web3Account; - privateKeyToAccount: (privateKey: Uint8Array | string) => Web3Account; - signTransaction: ( - transaction: Transaction, - privateKey: Bytes, - ) => ReturnType; - recoverTransaction: typeof recoverTransaction; - hashMessage: typeof hashMessage; - sign: typeof sign; - recover: typeof recover; - encrypt: typeof encrypt; - decrypt: ( - keystore: string, - password: string, - options?: Record, - ) => Promise; - wallet: Wallet; - - // Additional methods - signTransactionAsFeePayer: ( - transaction: Transaction, - privateKey: Bytes, - ) => ReturnType; - }; - personal: Personal; -} - -// Globally extend the Web3Account type -// which are returned by -// - web3.eth.accounts.privateKeyToAccount() -// - web3.eth.accounts.create() -// - web3.eth.accounts.decrypt() -declare module "web3-eth-accounts" { - interface Web3Account { - readonly signTransactionAsFeePayer: (tx: Transaction) => Promise<{ - readonly messageHash: string; - readonly r: string; - readonly s: string; - readonly v: string; - readonly rawTransaction: string; - readonly transactionHash: string; - }>; - } -} \ No newline at end of file diff --git a/web3js-ext/src/types.ts b/web3js-ext/src/types.ts new file mode 100644 index 000000000..59bd0acf9 --- /dev/null +++ b/web3js-ext/src/types.ts @@ -0,0 +1,118 @@ +import Eth from "web3-eth"; +import { + decodeLog, + decodeParameter, + decodeParameters, + encodeFunctionCall, + encodeFunctionSignature, + encodeParameter, + encodeParameters, +} from "web3-eth-abi"; +import { + encrypt, + hashMessage, + recover, + recoverTransaction, + sign, + signTransaction, + Wallet, + Web3Account, +} from "web3-eth-accounts"; +import { Contract } from "web3-eth-contract"; +import { ENS } from "web3-eth-ens"; +import { Iban } from "web3-eth-iban"; +import { Personal } from "web3-eth-personal"; +import { Net } from "web3-net"; +import { KeyStore, Bytes, Transaction } from "web3-types"; + +// Type analogous to web3-eth-accounts/src/types.ts:Web3Account +// Designed for the "account object" returned by +// - web3.eth.accounts.privateKeyToAccount() +// - web3.eth.accounts.create() +// - web3.eth.accounts.decrypt() +export interface KlaytnWeb3Account extends Web3Account { + readonly address: string; + readonly privateKey: string; + + readonly sign: (data: Record | string) => { + readonly messageHash: string; + readonly r: string; + readonly s: string; + readonly v: string; + readonly message?: string; + readonly signature: string; + }; + readonly encrypt: (password: string, options?: Record) => Promise; + + // Klaytn: modified methods + readonly signTransaction: (tx: Transaction | string) => Promise<{ + readonly messageHash: string; + readonly r: string; + readonly s: string; + readonly v: string; + readonly rawTransaction: string; + readonly transactionHash: string; + }>; + + // Klaytn: additional methods + readonly signTransactionAsFeePayer: (tx: Transaction | string) => Promise<{ + readonly messageHash: string; + readonly r: string; + readonly s: string; + readonly v: string; + readonly rawTransaction: string; + readonly transactionHash: string; + }>; +} + +// Type analogous to web3/src/types.ts:Web3EthInterface +// Designed for KlaytnWeb3.eth.accounts +export interface KlaytnWeb3EthInterface extends Eth { + Contract: typeof Contract; + Iban: typeof Iban; + net: Net; + ens: ENS; + abi: { + encodeEventSignature: typeof encodeFunctionSignature; + encodeFunctionCall: typeof encodeFunctionCall; + encodeFunctionSignature: typeof encodeFunctionSignature; + encodeParameter: typeof encodeParameter; + encodeParameters: typeof encodeParameters; + decodeParameter: typeof decodeParameter; + decodeParameters: typeof decodeParameters; + decodeLog: typeof decodeLog; + }; + accounts: KlaytnAccountsInterface; + personal: Personal; +} + +// This is the type of KlaytnWeb3EthInterface.accounts +// i.e. (typeof web3.eth.accounts) +export interface KlaytnAccountsInterface { + // Klaytn: contents may have changed, but types unchanged + recoverTransaction: typeof recoverTransaction; + hashMessage: typeof hashMessage; + sign: typeof sign; + recover: typeof recover; + encrypt: typeof encrypt; + wallet: Wallet; + + // Klaytn: modified methods + create: () => KlaytnWeb3Account; + privateKeyToAccount: (privateKey: Uint8Array | string) => KlaytnWeb3Account; + decrypt: ( + keystore: string, + password: string, + options?: Record, + ) => Promise; + signTransaction: ( + transaction: Transaction | string, + privateKey: Bytes, + ) => ReturnType; + + // Klaytn: additional methods + signTransactionAsFeePayer: ( + transaction: Transaction | string, + privateKey: Bytes, + ) => ReturnType; +} diff --git a/web3js-ext/src/web3.ts b/web3js-ext/src/web3.ts index 2f09cab93..dc2aa8ec9 100644 --- a/web3js-ext/src/web3.ts +++ b/web3js-ext/src/web3.ts @@ -4,20 +4,16 @@ import { Web3ContextInitOptions, isSupportedProvider } from "web3-core"; -import { RegisteredSubscription, SendTransactionOptions } from "web3-eth"; +import { RegisteredSubscription } from "web3-eth"; import { EthExecutionAPI, SupportedProviders, - Bytes, - DEFAULT_RETURN_FORMAT, - DataFormat, } from "web3-types"; import * as utils from "web3-utils"; -import { initAccountsForContext } from "./account"; -import { bound_getProtocolVersion, bound_sendSignedTransaction } from "./rpc"; -import { klay_sendSignedTransaction } from "./send_transaction"; -import { ExtWeb3EthInterface } from "./type-extensions"; +import { context_accounts } from "./account"; +import { context_getProtocolVersion, context_sendSignedTransaction } from "./rpc"; +import { KlaytnWeb3EthInterface } from "./types"; // Follow the Web3 class from the web3/src/web3.ts @@ -31,7 +27,7 @@ export class KlaytnWeb3 // Properties analogous to Web3 class public utils: typeof utils; - public eth: ExtWeb3EthInterface; + public eth: KlaytnWeb3EthInterface; // The inner Web3 instance that provides the base implementation. // KlaytnWeb3 will delegate most of its methods to this instance. @@ -52,21 +48,21 @@ export class KlaytnWeb3 // Expose required properties from inner Web3 object this.utils = this._web3.utils; - this.eth = this._web3.eth as ExtWeb3EthInterface; + this.eth = this._web3.eth as KlaytnWeb3EthInterface; // Override web3.eth.accounts methods - const accounts = initAccountsForContext(this); + const accounts = context_accounts(this); this.eth.accounts = accounts; - this._accountProvider = accounts; + this._accountProvider = accounts as any; // inevitable conflict due to signTransaction receiving string this._wallet = accounts.wallet; // Override web3.eth RPC method wrappers. // See web3-eth/src/web3_eth.ts:Web3Eth // Note that most of the web3.eth methods should keep calling eth_ RPCs to Klaytn node, // except below ones. - this.eth.getProtocolVersion = bound_getProtocolVersion(this._web3); + this.eth.getProtocolVersion = context_getProtocolVersion(this._web3); // TODO: fix typing - this.eth.sendSignedTransaction = bound_sendSignedTransaction(this._web3) as typeof this.eth.sendSignedTransaction; + this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3) as typeof this.eth.sendSignedTransaction; } } diff --git a/web3js-ext/test/account.spec.ts b/web3js-ext/test/account.spec.ts index 145c3f992..6f0ed21a2 100644 --- a/web3js-ext/test/account.spec.ts +++ b/web3js-ext/test/account.spec.ts @@ -141,12 +141,15 @@ describe("accounts", () => { const tx9 = { type: 9, from, to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }; it("account.signTransactionAsFeePayer", async () => { - const account = EW3.eth.accounts.privateKeyToAccount(priv); + const account = KW3.eth.accounts.privateKeyToAccount(priv); const signResult = await account.signTransactionAsFeePayer(tx9); checkSignResult(signResult); }); it("web3.eth.accounts.signTransactionAsFeePayer", async () => { - const signResult = await KW3.eth.accounts.signTransactionAsFeePayer(tx9, priv); + let signResult = await KW3.eth.accounts.signTransactionAsFeePayer(tx9, priv); + checkSignResult(signResult); + + signResult = await KW3.eth.accounts.signTransactionAsFeePayer(senderTxHashRLP as any, priv); checkSignResult(signResult); }); }); From 3a16e751de86c14a6d5973d7a1808a6562c15c0f Mon Sep 17 00:00:00 2001 From: Yunjong Jeong Date: Thu, 30 Nov 2023 01:03:23 +0900 Subject: [PATCH 56/69] web3js: Split tx.ts --- web3js-ext/src/account.ts | 40 ++++++++++--------------------------- web3js-ext/src/klaytn_tx.ts | 14 ++----------- web3js-ext/src/tx.ts | 32 +++++++++++++++++++++++++++++ web3js-ext/src/types.ts | 16 ++++++++++++++- 4 files changed, 59 insertions(+), 43 deletions(-) create mode 100644 web3js-ext/src/tx.ts diff --git a/web3js-ext/src/account.ts b/web3js-ext/src/account.ts index 0fd13e58a..660b5f3b6 100644 --- a/web3js-ext/src/account.ts +++ b/web3js-ext/src/account.ts @@ -1,7 +1,7 @@ import { KlaytnTxFactory } from "@klaytn/js-ext-core"; import _ from "lodash"; import { Web3Context } from "web3-core"; -import { TransactionSigningError, UndefinedRawTransactionError } from "web3-errors"; +import { TransactionSigningError} from "web3-errors"; import { Web3Account, create, @@ -13,28 +13,30 @@ import { recover, signTransaction, sign, - recoverTransaction, Wallet, - TransactionFactory, TypedTransaction, SignTransactionResult, } from "web3-eth-accounts"; -import { Address, HexString, EthExecutionAPI, Bytes, Transaction, KeyStore } from "web3-types"; -import { bytesToHex, hexToBytes, sha3Raw, toChecksumAddress, isHex } from "web3-utils"; +import { HexString, EthExecutionAPI, Bytes, Transaction, KeyStore } from "web3-types"; +import { bytesToHex, hexToBytes, sha3Raw } from "web3-utils"; import { isNullish } from "web3-validator"; import { prepareTransaction } from "./klaytn_tx"; +import { klaytnRecoverTransaction } from "./tx"; import { KlaytnAccountsInterface, KlaytnWeb3Account } from "./types"; +// Create an web3.eth.accounts object bound to given context +// See web3/src/accounts.ts:initAccountsForContext export function context_accounts(context: Web3Context): KlaytnAccountsInterface { const _signTransaction = context_signTransaction(context); + const _signTransactionAsFeePayer = context_signTransactionAsFeePayer(context); const _create = context_create(context); const _privateKeyToAccount = context_privateKeyToAccount(context); const _decrypt = context_decrypt(context); return { - recoverTransaction, + recoverTransaction: klaytnRecoverTransaction, hashMessage, sign, recover, @@ -44,7 +46,7 @@ export function context_accounts(context: Web3Context): KlaytnA privateKeyToAccount: _privateKeyToAccount, decrypt: _decrypt, signTransaction: _signTransaction, - signTransactionAsFeePayer: _signTransaction, + signTransactionAsFeePayer: _signTransactionAsFeePayer, wallet: new Wallet({ create: _create, @@ -79,6 +81,7 @@ export function context_decrypt(context: Web3Context) { }; } +// common components of create, privateKeyToAccount, decrypt. function wrapAccount(context: Web3Context, account: Web3Account): KlaytnWeb3Account { const _signTransaction = context_signTransaction(context); const _signTransactionAsFeePayer = context_signTransactionAsFeePayer(context); @@ -159,26 +162,3 @@ export const signTransactionAsFeePayer = async ( transactionHash: bytesToHex(txHash), }; }; - -// TODO: move to tx.ts -export const recoverTransactionWithKlaytnTx = (rawTransaction: HexString): Address => { - if (isNullish(rawTransaction)) { throw new UndefinedRawTransactionError(); } - - const data = hexToBytes(rawTransaction); - let tx; - - if (KlaytnTxFactory.has(data[0])) { - tx = KlaytnTxFactory.fromRLP(rawTransaction).toObject(); - - if (!tx.from) { - throw new Error("tx.from is not a property."); - } else if (typeof tx.from == "string") { - return toChecksumAddress(tx.from); - } else { - throw new Error("tx.from is not a string type."); - } - } - - tx = TransactionFactory.fromSerializedData(data); - return toChecksumAddress(tx.getSenderAddress().toString()); -}; \ No newline at end of file diff --git a/web3js-ext/src/klaytn_tx.ts b/web3js-ext/src/klaytn_tx.ts index de163fecf..c6c554e5c 100644 --- a/web3js-ext/src/klaytn_tx.ts +++ b/web3js-ext/src/klaytn_tx.ts @@ -11,19 +11,9 @@ import { bytesToHex, hexToBytes, toHex, toNumber, numberToHex, toBigInt } from " export const secp256k1 = ethereumCryptography.secp256k1 ?? ethereumCryptography; +import { KlaytnTxData } from "./types"; + import { KlaytnTxFactory, TxType, isFeePayerSigTxType } from "@klaytn/js-ext-core"; -export interface KlaytnTxData extends TxData { - from?: string, - chainId?: bigint, - key? : any, - feePayer? : string, - feePayer_v? : bigint, - feePayer_r? : Uint8Array, - feePayer_s? : Uint8Array, - txSignatures? : any, - feePayerSignatures? : any, - feeRatio? : Uint, -} // See web3-types/src/eth_types.ts:TransactionBase and its child interfaces const web3jsAllowedTransactionKeys = [ diff --git a/web3js-ext/src/tx.ts b/web3js-ext/src/tx.ts new file mode 100644 index 000000000..874d97984 --- /dev/null +++ b/web3js-ext/src/tx.ts @@ -0,0 +1,32 @@ +import { KlaytnTxFactory } from "@klaytn/js-ext-core"; +import { UndefinedRawTransactionError } from "web3-errors"; +import { TransactionFactory } from "web3-eth-accounts"; +import { Address } from "web3-types"; +import { hexToBytes, toChecksumAddress } from "web3-utils"; +import { isNullish } from "web3-validator"; + + +export function klaytnRecoverTransaction(rawTransaction: string): Address { + if (isNullish(rawTransaction)) { + throw new UndefinedRawTransactionError(); + } + + const data = hexToBytes(rawTransaction); + if (data.length < 1) { + throw new UndefinedRawTransactionError(); + } + const typeInt = data[0]; + + if (KlaytnTxFactory.has(typeInt)) { + const tx = KlaytnTxFactory.fromRLP(rawTransaction).toObject(); + if (!tx.from) { + // this should never happen because Klaytn RLP tx always contains `from`. + throw new Error("missing tx.from"); + } + return toChecksumAddress(tx.from); + } else { + const tx = TransactionFactory.fromSerializedData(data); + const from = tx.getSenderAddress().toString(); + return toChecksumAddress(from); + } +} \ No newline at end of file diff --git a/web3js-ext/src/types.ts b/web3js-ext/src/types.ts index 59bd0acf9..367370947 100644 --- a/web3js-ext/src/types.ts +++ b/web3js-ext/src/types.ts @@ -15,6 +15,7 @@ import { recoverTransaction, sign, signTransaction, + TxData, Wallet, Web3Account, } from "web3-eth-accounts"; @@ -23,7 +24,7 @@ import { ENS } from "web3-eth-ens"; import { Iban } from "web3-eth-iban"; import { Personal } from "web3-eth-personal"; import { Net } from "web3-net"; -import { KeyStore, Bytes, Transaction } from "web3-types"; +import { KeyStore, Bytes, Transaction, Uint } from "web3-types"; // Type analogous to web3-eth-accounts/src/types.ts:Web3Account // Designed for the "account object" returned by @@ -116,3 +117,16 @@ export interface KlaytnAccountsInterface { privateKey: Bytes, ) => ReturnType; } + +export interface KlaytnTxData extends TxData { + from?: string, + chainId?: bigint, + key? : any, + feePayer? : string, + feePayer_v? : bigint, + feePayer_r? : Uint8Array, + feePayer_s? : Uint8Array, + txSignatures? : any, + feePayerSignatures? : any, + feeRatio? : Uint, +} \ No newline at end of file From 4e4ba36e726484d563152b91e2dc92d2e84f3b74 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Thu, 30 Nov 2023 08:54:51 +0900 Subject: [PATCH 57/69] Update FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js --- ...Del_09_TxTypeFeeDelegatedValueTransfer2.js | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js index ca0d54de2..d1bf19b94 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js @@ -4,16 +4,13 @@ const { Wallet, TxType, parseKlay } = require("@klaytn/ethers-ext"); const ethers = require("ethers"); -const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; -const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; -const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; -const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; -const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; +async function userSign() { + const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; + const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; + const recieverAddr = "0xc40b6909eb7085590e1c26cb3becc25368e249e9"; -async function main() { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const senderWallet = new Wallet(senderPriv, provider); - const feePayerWallet = new Wallet(feePayerPriv, provider); let tx = { type: TxType.FeeDelegatedValueTransfer, @@ -28,6 +25,16 @@ async function main() { const senderTxHashRLP = await senderWallet.signTransaction(tx); console.log("senderTxHashRLP", senderTxHashRLP); + return senderTxHashRLP; +} + +async function backendSign( senderTxHashRLP ) { + const feePayerAddr = "0xcb0eb737dfda52756495a5e08a9b37aab3b271da"; + const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; + + const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); + const feePayerWallet = new Wallet(feePayerPriv, provider); + tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); console.log(tx); @@ -35,7 +42,12 @@ async function main() { console.log("sentTx", sentTx); const rc = await sentTx.wait(); - console.log("receipt", rc); + console.log("receipt", rc); +} + +async function main() { + const senderTxHashRLP = await userSign(); + backendSign( senderTxHashRLP ); } main(); From 3279c1c5259fbac0481193b32beb0185b4bba8b5 Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Thu, 30 Nov 2023 09:32:50 +0900 Subject: [PATCH 58/69] Update FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js --- .../transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js index d1bf19b94..75c2ab7a7 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js @@ -33,7 +33,7 @@ async function backendSign( senderTxHashRLP ) { const feePayerPriv = "0x9435261ed483b6efa3886d6ad9f64c12078a0e28d8d80715c773e16fc000cff4"; const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); - const feePayerWallet = new Wallet(feePayerPriv, provider); + const feePayerWallet = new Wallet(feePayerAddr, feePayerPriv, provider); tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); console.log(tx); From 2e19c3ae70ab0b32e94a30aaf3758dc3a8e6214f Mon Sep 17 00:00:00 2001 From: Nohyun Nehemiah Kwak Date: Thu, 30 Nov 2023 10:14:12 +0900 Subject: [PATCH 59/69] Debug for lint check --- .../transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js index 75c2ab7a7..bd85ba4e1 100644 --- a/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js +++ b/ethers-ext/example/transactions/FeeDel_09_TxTypeFeeDelegatedValueTransfer2.js @@ -35,7 +35,7 @@ async function backendSign( senderTxHashRLP ) { const provider = new ethers.providers.JsonRpcProvider("https://public-en-baobab.klaytn.net"); const feePayerWallet = new Wallet(feePayerAddr, feePayerPriv, provider); - tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); + const tx = feePayerWallet.decodeTxFromRLP(senderTxHashRLP); console.log(tx); const sentTx = await feePayerWallet.sendTransactionAsFeePayer(tx); From e289039b83a19e57ee7a5d6a182c213d6b879b82 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 30 Nov 2023 16:03:24 +0900 Subject: [PATCH 60/69] Organize tx related functions --- web3js-ext/src/account.ts | 92 +++++++------------ web3js-ext/src/klaytn_tx.ts | 76 +--------------- web3js-ext/src/tx.ts | 174 +++++++++++++++++++++++++++++++++++- web3js-ext/src/types.ts | 13 ++- web3js-ext/src/web3.ts | 5 +- 5 files changed, 219 insertions(+), 141 deletions(-) diff --git a/web3js-ext/src/account.ts b/web3js-ext/src/account.ts index 660b5f3b6..e91b55d89 100644 --- a/web3js-ext/src/account.ts +++ b/web3js-ext/src/account.ts @@ -1,7 +1,6 @@ import { KlaytnTxFactory } from "@klaytn/js-ext-core"; import _ from "lodash"; import { Web3Context } from "web3-core"; -import { TransactionSigningError} from "web3-errors"; import { Web3Account, create, @@ -14,16 +13,20 @@ import { signTransaction, sign, Wallet, - TypedTransaction, - SignTransactionResult, } from "web3-eth-accounts"; -import { HexString, EthExecutionAPI, Bytes, Transaction, KeyStore } from "web3-types"; -import { bytesToHex, hexToBytes, sha3Raw } from "web3-utils"; -import { isNullish } from "web3-validator"; +import { EthExecutionAPI, Bytes, KeyStore } from "web3-types"; +import { bytesToHex } from "web3-utils"; -import { prepareTransaction } from "./klaytn_tx"; -import { klaytnRecoverTransaction } from "./tx"; -import { KlaytnAccountsInterface, KlaytnWeb3Account } from "./types"; +import { + klaytnRecoverTransaction, + klaytnPrepareTransaction, + klaytnSignTransactionAsFeePayer, +} from "./tx"; +import { + KlaytnAccountsInterface, + KlaytnTransaction, + KlaytnWeb3Account, +} from "./types"; // Create an web3.eth.accounts object bound to given context @@ -51,11 +54,12 @@ export function context_accounts(context: Web3Context): KlaytnA wallet: new Wallet({ create: _create, privateKeyToAccount: _privateKeyToAccount, - decrypt: _decrypt as any, // inevitable conflict due to signTransaction receiving string + decrypt: _decrypt as any, // inevitable conflict in signTransaction types }), }; } +// Analogous to web3/src/accounts.ts:createWithContext export function context_create(context: Web3Context) { return function (): KlaytnWeb3Account { const account = create(); @@ -63,6 +67,7 @@ export function context_create(context: Web3Context) { }; } +// Analogous to web3/src/accounts.ts:privateKeyToAccountWithContext export function context_privateKeyToAccount(context: Web3Context) { return function (privateKey: Uint8Array | string): KlaytnWeb3Account { const account = privateKeyToAccount(privateKey); @@ -70,6 +75,7 @@ export function context_privateKeyToAccount(context: Web3Context) { return async function ( keystore: KeyStore | string, @@ -89,76 +95,44 @@ function wrapAccount(context: Web3Context, account: Web3Account return { ...account, signTransaction: - (transaction: Transaction | string) => _signTransaction(transaction, account.privateKey), + (transaction: KlaytnTransaction | string) => _signTransaction(transaction, account.privateKey), signTransactionAsFeePayer: - (transaction: Transaction | string) => _signTransactionAsFeePayer(transaction, account.privateKey), + (transaction: KlaytnTransaction | string) => _signTransactionAsFeePayer(transaction, account.privateKey), }; } +// Analogous to web3/src/accounts.ts:signTransactionWithContext export function context_signTransaction(context: Web3Context) { - return async (transaction: Transaction | string, privateKey: Bytes) => { + return async (transaction: KlaytnTransaction | string, privateKey: Bytes) => { const tx = resolveTransaction(transaction); const priv = bytesToHex(privateKey); - const preparedTx = await prepareTransaction(tx, context, privateKey); + const preparedTx = await klaytnPrepareTransaction(tx, context, privateKey); return signTransaction(preparedTx, priv); }; } +// Analogous to web3/src/accounts.ts:signTransactionWithContext +// but instead calls klaytnSignTransactionAsFeePayer at the end. export function context_signTransactionAsFeePayer(context: Web3Context) { - // TODO - return async (transaction: Transaction | string, privateKey: Bytes) => { + return async (transaction: KlaytnTransaction | string, privateKey: Bytes) => { const tx = resolveTransaction(transaction); const priv = bytesToHex(privateKey); - const preparedTx = await prepareTransaction(tx, context, privateKey); - return signTransaction(preparedTx, priv); + if (!tx.feePayer) { + tx.feePayer = privateKeyToAddress(privateKey); + } + + const preparedTx = await klaytnPrepareTransaction(tx, context, privateKey); + return klaytnSignTransactionAsFeePayer(preparedTx, priv); }; } -function resolveTransaction(transaction: Transaction | string): Transaction { +// Convert 'Transaction | string' type to 'Transaction' by decoding the RLP string. +function resolveTransaction(transaction: KlaytnTransaction | string): KlaytnTransaction { if (_.isString(transaction)) { return KlaytnTxFactory.fromRLP(transaction).toObject(); } else { return transaction; } -} - -// TODO: move to tx.ts -export const signTransactionAsFeePayer = async ( - transaction: TypedTransaction, - privateKey: HexString, - // To make it compatible with rest of the API, have to keep it async - // eslint-disable-next-line @typescript-eslint/require-await -): Promise => { - if (!(transaction as any).feePayer) { - (transaction as any).feePayer = privateKeyToAddress(privateKey); - } - - // @ts-ignore - const signedTx = transaction.signAsFeePayer(hexToBytes(privateKey)); - if (isNullish(signedTx.feePayer_v) || isNullish(signedTx.feePayer_r) || isNullish(signedTx.feePayer_s)) { throw new TransactionSigningError("Signer Error"); } - - const validationErrors = signedTx.validate(true); - - if (validationErrors.length > 0) { - let errorString = "Signer Error "; - for (const validationError of validationErrors) { - errorString += `${errorString} ${validationError}.`; - } - throw new TransactionSigningError(errorString); - } - - // @ts-ignore - const rawTx = bytesToHex(signedTx.serializeAsFeePayer()); - const txHash = sha3Raw(rawTx); // using keccak in web3-utils.sha3Raw instead of SHA3 (NIST Standard) as both are different - - return { - messageHash: bytesToHex(signedTx.getMessageToSignAsFeePayer(true)), - v: `0x${signedTx.feePayer_v.toString(16)}`, - r: `0x${signedTx.feePayer_r.toString(16).padStart(64, "0")}`, - s: `0x${signedTx.feePayer_s.toString(16).padStart(64, "0")}`, - rawTransaction: rawTx, - transactionHash: bytesToHex(txHash), - }; -}; +} \ No newline at end of file diff --git a/web3js-ext/src/klaytn_tx.ts b/web3js-ext/src/klaytn_tx.ts index c6c554e5c..19a1262c2 100644 --- a/web3js-ext/src/klaytn_tx.ts +++ b/web3js-ext/src/klaytn_tx.ts @@ -1,10 +1,9 @@ import { RLP } from "@ethereumjs/rlp"; +import { KlaytnTxFactory, TxType, isFeePayerSigTxType } from "@klaytn/js-ext-core"; import { keccak256 } from "ethereum-cryptography/keccak.js"; import * as ethereumCryptography from "ethereum-cryptography/secp256k1.js"; -import _ from "lodash"; -import { Bytes, Numbers, Transaction as TransactionFields, Uint, Web3Context } from "web3"; -import { prepareTransactionForSigning } from "web3-eth"; -import { Transaction as LegacyTransaction, TypedTransaction, TxData, TxOptions, ECDSASignature } from "web3-eth-accounts"; +import { Transaction as LegacyTransaction, TxOptions } from "web3-eth-accounts"; +import { Uint } from "web3-types"; import { bytesToHex, hexToBytes, toHex, toNumber, numberToHex, toBigInt } from "web3-utils"; // eslint-disable-next-line import/extensions @@ -13,75 +12,6 @@ export const secp256k1 = ethereumCryptography.secp256k1 ?? ethereumCryptography; import { KlaytnTxData } from "./types"; -import { KlaytnTxFactory, TxType, isFeePayerSigTxType } from "@klaytn/js-ext-core"; - -// See web3-types/src/eth_types.ts:TransactionBase and its child interfaces -const web3jsAllowedTransactionKeys = [ - "value", "accessList", "common", "gas", "gasPrice", "type", "maxFeePerGas", - "maxPriorityFeePerGas", "data", "input", "nonce", "chain", "hardfork", - "chainId", "networkId", "gasLimit", "yParity", "v", "r", "s", - "from", "to", -]; - -// web3.js may strip or reject some Klaytn-specific transaction fields. -// To prserve transaction fields around web3js function calls, use saveCustomFields. -export function saveCustomFields(tx: any): any { - // Save fields that are not allowed in web3.js - const savedFields: any = {}; - for (const key in tx) { - if (web3jsAllowedTransactionKeys.indexOf(key) === -1) { - savedFields[key] = _.get(tx, key); - _.unset(tx, key); - } - } - - // Save txtype that is not supported in web3.js. - // and disguise as legacy (type 0) transaction - // because web3js-ext's KlaytnTx is based on web3js's LegacyTransaction. - if (KlaytnTxFactory.has(tx.type)) { - savedFields["type"] = tx.type; - tx.type = 0; - } - - return savedFields; -} - -// Fill required fields from the context -export async function prepareTransaction( - transaction: TransactionFields, - context: Web3Context, - privateKey: Bytes): Promise { - if (KlaytnTxFactory.has(transaction.type)) { - transaction = _.clone(transaction); - const savedFields = saveCustomFields(transaction); - - // prepareTransactionForSigning expects ANY value (not undefined) - // because otherwise eth_estimateGas will fail with an RPC error '"0x"..*hexutil.Big'. - // however, some Klaytn tx types stipulates to NOT have value (e.g. TxTypeCancel, TxTypeAccountUpdate) - // Therefore we fill with zero value if not defined. - transaction.value ??= 0; - - const tx = await prepareTransactionForSigning( - transaction, context, privateKey, true, true); - - const txData = { ...tx, ...savedFields }; - - // Below fields might be - // (1) not specified at the first place, - // (2) or lost during prepareTransactionForSigning, - // (3) or not populated by prepareTransactionForSigning. - txData.from ??= transaction.from; - txData.chainId ??= tx.common.chainId(); - - const txOptions = (tx as any).txOptions; - - return new KlaytnTx(txData, txOptions); - } else { - return await prepareTransactionForSigning( - transaction, context, privateKey, true, true); - } -} - // Mimics the LegacyTransaction. // See web3-eth-accounts/src/tx/legacyTransaction.ts // and web3-eth-accounts/src/tx/baseTransaction.ts diff --git a/web3js-ext/src/tx.ts b/web3js-ext/src/tx.ts index 874d97984..c8277047c 100644 --- a/web3js-ext/src/tx.ts +++ b/web3js-ext/src/tx.ts @@ -1,11 +1,69 @@ import { KlaytnTxFactory } from "@klaytn/js-ext-core"; -import { UndefinedRawTransactionError } from "web3-errors"; -import { TransactionFactory } from "web3-eth-accounts"; -import { Address } from "web3-types"; -import { hexToBytes, toChecksumAddress } from "web3-utils"; +import _ from "lodash"; +import { Bytes, Transaction, Web3Context } from "web3"; +import { TransactionSigningError, UndefinedRawTransactionError } from "web3-errors"; +import { prepareTransactionForSigning } from "web3-eth"; +import { + privateKeyToAddress, + TransactionFactory, + TypedTransaction, + SignTransactionResult, +} from "web3-eth-accounts"; +import { Address, HexString } from "web3-types"; +import { bytesToHex, hexToBytes, sha3Raw, toChecksumAddress } from "web3-utils"; import { isNullish } from "web3-validator"; +import { KlaytnTx } from "./klaytn_tx"; +import { KlaytnTransaction } from "./types"; +/* +Klaytn tx signing flow + +User app.js + | Transaction + | KlaytnTransaction + | string + V +account.signTransaction @ account.ts:context_signTransaction +account.signTransactionAsFeePayer @ account.ts:context_signTransactionAsFeePayer +web3.eth.accounts.signTransaction @ account.ts:context_signTransaction +web3.eth.accounts.signTransactionAsFeePayer @ account.ts:context_signTransactionAsFeePayer + | Transaction + | KlaytnTransaction + | string + V +resolveTransaction @ account.ts + | KlaytnTransaction + V +klaytnPrepareTransaction @ tx.ts + | KlaytnTypedTransaction + | - TypedTransaction + | - LegacyTransaction (class Transaction extends BaseTransaction) @ legacyTransaction.ts + | - AccessListEIP2930Transaction (class ... extends BaseTransaction) @ eip2930Transaction.ts + | - FeeMarketEIP1559Transaction (class ... extends BaseTransaction) @ eip1559Transaction.ts + | - KlaytnTx (class ... extends LegacyTransaction) @ klaytn_tx.ts + V +klaytnSignTransaction @ tx.ts +klaytnSignTransactionAsFeePayer @ tx.ts + | tx: KlaytnTypedTransaction + V +tx.sign @ klaytn_tx.ts +tx.signAsFeePayer @ klaytn_tx.ts + | signedTx: KlaytnTypedTransaction + V +signedTx.validate @ klaytn_tx.ts +signedTx.serialize @ klaytn_tx.ts +signedTx.getMessageToSign @ klaytn_tx.ts +signedTx.{v,r,s,feePayer_v,feePayer_r,feePayer_s} @ klaytn_tx.ts + | SignTransactionResult + V +User app.js +*/ + +// Recover the sender address from the raw transaction. +// Analogous to recoverTransaction from web3-eth-accounts, +// but also support Klaytn TxTypes. +// See web3-eth-accounts/src/accounts.ts:recoverTransaction export function klaytnRecoverTransaction(rawTransaction: string): Address { if (isNullish(rawTransaction)) { throw new UndefinedRawTransactionError(); @@ -29,4 +87,112 @@ export function klaytnRecoverTransaction(rawTransaction: string): Address { const from = tx.getSenderAddress().toString(); return toChecksumAddress(from); } +} + +// Analogous to signTransaction from web3-eth-accounts, +// but instead calls KlaytnTx.*AsFeePayer methods. +export async function klaytnSignTransactionAsFeePayer( + transaction: TypedTransaction | KlaytnTx, + privateKey: HexString, +): Promise { + if (!(transaction instanceof KlaytnTx)) { + throw new Error("attempted signTransactionAsFeePayer with non-klaytn tx"); + } + + const signedTx: any = transaction.signAsFeePayer(hexToBytes(privateKey)); + if (isNullish(signedTx.feePayer_v) || isNullish(signedTx.feePayer_r) || isNullish(signedTx.feePayer_s)) { throw new TransactionSigningError("Signer Error"); } + + const validationErrors = signedTx.validate(true); + + if (validationErrors.length > 0) { + let errorString = "Signer Error "; + for (const validationError of validationErrors) { + errorString += `${errorString} ${validationError}.`; + } + throw new TransactionSigningError(errorString); + } + + // @ts-ignore + const rawTx = bytesToHex(signedTx.serializeAsFeePayer()); + const txHash = sha3Raw(rawTx); // using keccak in web3-utils.sha3Raw instead of SHA3 (NIST Standard) as both are different + + return { + messageHash: bytesToHex(signedTx.getMessageToSignAsFeePayer(true)), + v: `0x${signedTx.feePayer_v.toString(16)}`, + r: `0x${signedTx.feePayer_r.toString(16).padStart(64, "0")}`, + s: `0x${signedTx.feePayer_s.toString(16).padStart(64, "0")}`, + rawTransaction: rawTx, + transactionHash: bytesToHex(txHash), + }; +} + + +// Fill required fields from the context. +// Analogous to prepareTransactionForSigning from web3-eth, +// but also support Klaytn TxTypes. +// See web3-eth/src/utils/prepare_transaction_for_signing.ts:prepareTransactionForSigning +export async function klaytnPrepareTransaction( + transaction: KlaytnTransaction, + context: Web3Context, + privateKey: Bytes): Promise { + if (KlaytnTxFactory.has(transaction.type)) { + transaction = _.clone(transaction); + const savedFields = saveCustomFields(transaction); + + // prepareTransactionForSigning expects non-undefined 'value' field + // because otherwise eth_estimateGas will fail with an RPC error '"0x"..*hexutil.Big'. + // however, some Klaytn tx types stipulates to NOT have value (e.g. TxTypeCancel, TxTypeAccountUpdate) + // Therefore we fill with zero value if not defined. + transaction.value ??= 0; + + const tx = await prepareTransactionForSigning( + transaction, context, privateKey, true, true); + + const txData = { ...tx, ...savedFields }; + + // Below fields might be + // (1) not specified at the first place, + // (2) or lost during prepareTransactionForSigning, + // (3) or not populated by prepareTransactionForSigning. + txData.from ??= transaction.from; + txData.chainId ??= tx.common.chainId(); + + const txOptions = (tx as any).txOptions; + + return new KlaytnTx(txData, txOptions); + } else { + return await prepareTransactionForSigning( + transaction, context, privateKey, true, true); + } +} + +// See web3-types/src/eth_types.ts:TransactionBase and its child interfaces +const web3jsAllowedTransactionKeys = [ + "value", "accessList", "common", "gas", "gasPrice", "type", "maxFeePerGas", + "maxPriorityFeePerGas", "data", "input", "nonce", "chain", "hardfork", + "chainId", "networkId", "gasLimit", "yParity", "v", "r", "s", + "from", "to", +]; + +// web3.js may strip or reject some Klaytn-specific transaction fields. +// To prserve transaction fields around web3js function calls, use saveCustomFields. +export function saveCustomFields(tx: any): any { + // Save fields that are not allowed in web3.js + const savedFields: any = {}; + for (const key in tx) { + if (web3jsAllowedTransactionKeys.indexOf(key) === -1) { + savedFields[key] = _.get(tx, key); + _.unset(tx, key); + } + } + + // Save txtype that is not supported in web3.js. + // and disguise as legacy (type 0) transaction + // because web3js-ext's KlaytnTx is based on web3js's LegacyTransaction. + if (KlaytnTxFactory.has(tx.type)) { + savedFields["type"] = tx.type; + tx.type = 0; + } + + return savedFields; } \ No newline at end of file diff --git a/web3js-ext/src/types.ts b/web3js-ext/src/types.ts index 367370947..5ae8e07b0 100644 --- a/web3js-ext/src/types.ts +++ b/web3js-ext/src/types.ts @@ -107,17 +107,26 @@ export interface KlaytnAccountsInterface { options?: Record, ) => Promise; signTransaction: ( - transaction: Transaction | string, + transaction: KlaytnTransaction | string, privateKey: Bytes, ) => ReturnType; // Klaytn: additional methods signTransactionAsFeePayer: ( - transaction: Transaction | string, + transaction: KlaytnTransaction | string, privateKey: Bytes, ) => ReturnType; } +// The plain Transaction object supplied by the users. +// Used as argument to prepareTransaction() +export interface KlaytnTransaction extends Transaction { + // TODO: add fields + feePayer? : string, +} + +// The plain Transaction object used internally. +// Used as argument to KlaytnTx.fromTxData() export interface KlaytnTxData extends TxData { from?: string, chainId?: bigint, diff --git a/web3js-ext/src/web3.ts b/web3js-ext/src/web3.ts index dc2aa8ec9..bada8b0ac 100644 --- a/web3js-ext/src/web3.ts +++ b/web3js-ext/src/web3.ts @@ -53,7 +53,7 @@ export class KlaytnWeb3 // Override web3.eth.accounts methods const accounts = context_accounts(this); this.eth.accounts = accounts; - this._accountProvider = accounts as any; // inevitable conflict due to signTransaction receiving string + this._accountProvider = accounts as any; // inevitable conflict in signTransaction types this._wallet = accounts.wallet; // Override web3.eth RPC method wrappers. @@ -61,8 +61,7 @@ export class KlaytnWeb3 // Note that most of the web3.eth methods should keep calling eth_ RPCs to Klaytn node, // except below ones. this.eth.getProtocolVersion = context_getProtocolVersion(this._web3); - // TODO: fix typing - this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3) as typeof this.eth.sendSignedTransaction; + this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3) as typeof this.eth.sendSignedTransaction; // TODO: fix typing } } From 0db3fcd49bbc0362cdd4fee4a7d08376879a5558 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 30 Nov 2023 16:36:51 +0900 Subject: [PATCH 61/69] Cleanup KlaytnTx --- web3js-ext/src/klaytn_tx.ts | 185 ++++++++++++++++---------------- web3js-ext/src/tx.ts | 3 +- web3js-ext/src/types.ts | 39 ++++--- web3js-ext/test/account.spec.ts | 1 + 4 files changed, 122 insertions(+), 106 deletions(-) diff --git a/web3js-ext/src/klaytn_tx.ts b/web3js-ext/src/klaytn_tx.ts index 19a1262c2..99e7ff0f2 100644 --- a/web3js-ext/src/klaytn_tx.ts +++ b/web3js-ext/src/klaytn_tx.ts @@ -1,46 +1,39 @@ import { RLP } from "@ethereumjs/rlp"; -import { KlaytnTxFactory, TxType, isFeePayerSigTxType } from "@klaytn/js-ext-core"; +import { KlaytnTxFactory, TxType, isFeePayerSigTxType, KlaytnTx as CoreKlaytnTx } from "@klaytn/js-ext-core"; import { keccak256 } from "ethereum-cryptography/keccak.js"; import * as ethereumCryptography from "ethereum-cryptography/secp256k1.js"; -import { Transaction as LegacyTransaction, TxOptions } from "web3-eth-accounts"; -import { Uint } from "web3-types"; +import { Transaction as LegacyTransaction, TxOptions, ECDSASignature } from "web3-eth-accounts"; import { bytesToHex, hexToBytes, toHex, toNumber, numberToHex, toBigInt } from "web3-utils"; -// eslint-disable-next-line import/extensions +import { KlaytnTxData } from "./types"; export const secp256k1 = ethereumCryptography.secp256k1 ?? ethereumCryptography; -import { KlaytnTxData } from "./types"; // Mimics the LegacyTransaction. // See web3-eth-accounts/src/tx/legacyTransaction.ts // and web3-eth-accounts/src/tx/baseTransaction.ts -// -// Functions modified to support sign(): -// - getMessageToSign -// - _processSignature -// - serialize export class KlaytnTx extends LegacyTransaction { - // BaseTransaction._type is always 0. KlaytnTx._klaytnType is nonzero. + // Override 'type' field (actually a getter) because LegacyTransaction.type is always 0. private readonly _klaytnType: number; + public override get type(): number { + return this._klaytnType; + } + + // Additional fields not in LegacyTransaction public readonly from?: string; public readonly chainId?: bigint; public readonly key?: any; public readonly feePayer?: string; public readonly feePayer_v?: bigint; - public readonly feePayer_r?: Uint8Array; - public readonly feePayer_s?: Uint8Array; + public readonly feePayer_r?: bigint; + public readonly feePayer_s?: bigint; public readonly txSignatures?: any; public readonly feePayerSignatures?: any; - public readonly feeRatio?: Uint; - - // Parsed KlaytnTx object - private readonly klaytnTxData: any; // TODO: import KlaytnTx as CoreKlaytnTx from ethers-ext + public readonly feeRatio?: number; - // Most fields are class properties, except 'type' is defined as getter in BaseTransaction. - public override get type(): number { - return this._klaytnType; - } + // The CoreKlaytnTx object to be used to calculate RLP encoding. + private readonly coreKlaytnTx: CoreKlaytnTx; // This constructor creates a frozen read-only transaction object out of TxData. // Any modifications to the fields (e.g. adding the signature) should involve @@ -53,7 +46,7 @@ export class KlaytnTx extends LegacyTransaction { // Construct LegacyTransaction and parse TxData fields super(txData, txOptions); - // parse Klaytn-specific fields + // Parse KlaytnTxData fields if (!txData.type) { // Should not reach here because KlaytnTx is selected via explicit type field. throw new Error("Missing 'type' field"); @@ -70,26 +63,27 @@ export class KlaytnTx extends LegacyTransaction { this.feePayerSignatures = txData.feePayerSignatures; this.feeRatio = txData.feeRatio; + // Build the inner CoreKlaytnTx object. + + // Convert to type understood by CoreKlaytnTx. const klaytnTxObject = { - // Convert to type understood by CoreKlaytnTx. - // TODO: add more fields for other TxTypes - type: toHex(this.type || 0), - nonce: toHex(this.nonce), - gasPrice: toHex(this.gasPrice), - gasLimit: toHex(this.gasLimit), - to: this.to ? bytesToHex(this.to.toString()) : undefined, - value: toHex(this.value), - from: this.from ? this.from : undefined, - data: bytesToHex(this.data), - input: bytesToHex(this.data), - chainId: this.chainId ? toHex(this.chainId) : undefined, - humanReadable: false, - codeFormat: 0x00, - key: this.key, - feePayer: this.feePayer, - txSignatures: this.txSignatures, + type: toHex(this.type || 0), + nonce: toHex(this.nonce), + gasPrice: toHex(this.gasPrice), + gasLimit: toHex(this.gasLimit), + to: this.to ? bytesToHex(this.to.toString()) : undefined, + value: toHex(this.value), + from: this.from, + data: bytesToHex(this.data), + input: bytesToHex(this.data), + chainId: this.chainId ? toHex(this.chainId) : undefined, + humanReadable: false, + codeFormat: 0x00, + key: this.key, + feePayer: this.feePayer, + txSignatures: this.txSignatures, feePayerSignatures: this.feePayerSignatures, - feeRatio: this.feeRatio, + feeRatio: this.feeRatio, }; if (txData.type == TxType.SmartContractDeploy || @@ -98,40 +92,36 @@ export class KlaytnTx extends LegacyTransaction { klaytnTxObject.to = "0x0000000000000000000000000000000000000000"; } - // A readonly CoreKlaytnTx object - this.klaytnTxData = KlaytnTxFactory.fromObject(klaytnTxObject); + this.coreKlaytnTx = KlaytnTxFactory.fromObject(klaytnTxObject); if (this.v && this.r && this.s) { - this.klaytnTxData.addSenderSig([ - Number(this.v), - numberToHex(this.r), - numberToHex(this.s), - ]); + this.coreKlaytnTx.addSenderSig({ + v: Number(this.v), + r: numberToHex(this.r), + s: numberToHex(this.s), + }); } - // @ts-ignore if (this.feePayer_v && this.feePayer_r && this.feePayer_s) { - this.klaytnTxData.addFeePayerSig([ - // @ts-ignore - Number(this.feePayer_v), - // @ts-ignore - numberToHex(this.feePayer_r), - // @ts-ignore - numberToHex(this.feePayer_s), - ]); + this.coreKlaytnTx.addFeePayerSig({ + v: Number(this.feePayer_v), + r: numberToHex(this.feePayer_r), + s: numberToHex(this.feePayer_s), + }); } - // Recreate the behavior at the end of LegacyTransaction.constructor(). + // Resume the freeze behavior at the end of LegacyTransaction.constructor(). this.txOptions.freeze = savedFreeze; if (this.txOptions.freeze ?? true) { Object.freeze(this); } } + // Return sender signing message. i.e. SigRLP public getMessageToSign(hashMessage: false): Uint8Array[]; public getMessageToSign(hashMessage?: true): Uint8Array; public getMessageToSign(hashMessage = true) { - const rlp = hexToBytes(this.klaytnTxData.sigRLP()); + const rlp = hexToBytes(this.coreKlaytnTx.sigRLP()); if (hashMessage) { return keccak256(rlp); // Hashed Uint8Array } else { @@ -139,10 +129,11 @@ export class KlaytnTx extends LegacyTransaction { } } + // Return feePayer signing message. i.e. sigFeePayerRLP public getMessageToSignAsFeePayer(hashMessage: false): Uint8Array[]; public getMessageToSignAsFeePayer(hashMessage?: true): Uint8Array; public getMessageToSignAsFeePayer(hashMessage = true) { - const rlp = hexToBytes(this.klaytnTxData.sigFeePayerRLP()); + const rlp = hexToBytes(this.coreKlaytnTx.sigFeePayerRLP()); if (hashMessage) { return keccak256(rlp); // Hashed Uint8Array } else { @@ -150,67 +141,77 @@ export class KlaytnTx extends LegacyTransaction { } } - public signAsFeePayer(privateKey: Uint8Array): KlaytnTx { + // Return a new KlaytnTx object with the (v,r,s) signature added. + public sign(privateKey: Uint8Array): KlaytnTx { if (privateKey.length !== 32) { const msg = this._errorMsg("Private key must be 32 bytes in length."); throw new Error(msg); } + if (!this.chainId) { + // shouldn't reach here because chainId is required in every Klaytn TxType. + // The chainId should have been supplied by user or filled at klaytnPrepareTransaction(). + throw new Error("Missing 'chainId' field"); + } - const msgHash = this.getMessageToSignAsFeePayer(true); - const signature = secp256k1.sign(msgHash, privateKey); - const signatureBytes = signature.toCompactRawBytes(); - - const r = signatureBytes.subarray(0, 32); - const s = signatureBytes.subarray(32, 64); - const v = BigInt(signature.recovery! + 27); - - const tx = this._processSignatureAsFeePayer(v, r, s); - - return tx; - } - - // Returns a new KlaytnTx by adding the signature - protected _processSignature(v: bigint, r: Uint8Array, s: Uint8Array): KlaytnTx { - // Klaytn TxTypes must comply to EIP-155. - v += this.common.chainId() * BigInt(2) + BigInt(8); + const msgHash = this.getMessageToSign(true); + const { r, s, v } = this._eip155sign(msgHash, privateKey, this.chainId); return new KlaytnTx({ ...this, - type: this.type, // The '...this' expression does not include this.type because it's a getter. + type: this.type, // The '...this' expression does not include this.type because 'type()' a getter. v: v, r: toBigInt(bytesToHex(r)), s: toBigInt(bytesToHex(s)), }, this.txOptions); } - // Returns a new KlaytnTx by adding the signature - protected _processSignatureAsFeePayer(v: bigint, r: Uint8Array, s: Uint8Array): KlaytnTx { - // Klaytn TxTypes must comply to EIP-155. - v += this.common.chainId() * BigInt(2) + BigInt(8); + // Analogous to sign(), but uses *AsFeePayer methods. + // See web3-eth-accounts/src/tx/baseTransaction.ts:sign() + public signAsFeePayer(privateKey: Uint8Array): KlaytnTx { + if (privateKey.length !== 32) { + const msg = this._errorMsg("Private key must be 32 bytes in length."); + throw new Error(msg); + } + if (!this.chainId) { + // shouldn't reach here because chainId is required in every Klaytn TxType. + // The chainId should have been supplied by user or filled at klaytnPrepareTransaction(). + throw new Error("Missing 'chainId' field"); + } + + const msgHash = this.getMessageToSignAsFeePayer(true); + const { v, r, s } = this._eip155sign(msgHash, privateKey, this.chainId); return new KlaytnTx({ ...this, - type: this.type, // The '...this' expression does not include this.type because it's a getter. + type: this.type, // The '...this' expression does not include this.type because 'type()' is a getter. feePayer_v: v, feePayer_r: toBigInt(bytesToHex(r)), feePayer_s: toBigInt(bytesToHex(s)), }, this.txOptions); } - // Returns the raw transaction + // Return the sender-signed raw transaction. i.e. SenderTxHashRLP or TxHashRLP public serialize(): Uint8Array { - const tx = this.klaytnTxData; - - if (isFeePayerSigTxType(tx.type)) { - return hexToBytes(tx.senderTxHashRLP()); + if (isFeePayerSigTxType(this.type)) { + return hexToBytes(this.coreKlaytnTx.senderTxHashRLP()); } - return hexToBytes(tx.txHashRLP()); + return hexToBytes(this.coreKlaytnTx.txHashRLP()); } - // Returns the raw transaction + // Return the feePayer-signed raw transaction. i.e. TxHashRLP public serializeAsFeePayer(): Uint8Array { - const tx = this.klaytnTxData; + return hexToBytes(this.coreKlaytnTx.txHashRLP()); + } - return hexToBytes(tx.txHashRLP()); + // Recreating BaseTransaction._ecsign because that's private. + private _eip155sign(msgHash: Uint8Array, privateKey: Uint8Array, chainId: bigint): ECDSASignature { + const signature = secp256k1.sign(msgHash, privateKey); + const signatureBytes = signature.toCompactRawBytes(); + + const r = signatureBytes.subarray(0, 32); + const s = signatureBytes.subarray(32, 64); + const recoveryParam = signature.recovery; + const v = BigInt(recoveryParam + 35) + chainId * BigInt(2); + return { v, r, s }; } } diff --git a/web3js-ext/src/tx.ts b/web3js-ext/src/tx.ts index c8277047c..4aa088248 100644 --- a/web3js-ext/src/tx.ts +++ b/web3js-ext/src/tx.ts @@ -39,8 +39,8 @@ klaytnPrepareTransaction @ tx.ts | KlaytnTypedTransaction | - TypedTransaction | - LegacyTransaction (class Transaction extends BaseTransaction) @ legacyTransaction.ts - | - AccessListEIP2930Transaction (class ... extends BaseTransaction) @ eip2930Transaction.ts | - FeeMarketEIP1559Transaction (class ... extends BaseTransaction) @ eip1559Transaction.ts + | - AccessListEIP2930Transaction (class ... extends BaseTransaction) @ eip2930Transaction.ts | - KlaytnTx (class ... extends LegacyTransaction) @ klaytn_tx.ts V klaytnSignTransaction @ tx.ts @@ -157,6 +157,7 @@ export async function klaytnPrepareTransaction( txData.from ??= transaction.from; txData.chainId ??= tx.common.chainId(); + // Access the private field 'txOptions' of BaseTransaction. const txOptions = (tx as any).txOptions; return new KlaytnTx(txData, txOptions); diff --git a/web3js-ext/src/types.ts b/web3js-ext/src/types.ts index 5ae8e07b0..0a843a757 100644 --- a/web3js-ext/src/types.ts +++ b/web3js-ext/src/types.ts @@ -1,3 +1,4 @@ +import { SignatureLike } from "@klaytn/js-ext-core"; import Eth from "web3-eth"; import { decodeLog, @@ -16,6 +17,7 @@ import { sign, signTransaction, TxData, + TypedTransaction, Wallet, Web3Account, } from "web3-eth-accounts"; @@ -26,6 +28,8 @@ import { Personal } from "web3-eth-personal"; import { Net } from "web3-net"; import { KeyStore, Bytes, Transaction, Uint } from "web3-types"; +import { KlaytnTx } from "./klaytn_tx"; + // Type analogous to web3-eth-accounts/src/types.ts:Web3Account // Designed for the "account object" returned by // - web3.eth.accounts.privateKeyToAccount() @@ -121,21 +125,30 @@ export interface KlaytnAccountsInterface { // The plain Transaction object supplied by the users. // Used as argument to prepareTransaction() export interface KlaytnTransaction extends Transaction { - // TODO: add fields - feePayer? : string, + key?: any; + feePayer?: string; + txSignatures?: any; + feePayerSignatures?: any; + feeRatio?: number; } // The plain Transaction object used internally. // Used as argument to KlaytnTx.fromTxData() export interface KlaytnTxData extends TxData { - from?: string, - chainId?: bigint, - key? : any, - feePayer? : string, - feePayer_v? : bigint, - feePayer_r? : Uint8Array, - feePayer_s? : Uint8Array, - txSignatures? : any, - feePayerSignatures? : any, - feeRatio? : Uint, -} \ No newline at end of file + from?: string; + chainId?: bigint; + key?: any; + feePayer?: string; + feePayer_v?: bigint; + feePayer_r?: bigint; + feePayer_s?: bigint; + txSignatures?: any; + feePayerSignatures?: any; + feeRatio?: number; +} + +// The child classes of BaseTransaction. +// Used inside signTransaction() and signTransactionAsFeePayer() +export type KlaytnTypedTransaction = + | TypedTransaction // Type 0 (LegacyTransaction), Type 1, Type 2 + | KlaytnTx; // Klaytn TxTypes \ No newline at end of file diff --git a/web3js-ext/test/account.spec.ts b/web3js-ext/test/account.spec.ts index 6f0ed21a2..daa1df1cb 100644 --- a/web3js-ext/test/account.spec.ts +++ b/web3js-ext/test/account.spec.ts @@ -1,3 +1,4 @@ +import { SignatureLike } from "@klaytn/js-ext-core"; import { assert } from "chai"; import { describe, it } from "mocha"; import { EthExecutionAPI, Web3, Web3BaseProvider } from "web3"; From 3166fe6e35c87e6b6b33eb707a5e348f3f321304 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 30 Nov 2023 18:48:58 +0900 Subject: [PATCH 62/69] web3js: More account tests --- web3js-ext/src/types.ts | 7 +- web3js-ext/test/account.spec.ts | 265 ++++++++++++++++++++------------ web3js-ext/test/sig.spec.ts | 14 -- 3 files changed, 171 insertions(+), 115 deletions(-) delete mode 100644 web3js-ext/test/sig.spec.ts diff --git a/web3js-ext/src/types.ts b/web3js-ext/src/types.ts index 0a843a757..4ae9b6bdb 100644 --- a/web3js-ext/src/types.ts +++ b/web3js-ext/src/types.ts @@ -1,4 +1,3 @@ -import { SignatureLike } from "@klaytn/js-ext-core"; import Eth from "web3-eth"; import { decodeLog, @@ -26,7 +25,7 @@ import { ENS } from "web3-eth-ens"; import { Iban } from "web3-eth-iban"; import { Personal } from "web3-eth-personal"; import { Net } from "web3-net"; -import { KeyStore, Bytes, Transaction, Uint } from "web3-types"; +import { KeyStore, Bytes, Transaction } from "web3-types"; import { KlaytnTx } from "./klaytn_tx"; @@ -50,7 +49,7 @@ export interface KlaytnWeb3Account extends Web3Account { readonly encrypt: (password: string, options?: Record) => Promise; // Klaytn: modified methods - readonly signTransaction: (tx: Transaction | string) => Promise<{ + readonly signTransaction: (tx: KlaytnTransaction | string) => Promise<{ readonly messageHash: string; readonly r: string; readonly s: string; @@ -60,7 +59,7 @@ export interface KlaytnWeb3Account extends Web3Account { }>; // Klaytn: additional methods - readonly signTransactionAsFeePayer: (tx: Transaction | string) => Promise<{ + readonly signTransactionAsFeePayer: (tx: KlaytnTransaction | string) => Promise<{ readonly messageHash: string; readonly r: string; readonly s: string; diff --git a/web3js-ext/test/account.spec.ts b/web3js-ext/test/account.spec.ts index daa1df1cb..f024e08e7 100644 --- a/web3js-ext/test/account.spec.ts +++ b/web3js-ext/test/account.spec.ts @@ -1,10 +1,10 @@ -import { SignatureLike } from "@klaytn/js-ext-core"; import { assert } from "chai"; import { describe, it } from "mocha"; -import { EthExecutionAPI, Web3, Web3BaseProvider } from "web3"; -import { toWei } from "web3-utils"; +import { CipherOptions, KeyStore, Web3 } from "web3"; +import { sign, recover, Web3Account } from "web3-eth-accounts"; import { KlaytnWeb3 } from "../src"; +import { KlaytnWeb3Account } from "../src/types"; import { MockProvider } from "./mock_provider"; @@ -13,45 +13,24 @@ import { MockProvider } from "./mock_provider"; /* eslint-disable quotes */ const url = "https://public-en-baobab.klaytn.net"; -const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const to = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; const feePayer = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; -const value = toWei("0.01", "ether"); +const value = 1000000000000; const nonce = 2; const gasPrice = 25e9; const gasLimit = 50000; const chainId = 1001; const senderTxHashRLP = "0x09f87a8204d219830f4240947b65b75d204abed71587c9e519a89277766ee1d00a94a94f5374fce5edbc8e2a8697c15331677e6ebf0bf845f84325a09f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956a06bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"; const txSignatures = [["0x25", "0x9f8e49e2ad84b0732984398749956e807e4b526c786af3c5f7416b293e638956", "0x6bf88342092f6ff9fabe31739b2ebfa1409707ce54a54693e91a6b9bb77df0e7"]]; -const keystore_v3 = `{"address":"3c44cdddb6a900fa2b585dd299e03d12fa4293bc","id":"3d73e4aa-2102-4203-8f90-2fb1b0690af7","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"c65d46f512e3e3c66729cdec6884123c"},"ciphertext":"32f222a3b6f454559331f04f0645b76733e924c770bfe311d6a80a11b952c97a","kdf":"scrypt","kdfparams":{"salt":"317e916c3caa8da89868c41300ec8e2eba88abc2474ee5f7954ba757e7c81caf","n":2,"dklen":32,"p":1,"r":8},"mac":"36ed4164aab7f139aa42990d11d7f790078f454b46a4d4d0b9ed718de2dd3e9a"},"x-ethers":{"client":"ethers.js","gethFilename":"UTC--2023-11-29T09-26-20.0Z--3c44cdddb6a900fa2b585dd299e03d12fa4293bc","mnemonicCounter":"6c3b6d22c9e7361b65043ef05430febd","mnemonicCiphertext":"63bd4059afc9294ae4e748cf5cee4b61","path":"m/44'/60'/0'/0/2","locale":"en","version":"0.1"}}`; +const tx0 = { type: 0, from, to, value, gasPrice }; +const tx9 = { type: 9, from, to, value, gasPrice, txSignatures }; +const lightKdf: CipherOptions = { kdf: "scrypt", n: 2, p: 1 }; // For faster testing /* eslint-enable quotes */ -function checkSignResult(signResult: any) { - assert.isDefined(signResult.messageHash); - assert.isDefined(signResult.v); - assert.isDefined(signResult.r); - assert.isDefined(signResult.s); - assert.isDefined(signResult.rawTransaction); - assert.isDefined(signResult.transactionHash); -} - -function checkAccountObject(account: any, klaytn: boolean) { - // TODO: check account.signTransaction accepts klaytn tx type - // TODO: check account.sign works - // TODO: check account.encrypt works - - assert.isDefined(account.address); - assert.isDefined(account.privateKey); - assert.isDefined(account.signTransaction); - assert.isDefined(account.sign); - assert.isDefined(account.encrypt); - if (klaytn) { - // assert.isDefined(account.signTransactionAsFeePayer); - } -} -describe("accounts", () => { +// Test each properties of web3.eth.accounts (of type KlaytnAccountsInterface) +describe("web3.eth.accounts", () => { let P: MockProvider; let EW3: Web3; let KW3: KlaytnWeb3; @@ -71,87 +50,179 @@ describe("accounts", () => { P.mock_override("eth_estimateGas", () => "0x5208"); }); - describe("privateKeyToAccount", () => { - it("account has all necessary fields", () => { - let account = EW3.eth.accounts.privateKeyToAccount(priv); - checkAccountObject(account, false); - - account = KW3.eth.accounts.privateKeyToAccount(priv); - checkAccountObject(account, true); - }); - it("address and private key are correct", () => { - const account = EW3.eth.accounts.privateKeyToAccount(priv); - assert.equal(account.address, from); - assert.equal(account.privateKey, priv); - }); + it("recoverTransaction()", async () => { + // var a = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" + // var b = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" + // klay.sendTransaction({ typeInt: 0, from: a, to: b, value: 1e12 }) + // klay.sendTransaction({ typeInt: 8, from: a, to: b, value: 1e12 }) + const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + const rawTx0 = "0xf86c80850ba43b740083015f909470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a510008082f4f6a0e0695a8467fca213751d5f31082ebcce69b14d1398d02978fb989744027c2414a04edf04c0bae5326942edc512a6fa793f01a09c14f9a6c1ef526cea75f7afcd97"; + const rawTx8 = "0x08f88401850ba43b740083015f909470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f847f84582f4f5a0855117ad19a1abf7931e9b06211f83d8508611a1d4ca307f1e0f986b99c7161ca0136ff93afe61264e9704eb13d8de8f68d1cb50060f4b392cf9083e86b3650cc2"; + + assert.equal(EW3.eth.accounts.recoverTransaction(rawTx0), from); + assert.equal(KW3.eth.accounts.recoverTransaction(rawTx0), from); + assert.equal(KW3.eth.accounts.recoverTransaction(rawTx8), from); }); - describe("create", () => { - it("account has all necessary fields", () => { - let account = EW3.eth.accounts.create(); - checkAccountObject(account, false); + it("hashMessage()", async () => { + const msg = "hello"; + const msgHash = "0x50b2c43fd39106bafbba0da34fc430e1f91e3c96ea2acee2bc34119f92b37750"; - account = KW3.eth.accounts.create(); - checkAccountObject(account, true); - }); + assert.equal(EW3.eth.accounts.hashMessage(msg), msgHash); + assert.equal(KW3.eth.accounts.hashMessage(msg), msgHash); }); - describe("decrypt", () => { - it("account has all necessary fields", async () => { - let account = await EW3.eth.accounts.decrypt(keystore_v3, ""); - checkAccountObject(account, false); + it("sign()", async () => { + const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + const addr = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + const msg = "hello"; + const msgHash = "0x50b2c43fd39106bafbba0da34fc430e1f91e3c96ea2acee2bc34119f92b37750"; + + function checkMsgSignResult(signResult: ReturnType) { + assert.equal(signResult.message, msg); + assert.equal(signResult.messageHash, msgHash); + assert.equal(recover(msg, signResult.signature), addr); + assert.equal(recover(msg, signResult.v, signResult.r, signResult.s), addr); + } - account = await KW3.eth.accounts.decrypt(keystore_v3, ""); - checkAccountObject(account, true); - }); + checkMsgSignResult(EW3.eth.accounts.sign(msg, priv)); + checkMsgSignResult(KW3.eth.accounts.sign(msg, priv)); }); - describe("signTransaction", () => { - const tx0 = { type: 0, from, to, value, gasPrice }; - const tx9 = { type: 9, from, to, value, gasPrice }; + it("encrypt()", async () => { + const priv = "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"; + const addr = "3c44cdddb6a900fa2b585dd299e03d12fa4293bc"; + + function checkKeyStore(ks: KeyStore) { + assert.equal(ks.version, 3); + assert.equal(ks.address, addr); + assert.isString(ks.id); + assert.isObject(ks.crypto); + } - async function testOK_withAccount(W3: Web3, tx: any) { - const account = W3.eth.accounts.privateKeyToAccount(priv); - const signResult = await account.signTransaction(tx); - checkSignResult(signResult); + checkKeyStore(await EW3.eth.accounts.encrypt(priv, "password", lightKdf)); + checkKeyStore(await KW3.eth.accounts.encrypt(priv, "password", lightKdf)); + }); + + it("wallet", async () => { + const priv1 = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + const addr1 = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + const json2 = "{\"address\":\"3c44cdddb6a900fa2b585dd299e03d12fa4293bc\",\"id\":\"3d73e4aa-2102-4203-8f90-2fb1b0690af7\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"c65d46f512e3e3c66729cdec6884123c\"},\"ciphertext\":\"32f222a3b6f454559331f04f0645b76733e924c770bfe311d6a80a11b952c97a\",\"kdf\":\"scrypt\",\"kdfparams\":{\"salt\":\"317e916c3caa8da89868c41300ec8e2eba88abc2474ee5f7954ba757e7c81caf\",\"n\":2,\"dklen\":32,\"p\":1,\"r\":8},\"mac\":\"36ed4164aab7f139aa42990d11d7f790078f454b46a4d4d0b9ed718de2dd3e9a\"},\"x-ethers\":{\"client\":\"ethers.js\",\"gethFilename\":\"UTC--2023-11-29T09-26-20.0Z--3c44cdddb6a900fa2b585dd299e03d12fa4293bc\",\"mnemonicCounter\":\"6c3b6d22c9e7361b65043ef05430febd\",\"mnemonicCiphertext\":\"63bd4059afc9294ae4e748cf5cee4b61\",\"path\":\"m/44'/60'/0'/0/2\",\"locale\":\"en\",\"version\":\"0.1\"}}"; + const priv2 = "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"; + const addr2 = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; + + async function checkWallet(W3: Web3) { + await W3.eth.accounts.wallet.create(1); + await W3.eth.accounts.wallet.add(priv1); + await W3.eth.accounts.wallet.decrypt([JSON.parse(json2)], ""); + + assert.equal(W3.eth.accounts.wallet.length, 3); + assert.equal(W3.eth.accounts.wallet.at(1)?.address, addr1); + assert.equal(W3.eth.accounts.wallet.at(2)?.privateKey, priv2); + assert.equal(W3.eth.accounts.wallet.at(2)?.address, addr2); + checkAccountObject(W3.eth.accounts.wallet.at(0)!); } - async function testOK_withWeb3(W3: Web3, tx: any) { - const signResult = await W3.eth.accounts.signTransaction(tx, priv); - checkSignResult(signResult); + async function checkKlaytnWallet(W3: KlaytnWeb3) { + await checkWallet(W3); + checkKlaytnAccountObject(W3.eth.accounts.wallet.at(0) as KlaytnWeb3Account); // TODO: fix type } - it("account.signTransaction", async () => { - for (const W3 of [EW3, KW3]) { - await testOK_withAccount(W3, tx0); - } - for (const W3 of [KW3]) { - await testOK_withAccount(W3, tx9); - } - }); - it("web3.eth.accounts.signTransaction", async () => { - for (const W3 of [EW3, KW3]) { - await testOK_withWeb3(W3, { type: 0, from, to, value, gasPrice }); - } - for (const W3 of [KW3]) { - await testOK_withWeb3(W3, { type: 9, from, to, value, gasPrice }); - } - }); + await checkWallet(EW3); + await checkKlaytnWallet(KW3); + }); + + it("create()", async () => { + await checkAccountObject(EW3.eth.accounts.create()); + await checkKlaytnAccountObject(KW3.eth.accounts.create()); + }); + + it("privateKeyToAccount()", async () => { + const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + const addr = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + + await checkAccountObject(EW3.eth.accounts.privateKeyToAccount(priv), addr, priv); + await checkKlaytnAccountObject(KW3.eth.accounts.privateKeyToAccount(priv), addr, priv); + }); + + it("decrypt()", async () => { + const json = "{\"address\":\"3c44cdddb6a900fa2b585dd299e03d12fa4293bc\",\"id\":\"3d73e4aa-2102-4203-8f90-2fb1b0690af7\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"c65d46f512e3e3c66729cdec6884123c\"},\"ciphertext\":\"32f222a3b6f454559331f04f0645b76733e924c770bfe311d6a80a11b952c97a\",\"kdf\":\"scrypt\",\"kdfparams\":{\"salt\":\"317e916c3caa8da89868c41300ec8e2eba88abc2474ee5f7954ba757e7c81caf\",\"n\":2,\"dklen\":32,\"p\":1,\"r\":8},\"mac\":\"36ed4164aab7f139aa42990d11d7f790078f454b46a4d4d0b9ed718de2dd3e9a\"},\"x-ethers\":{\"client\":\"ethers.js\",\"gethFilename\":\"UTC--2023-11-29T09-26-20.0Z--3c44cdddb6a900fa2b585dd299e03d12fa4293bc\",\"mnemonicCounter\":\"6c3b6d22c9e7361b65043ef05430febd\",\"mnemonicCiphertext\":\"63bd4059afc9294ae4e748cf5cee4b61\",\"path\":\"m/44'/60'/0'/0/2\",\"locale\":\"en\",\"version\":\"0.1\"}}"; + const priv = "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"; + const addr = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; + + await checkAccountObject(await EW3.eth.accounts.decrypt(json, ""), addr, priv); + await checkKlaytnAccountObject(await KW3.eth.accounts.decrypt(json, ""), addr, priv); + }); + + it("signTransaction()", async () => { + const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + const tx0 = { type: 0, from, to, value, gasPrice }; + const tx9 = { type: 9, from, to, value, gasPrice }; + + await checkTxSignResult(await EW3.eth.accounts.signTransaction(tx0, priv)); + await checkTxSignResult(await KW3.eth.accounts.signTransaction(tx0, priv)); + await checkTxSignResult(await KW3.eth.accounts.signTransaction(tx9, priv)); }); - describe("signTransactionAsFeePayer", () => { + it("signTransactionAsFeePayer()", async () => { + const priv = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const tx9 = { type: 9, from, to, feePayer, value, nonce, gasPrice, gasLimit, chainId, txSignatures }; - it("account.signTransactionAsFeePayer", async () => { - const account = KW3.eth.accounts.privateKeyToAccount(priv); - const signResult = await account.signTransactionAsFeePayer(tx9); - checkSignResult(signResult); - }); - it("web3.eth.accounts.signTransactionAsFeePayer", async () => { - let signResult = await KW3.eth.accounts.signTransactionAsFeePayer(tx9, priv); - checkSignResult(signResult); - - signResult = await KW3.eth.accounts.signTransactionAsFeePayer(senderTxHashRLP as any, priv); - checkSignResult(signResult); - }); + await checkTxSignResult(await KW3.eth.accounts.signTransactionAsFeePayer(tx9, priv)); + await checkTxSignResult(await KW3.eth.accounts.signTransactionAsFeePayer(senderTxHashRLP, priv)); }); -}); \ No newline at end of file +}); + +// Check the result of web3.eth.accounts.create(), decrypt(), and privateKeyToAccount() from Web3. +async function checkAccountObject(account: Web3Account, expectedAddr?: string, expectedPriv?: string) { + // All properties are defined. + assert.isString(account.address); + assert.isString(account.privateKey); + assert.isFunction(account.signTransaction); + assert.isFunction(account.sign); + assert.isFunction(account.encrypt); + if (expectedAddr) { assert.equal(account.address, expectedAddr); } + if (expectedPriv) { assert.equal(account.privateKey, expectedPriv); } + + // Functions work. + checkTxSignResult(await account.signTransaction(tx0)); + checkMsgSignResult(account.sign("hello")); + checkKeyStore(await account.encrypt("password", lightKdf)); +} + +// Check the result of web3.eth.accounts.create(), decrypt(), and privateKeyToAccount() from KlaytnWeb3. +async function checkKlaytnAccountObject(account: KlaytnWeb3Account, expectedAddr?: string, expectedPriv?: string) { + // All properties are defined. + await checkAccountObject(account, expectedAddr, expectedPriv); + assert.isFunction(account.signTransactionAsFeePayer); + + // Functions work. + checkTxSignResult(await account.signTransaction(tx9)); + checkTxSignResult(await account.signTransactionAsFeePayer(tx9)); + checkTxSignResult(await account.signTransactionAsFeePayer(senderTxHashRLP)); +} + +function checkTxSignResult(signResult: any) { + assert.isString(signResult.messageHash); + assert.isString(signResult.v); + assert.isString(signResult.r); + assert.isString(signResult.s); + assert.isString(signResult.rawTransaction); + assert.isString(signResult.transactionHash); +} + +function checkMsgSignResult(signResult: ReturnType) { + assert.isString(signResult.messageHash); + assert.isString(signResult.v); + assert.isString(signResult.r); + assert.isString(signResult.s); + assert.isString(signResult.signature); +} + +function checkKeyStore(ks: KeyStore) { + assert.equal(ks.version, 3); + assert.isString(ks.address); + assert.isString(ks.id); + assert.isObject(ks.crypto); +} \ No newline at end of file diff --git a/web3js-ext/test/sig.spec.ts b/web3js-ext/test/sig.spec.ts deleted file mode 100644 index bc0c0395e..000000000 --- a/web3js-ext/test/sig.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { assert } from "chai"; -import Web3 from "web3"; - -import { KlaytnWeb3 } from "../src/web3"; - -describe("KlaytnWeb3", () => { - it("success", () => { - let url = "http://localhost:8545"; - let provider = new Web3.providers.HttpProvider(url); - let web3 = new KlaytnWeb3(provider); - - assert.isDefined(web3.eth.accounts.signTransaction); - }); -}); From 40e428ed06092beb404065720f670983dbbaf257 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Thu, 30 Nov 2023 19:18:24 +0900 Subject: [PATCH 63/69] Test sendSignedTransaction --- web3js-ext/test/rpc.spec.ts | 133 ++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 web3js-ext/test/rpc.spec.ts diff --git a/web3js-ext/test/rpc.spec.ts b/web3js-ext/test/rpc.spec.ts new file mode 100644 index 000000000..72d111485 --- /dev/null +++ b/web3js-ext/test/rpc.spec.ts @@ -0,0 +1,133 @@ +import { assert } from "chai"; +import _ from "lodash"; +import { describe, it } from "mocha"; +import { Receipt, Web3 } from "web3"; + +import { KlaytnWeb3 } from "../src"; + +import { MockProvider } from "./mock_provider"; + +// Dummy values +const url = "https://public-en-baobab.klaytn.net"; + +const rawTx0 = "0xf86c80850ba43b740083015f909470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a510008082f4f6a0e0695a8467fca213751d5f31082ebcce69b14d1398d02978fb989744027c2414a04edf04c0bae5326942edc512a6fa793f01a09c14f9a6c1ef526cea75f7afcd97"; +const rc0 = { + blockHash: "0x76938e2a9b83600621d51465a66a725130de1963e9e5d546adf755939bf74799", + blockNumber: 18, + contractAddress: null, + cumulativeGasUsed: "0x5208", + effectiveGasPrice: "0x5d21dba00", + from: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + gasUsed: 21000, + logs: [], + logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + status: "0x1", + to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + transactionHash: "0x3c3b448e03b34c09c19f3dacaaeaac20e5367a63da64ad0a219cc490ad0cf062", + transactionIndex: 0, + type: "0x0" +}; + +const rawTx8 = "0x08f88401850ba43b740083015f909470997970c51812dc3a010c7d01b50e0d17dc79c885e8d4a5100094f39fd6e51aad88f6f4ce6ab8827279cfffb92266f847f84582f4f5a0855117ad19a1abf7931e9b06211f83d8508611a1d4ca307f1e0f986b99c7161ca0136ff93afe61264e9704eb13d8de8f68d1cb50060f4b392cf9083e86b3650cc2"; +const rc8 = { + blockHash: "0x9e98fff0e594ba898abd9406d7b2b79ca0b21fa0cc7822b48d897bcc50b4888c", + blockNumber: 91, + contractAddress: null, + cumulativeGasUsed: "0x5208", + effectiveGasPrice: "0x5d21dba00", + from: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + gasUsed: 21000, + logs: [], + logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + status: "0x1", + to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + transactionHash: "0x8d8e09e21311c53469a0cd82d310641b82819d723b09762166178f194f9eecd1", + transactionIndex: 0, + type: "0x0" +}; + +const block = { + baseFeePerGas: "0x5d21dba00", + difficulty: "0x1", + extraData: "0x", + gasLimit: "0xe8d4a50fff", + gasUsed: 0, + hash: "0x92694a6b75a012a15559d60e92ff30d855e2722292b7d1b05f94e5c34ff02a42", + logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + miner: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + nonce: "0x0000000000000000", + number: 19, + parentHash: "0x76938e2a9b83600621d51465a66a725130de1963e9e5d546adf755939bf74799", + receiptsRoot: "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + size: 630, + stateRoot: "0x61f886eb9904d0c776c4871f9b955d5d849938340ad2cec78b35e4ab0fa9bb1a", + timestamp: 1701338345, + timestampFoS: 0, + totalDifficulty: "0x14", + transactions: [], + transactionsRoot: "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + uncles: [] +}; + + +// Test overriden methods of web3.eth. +describe("web3.eth", () => { + let P: MockProvider; + let EW3: Web3; + let KW3: KlaytnWeb3; + + before(() => { + P = new MockProvider(url); + EW3 = new Web3(P); + KW3 = new KlaytnWeb3(P); + + // Stuff dummy values to the mock provider + P.mock_override("eth_chainId", () => "0x3e9"); + P.mock_override("net_version", () => "0x3e9"); + + P.mock_override("eth_protocolVersion", () => "0x1111"); + P.mock_override("klay_protocolVersion", () => "0x2222"); + + P.mock_override("eth_call", () => {}); + P.mock_override("eth_blockNumber", () => "0x64"); + P.mock_override("eth_getBlockByNumber", ([num]) => { + const b = _.clone(block); + b.number = Number(num); + return b; // Return a dummy block with the requested number + }); + + P.mock_override("eth_sendRawTransaction", () => rc0.transactionHash); + P.mock_override("eth_getTransactionReceipt", () => rc0); + P.mock_override("klay_sendRawTransaction", () => rc8.transactionHash); + P.mock_override("klay_getTransactionReceipt", () => rc8); + }); + + it("getProtocolVersion()", async () => { + // calls different namespace + assert.equal(await EW3.eth.getProtocolVersion(), "0x1111"); + assert.equal(await KW3.eth.getProtocolVersion(), "0x2222"); + }); + + it.only("sendSignedTransaction()", async () => { + async function checkSend(W3: Web3, rawTx: string, receipt: Receipt) { + let onSent: string = ""; + let onTxHash: string = ""; + let onRc: Receipt = {}; + + const rc = await W3.eth.sendSignedTransaction(rawTx) + .on("sending", (sent: string) => { onSent = sent; }) + .on("sent", (sent: string) => { onSent = sent; }) + .on("transactionHash", (hash: string) => { onTxHash = hash; }) + .on("receipt", (rc: Receipt) => { onRc = rc; }); + + assert.equal(onSent, rawTx); + assert.equal(onTxHash, receipt.transactionHash); + assert.equal(onRc.transactionHash, receipt.transactionHash); + assert.equal(rc.transactionHash, receipt.transactionHash); + } + + await checkSend(EW3, rawTx0, rc0); + }); +}); From 1a032e86dfef535a614d2c79e0a278316b9b5144 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Fri, 1 Dec 2023 16:30:28 +0900 Subject: [PATCH 64/69] Fix sendSignedTransaction typing --- web3js-ext/src/rpc.ts | 8 ++++---- web3js-ext/src/send_transaction.ts | 2 +- web3js-ext/src/web3.ts | 2 +- web3js-ext/test/rpc.spec.ts | 19 +++++++++++++++---- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/web3js-ext/src/rpc.ts b/web3js-ext/src/rpc.ts index c0bcd09c8..f73f4f6ac 100644 --- a/web3js-ext/src/rpc.ts +++ b/web3js-ext/src/rpc.ts @@ -2,7 +2,7 @@ import { Web3Context } from "web3-core"; import { SendTransactionOptions } from "web3-eth"; import { Bytes, DEFAULT_RETURN_FORMAT, DataFormat } from "web3-types"; -import { klay_sendSignedTransaction } from "./send_transaction"; +import { klaytnSendSignedTransaction } from "./send_transaction"; // Create a getProtocolVersion() function bound to given context // Should replace web3.eth.getProtocolVersion(). @@ -23,10 +23,10 @@ export function context_getProtocolVersion(context: Web3Context) { // Override it because eth_sendRawTransaction cannot accept Klaytn TxTypes. export function context_sendSignedTransaction(context: Web3Context) { // See web3-eth/src/web3_eth.ts:Web3Eth - return async ( + return function ( transaction: Bytes, returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat, - options?: SendTransactionOptions) => { - return klay_sendSignedTransaction(context, transaction, returnFormat, options); + options?: SendTransactionOptions) { + return klaytnSendSignedTransaction(context, transaction, returnFormat, options); }; } \ No newline at end of file diff --git a/web3js-ext/src/send_transaction.ts b/web3js-ext/src/send_transaction.ts index 6c0d91a72..5e7d084f3 100644 --- a/web3js-ext/src/send_transaction.ts +++ b/web3js-ext/src/send_transaction.ts @@ -29,7 +29,7 @@ type TimeoutT = ReturnType; // A wrapper around the sendRawTransaction RPC. There is no such RPC named "sendSignedTransaction". // See web3-eth/src/rpc_method_wrappers.ts:sendSignedTransaction // See web3-eth/src/utils/try_send_transaction.ts -export function klay_sendSignedTransaction< +export function klaytnSendSignedTransaction< ReturnFormat extends DataFormat, ResolveType = FormatType, >( diff --git a/web3js-ext/src/web3.ts b/web3js-ext/src/web3.ts index bada8b0ac..39be17782 100644 --- a/web3js-ext/src/web3.ts +++ b/web3js-ext/src/web3.ts @@ -61,7 +61,7 @@ export class KlaytnWeb3 // Note that most of the web3.eth methods should keep calling eth_ RPCs to Klaytn node, // except below ones. this.eth.getProtocolVersion = context_getProtocolVersion(this._web3); - this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3) as typeof this.eth.sendSignedTransaction; // TODO: fix typing + this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3); } } diff --git a/web3js-ext/test/rpc.spec.ts b/web3js-ext/test/rpc.spec.ts index 72d111485..286b4824b 100644 --- a/web3js-ext/test/rpc.spec.ts +++ b/web3js-ext/test/rpc.spec.ts @@ -98,10 +98,19 @@ describe("web3.eth", () => { return b; // Return a dummy block with the requested number }); - P.mock_override("eth_sendRawTransaction", () => rc0.transactionHash); - P.mock_override("eth_getTransactionReceipt", () => rc0); - P.mock_override("klay_sendRawTransaction", () => rc8.transactionHash); - P.mock_override("klay_getTransactionReceipt", () => rc8); + function mockSendRawTransaction(params: any[]) { + if (params[0] == rawTx0) { return rc0.transactionHash; } + if (params[0] == rawTx8) { return rc8.transactionHash; } + return null; + } + function mockGetTransactionReceipt(params: any[]) { + if (params[0] == rc0.transactionHash) { return rc0; } + if (params[0] == rc8.transactionHash) { return rc8; } + return null; + } + P.mock_override("eth_sendRawTransaction", mockSendRawTransaction); + P.mock_override("eth_getTransactionReceipt", mockGetTransactionReceipt); + P.mock_override("klay_sendRawTransaction", mockSendRawTransaction); }); it("getProtocolVersion()", async () => { @@ -129,5 +138,7 @@ describe("web3.eth", () => { } await checkSend(EW3, rawTx0, rc0); + await checkSend(KW3, rawTx0, rc0); + await checkSend(KW3, rawTx8, rc8); }); }); From f7ef0a85a363f441aeaef5b1642a9cbf19e33276 Mon Sep 17 00:00:00 2001 From: "ollie.j" Date: Fri, 1 Dec 2023 16:56:33 +0900 Subject: [PATCH 65/69] Attach RPC namespaces --- web3js-ext/src/web3.ts | 45 +++++++++++++++++++++++++++++++++++++ web3js-ext/test/rpc.spec.ts | 28 +++++++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/web3js-ext/src/web3.ts b/web3js-ext/src/web3.ts index 39be17782..c34fcd097 100644 --- a/web3js-ext/src/web3.ts +++ b/web3js-ext/src/web3.ts @@ -1,9 +1,13 @@ +import { AsyncNamespaceApi, rpcSendFunction, asyncOpenApi } from "@klaytn/js-ext-core"; +// @ts-ignore: package @klaytn/web3rpc has no .d.ts file. +import { AdminApi, DebugApi, GovernanceApi, KlayApi, NetApi, PersonalApi, TxpoolApi } from "@klaytn/web3rpc"; import { Web3 } from "web3"; import { Web3Context, Web3ContextInitOptions, isSupportedProvider } from "web3-core"; +import { ResponseError, ProviderError } from "web3-errors"; import { RegisteredSubscription } from "web3-eth"; import { EthExecutionAPI, @@ -29,6 +33,15 @@ export class KlaytnWeb3 public utils: typeof utils; public eth: KlaytnWeb3EthInterface; + // Additional RPC namespaces + public admin: AsyncNamespaceApi; + public debug: AsyncNamespaceApi; + public governance: AsyncNamespaceApi; + public klay: AsyncNamespaceApi; + public net: AsyncNamespaceApi; + public personal: AsyncNamespaceApi; + public txpool: AsyncNamespaceApi; + // The inner Web3 instance that provides the base implementation. // KlaytnWeb3 will delegate most of its methods to this instance. private _web3: Web3; @@ -62,6 +75,38 @@ export class KlaytnWeb3 // except below ones. this.eth.getProtocolVersion = context_getProtocolVersion(this._web3); this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3); + + // Attach additional RPC namespaces. + const send = this.makeSendFunction(); + this.admin = asyncOpenApi(send, AdminApi); + this.debug = asyncOpenApi(send, DebugApi); + this.governance = asyncOpenApi(send, GovernanceApi); + this.klay = asyncOpenApi(send, KlayApi); + this.net = asyncOpenApi(send, NetApi); + this.personal = asyncOpenApi(send, PersonalApi); + this.txpool = asyncOpenApi(send, TxpoolApi); + } + + private makeSendFunction(): rpcSendFunction { + if (!this.provider) { + return async (_method: string, _params: any[]): Promise => { + throw new ProviderError("no provider set"); + }; + } + + return async (method: string, params: any[]): Promise => { + const response = await this.provider?.request({ + jsonrpc: "2.0", + id: "1", + method: method, + params: params, + }); + if (response?.error) { + throw new ResponseError(response); + } else { + return response?.result; + } + }; } } diff --git a/web3js-ext/test/rpc.spec.ts b/web3js-ext/test/rpc.spec.ts index 286b4824b..359b65800 100644 --- a/web3js-ext/test/rpc.spec.ts +++ b/web3js-ext/test/rpc.spec.ts @@ -87,9 +87,11 @@ describe("web3.eth", () => { P.mock_override("eth_chainId", () => "0x3e9"); P.mock_override("net_version", () => "0x3e9"); + // To test getProtocolVersion P.mock_override("eth_protocolVersion", () => "0x1111"); P.mock_override("klay_protocolVersion", () => "0x2222"); + // To test sendSignedTransaction P.mock_override("eth_call", () => {}); P.mock_override("eth_blockNumber", () => "0x64"); P.mock_override("eth_getBlockByNumber", ([num]) => { @@ -97,7 +99,6 @@ describe("web3.eth", () => { b.number = Number(num); return b; // Return a dummy block with the requested number }); - function mockSendRawTransaction(params: any[]) { if (params[0] == rawTx0) { return rc0.transactionHash; } if (params[0] == rawTx8) { return rc8.transactionHash; } @@ -111,6 +112,18 @@ describe("web3.eth", () => { P.mock_override("eth_sendRawTransaction", mockSendRawTransaction); P.mock_override("eth_getTransactionReceipt", mockGetTransactionReceipt); P.mock_override("klay_sendRawTransaction", mockSendRawTransaction); + + // To test additional RPC namespaces + P.mock_override("admin_datadir", () => "/home/ubuntu/klaytn/data"); + P.mock_override("debug_isPProfRunning", () => false); + P.mock_override("governance_idxCache", () => [0]); + P.mock_override("klay_blockNumber", () => "0x64"); + P.mock_override("klay_getTransactionReceipt", mockGetTransactionReceipt); + P.mock_override("net_networkID", () => 1001); + P.mock_override("personal_listAccounts", () => ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"]); + P.mock_override("txpool_status", () => { + return { pending: 1, queued: 2 }; + }); }); it("getProtocolVersion()", async () => { @@ -119,7 +132,7 @@ describe("web3.eth", () => { assert.equal(await KW3.eth.getProtocolVersion(), "0x2222"); }); - it.only("sendSignedTransaction()", async () => { + it("sendSignedTransaction()", async () => { async function checkSend(W3: Web3, rawTx: string, receipt: Receipt) { let onSent: string = ""; let onTxHash: string = ""; @@ -141,4 +154,15 @@ describe("web3.eth", () => { await checkSend(KW3, rawTx0, rc0); await checkSend(KW3, rawTx8, rc8); }); + + it("additional RPC namespaces", async () => { + assert.deepEqual(await KW3.admin.datadir(), "/home/ubuntu/klaytn/data"); + assert.deepEqual(await KW3.debug.isPProfRunning(), false); + assert.deepEqual(await KW3.governance.idxCache(), [0]); + assert.deepEqual(await KW3.klay.blockNumber(), "0x64"); + assert.deepEqual(await KW3.klay.getTransactionReceipt(rc0.transactionHash), rc0); // example with nonzero params + assert.deepEqual(await KW3.net.networkID(), 1001); + assert.deepEqual(await KW3.personal.listAccounts(), ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"]); + assert.deepEqual(await KW3.txpool.status(), { pending: 1, queued: 2 }); + }); }); From f3ef8959d6433bf13da0fde90e59be0535b4bcad Mon Sep 17 00:00:00 2001 From: Yunjong Jeong Date: Sun, 3 Dec 2023 14:34:23 +0900 Subject: [PATCH 66/69] ethers: Update example/util --- ethers-ext/README.md | 10 +--- ethers-ext/example/README.md | 9 ++++ ethers-ext/example/unit/formatKlaytnUnits.js | 49 -------------------- ethers-ext/example/unit/parseKlaytnUnits.js | 44 ------------------ ethers-ext/example/util/util.js | 36 ++++++++++++++ js-ext-core/src/util/data.ts | 6 +++ js-ext-core/src/util/ec.ts | 25 +++++++--- js-ext-core/test/util.spec.ts | 19 +++++++- 8 files changed, 89 insertions(+), 109 deletions(-) create mode 100644 ethers-ext/example/README.md delete mode 100644 ethers-ext/example/unit/formatKlaytnUnits.js delete mode 100644 ethers-ext/example/unit/parseKlaytnUnits.js create mode 100644 ethers-ext/example/util/util.js diff --git a/ethers-ext/README.md b/ethers-ext/README.md index 1db5e566f..9f90c34e2 100644 --- a/ethers-ext/README.md +++ b/ethers-ext/README.md @@ -16,7 +16,8 @@ npm install --save @klaytn/ethers-ext ## Usage -See examples. +See [example](./example) and [test](./test). + ## Build @@ -26,13 +27,6 @@ See examples. npm install ``` -- (optional) Import @klaytn/web3rpc from local file. - Use this method to use the latest version of the web3rpc. - - ``` - npm link ../web3rpc/sdk/client/javascript/openapi - ``` - - Build the library ``` diff --git a/ethers-ext/example/README.md b/ethers-ext/example/README.md new file mode 100644 index 000000000..87f5c4c83 --- /dev/null +++ b/ethers-ext/example/README.md @@ -0,0 +1,9 @@ +# ethers-ext examples + +- [accountKey](./accountKey) Klaytn AccountKey types +- [accountStore](./accountStore) AccountStore usage +- [rpc](./rpc) Klaytn node RPC wrappers +- [smartContract](./smartContract) Smart contract usage +- [transactions](./transactions) Klaytn transaction types +- [util](./util) Utility functions + diff --git a/ethers-ext/example/unit/formatKlaytnUnits.js b/ethers-ext/example/unit/formatKlaytnUnits.js deleted file mode 100644 index 46b675a5d..000000000 --- a/ethers-ext/example/unit/formatKlaytnUnits.js +++ /dev/null @@ -1,49 +0,0 @@ -const { BigNumber } = require("@ethersproject/bignumber"); -const { formatKlaytnUnits, formatKlay } = require("@klaytn/ethers-ext"); - -// -// https://docs.klaytn.foundation/content/klaytn/design/klaytn-native-coin-klay -// https://docs.ethers.org/v5/api/utils/display-logic/#display-logic--units -// -async function main() { - const oneGpeb = BigNumber.from("1000000000"); - const oneKLAY = BigNumber.from("1000000000000000000"); - - console.log(formatKlaytnUnits(oneGpeb, 0)); - // '1000000000' - - console.log(formatKlaytnUnits(oneGpeb, "kpeb")); - // '1000000.0' - - console.log(formatKlaytnUnits(oneGpeb, "Mpeb")); - // '1000.0' - - console.log(formatKlaytnUnits(oneGpeb, "Gpeb")); - // '1.0' - - console.log(formatKlaytnUnits(oneGpeb, "ston")); - // '1.0' - - console.log(formatKlaytnUnits(oneGpeb, "STON")); - // '1.0' - - console.log(formatKlaytnUnits(oneGpeb, 9)); - // '1.0' - - console.log(formatKlaytnUnits(oneGpeb, "KLAY")); - // '0.000000001' - - console.log(formatKlaytnUnits(oneKLAY, "KLAY")); - // '1.0' - - console.log(formatKlaytnUnits(oneKLAY)); - // '1.0' - - console.log(formatKlaytnUnits(oneKLAY, 18)); - // '1.0' - - console.log(formatKlay(oneKLAY)); - // '1.0' -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/unit/parseKlaytnUnits.js b/ethers-ext/example/unit/parseKlaytnUnits.js deleted file mode 100644 index 822b8f985..000000000 --- a/ethers-ext/example/unit/parseKlaytnUnits.js +++ /dev/null @@ -1,44 +0,0 @@ -const { BigNumber } = require("@ethersproject/bignumber"); -const { parseKlaytnUnits, parseKlay } = require("@klaytn/ethers-ext"); - -// -// https://docs.klaytn.foundation/content/klaytn/design/klaytn-native-coin-klay -// https://docs.ethers.org/v5/api/utils/display-logic/#display-logic--units -// -async function main() { - let n = BigNumber.from(parseKlaytnUnits("1.0")); - console.log(n); - // { BigNumber: "1000000000000000000" } - console.log(n.toString()); - // "1000000000000000000" - - n = BigNumber.from(parseKlaytnUnits("1.0", "KLAY")); - console.log(n.toString()); - // "1000000000000000000" - - n = BigNumber.from(parseKlaytnUnits("1.0", 18)); - console.log(n.toString()); - // "1000000000000000000" - - n = BigNumber.from(parseKlaytnUnits("121.0", "StoN")); - console.log(n.toString()); - // "121000000000" - - n = BigNumber.from(parseKlaytnUnits("121.0", "Gpeb")); - console.log(n.toString()); - // "121000000000" - - n = BigNumber.from(parseKlaytnUnits("121.0", 9)); - console.log(n.toString()); - // "121000000000" - - n = BigNumber.from(parseKlay("3.0")); - console.log(n.toString()); - // "3000000000000000000" - - n = BigNumber.from(parseKlay("0.5")); - console.log(n.toString()); - // "500000000000000000" -} - -main(); \ No newline at end of file diff --git a/ethers-ext/example/util/util.js b/ethers-ext/example/util/util.js new file mode 100644 index 000000000..e576d5959 --- /dev/null +++ b/ethers-ext/example/util/util.js @@ -0,0 +1,36 @@ +const { + TxType, AccountKeyType, + getCompressedPublicKey, + getSignatureTuple, + formatKlayUnits, parseKlayUnits, + formatKlay, parseKlay, +} = require("@klaytn/ethers-ext"); + +async function main() { + // Transaction and AccountKey types + console.log("TxTypeValueTransfer =", TxType.ValueTransfer); + console.log("AccountKeyWeightedMultiSig =", AccountKeyType.WeightedMultiSig); + + // ECDSA public key + console.log("pubkey from { x, y } object =", getCompressedPublicKey({ + x: "0xdc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", + y: "0xaf06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79", + })); + console.log("pubkey from uncompressed format =", getCompressedPublicKey("0x04dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cdaf06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79")); + + // ECDSA signature + console.log("signature from { v, r, s } object =", getSignatureTuple({ + v: 27, + r: "0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b99", + s: "0x75c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c508", + })); + console.log("signature from compact 65 bytes =", getSignatureTuple("0x66809fb130a6ea4ae4e823baa92573a5f1bfb4e88e64048aecfb18a2b4012b9975c2c3e5f7b0a182c767137c488649cd5104a5e747371fd922d618e328e5c5081b")); + + // Currency units + console.log("example basefee in ston =", formatKlayUnits("0x5d21dba00", "ston")); + console.log("transfer amount in klay =", formatKlay("1230000000000000000")); + console.log("example gas price in peb =", parseKlayUnits("50", "ston").toString()); + console.log("transfer amount in peb =", parseKlay("9.87").toString()); +} + +main(); diff --git a/js-ext-core/src/util/data.ts b/js-ext-core/src/util/data.ts index ba7b8d4e9..5d56781f6 100644 --- a/js-ext-core/src/util/data.ts +++ b/js-ext-core/src/util/data.ts @@ -30,5 +30,11 @@ export const HexStr = { }, zeroPad(value: string, length: number): string { return bytes.hexZeroPad(value, length); + }, + withHexPrefix(value: string): string { + return value.replace(/^(0x)?/, "0x"); + }, + stripHexPrefix(value: string): string { + return value.replace(/^(0x)?/, ""); } }; diff --git a/js-ext-core/src/util/ec.ts b/js-ext-core/src/util/ec.ts index 578552362..4c3dcd88a 100644 --- a/js-ext-core/src/util/ec.ts +++ b/js-ext-core/src/util/ec.ts @@ -7,15 +7,26 @@ import { HexStr } from "./data"; const secp256k1 = new ec("secp256k1"); // Returns a 33-byte compressed public key from -// a compressed (33-byte) or uncompressed (65-byte) public key. +// a compressed (33-byte), uncompressed (65-byte) public key, +// or an object { x, y } (each 32-byte). export function getCompressedPublicKey(pub: any): string { - const hex = HexStr.from(pub); - if (HexStr.isHex(hex, 33) || HexStr.isHex(hex, 65)) { - const pub = secp256k1.keyFromPublic(hex.substring(2), "hex"); - return "0x" + pub.getPublic(true, "hex"); - } else { - throw new Error("Public key must be 33 or 65 bytes"); + if (_.isString(pub)) { // Hex string + const hex = HexStr.from(HexStr.withHexPrefix(pub)); + if (HexStr.isHex(hex, 33) || HexStr.isHex(hex, 65)) { + const serialized = HexStr.stripHexPrefix(hex); + const pubkey = secp256k1.keyFromPublic(serialized, "hex"); + return "0x" + pubkey.getPublic(true, "hex"); + } } + + if (_.isString(pub.x) && _.isString(pub.y)) { + pub.x = HexStr.stripHexPrefix(pub.x); + pub.y = HexStr.stripHexPrefix(pub.y); + const pubkey = secp256k1.keyFromPublic(pub); + return "0x" + pubkey.getPublic(true, "hex"); + } + + throw new Error("Public key must be a hex string of 33 or 65 bytes, or an { x, y } object"); } // List of signature tuples used in Klaytn transactions. diff --git a/js-ext-core/test/util.spec.ts b/js-ext-core/test/util.spec.ts index 994442ce0..ca85ac6c5 100644 --- a/js-ext-core/test/util.spec.ts +++ b/js-ext-core/test/util.spec.ts @@ -1,7 +1,6 @@ import { BigNumber } from "@ethersproject/bignumber"; import { formatUnits as formatEthUnits, parseUnits as parseEthUnits, formatEther, parseEther } from "@ethersproject/units"; import { assert } from "chai"; -import {split} from "lodash"; /* eslint-disable */ // @ts-ignore: package @klaytn/web3rpc has no .d.ts file. //import { ApiClient, KlayApi } from "@klaytn/web3rpc"; @@ -13,6 +12,7 @@ import { isFeeDelegationTxType, isKlaytnTxType, isPartialFeeDelegationTxType, + getCompressedPublicKey, getSignatureTuple, getRpcTxObject, formatKlayUnits, @@ -50,6 +50,23 @@ describe("util", () => { assert.isTrue(isPartialFeeDelegationTxType(ty)); }); + it.only("getCompressedPublicKey", () => { + const testcases = [ + { x: "dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", y: "af06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79" }, + { x: "0xdc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", y: "0xaf06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79" }, + "03dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", + "0x03dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd", + "04dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cdaf06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79", + "0x04dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cdaf06ca34ae8714cf3dae06bacdb78c7c2d4054bd38961d40853cd5f15955da79", + ]; + const compressed = "0x03dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd"; + + for (const tc of testcases) { + const pub = getCompressedPublicKey(tc); + assert.equal(pub, compressed); + } + }); + it("getSignatureTuple", () => { const vNum = 27; const vHex = "0x1b"; From f48519ca1a8fb05a3eb8d20e94be9176377ac977 Mon Sep 17 00:00:00 2001 From: Yunjong Jeong Date: Sun, 3 Dec 2023 19:47:20 +0900 Subject: [PATCH 67/69] web3js: Export more symbols from js-ext-core --- web3js-ext/src/index.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web3js-ext/src/index.ts b/web3js-ext/src/index.ts index 8c7a8fd06..36a51f1dd 100644 --- a/web3js-ext/src/index.ts +++ b/web3js-ext/src/index.ts @@ -1,5 +1,12 @@ export * from "@klaytn/js-ext-core/util"; +export { + AccountKey, + AccountKeyFactory, + KlaytnTx, + KlaytnTxFactory, + parseTransaction, +} from "@klaytn/js-ext-core"; export * from "./web3"; export * from "./klaytn_tx"; -export { fromPeb, toPeb } from "./utils"; // TODO: remove when js-ext-core toPeb is fixed \ No newline at end of file +export { fromPeb, toPeb } from "./utils"; // TODO: remove when js-ext-core toPeb is fixed From 81a1de9093065b27048497d3b4a63eb778f7a31a Mon Sep 17 00:00:00 2001 From: Yunjong Jeong Date: Sun, 3 Dec 2023 19:42:12 +0900 Subject: [PATCH 68/69] ethers: Export AccountKey and KlaytnTx --- ethers-ext/src/index.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ethers-ext/src/index.ts b/ethers-ext/src/index.ts index d3d2a1920..e0912204c 100644 --- a/ethers-ext/src/index.ts +++ b/ethers-ext/src/index.ts @@ -1,6 +1,13 @@ export * from "@klaytn/js-ext-core/util"; +export { + AccountKey, + AccountKeyFactory, + KlaytnTx, + KlaytnTxFactory, + parseTransaction, +} from "@klaytn/js-ext-core"; export * from "./accountStore"; export * from "./keystore"; export * from "./provider"; -export * from "./signer"; \ No newline at end of file +export * from "./signer"; From a346e690e112cc85de77af0308b8066de954f455 Mon Sep 17 00:00:00 2001 From: kjeom Date: Mon, 4 Dec 2023 19:01:33 +0900 Subject: [PATCH 69/69] version up to 0.9.8-beta --- ethers-ext/package.json | 2 +- js-ext-core/package.json | 2 +- web3j-ext/web3j-ext/build.gradle | 4 ++-- web3js-ext/package.json | 5 ++--- web3py-ext/setup.py | 2 +- web3rpc/rpc-specs/package.json | 2 +- web3rpc/sdk/client/java/java-config.yaml | 2 +- web3rpc/sdk/client/javascript/javascript-config.yaml | 2 +- 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ethers-ext/package.json b/ethers-ext/package.json index 96478cd0f..ac755a3b4 100644 --- a/ethers-ext/package.json +++ b/ethers-ext/package.json @@ -1,6 +1,6 @@ { "name": "@klaytn/ethers-ext", - "version": "0.9.7-beta", + "version": "0.9.8-beta", "main": "dist/index.js", "types": "dist/index.d.ts", "files": [ diff --git a/js-ext-core/package.json b/js-ext-core/package.json index 2b9072090..671ff9cd9 100644 --- a/js-ext-core/package.json +++ b/js-ext-core/package.json @@ -1,6 +1,6 @@ { "name": "@klaytn/js-ext-core", - "version": "0.9.7-beta", + "version": "0.9.8-beta", "license": "MIT", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/web3j-ext/web3j-ext/build.gradle b/web3j-ext/web3j-ext/build.gradle index 705c059b1..14cc28037 100644 --- a/web3j-ext/web3j-ext/build.gradle +++ b/web3j-ext/web3j-ext/build.gradle @@ -7,7 +7,7 @@ plugins { } group 'foundation.klaytn' -version 'v0.9.7' +version 'v0.9.8' repositories { mavenCentral() @@ -15,7 +15,7 @@ repositories { } dependencies { - implementation "foundation.klaytn:web3rpc-java:v0.9.6" + implementation "foundation.klaytn:web3rpc-java:v0.9.7" implementation "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0" implementation "org.web3j:core:4.9.8" implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.14.2' diff --git a/web3js-ext/package.json b/web3js-ext/package.json index ec35df809..602fd0c69 100644 --- a/web3js-ext/package.json +++ b/web3js-ext/package.json @@ -1,6 +1,6 @@ { "name": "@klaytn/web3js-ext", - "version": "0.9.3-beta", + "version": "0.9.8-beta", "main": "dist/src/index.js", "files": [ "./dist", @@ -34,9 +34,8 @@ "typescript": "^5.0.4" }, "dependencies": { - "@klaytn/ethers-ext": "^0.9.3-beta", "@klaytn/js-ext-core": "^0.9.7-beta", - "@klaytn/web3rpc": "^0.9.0", + "@klaytn/web3rpc": "^0.9.7", "ethereum-cryptography": "^2.1.2", "lodash": "^4.17.21" } diff --git a/web3py-ext/setup.py b/web3py-ext/setup.py index f6c2736f5..be2c9081b 100644 --- a/web3py-ext/setup.py +++ b/web3py-ext/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages NAME = "web3py_ext" -VERSION = "0.9.7-beta" +VERSION = "0.9.8-beta" # To install the library, run the following # # python setup.py install diff --git a/web3rpc/rpc-specs/package.json b/web3rpc/rpc-specs/package.json index b1319e38e..6fb000922 100644 --- a/web3rpc/rpc-specs/package.json +++ b/web3rpc/rpc-specs/package.json @@ -1,6 +1,6 @@ { "name": "redocly", - "version": "0.9.7", + "version": "0.9.8", "main": "index.js", "license": "MIT", "dependencies": { diff --git a/web3rpc/sdk/client/java/java-config.yaml b/web3rpc/sdk/client/java/java-config.yaml index 98170b62e..61e2b173e 100644 --- a/web3rpc/sdk/client/java/java-config.yaml +++ b/web3rpc/sdk/client/java/java-config.yaml @@ -3,7 +3,7 @@ outputDir: ./openapi/ inputSpec: ../../../rpc-specs/namespaces/all-except-eth.yaml groupId: foundation.klaytn artifactId: web3rpc-java -artifactVersion: v0.9.7 +artifactVersion: v0.9.8 library: retrofit2 templateDir: ./template globalProperties: diff --git a/web3rpc/sdk/client/javascript/javascript-config.yaml b/web3rpc/sdk/client/javascript/javascript-config.yaml index a9f8b6f7a..b25e9ab10 100644 --- a/web3rpc/sdk/client/javascript/javascript-config.yaml +++ b/web3rpc/sdk/client/javascript/javascript-config.yaml @@ -2,7 +2,7 @@ generatorName: web3rpc-javascript outputDir: ./openapi inputSpec: ../../../rpc-specs/namespaces/all-except-eth.yaml projectName: "@klaytn/web3rpc" -projectVersion: "0.9.7" +projectVersion: "0.9.8" templateDir: ./template sortParamsByRequiredFlag: false globalProperties: