@kaiachain/web3js-ext
Version:
web3.js extension for kaiachain blockchain
90 lines (89 loc) • 3.92 kB
JavaScript
import { asyncOpenApi } from "@kaiachain/js-ext-core";
// @ts-ignore: package @kaiachain/web3rpc has no .d.ts file.
import * as web3rpc from "@kaiachain/web3rpc";
import { Web3 } from "web3";
import { Web3Context, isSupportedProvider } from "web3-core";
import { ResponseError, ProviderError } from "web3-errors";
import { context_accounts } from "./accounts/index.js";
import { context_getProtocolVersion, context_sendSignedTransaction, context_sendTransaction, context_signTransaction, } from "./eth/index.js";
// Follow the Web3 class from the web3/src/web3.ts
// with slight difference in the web3.eth property.
export class KlaytnWeb3 extends Web3Context {
constructor(providerOrContext) {
// 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;
// Override web3.eth.accounts methods
const accounts = context_accounts(this);
this.eth = {
...this._web3.eth,
accounts: accounts
};
this._accountProvider = accounts; // inevitable conflict in signTransaction types
this._wallet = accounts.wallet;
// Override web3.eth RPC method wrappers. See web3-eth/src/web3_eth.ts:Web3Eth
// Note that other web3.eth methods should just calling eth_ RPCs to Klaytn node.
this.eth.getProtocolVersion = context_getProtocolVersion(this._web3);
this.eth.sendTransaction = context_sendTransaction(this._web3);
this.eth.sendSignedTransaction = context_sendSignedTransaction(this._web3);
this.eth.signTransaction = context_signTransaction(this._web3);
// Attach additional RPC namespaces.
const send = this.makeSendFunction();
const { AdminApi, DebugApi, GovernanceApi, KlayApi, NetApi, PersonalApi, TxpoolApi } = web3rpc;
this.admin = asyncOpenApi(send, AdminApi);
this.debug = asyncOpenApi(send, DebugApi);
this.governance = asyncOpenApi(send, GovernanceApi);
this.klay = asyncOpenApi(send, KlayApi);
this.kaia = asyncOpenApi(send, KlayApi);
this.net = asyncOpenApi(send, NetApi);
this.personal = asyncOpenApi(send, PersonalApi);
this.txpool = asyncOpenApi(send, TxpoolApi);
}
makeSendFunction() {
if (!this.provider) {
return async (_method, _params) => {
throw new ProviderError("no provider set");
};
}
return async (method, params) => {
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;
}
};
}
}
// Static properties analogous to Web3 class
KlaytnWeb3.version = Web3.version;
KlaytnWeb3.utils = Web3.utils;
KlaytnWeb3.modules = Web3.modules;
// Parse providerOrContext into Web3ContextInitOptions.
// See web3/src/web3.ts:Web3
function getContextInitOptions(providerOrContext) {
// 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 = {};
if (typeof providerOrContext === "string" ||
isSupportedProvider(providerOrContext)) {
contextInitOptions.provider = providerOrContext;
}
else if (providerOrContext) {
contextInitOptions = providerOrContext;
}
else {
contextInitOptions = {};
}
return contextInitOptions;
}