@vechain/web3-providers-connex
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -7,2 +7,1 @@ import { ZeroBytes8, ZeroBytes20, ZeroBytes32, ZeroBytes256 } from "./types"; | ||
export declare const EthJsonRpcMethods: string[]; | ||
//# sourceMappingURL=common.d.ts.map |
@@ -56,4 +56,6 @@ 'use strict'; | ||
'eth_unsubscribe', | ||
'debug_traceTransaction', | ||
'debug_traceCall', | ||
'evm_mine' | ||
]; | ||
//# sourceMappingURL=common.js.map |
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
import { Provider } from "./provider"; | ||
@@ -13,2 +20,1 @@ import { Net, Wallet, DelegateOpt, JsonRpcPayload } from './types'; | ||
} | ||
//# sourceMappingURL=compatProvider.d.ts.map |
@@ -23,2 +23,1 @@ export interface RequestArguments { | ||
} | ||
//# sourceMappingURL=eip1193.d.ts.map |
@@ -5,2 +5,4 @@ "use strict"; | ||
class ProviderRpcError extends Error { | ||
code; | ||
data; | ||
constructor(code, message, data) { | ||
@@ -7,0 +9,0 @@ super(message); |
export declare const ErrMsg: { | ||
MethodParamNotSupported: (method: string, index: number) => string; | ||
ArgumentMissingOrInvalid: (method: string, arg?: string | undefined) => string; | ||
ArgumentMissingOrInvalid: (method: string, arg?: string) => string; | ||
SubscriptionIdNotFound: (id: string) => string; | ||
@@ -15,2 +15,1 @@ InvalidSubscriptionName: (name: string) => string; | ||
}; | ||
//# sourceMappingURL=error.d.ts.map |
@@ -1,5 +0,3 @@ | ||
import { JsonRpcProvider } from '@ethersproject/providers'; | ||
import { ContractFactory } from 'ethers'; | ||
export declare const modifyProvider: (provider: JsonRpcProvider) => JsonRpcProvider; | ||
export declare const modifyFactory: (factory: ContractFactory) => ContractFactory; | ||
//# sourceMappingURL=ethers.d.ts.map | ||
import { BaseContract, ContractFactory, BrowserProvider } from "ethers"; | ||
export declare const modifyFactory: (factory: ContractFactory<Array<any>, BaseContract>) => ContractFactory<any[], BaseContract>; | ||
export declare const modifyProvider: (provider: BrowserProvider) => BrowserProvider; |
'use strict'; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.modifyFactory = exports.modifyProvider = void 0; | ||
const providers_1 = require("@ethersproject/providers"); | ||
const web_1 = require("@ethersproject/web"); | ||
exports.modifyProvider = exports.modifyFactory = void 0; | ||
const ethers_1 = require("ethers"); | ||
const utils_1 = require("ethers/lib/utils"); | ||
const logger_1 = require("@ethersproject/logger"); | ||
const logger = new logger_1.Logger('web3-providers-connex/ethers'); | ||
const modifyProvider = (provider) => { | ||
provider.getTransaction = (transactionHash) => __awaiter(void 0, void 0, void 0, function* () { | ||
yield provider.getNetwork(); | ||
transactionHash = yield transactionHash; | ||
const params = { transactionHash: provider.formatter.hash(transactionHash, true) }; | ||
return (0, web_1.poll)(() => __awaiter(void 0, void 0, void 0, function* () { | ||
// const result = await provider.perform("getTransaction", params); | ||
const result = yield provider.send('eth_getTransactionByHash', [transactionHash]); | ||
if (result == null) { | ||
if (provider._emitted["t:" + transactionHash] == null) { | ||
return null; | ||
} | ||
return undefined; | ||
const format_1 = require("../node_modules/ethers/lib.commonjs/providers/format"); | ||
const modifyFactory = (factory) => { | ||
factory.deploy = async function (...args) { | ||
const tx = await this.getDeployTransaction(...args); | ||
(0, ethers_1.assert)(this.runner && typeof (this.runner.sendTransaction) === "function", "factory runner does not support sending transactions", "UNSUPPORTED_OPERATION", { | ||
operation: "sendTransaction" | ||
}); | ||
const sentTx = await this.runner.sendTransaction(tx); | ||
// Patch the original code (Line 112 in contract/factory.ts): | ||
// | ||
// const address = getCreateAddress(sentTx); | ||
// | ||
let address = null; | ||
let count = 0; // try 5 times | ||
while (count < 5) { | ||
if (!this.runner.provider) { | ||
throw new Error("no provider"); | ||
} | ||
// const tx = provider.formatter.transactionResponse(result); | ||
if (result.to == null && result.creates == null) { | ||
// transaction.creates = this.contractAddress(transaction); | ||
const receipt = yield provider.send('eth_getTransactionReceipt', [transactionHash]); | ||
result.creates = receipt.contractAddress; | ||
const receipt = await this.runner.provider.getTransactionReceipt(sentTx.hash); | ||
if (receipt) { | ||
address = receipt.contractAddress; | ||
break; | ||
} | ||
const tx = transactionResponse(provider, result); | ||
if (tx.blockNumber == null) { | ||
tx.confirmations = 0; | ||
} | ||
else if (tx.confirmations == null) { | ||
const blockNumber = yield provider._getInternalBlockNumber(100 + 2 * provider.pollingInterval); | ||
// Add the confirmations using the fast block number (pessimistic) | ||
let confirmations = (blockNumber - tx.blockNumber) + 1; | ||
if (confirmations <= 0) { | ||
confirmations = 1; | ||
} | ||
tx.confirmations = confirmations; | ||
} | ||
return provider._wrapTransaction(tx); | ||
}), { oncePoll: this }); | ||
}); | ||
const transactionResponse = (provider, transaction) => { | ||
// Rename gas to gasLimit | ||
if (transaction.gas != null && transaction.gasLimit == null) { | ||
transaction.gasLimit = transaction.gas; | ||
count++; | ||
} | ||
// Some clients (TestRPC) do strange things like return 0x0 for the | ||
// 0 address; correct this to be a real address | ||
if (transaction.to && ethers_1.BigNumber.from(transaction.to).isZero()) { | ||
transaction.to = "0x0000000000000000000000000000000000000000"; | ||
} | ||
// Rename input to data | ||
if (transaction.input != null && transaction.data == null) { | ||
transaction.data = transaction.input; | ||
} | ||
// // If to and creates are empty, populate the creates from the transaction | ||
// if (transaction.to == null && transaction.creates == null) { | ||
// transaction.creates = this.contractAddress(transaction); | ||
// } | ||
if ((transaction.type === 1 || transaction.type === 2) && transaction.accessList == null) { | ||
transaction.accessList = []; | ||
} | ||
const result = providers_1.Formatter.check(provider.formatter.formats.transaction, transaction); | ||
if (transaction.chainId != null) { | ||
let chainId = transaction.chainId; | ||
if ((0, utils_1.isHexString)(chainId)) { | ||
chainId = ethers_1.BigNumber.from(chainId).toNumber(); | ||
} | ||
result.chainId = chainId; | ||
} | ||
else { | ||
let chainId = transaction.networkId; | ||
// geth-etc returns chainId | ||
if (chainId == null && result.v == null) { | ||
chainId = transaction.chainId; | ||
} | ||
if ((0, utils_1.isHexString)(chainId)) { | ||
chainId = ethers_1.BigNumber.from(chainId).toNumber(); | ||
} | ||
if (typeof (chainId) !== "number" && result.v != null) { | ||
chainId = (result.v - 35) / 2; | ||
if (chainId < 0) { | ||
chainId = 0; | ||
} | ||
chainId = parseInt(chainId); | ||
} | ||
if (typeof (chainId) !== "number") { | ||
chainId = 0; | ||
} | ||
result.chainId = chainId; | ||
} | ||
// // 0x0000... should actually be null | ||
// if (result.blockHash && result.blockHash.replace(/0/g, "") === "x") { | ||
// result.blockHash = null; | ||
// } | ||
return result; | ||
// End of the patch | ||
return new ethers_1.BaseContract(address, this.interface, this.runner, sentTx); | ||
}; | ||
return factory; | ||
}; | ||
exports.modifyFactory = modifyFactory; | ||
const modifyProvider = (provider) => { | ||
provider._wrapTransactionResponse = function (tx, network) { | ||
return new ethers_1.TransactionResponse(formatTransactionResponse(tx), this); | ||
}; | ||
return provider; | ||
}; | ||
exports.modifyProvider = modifyProvider; | ||
const modifyFactory = (factory) => { | ||
factory.deploy = (...args) => __awaiter(void 0, void 0, void 0, function* () { | ||
let overrides = {}; | ||
// If 1 extra parameter was passed in, it contains overrides | ||
if (args.length === factory.interface.deploy.inputs.length + 1) { | ||
overrides = args.pop(); | ||
} | ||
// Make sure the call matches the constructor signature | ||
logger.checkArgumentCount(args.length, factory.interface.deploy.inputs.length, " in Contract constructor"); | ||
// Resolve ENS names and promises in the arguments | ||
const params = yield resolveAddresses(factory.signer, args, factory.interface.deploy.inputs); | ||
params.push(overrides); | ||
// Get the deployment transaction (with optional overrides) | ||
const unsignedTx = factory.getDeployTransaction(...params); | ||
// Send the deployment transaction | ||
const tx = yield factory.signer.sendTransaction(unsignedTx); | ||
// const address = getStatic<(tx: TransactionResponse) => string>(this.constructor, "getContractAddress")(tx); | ||
const address = tx.creates; | ||
const contract = (0, utils_1.getStatic)(factory.constructor, "getContract")(address, factory.interface, factory.signer); | ||
// Add the modified wait that wraps events | ||
addContractWait(contract, tx); | ||
(0, utils_1.defineReadOnly)(contract, "deployTransaction", tx); | ||
return contract; | ||
}); | ||
const resolveAddresses = (resolver, value, paramType) => __awaiter(void 0, void 0, void 0, function* () { | ||
if (Array.isArray(paramType)) { | ||
return yield Promise.all(paramType.map((paramType, index) => { | ||
return resolveAddresses(resolver, ((Array.isArray(value)) ? value[index] : value[paramType.name]), paramType); | ||
})); | ||
} | ||
if (paramType.type === "address") { | ||
return yield resolveName(resolver, value); | ||
} | ||
if (paramType.type === "tuple") { | ||
return yield resolveAddresses(resolver, value, paramType.components); | ||
} | ||
if (paramType.baseType === "array") { | ||
if (!Array.isArray(value)) { | ||
return Promise.reject(logger.makeError("invalid value for array", logger_1.Logger.errors.INVALID_ARGUMENT, { | ||
argument: "value", | ||
value | ||
})); | ||
function formatTransactionResponse(value) { | ||
const BN_0 = BigInt(0); | ||
// Some clients (TestRPC) do strange things like return 0x0 for the | ||
// 0 address; correct this to be a real address | ||
if (value.to && (0, ethers_1.getBigInt)(value.to) === BN_0) { | ||
value.to = "0x0000000000000000000000000000000000000000"; | ||
} | ||
const result = (0, format_1.object)({ | ||
hash: format_1.formatHash, | ||
type: (value) => { | ||
if (value === "0x" || value == null) { | ||
return 0; | ||
} | ||
return yield Promise.all(value.map((v) => resolveAddresses(resolver, v, paramType.arrayChildren))); | ||
} | ||
return value; | ||
}); | ||
const resolveName = (resolver, nameOrPromise) => __awaiter(void 0, void 0, void 0, function* () { | ||
const name = yield nameOrPromise; | ||
if (typeof (name) !== "string") { | ||
logger.throwArgumentError("invalid address or ENS name", "name", name); | ||
} | ||
// If it is already an address, just use it (after adding checksum) | ||
try { | ||
return (0, utils_1.getAddress)(name); | ||
} | ||
catch (error) { } | ||
if (!resolver) { | ||
logger.throwError("a provider or signer is needed to resolve ENS names", logger_1.Logger.errors.UNSUPPORTED_OPERATION, { | ||
operation: "resolveName" | ||
}); | ||
} | ||
const address = yield resolver.resolveName(name); | ||
if (address == null) { | ||
logger.throwArgumentError("resolver or addr is not configured for ENS name", "name", name); | ||
} | ||
return address; | ||
}); | ||
const addContractWait = (contract, tx) => { | ||
const wait = tx.wait.bind(tx); | ||
tx.wait = (confirmations) => { | ||
return wait(confirmations).then((receipt) => { | ||
receipt.events = receipt.logs.map((log) => { | ||
let event = (0, utils_1.deepCopy)(log); | ||
let parsed = null; | ||
try { | ||
parsed = contract.interface.parseLog(log); | ||
} | ||
catch (e) { } | ||
// Successfully parsed the event log; include it | ||
if (parsed) { | ||
event.args = parsed.args; | ||
event.decode = (data, topics) => { | ||
if (!!parsed) { | ||
return contract.interface.decodeEventLog(parsed.eventFragment, data, topics); | ||
} | ||
}; | ||
event.event = parsed.name; | ||
event.eventSignature = parsed.signature; | ||
} | ||
// Useful operations | ||
event.removeListener = () => { return contract.provider; }; | ||
event.getBlock = () => { | ||
return contract.provider.getBlock(receipt.blockHash); | ||
}; | ||
event.getTransaction = () => { | ||
return contract.provider.getTransaction(receipt.transactionHash); | ||
}; | ||
event.getTransactionReceipt = () => { | ||
return Promise.resolve(receipt); | ||
}; | ||
return event; | ||
}); | ||
return receipt; | ||
}); | ||
}; | ||
}; | ||
return factory; | ||
}; | ||
exports.modifyFactory = modifyFactory; | ||
return (0, ethers_1.getNumber)(value); | ||
}, | ||
accessList: (0, format_1.allowNull)(ethers_1.accessListify, null), | ||
blockHash: (0, format_1.allowNull)(format_1.formatHash, null), | ||
blockNumber: (0, format_1.allowNull)(ethers_1.getNumber, null), | ||
transactionIndex: (0, format_1.allowNull)(ethers_1.getNumber, null), | ||
//confirmations: allowNull(getNumber, null), | ||
from: ethers_1.getAddress, | ||
// either (gasPrice) or (maxPriorityFeePerGas + maxFeePerGas) must be set | ||
gasPrice: (0, format_1.allowNull)(ethers_1.getBigInt), | ||
maxPriorityFeePerGas: (0, format_1.allowNull)(ethers_1.getBigInt), | ||
maxFeePerGas: (0, format_1.allowNull)(ethers_1.getBigInt), | ||
gasLimit: ethers_1.getBigInt, | ||
to: (0, format_1.allowNull)(ethers_1.getAddress, null), | ||
value: ethers_1.getBigInt, | ||
nonce: ethers_1.getNumber, | ||
data: format_1.formatData, | ||
creates: (0, format_1.allowNull)(ethers_1.getAddress, null), | ||
chainId: (0, format_1.allowNull)(ethers_1.getBigInt, null) | ||
}, { | ||
data: ["input"], | ||
gasLimit: ["gas"] | ||
})(value); | ||
// Remove the original code (Line 227-229 in providers/format.ts) due to | ||
// the incompactibility of fn getCreateAddress: | ||
// | ||
// // If to and creates are empty, populate the creates from the value | ||
// if (result.to == null && result.creates == null) { | ||
// result.creates = getCreateAddress(result) | ||
// } | ||
// @TODO: Check fee data | ||
// Add an access list to supported transaction types | ||
if ((value.type === 1 || value.type === 2) && value.accessList == null) { | ||
result.accessList = []; | ||
} | ||
// Remove the original code (Line 239-243 in providers/format.ts) | ||
// | ||
// // Compute the signature | ||
// if (value.signature) { | ||
// result.signature = Signature.from(value.signature); | ||
// } else { | ||
// result.signature = Signature.from(value); | ||
// } | ||
// Remove the original code (Line 246-249 in providers/format.ts): | ||
// | ||
// // Some backends omit ChainId on legacy transactions, but we can compute it | ||
// if (result.chainId == null) { | ||
// const chainId = result.signature.legacyChainId; | ||
// if (chainId != null) { result.chainId = chainId; } | ||
// } | ||
// 0x0000... should actually be null | ||
if (result.blockHash && (0, ethers_1.getBigInt)(result.blockHash) === BN_0) { | ||
result.blockHash = null; | ||
} | ||
return result; | ||
} | ||
//# sourceMappingURL=ethers.js.map |
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
import { RetLog, RetReceipt, RetBlock, RetTransaction, RetHeader } from './types'; | ||
@@ -8,3 +15,3 @@ export declare class Formatter { | ||
constructor(connex: Connex, ifSetNet: boolean); | ||
formatInput: (method: string, params?: any[] | undefined) => any[]; | ||
formatInput: (method: string, params?: any[]) => any[]; | ||
private _getBlockByNumber; | ||
@@ -19,2 +26,3 @@ private _getBlockByHash; | ||
private _getLogs; | ||
private _traceCall; | ||
private _subscribe; | ||
@@ -39,2 +47,1 @@ private _sendRawTransaction; | ||
} | ||
//# sourceMappingURL=formatter.d.ts.map |
@@ -9,305 +9,338 @@ 'use strict'; | ||
class Formatter { | ||
_connex; | ||
_inputFormatters = {}; | ||
_ifSetNet; | ||
constructor(connex, ifSetNet) { | ||
this._inputFormatters = {}; | ||
this.formatInput = (method, params) => { | ||
const inputFormatter = this._inputFormatters[method]; | ||
if (!inputFormatter) { | ||
return params || []; | ||
this._connex = connex; | ||
this._ifSetNet = ifSetNet; | ||
this._inputFormatters['eth_getBlockByNumber'] = this._getBlockByNumber; | ||
this._inputFormatters['eth_getBlockByHash'] = this._getBlockByHash; | ||
this._inputFormatters['eth_getBalance'] = this._getBalance; | ||
this._inputFormatters['eth_getCode'] = this._getCode; | ||
this._inputFormatters['eth_getStorageAt'] = this._getStorageAt; | ||
this._inputFormatters['eth_sendTransaction'] = this._sendTransaction; | ||
this._inputFormatters['eth_call'] = this._call; | ||
this._inputFormatters['eth_estimateGas'] = this._estimateGas; | ||
this._inputFormatters['eth_getLogs'] = this._getLogs; | ||
this._inputFormatters['eth_subscribe'] = this._subscribe; | ||
this._inputFormatters['eth_sendRawTransaction'] = this._sendRawTransaction; | ||
this._inputFormatters['debug_traceCall'] = this._traceCall; | ||
} | ||
formatInput = (method, params) => { | ||
const inputFormatter = this._inputFormatters[method]; | ||
if (!inputFormatter) { | ||
return params ? params : []; | ||
} | ||
if (!params) { | ||
const msg = 'Parameters missing'; | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return inputFormatter(params); | ||
}; | ||
_getBlockByNumber = (params) => { | ||
const num = (0, utils_1.parseBlockNumber)(params[0]); | ||
if (num === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getBlockByNumber', 'blockNumber'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [num]; | ||
}; | ||
_getBlockByHash = (params) => { | ||
const num = params[0]; | ||
if (num !== (0, utils_1.parseBlockNumber)(num)) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getBlockByNumber', 'blockHash'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [num]; | ||
}; | ||
_getBalance = (params) => { | ||
let [addr, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length == 2 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_getBalance', 2); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
if (!params) { | ||
const msg = 'Parameters missing'; | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getBalance', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return inputFormatter(params); | ||
}; | ||
this._getBlockByNumber = (params) => { | ||
const num = (0, utils_1.parseBlockNumber)(params[0]); | ||
if (num === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getBlockByNumber', 'blockNumber'); | ||
} | ||
return revision ? [addr, revision] : [addr]; | ||
}; | ||
_getCode = (params) => { | ||
let [addr, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length >= 2 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_getCode', 2); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [num]; | ||
}; | ||
this._getBlockByHash = (params) => { | ||
const num = params[0]; | ||
if (num !== (0, utils_1.parseBlockNumber)(num)) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getBlockByNumber', 'blockHash'); | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getCode', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [num]; | ||
}; | ||
this._getBalance = (params) => { | ||
let [addr, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length == 2 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_getBalance', 2); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
} | ||
return revision ? [addr, revision] : [addr]; | ||
}; | ||
_getStorageAt = (params) => { | ||
let [addr, key, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length >= 3 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_getStorageAt', 3); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getBalance', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getStorageAt', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return revision ? [addr, revision] : [addr]; | ||
} | ||
key = (0, utils_1.toBytes32)(key); | ||
return revision ? [addr, key, revision] : [addr, key]; | ||
}; | ||
_sendTransaction = (params) => { | ||
const o1 = params[0]; | ||
let data = '0x'; | ||
if (o1.data) { | ||
data = o1.data; | ||
} | ||
if (o1.input) { | ||
data = o1.input; | ||
} | ||
const o2 = { | ||
clauses: [{ | ||
to: o1.to || null, | ||
value: o1.value ? (0, utils_1.toHex)(o1.value) : '0x0', | ||
data: data, | ||
}], | ||
gas: o1.gas ? (0, utils_1.hexToNumber)(o1.gas) : undefined, | ||
gasPrice: o1.gasPrice, | ||
caller: o1.from, | ||
}; | ||
this._getCode = (params) => { | ||
let [addr, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length >= 2 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_getCode', 2); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [o2, params[1]]; | ||
}; | ||
_call = (params) => { | ||
let [callObj, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length >= 2 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_call', 2); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getCode', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_call', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return revision ? [addr, revision] : [addr]; | ||
}; | ||
this._getStorageAt = (params) => { | ||
let [addr, key, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length >= 3 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_getStorageAt', 3); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
} | ||
callObj = this._sendTransaction([callObj])[0]; | ||
return revision ? [callObj, revision] : [callObj]; | ||
}; | ||
_estimateGas = (params) => { | ||
return this._sendTransaction(params); | ||
}; | ||
_getLogs = (params) => { | ||
const args = params[0]; | ||
let fromBlock, toBlock; | ||
if (!args.fromBlock) { | ||
fromBlock = this._connex.thor.status.head.number; // fromBlock default set to latest | ||
} | ||
else { | ||
let test = (0, utils_1.parseBlockNumber)(args.fromBlock); | ||
if (test === undefined) { | ||
test = this._connex.thor.status.head.number; | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getStorageAt', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
else if (typeof test !== 'number') { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getLogs', 'options.fromBlock'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
key = (0, utils_1.toBytes32)(key); | ||
return revision ? [addr, key, revision] : [addr, key]; | ||
}; | ||
this._sendTransaction = (params) => { | ||
const o1 = params[0]; | ||
const o2 = { | ||
clauses: [{ | ||
to: o1.to || null, | ||
value: !!o1.value ? (0, utils_1.toHex)(o1.value) : '0x0', | ||
data: o1.data || '0x', | ||
}], | ||
gas: !!o1.gas ? (0, utils_1.hexToNumber)(o1.gas) : undefined, | ||
caller: o1.from, | ||
}; | ||
return [o2, params[1]]; | ||
}; | ||
this._call = (params) => { | ||
let [callObj, revision = 'latest'] = params; | ||
if (!this._ifSetNet) { | ||
if (params.length >= 2 && | ||
!(typeof revision === 'string' && revision === 'latest')) { | ||
const msg = error_1.ErrMsg.MethodParamNotSupported('eth_call', 2); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
fromBlock = test; | ||
} | ||
if (!args.toBlock) { | ||
toBlock = this._connex.thor.status.head.number; // toBlock default set to latest | ||
} | ||
else { | ||
let test = (0, utils_1.parseBlockNumber)(args.toBlock); | ||
if (test === undefined) { | ||
test = this._connex.thor.status.head.number; | ||
} | ||
else if (typeof revision !== 'number') { | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_call', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
else if (typeof test !== 'number') { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getLogs', 'options.toBlock'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
callObj = this._sendTransaction([callObj])[0]; | ||
return revision ? [callObj, revision] : [callObj]; | ||
}; | ||
this._estimateGas = (params) => { | ||
return this._sendTransaction(params); | ||
}; | ||
this._getLogs = (params) => { | ||
const args = params[0]; | ||
let fromBlock, toBlock; | ||
if (!args.fromBlock) { | ||
fromBlock = this._connex.thor.status.head.number; // fromBlock default set to latest | ||
toBlock = test; | ||
if (fromBlock > toBlock) { | ||
fromBlock = toBlock; | ||
} | ||
else { | ||
let test = (0, utils_1.parseBlockNumber)(args.fromBlock); | ||
if (test === undefined) { | ||
test = this._connex.thor.status.head.number; | ||
} | ||
else if (typeof test !== 'number') { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getLogs', 'options.fromBlock'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
fromBlock = test; | ||
} | ||
if (!args.toBlock) { | ||
toBlock = this._connex.thor.status.head.number; // toBlock default set to latest | ||
} | ||
else { | ||
let test = (0, utils_1.parseBlockNumber)(args.toBlock); | ||
if (test === undefined) { | ||
test = this._connex.thor.status.head.number; | ||
} | ||
else if (typeof test !== 'number') { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_getLogs', 'options.toBlock'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
toBlock = test; | ||
if (fromBlock > toBlock) { | ||
fromBlock = toBlock; | ||
} | ||
} | ||
const out = { | ||
range: { | ||
unit: 'block', | ||
from: fromBlock, | ||
to: toBlock, | ||
}, | ||
criteria: (0, utils_1.toFilterCriteria)(args), | ||
}; | ||
return [out]; | ||
} | ||
const out = { | ||
range: { | ||
unit: 'block', | ||
from: fromBlock, | ||
to: toBlock, | ||
}, | ||
criteria: (0, utils_1.toFilterCriteria)(args), | ||
}; | ||
this._subscribe = (params) => { | ||
const name = params[0]; | ||
switch (name) { | ||
case 'newHeads': | ||
return ['newHeads']; | ||
case 'logs': | ||
return ['logs', (0, utils_1.toFilterCriteria)(params[1])]; | ||
default: | ||
const msg = error_1.ErrMsg.InvalidSubscriptionName(name); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [out]; | ||
}; | ||
_traceCall = (params) => { | ||
// trace call needs net, bypass if net not set | ||
if (!this._ifSetNet) { | ||
return params; | ||
} | ||
let [callObj, revision = 'latest', opt] = params; | ||
revision = (0, utils_1.parseBlockNumber)(revision); | ||
if (revision === null) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('debug_traceCall', 'revision'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
const arg = { | ||
to: callObj.to || null, | ||
value: callObj.value || '0x0', | ||
data: callObj.data || '0x', | ||
gas: callObj.gas ? (0, utils_1.hexToNumber)(callObj.gas) : undefined, | ||
gasPrice: callObj.gasPrice, | ||
caller: callObj.from, | ||
}; | ||
this._sendRawTransaction = (params) => { | ||
const raw = params[0]; | ||
if (!(0, utils_1.isHexStrict)(raw)) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_sendRawTransaction', 'raw'); | ||
return [arg, revision, opt]; | ||
}; | ||
_subscribe = (params) => { | ||
const name = params[0]; | ||
switch (name) { | ||
case 'newHeads': | ||
return ['newHeads']; | ||
case 'logs': | ||
return ['logs', (0, utils_1.toFilterCriteria)(params[1])]; | ||
default: | ||
const msg = error_1.ErrMsg.InvalidSubscriptionName(name); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [raw]; | ||
}; | ||
this.outputReceiptFormatter = (receipt) => { | ||
const logs = (receipt.outputs.length > 0 && receipt.outputs[0].events.length > 0) ? | ||
receipt.outputs[0].events.map((event, index) => { | ||
return { | ||
blockHash: receipt.meta.blockID, | ||
blockNumber: (0, utils_1.toHex)(receipt.meta.blockNumber), | ||
transactionHash: receipt.meta.txID, | ||
address: event.address, | ||
topics: event.topics.map((x) => x), | ||
data: event.data, | ||
removed: false, | ||
transactionIndex: receipt.transactionIndex, | ||
logIndex: receipt.logInds[index], | ||
}; | ||
}) : []; | ||
return { | ||
status: !receipt.reverted ? '0x1' : '0x0', | ||
blockHash: receipt.meta.blockID, | ||
blockNumber: (0, utils_1.toHex)(receipt.meta.blockNumber), | ||
transactionHash: receipt.meta.txID, | ||
gasUsed: (0, utils_1.toHex)(receipt.gasUsed), | ||
transactionIndex: receipt.transactionIndex, | ||
from: receipt.from, | ||
to: receipt.to, | ||
cumulativeGasUsed: '0x0', | ||
logsBloom: common_1.zeroBytes256, | ||
contractAddress: (receipt.outputs.length && receipt.outputs[0].contractAddress) ? receipt.outputs[0].contractAddress : null, | ||
logs: logs, | ||
}; | ||
}; | ||
this.outputBlockFormatter = (b) => { | ||
return { | ||
hash: b.id, | ||
parentHash: b.parentID, | ||
number: (0, utils_1.toHex)(b.number), | ||
size: (0, utils_1.toHex)(b.size), | ||
stateRoot: b.stateRoot, | ||
receiptsRoot: b.receiptsRoot, | ||
transactionsRoot: b.txsRoot, | ||
timestamp: (0, utils_1.toHex)(b.timestamp), | ||
gasLimit: (0, utils_1.toHex)(b.gasLimit), | ||
gasUsed: (0, utils_1.toHex)(b.gasUsed), | ||
transactions: b.transactions, | ||
miner: b.signer, | ||
// incompatible fields | ||
difficulty: '0x0', | ||
totalDifficulty: '0x0', | ||
uncles: [], | ||
sha3Uncles: common_1.zeroBytes32, | ||
nonce: common_1.zeroBytes8, | ||
logsBloom: common_1.zeroBytes256, | ||
extraData: '0x', | ||
}; | ||
}; | ||
this.outputTransactionFormatter = (tx) => { | ||
return { | ||
hash: tx.id, | ||
blockNumber: (0, utils_1.toHex)(tx.meta.blockNumber), | ||
blockHash: tx.meta.blockID, | ||
from: tx.origin, | ||
to: tx.clauses[0].to, | ||
input: tx.clauses[0].data, | ||
value: tx.clauses[0].value, | ||
gas: (0, utils_1.toHex)(tx.gas), | ||
transactionIndex: tx.transactionIndex, | ||
// incompatible fields | ||
nonce: '0x0', | ||
gasPrice: '0x0' | ||
}; | ||
}; | ||
this.outputLogsFormatter = (ret) => { | ||
return ret.logs.map((log, i) => { | ||
} | ||
}; | ||
_sendRawTransaction = (params) => { | ||
const raw = params[0]; | ||
if (!(0, utils_1.isHexStrict)(raw)) { | ||
const msg = error_1.ErrMsg.ArgumentMissingOrInvalid('eth_sendRawTransaction', 'raw'); | ||
throw new eip1193_1.ProviderRpcError(error_1.ErrCode.InvalidParams, msg); | ||
} | ||
return [raw]; | ||
}; | ||
outputReceiptFormatter = (receipt) => { | ||
const logs = (receipt.outputs.length > 0 && receipt.outputs[0].events.length > 0) ? | ||
receipt.outputs[0].events.map((event, index) => { | ||
return { | ||
address: log.address, | ||
topics: log.topics, | ||
data: log.data, | ||
blockHash: log.meta.blockID, | ||
blockNumber: (0, utils_1.toHex)(log.meta.blockNumber), | ||
transactionHash: log.meta.txID, | ||
blockHash: receipt.meta.blockID, | ||
blockNumber: (0, utils_1.toHex)(receipt.meta.blockNumber), | ||
transactionHash: receipt.meta.txID, | ||
address: event.address, | ||
topics: event.topics.map((x) => x), | ||
data: event.data, | ||
removed: false, | ||
transactionIndex: ret.txInds[i], | ||
logIndex: ret.logInds[i], | ||
transactionIndex: receipt.transactionIndex, | ||
logIndex: receipt.logInds[index], | ||
}; | ||
}); | ||
}) : []; | ||
return { | ||
status: !receipt.reverted ? '0x1' : '0x0', | ||
blockHash: receipt.meta.blockID, | ||
blockNumber: (0, utils_1.toHex)(receipt.meta.blockNumber), | ||
transactionHash: receipt.meta.txID, | ||
gasUsed: (0, utils_1.toHex)(receipt.gasUsed), | ||
transactionIndex: receipt.transactionIndex, | ||
from: receipt.from, | ||
to: receipt.to, | ||
cumulativeGasUsed: '0x0', | ||
logsBloom: common_1.zeroBytes256, | ||
contractAddress: (receipt.outputs.length && receipt.outputs[0].contractAddress) ? receipt.outputs[0].contractAddress : null, | ||
logs: logs, | ||
}; | ||
this.outputHeaderFormatter = (b) => { | ||
}; | ||
outputBlockFormatter = (b) => { | ||
return { | ||
hash: b.id, | ||
parentHash: b.parentID, | ||
number: (0, utils_1.toHex)(b.number), | ||
size: (0, utils_1.toHex)(b.size), | ||
stateRoot: b.stateRoot, | ||
receiptsRoot: b.receiptsRoot, | ||
transactionsRoot: b.txsRoot, | ||
timestamp: (0, utils_1.toHex)(b.timestamp), | ||
gasLimit: (0, utils_1.toHex)(b.gasLimit), | ||
gasUsed: (0, utils_1.toHex)(b.gasUsed), | ||
transactions: b.transactions, | ||
miner: b.signer, | ||
// incompatible fields | ||
difficulty: '0x0', | ||
totalDifficulty: '0x0', | ||
uncles: [], | ||
sha3Uncles: common_1.zeroBytes32, | ||
nonce: common_1.zeroBytes8, | ||
logsBloom: common_1.zeroBytes256, | ||
extraData: '0x', | ||
}; | ||
}; | ||
outputTransactionFormatter = (tx) => { | ||
return { | ||
hash: tx.id, | ||
blockNumber: (0, utils_1.toHex)(tx.meta.blockNumber), | ||
blockHash: tx.meta.blockID, | ||
from: tx.origin, | ||
to: tx.clauses[0].to, | ||
input: tx.clauses[0].data, | ||
value: tx.clauses[0].value, | ||
gas: (0, utils_1.toHex)(tx.gas), | ||
transactionIndex: tx.transactionIndex, | ||
// incompatible fields | ||
nonce: '0x0', | ||
gasPrice: '0x0', | ||
signature: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" | ||
}; | ||
}; | ||
outputLogsFormatter = (ret) => { | ||
return ret.logs.map((log, i) => { | ||
return { | ||
hash: b.id, | ||
parentHash: b.parentID, | ||
number: (0, utils_1.toHex)(b.number), | ||
stateRoot: b.stateRoot, | ||
receiptsRoot: b.receiptsRoot, | ||
transactionsRoot: b.txsRoot, | ||
timestamp: (0, utils_1.toHex)(b.timestamp), | ||
gasLimit: (0, utils_1.toHex)(b.gasLimit), | ||
gasUsed: (0, utils_1.toHex)(b.gasUsed), | ||
miner: b.signer, | ||
// incompatible fields | ||
sha3Uncles: common_1.zeroBytes32, | ||
nonce: common_1.zeroBytes8, | ||
logsBloom: common_1.zeroBytes256, | ||
extraData: '0x', | ||
address: log.address, | ||
topics: log.topics, | ||
data: log.data, | ||
blockHash: log.meta.blockID, | ||
blockNumber: (0, utils_1.toHex)(log.meta.blockNumber), | ||
transactionHash: log.meta.txID, | ||
removed: false, | ||
transactionIndex: ret.txInds[i], | ||
logIndex: ret.logInds[i], | ||
}; | ||
}); | ||
}; | ||
outputHeaderFormatter = (b) => { | ||
return { | ||
hash: b.id, | ||
parentHash: b.parentID, | ||
number: (0, utils_1.toHex)(b.number), | ||
stateRoot: b.stateRoot, | ||
receiptsRoot: b.receiptsRoot, | ||
transactionsRoot: b.txsRoot, | ||
timestamp: (0, utils_1.toHex)(b.timestamp), | ||
gasLimit: (0, utils_1.toHex)(b.gasLimit), | ||
gasUsed: (0, utils_1.toHex)(b.gasUsed), | ||
miner: b.signer, | ||
// incompatible fields | ||
sha3Uncles: common_1.zeroBytes32, | ||
nonce: common_1.zeroBytes8, | ||
logsBloom: common_1.zeroBytes256, | ||
extraData: '0x', | ||
}; | ||
this._connex = connex; | ||
this._ifSetNet = ifSetNet; | ||
this._inputFormatters['eth_getBlockByNumber'] = this._getBlockByNumber; | ||
this._inputFormatters['eth_getBlockByHash'] = this._getBlockByHash; | ||
this._inputFormatters['eth_getBalance'] = this._getBalance; | ||
this._inputFormatters['eth_getCode'] = this._getCode; | ||
this._inputFormatters['eth_getStorageAt'] = this._getStorageAt; | ||
this._inputFormatters['eth_sendTransaction'] = this._sendTransaction; | ||
this._inputFormatters['eth_call'] = this._call; | ||
this._inputFormatters['eth_estimateGas'] = this._estimateGas; | ||
this._inputFormatters['eth_getLogs'] = this._getLogs; | ||
this._inputFormatters['eth_subscribe'] = this._subscribe; | ||
this._inputFormatters['eth_sendRawTransaction'] = this._sendRawTransaction; | ||
} | ||
}; | ||
} | ||
exports.Formatter = Formatter; | ||
//# sourceMappingURL=formatter.js.map |
@@ -7,2 +7,1 @@ export { Provider } from './provider'; | ||
export * as ethers from './ethers'; | ||
//# sourceMappingURL=index.d.ts.map |
'use strict'; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
@@ -6,0 +10,0 @@ if (k2 === undefined) k2 = k; |
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
import { Net, Wallet, DelegateOpt } from './types'; | ||
@@ -9,2 +16,3 @@ import EventEmitter from 'eventemitter3'; | ||
readonly chainTag: number; | ||
readonly chainId: string; | ||
readonly restful?: Restful; | ||
@@ -25,2 +33,3 @@ readonly wallet?: Wallet; | ||
request(req: RequestArguments): Promise<any>; | ||
private _requestAccounts; | ||
private _getTransactionIndex; | ||
@@ -50,3 +59,4 @@ private _getNumOfLogsAhead; | ||
private _getBlockByHash; | ||
private _traceTransaction; | ||
private _traceCall; | ||
} | ||
//# sourceMappingURL=provider.d.ts.map |
/// <reference types='@vechain/connex-types'/> | ||
'use strict'; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -27,182 +18,306 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
class Provider extends eventemitter3_1.default { | ||
connex; | ||
chainTag; | ||
chainId; | ||
restful; | ||
wallet; | ||
_formatter; | ||
_methodMap = {}; | ||
_subscriptions = { | ||
newHeads: {}, | ||
logs: {}, | ||
}; | ||
_delegate; | ||
constructor(opt) { | ||
super(); | ||
this._methodMap = {}; | ||
this._subscriptions = { | ||
newHeads: {}, | ||
logs: {}, | ||
}; | ||
this._getTransactionIndex = (blkId, txId) => __awaiter(this, void 0, void 0, function* () { | ||
const blk = yield this.connex.thor.block(blkId).get(); | ||
if (!blk) { | ||
return Promise.reject(new Error(`Block ${blkId} not found`)); | ||
this.connex = opt.connex; | ||
const id = opt.connex.thor.genesis.id; | ||
this.chainTag = (0, utils_1.hexToNumber)('0x' + id.substring(id.length - 2)); | ||
this.chainId = id; | ||
this._formatter = new formatter_1.Formatter(opt.connex, !!opt.net); | ||
this._delegate = opt.delegate ? opt.delegate : null; | ||
this._methodMap['eth_getBlockByHash'] = this._getBlockByHash; | ||
this._methodMap['eth_getBlockByNumber'] = this._getBlockByNumber; | ||
this._methodMap['eth_chainId'] = this._getChainId; | ||
this._methodMap['eth_getTransactionByHash'] = this._getTransactionByHash; | ||
this._methodMap['eth_getBalance'] = this._getBalance; | ||
this._methodMap['eth_blockNumber'] = this._getBlockNumber; | ||
this._methodMap['eth_getCode'] = this._getCode; | ||
this._methodMap['eth_syncing'] = this._isSyncing; | ||
this._methodMap['eth_getTransactionReceipt'] = this._getTransactionReceipt; | ||
this._methodMap['eth_getStorageAt'] = this._getStorageAt; | ||
this._methodMap['eth_sendTransaction'] = this._sendTransaction; | ||
this._methodMap['eth_call'] = this._call; | ||
this._methodMap['eth_estimateGas'] = this._estimateGas; | ||
this._methodMap['eth_getLogs'] = this._getLogs; | ||
this._methodMap['eth_subscribe'] = this._subscribe; | ||
this._methodMap['eth_unsubscribe'] = this._unsubscribe; | ||
this._methodMap['eth_accounts'] = this._accounts; | ||
this._methodMap['net_version'] = this._getChainId; | ||
this._methodMap['eth_requestAccounts'] = this._requestAccounts; | ||
if (opt.net) { | ||
this.restful = new restful_1.Restful(opt.net, this.connex.thor.genesis.id); | ||
this._methodMap['eth_sendRawTransaction'] = this._sendRawTransaction; | ||
this._methodMap['debug_traceTransaction'] = this._traceTransaction; | ||
this._methodMap['debug_traceCall'] = this._traceCall; | ||
} | ||
if (opt.wallet) { | ||
this.wallet = opt.wallet; | ||
} | ||
this._methodMap['web3_clientVersion'] = async () => { return "thor"; }; | ||
// dummy | ||
this._methodMap['eth_gasPrice'] = async () => { return '0x0'; }; | ||
this._methodMap['eth_getTransactionCount'] = async () => { return '0x0'; }; | ||
this._subLoop(); | ||
// Ganache methods | ||
this._methodMap['evm_mine'] = this._mine; | ||
} | ||
enableDelegate(opt) { | ||
const old = this._delegate; | ||
this._delegate = opt; | ||
return old; | ||
} | ||
disableDelegate() { | ||
const opt = this._delegate; | ||
this._delegate = null; | ||
return opt; | ||
} | ||
async request(req) { | ||
if (!common_1.EthJsonRpcMethods.includes(req.method)) { | ||
const msg = `Method ${req.method} not found`; | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.MethodNotFound, msg)); | ||
} | ||
const exec = this._methodMap[req.method]; | ||
if (!exec) { | ||
const msg = `Method ${req.method} not implemented`; | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.MethodNotFound, msg)); | ||
} | ||
let params; | ||
try { | ||
params = this._formatter.formatInput(req.method, req.params); | ||
} | ||
catch (err) { | ||
return Promise.reject(err); | ||
} | ||
return exec(params); | ||
} | ||
_requestAccounts = async () => { | ||
if (!this.wallet || this.wallet.list.length === 0) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'No account')); | ||
} | ||
const addrs = this.wallet.list.map(key => key.address); | ||
return addrs; | ||
}; | ||
_getTransactionIndex = async (blkId, txId) => { | ||
const blk = await this.connex.thor.block(blkId).get(); | ||
if (!blk) { | ||
return Promise.reject(new Error(`Block ${blkId} not found`)); | ||
} | ||
const txIndex = blk.transactions.findIndex(elem => elem == txId); | ||
if (txIndex == -1) { | ||
return Promise.reject(new Error(`Tx ${txId} not found in block`)); | ||
} | ||
return txIndex; | ||
}; | ||
_getNumOfLogsAhead = async (blkId, txId) => { | ||
const blk = await this.connex.thor.block(blkId).get(); | ||
if (!blk) { | ||
return Promise.reject(new Error(`Block ${blkId} not found`)); | ||
} | ||
const txInd = await this._getTransactionIndex(blkId, txId); | ||
// Count the number of logs in the txs whose number is lower than txId | ||
let logInd = 0; | ||
for (let i = 0; i < txInd; i++) { | ||
const txId = blk.transactions[i]; | ||
const receipt = await this.connex.thor.transaction(txId).getReceipt(); | ||
if (!receipt) { | ||
return Promise.reject(new Error(`Receipt of Tx ${txId} not found`)); | ||
} | ||
const txIndex = blk.transactions.findIndex(elem => elem == txId); | ||
if (txIndex == -1) { | ||
return Promise.reject(new Error(`Tx ${txId} not found in block`)); | ||
} | ||
return txIndex; | ||
}); | ||
this._getNumOfLogsAhead = (blkId, txId) => __awaiter(this, void 0, void 0, function* () { | ||
const blk = yield this.connex.thor.block(blkId).get(); | ||
if (!blk) { | ||
return Promise.reject(new Error(`Block ${blkId} not found`)); | ||
} | ||
const txInd = yield this._getTransactionIndex(blkId, txId); | ||
// Count the number of logs in the txs whose number is lower than txId | ||
let logInd = 0; | ||
for (let i = 0; i < txInd; i++) { | ||
const txId = blk.transactions[i]; | ||
const receipt = yield this.connex.thor.transaction(txId).getReceipt(); | ||
if (!receipt) { | ||
return Promise.reject(new Error(`Receipt of Tx ${txId} not found`)); | ||
receipt.outputs.forEach(output => { | ||
logInd += output.events.length; | ||
}); | ||
} | ||
return logInd; | ||
}; | ||
_getLogIndexWithinTx = async (log) => { | ||
const receipt = await this.connex.thor.transaction(log.meta.txID).getReceipt(); | ||
if (!receipt) { | ||
return Promise.reject(new Error(`Receipt of Tx ${log.meta.txID}} not found`)); | ||
} | ||
let offset = 0; | ||
for (let output of receipt.outputs) { | ||
const events = output.events; | ||
for (let i = 0; i < events.length; i++) { | ||
const ev = events[i]; | ||
if (log.address !== ev.address | ||
|| log.topics.length !== ev.topics.length | ||
|| log.data !== ev.data) { | ||
continue; | ||
} | ||
receipt.outputs.forEach(output => { | ||
logInd += output.events.length; | ||
}); | ||
} | ||
return logInd; | ||
}); | ||
this._getLogIndexWithinTx = (log) => __awaiter(this, void 0, void 0, function* () { | ||
const receipt = yield this.connex.thor.transaction(log.meta.txID).getReceipt(); | ||
if (!receipt) { | ||
return Promise.reject(new Error(`Receipt of Tx ${log.meta.txID}} not found`)); | ||
} | ||
let offset = 0; | ||
for (let output of receipt.outputs) { | ||
const events = output.events; | ||
for (let i = 0; i < events.length; i++) { | ||
const ev = events[i]; | ||
if (log.address !== ev.address | ||
|| log.topics.length !== ev.topics.length | ||
|| log.data !== ev.data) { | ||
for (let j = 0; j < log.topics.length; j++) { | ||
if (log.topics[j] !== ev.topics[j]) { | ||
continue; | ||
} | ||
for (let j = 0; j < log.topics.length; j++) { | ||
if (log.topics[j] !== ev.topics[j]) { | ||
continue; | ||
} | ||
} | ||
return i + offset; | ||
} | ||
offset += events.length; | ||
return i + offset; | ||
} | ||
return Promise.reject(new Error('Log not found')); | ||
}); | ||
this._mine = (_) => __awaiter(this, void 0, void 0, function* () { | ||
yield this.connex.thor.ticker().next(); | ||
}); | ||
this._accounts = (_) => __awaiter(this, void 0, void 0, function* () { | ||
if (!this.wallet || this.wallet.list.length === 0) { | ||
return []; | ||
offset += events.length; | ||
} | ||
return Promise.reject(new Error('Log not found')); | ||
}; | ||
_mine = async (_) => { | ||
await this.connex.thor.ticker().next(); | ||
}; | ||
_accounts = async (_) => { | ||
if (!this.wallet || this.wallet.list.length === 0) { | ||
return []; | ||
} | ||
const addrs = this.wallet.list.map(key => key.address); | ||
return addrs; | ||
}; | ||
_sendRawTransaction = async (params) => { | ||
try { | ||
if (this.restful) { | ||
return await this.restful.sendRawTransaction(params[0]); | ||
} | ||
return this.wallet.list.map(key => key.address); | ||
}); | ||
this._sendRawTransaction = (params) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
if (this.restful) { | ||
return yield this.restful.sendRawTransaction(params[0]); | ||
} | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, (0, utils_1.getErrMsg)(err))); | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Restful API not supported')); | ||
}; | ||
_subscribe = async (params) => { | ||
const subId = this._getSubscriptionId(params); | ||
const subName = params[0]; | ||
this._subscriptions[subName][subId] = params[1] || {}; | ||
return subId; | ||
}; | ||
_unsubscribe = async (params) => { | ||
const subId = params[0]; | ||
if (!this._subscriptions['newHeads'][subId] && !this._subscriptions['logs'][subId]) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, error_1.ErrMsg.SubscriptionIdNotFound(subId))); | ||
} | ||
this._subscriptions['newHeads'][subId] ? | ||
delete this._subscriptions['newHeads'][subId] : | ||
delete this._subscriptions['logs'][subId]; | ||
return true; | ||
}; | ||
_subLoop = async () => { | ||
const ticker = this.connex.thor.ticker(); | ||
try { | ||
for (;;) { | ||
const best = await ticker.next(); | ||
const newHeadsKeys = Object.keys(this._subscriptions['newHeads']); | ||
if (newHeadsKeys.length > 0) { | ||
const blk = await this.connex.thor.block().get(); | ||
if (blk) { | ||
newHeadsKeys.forEach(key => { | ||
this.emit('message', (0, utils_1.toSubscription)(this._formatter.outputHeaderFormatter(blk), key)); | ||
}); | ||
} | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, (0, utils_1.getErrMsg)(err))); | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Restful API not supported')); | ||
}); | ||
this._subscribe = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const subId = this._getSubscriptionId(params); | ||
const subName = params[0]; | ||
this._subscriptions[subName][subId] = params[1] || {}; | ||
return subId; | ||
}); | ||
this._unsubscribe = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const subId = params[0]; | ||
if (!this._subscriptions['newHeads'][subId] && !this._subscriptions['logs'][subId]) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, error_1.ErrMsg.SubscriptionIdNotFound(subId))); | ||
} | ||
this._subscriptions['newHeads'][subId] ? | ||
delete this._subscriptions['newHeads'][subId] : | ||
delete this._subscriptions['logs'][subId]; | ||
return true; | ||
}); | ||
this._subLoop = () => __awaiter(this, void 0, void 0, function* () { | ||
const ticker = this.connex.thor.ticker(); | ||
try { | ||
for (;;) { | ||
const best = yield ticker.next(); | ||
const newHeadsKeys = Object.keys(this._subscriptions['newHeads']); | ||
if (newHeadsKeys.length > 0) { | ||
const blk = yield this.connex.thor.block().get(); | ||
if (blk) { | ||
newHeadsKeys.forEach(key => { | ||
this.emit('message', (0, utils_1.toSubscription)(this._formatter.outputHeaderFormatter(blk), key)); | ||
}); | ||
const logsKeys = Object.keys(this._subscriptions['logs']); | ||
if (logsKeys.length > 0) { | ||
await Promise.all(logsKeys.map(async (key) => { | ||
const MAX_LIMIT = 256; | ||
const range = { | ||
unit: 'block', | ||
from: best.number, | ||
to: best.number, | ||
}; | ||
let logs = await this.connex.thor.filter('event', this._subscriptions['logs'][key]) | ||
.range(range) | ||
.apply(0, MAX_LIMIT); | ||
if (logs) { | ||
const txInds = []; | ||
const logInds = []; | ||
for (let i = 0; i < logs.length; i++) { | ||
const log = logs[i]; | ||
const offset = await this._getNumOfLogsAhead(log.meta.blockID, log.meta.txID); | ||
const ind = await this._getLogIndexWithinTx(log); | ||
logInds[i] = (0, web3_utils_1.numberToHex)(offset + ind); | ||
txInds[i] = (0, web3_utils_1.numberToHex)(await this._getTransactionIndex(log.meta.blockID, log.meta.txID)); | ||
} | ||
; | ||
this.emit('message', (0, utils_1.toSubscription)(this._formatter.outputLogsFormatter({ logs: logs, txInds: txInds, logInds: logInds }), key)); | ||
} | ||
} | ||
const logsKeys = Object.keys(this._subscriptions['logs']); | ||
if (logsKeys.length > 0) { | ||
yield Promise.all(logsKeys.map((key) => __awaiter(this, void 0, void 0, function* () { | ||
const MAX_LIMIT = 256; | ||
const range = { | ||
unit: 'block', | ||
from: best.number, | ||
to: best.number, | ||
}; | ||
let logs = yield this.connex.thor.filter('event', this._subscriptions['logs'][key]) | ||
.range(range) | ||
.apply(0, MAX_LIMIT); | ||
if (logs) { | ||
const txInds = []; | ||
const logInds = []; | ||
for (let i = 0; i < logs.length; i++) { | ||
const log = logs[i]; | ||
const offset = yield this._getNumOfLogsAhead(log.meta.blockID, log.meta.txID); | ||
const ind = yield this._getLogIndexWithinTx(log); | ||
logInds[i] = (0, web3_utils_1.numberToHex)(offset + ind); | ||
txInds[i] = (0, web3_utils_1.numberToHex)(yield this._getTransactionIndex(log.meta.blockID, log.meta.txID)); | ||
} | ||
; | ||
this.emit('message', (0, utils_1.toSubscription)(this._formatter.outputLogsFormatter({ logs: logs, txInds: txInds, logInds: logInds }), key)); | ||
} | ||
}))); | ||
} | ||
})); | ||
} | ||
} | ||
catch (err) { | ||
throw new Error(err); | ||
} | ||
catch (err) { | ||
throw new Error(err); | ||
} | ||
}; | ||
_getSubscriptionId = (params) => { | ||
return '0x' + (0, thor_devkit_1.keccak256)((new Date()).getTime().toString(), JSON.stringify(params)).toString('hex'); | ||
}; | ||
_getLogs = async (params) => { | ||
const MAX_LIMIT = 256; | ||
const opts = params[0]; | ||
try { | ||
let logs = await this.connex.thor.filter('event', opts.criteria) | ||
.range(opts.range) | ||
.apply(0, MAX_LIMIT); | ||
if (logs.length === 0) { | ||
return []; | ||
} | ||
}); | ||
this._getSubscriptionId = (params) => { | ||
return '0x' + (0, thor_devkit_1.keccak256)((new Date()).getTime().toString(), JSON.stringify(params)).toString('hex'); | ||
}; | ||
this._getLogs = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const MAX_LIMIT = 256; | ||
const opts = params[0]; | ||
try { | ||
let logs = yield this.connex.thor.filter('event', opts.criteria) | ||
.range(opts.range) | ||
.apply(0, MAX_LIMIT); | ||
if (logs.length === 0) { | ||
return []; | ||
const txInds = []; | ||
const logInds = []; | ||
for (let i = 0; i < logs.length; i++) { | ||
const log = logs[i]; | ||
const offset = await this._getNumOfLogsAhead(log.meta.blockID, log.meta.txID); | ||
const ind = await this._getLogIndexWithinTx(log); | ||
logInds[i] = (0, web3_utils_1.numberToHex)(offset + ind); | ||
txInds[i] = (0, web3_utils_1.numberToHex)(await this._getTransactionIndex(log.meta.blockID, log.meta.txID)); | ||
} | ||
return this._formatter.outputLogsFormatter({ logs: logs, txInds: txInds, logInds: logInds }); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_estimateGas = async (params) => { | ||
const txObj = params[0]; | ||
let explainer = this.connex.thor.explain([txObj.clauses[0]]); | ||
if (txObj.caller) { | ||
explainer = explainer.caller(txObj.caller); | ||
} | ||
if (txObj.gas) { | ||
explainer = explainer.gas(txObj.gas); | ||
} | ||
try { | ||
const outputs = await explainer.execute(); | ||
const output = outputs[0]; | ||
if (output.reverted) { | ||
if (output.vmError === 'execution reverted' && output.revertReason) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, `execution reverted: ${output.revertReason}`, output.data)); | ||
} | ||
const txInds = []; | ||
const logInds = []; | ||
for (let i = 0; i < logs.length; i++) { | ||
const log = logs[i]; | ||
const offset = yield this._getNumOfLogsAhead(log.meta.blockID, log.meta.txID); | ||
const ind = yield this._getLogIndexWithinTx(log); | ||
logInds[i] = (0, web3_utils_1.numberToHex)(offset + ind); | ||
txInds[i] = (0, web3_utils_1.numberToHex)(yield this._getTransactionIndex(log.meta.blockID, log.meta.txID)); | ||
else { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, output.vmError)); | ||
} | ||
return this._formatter.outputLogsFormatter({ logs: logs, txInds: txInds, logInds: logInds }); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
const clause = { | ||
to: txObj.clauses[0].to, | ||
value: txObj.clauses[0].value, | ||
data: txObj.clauses[0].data ? txObj.clauses[0].data : '0x', | ||
}; | ||
const execGas = outputs.reduce((sum, out) => sum + out.gasUsed, 0); | ||
const intrinsicGas = thor_devkit_1.Transaction.intrinsicGas([clause]); | ||
const estimatedGas = intrinsicGas + (execGas ? (execGas + 15000) : 0); | ||
return (0, utils_1.toHex)(estimatedGas); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_call = async (params) => { | ||
const txObj = params[0]; | ||
try { | ||
if (this.restful) { | ||
return await this.restful.call(txObj, params[1]); | ||
} | ||
}); | ||
this._estimateGas = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const txObj = params[0]; | ||
let explainer = this.connex.thor.explain([txObj.clauses[0]]); | ||
@@ -215,125 +330,87 @@ if (txObj.caller) { | ||
} | ||
try { | ||
const outputs = yield explainer.execute(); | ||
const output = outputs[0]; | ||
if (output.reverted) { | ||
if (output.vmError === 'execution reverted' && output.revertReason) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, `execution reverted: ${output.revertReason}`, output.data)); | ||
} | ||
else { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, output.vmError)); | ||
} | ||
const outputs = await explainer.execute(); | ||
const output = outputs[0]; | ||
if (output.reverted) { | ||
if (output.vmError === 'execution reverted' && output.revertReason) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, `execution reverted: ${output.revertReason}`, output.data)); | ||
} | ||
const clause = { | ||
to: txObj.clauses[0].to, | ||
value: txObj.clauses[0].value, | ||
data: txObj.clauses[0].data ? txObj.clauses[0].data : '0x', | ||
}; | ||
const execGas = outputs.reduce((sum, out) => sum + out.gasUsed, 0); | ||
const intrinsicGas = thor_devkit_1.Transaction.intrinsicGas([clause]); | ||
const estimatedGas = intrinsicGas + (execGas ? (execGas + 15000) : 0); | ||
return (0, utils_1.toHex)(estimatedGas); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this._call = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const txObj = params[0]; | ||
try { | ||
if (this.restful) { | ||
return yield this.restful.call(txObj, params[1]); | ||
else { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, output.vmError)); | ||
} | ||
let explainer = this.connex.thor.explain([txObj.clauses[0]]); | ||
if (txObj.caller) { | ||
explainer = explainer.caller(txObj.caller); | ||
} | ||
if (txObj.gas) { | ||
explainer = explainer.gas(txObj.gas); | ||
} | ||
const outputs = yield explainer.execute(); | ||
const output = outputs[0]; | ||
if (output.reverted) { | ||
if (output.vmError === 'execution reverted' && output.revertReason) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, `execution reverted: ${output.revertReason}`, output.data)); | ||
} | ||
else { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, output.vmError)); | ||
} | ||
} | ||
return output.data; | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
return output.data; | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
}); | ||
this._sendTransaction = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const txObj = params[0]; | ||
let ss = this.connex.vendor.sign('tx', [txObj.clauses[0]]); | ||
if (txObj.caller) { | ||
ss = ss.signer(txObj.caller); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_sendTransaction = async (params) => { | ||
const txObj = params[0]; | ||
let ss = this.connex.vendor.sign('tx', [txObj.clauses[0]]); | ||
if (txObj.caller) { | ||
ss = ss.signer(txObj.caller); | ||
} | ||
if (this._delegate) { | ||
if (this._delegate.signer) { | ||
ss = ss.delegate(this._delegate.url, this._delegate.signer); | ||
} | ||
if (this._delegate) { | ||
if (this._delegate.signer) { | ||
ss = ss.delegate(this._delegate.url, this._delegate.signer); | ||
} | ||
else { | ||
ss = ss.delegate(this._delegate.url); | ||
} | ||
else { | ||
ss = ss.delegate(this._delegate.url); | ||
} | ||
if (txObj.gas) { | ||
ss = ss.gas(txObj.gas); | ||
} | ||
if (txObj.gas) { | ||
ss = ss.gas(txObj.gas); | ||
} | ||
try { | ||
const ret = await ss.request(); | ||
return ret.txid; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getStorageAt = async (params) => { | ||
const [addr, key, revision] = params; | ||
try { | ||
if (this.restful) { | ||
return await this.restful.getStorageAt(addr, key, revision); | ||
} | ||
try { | ||
const ret = yield ss.request(); | ||
return ret.txid; | ||
const storage = await this.connex.thor.account(addr).getStorage(key); | ||
return storage.value; | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, (0, utils_1.getErrMsg)(err))); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getTransactionReceipt = async (params) => { | ||
const hash = params[0]; | ||
try { | ||
const receipt = await this.connex.thor.transaction(hash).getReceipt(); | ||
if (!receipt) { | ||
return null; | ||
} | ||
}); | ||
this._getStorageAt = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const [addr, key, revision] = params; | ||
try { | ||
if (this.restful) { | ||
return yield this.restful.getStorageAt(addr, key, revision); | ||
else { | ||
const blkId = receipt.meta.blockID; | ||
const blk = await this.connex.thor.block(blkId).get(); | ||
if (!blk) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Block not found')); | ||
} | ||
const storage = yield this.connex.thor.account(addr).getStorage(key); | ||
return storage.value; | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
const tx = await this.connex.thor.transaction(hash).get(); | ||
if (!tx) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Tx not found')); | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this._getTransactionReceipt = (params) => __awaiter(this, void 0, void 0, function* () { | ||
var _a; | ||
const hash = params[0]; | ||
try { | ||
const receipt = yield this.connex.thor.transaction(hash).getReceipt(); | ||
if (!receipt) { | ||
return null; | ||
} | ||
else { | ||
const blkId = receipt.meta.blockID; | ||
const blk = yield this.connex.thor.block(blkId).get(); | ||
if (!blk) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Block not found')); | ||
} | ||
const tx = yield this.connex.thor.transaction(hash).get(); | ||
if (!tx) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Tx not found')); | ||
} | ||
const txInd = (0, web3_utils_1.numberToHex)(yield this._getTransactionIndex(blkId, hash)); | ||
const logIndOffset = yield this._getNumOfLogsAhead(blkId, hash); | ||
const n = ((_a = receipt.outputs[0]) === null || _a === void 0 ? void 0 : _a.events.length) || 0; | ||
const logInds = new Array(n) | ||
.fill(logIndOffset) | ||
.map((_, i) => { return (0, web3_utils_1.numberToHex)(logIndOffset + i); }); | ||
return this._formatter.outputReceiptFormatter(Object.assign(Object.assign({}, receipt), { | ||
const txInd = (0, web3_utils_1.numberToHex)(await this._getTransactionIndex(blkId, hash)); | ||
const logIndOffset = await this._getNumOfLogsAhead(blkId, hash); | ||
const n = receipt.outputs[0]?.events.length || 0; | ||
const logInds = new Array(n) | ||
.fill(logIndOffset) | ||
.map((_, i) => { return (0, web3_utils_1.numberToHex)(logIndOffset + i); }); | ||
return this._formatter.outputReceiptFormatter({ | ||
...receipt, ...{ | ||
transactionIndex: txInd, | ||
@@ -343,195 +420,207 @@ logInds: logInds, | ||
to: tx.clauses[0].to | ||
})); | ||
} | ||
}, | ||
}); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
; | ||
}; | ||
_isSyncing = async (_) => { | ||
try { | ||
await this.connex.thor.ticker().next(); | ||
if (this.connex.thor.status.progress == 1) { | ||
return false; | ||
} | ||
; | ||
}); | ||
this._isSyncing = (_) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield this.connex.thor.ticker().next(); | ||
if (this.connex.thor.status.progress == 1) { | ||
return false; | ||
} | ||
else { | ||
const highestBlock = Math.floor((Date.now() - this.connex.thor.genesis.timestamp) / 10000); | ||
return { | ||
startingBlock: null, | ||
currentBlock: (0, utils_1.toHex)(this.connex.thor.status.head.number), | ||
highestBlock: (0, utils_1.toHex)(highestBlock), | ||
}; | ||
} | ||
else { | ||
const highestBlock = Math.floor((Date.now() - this.connex.thor.genesis.timestamp) / 10000); | ||
return { | ||
startingBlock: null, | ||
currentBlock: (0, utils_1.toHex)(this.connex.thor.status.head.number), | ||
highestBlock: (0, utils_1.toHex)(highestBlock), | ||
}; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getCode = async (params) => { | ||
const [addr, revision] = params; | ||
try { | ||
if (this.restful) { | ||
return await this.restful.getCode(addr, revision); | ||
} | ||
}); | ||
this._getCode = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const [addr, revision] = params; | ||
try { | ||
if (this.restful) { | ||
return yield this.restful.getCode(addr, revision); | ||
} | ||
const code = yield this.connex.thor.account(addr).getCode(); | ||
return code.code; | ||
const code = await this.connex.thor.account(addr).getCode(); | ||
return code.code; | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getBlockNumber = async (_) => { | ||
try { | ||
const blk = await this.connex.thor.block().get(); | ||
if (!blk) { | ||
return null; | ||
} | ||
}); | ||
this._getBlockNumber = (_) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const blk = yield this.connex.thor.block().get(); | ||
if (!blk) { | ||
return null; | ||
} | ||
else { | ||
return (0, utils_1.toHex)(blk.number); | ||
} | ||
else { | ||
return (0, utils_1.toHex)(blk.number); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getBalance = async (params) => { | ||
const [addr, revision] = params; | ||
try { | ||
if (this.restful) { | ||
return await this.restful.getBalance(addr, revision); | ||
} | ||
}); | ||
this._getBalance = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const [addr, revision] = params; | ||
try { | ||
if (this.restful) { | ||
return yield this.restful.getBalance(addr, revision); | ||
} | ||
const acc = yield this.connex.thor.account(addr).get(); | ||
return acc.balance; | ||
const acc = await this.connex.thor.account(addr).get(); | ||
return acc.balance; | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
catch (err) { | ||
if (err instanceof eip1193_1.ProviderRpcError) { | ||
return Promise.reject(err); | ||
} | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getTransactionByHash = async (params) => { | ||
const hash = params[0]; | ||
try { | ||
const tx = await this.connex.thor.transaction(hash).get(); | ||
if (!tx) { | ||
return null; | ||
} | ||
}); | ||
this._getTransactionByHash = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const hash = params[0]; | ||
try { | ||
const tx = yield this.connex.thor.transaction(hash).get(); | ||
if (!tx) { | ||
return null; | ||
} | ||
else { | ||
const ind = (0, web3_utils_1.numberToHex)(yield this._getTransactionIndex(tx.meta.blockID, hash)); | ||
return this._formatter.outputTransactionFormatter(Object.assign(Object.assign({}, tx), { transactionIndex: ind })); | ||
} | ||
else { | ||
const ind = (0, web3_utils_1.numberToHex)(await this._getTransactionIndex(tx.meta.blockID, hash)); | ||
return this._formatter.outputTransactionFormatter({ ...tx, ...{ transactionIndex: ind } }); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getChainId = async (_) => { | ||
const bigIntValue = BigInt(this.chainId); | ||
return bigIntValue; | ||
}; | ||
_getBlockByNumber = async (params) => { | ||
const num = params[0]; | ||
try { | ||
const blk = await this.connex.thor.block(num).get(); | ||
if (!blk) { | ||
return null; | ||
} | ||
}); | ||
this._getChainId = (_) => __awaiter(this, void 0, void 0, function* () { | ||
return (0, utils_1.toHex)(this.chainTag); | ||
}); | ||
this._getBlockByNumber = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const num = params[0]; | ||
try { | ||
const blk = yield this.connex.thor.block(num).get(); | ||
if (!blk) { | ||
return null; | ||
} | ||
else { | ||
return this._formatter.outputBlockFormatter(blk); | ||
} | ||
else { | ||
return this._formatter.outputBlockFormatter(blk); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_getBlockByHash = async (params) => { | ||
const hash = params[0]; | ||
try { | ||
const blk = await this.connex.thor.block(hash).get(); | ||
if (!blk) { | ||
return null; | ||
} | ||
}); | ||
this._getBlockByHash = (params) => __awaiter(this, void 0, void 0, function* () { | ||
const hash = params[0]; | ||
try { | ||
const blk = yield this.connex.thor.block(hash).get(); | ||
if (!blk) { | ||
return null; | ||
} | ||
else { | ||
return this._formatter.outputBlockFormatter(blk); | ||
} | ||
else { | ||
return this._formatter.outputBlockFormatter(blk); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this.connex = opt.connex; | ||
const id = opt.connex.thor.genesis.id; | ||
this.chainTag = (0, utils_1.hexToNumber)('0x' + id.substring(id.length - 2)); | ||
this._formatter = new formatter_1.Formatter(opt.connex, !!opt.net); | ||
this._delegate = opt.delegate || null; | ||
this._methodMap['eth_getBlockByHash'] = this._getBlockByHash; | ||
this._methodMap['eth_getBlockByNumber'] = this._getBlockByNumber; | ||
this._methodMap['eth_chainId'] = this._getChainId; | ||
this._methodMap['eth_getTransactionByHash'] = this._getTransactionByHash; | ||
this._methodMap['eth_getBalance'] = this._getBalance; | ||
this._methodMap['eth_blockNumber'] = this._getBlockNumber; | ||
this._methodMap['eth_getCode'] = this._getCode; | ||
this._methodMap['eth_syncing'] = this._isSyncing; | ||
this._methodMap['eth_getTransactionReceipt'] = this._getTransactionReceipt; | ||
this._methodMap['eth_getStorageAt'] = this._getStorageAt; | ||
this._methodMap['eth_sendTransaction'] = this._sendTransaction; | ||
this._methodMap['eth_call'] = this._call; | ||
this._methodMap['eth_estimateGas'] = this._estimateGas; | ||
this._methodMap['eth_getLogs'] = this._getLogs; | ||
this._methodMap['eth_subscribe'] = this._subscribe; | ||
this._methodMap['eth_unsubscribe'] = this._unsubscribe; | ||
this._methodMap['eth_accounts'] = this._accounts; | ||
this._methodMap['net_version'] = this._getChainId; | ||
if (opt.net) { | ||
this.restful = new restful_1.Restful(opt.net, this.connex.thor.genesis.id); | ||
this._methodMap['eth_sendRawTransaction'] = this._sendRawTransaction; | ||
} | ||
if (opt.wallet) { | ||
this.wallet = opt.wallet; | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
this._methodMap['web3_clientVersion'] = () => __awaiter(this, void 0, void 0, function* () { return "thor"; }); | ||
// dummy | ||
this._methodMap['eth_gasPrice'] = () => __awaiter(this, void 0, void 0, function* () { return '0x0'; }); | ||
this._methodMap['eth_getTransactionCount'] = () => __awaiter(this, void 0, void 0, function* () { return '0x0'; }); | ||
this._subLoop(); | ||
// Ganache methods | ||
this._methodMap['evm_mine'] = this._mine; | ||
} | ||
enableDelegate(opt) { | ||
const old = this._delegate; | ||
this._delegate = opt; | ||
return old; | ||
} | ||
disableDelegate() { | ||
const opt = this._delegate; | ||
this._delegate = null; | ||
return opt; | ||
} | ||
request(req) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!common_1.EthJsonRpcMethods.includes(req.method)) { | ||
const msg = `Method ${req.method} not found`; | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.MethodNotFound, msg)); | ||
}; | ||
_traceTransaction = async (params) => { | ||
/** | ||
* debug_traceTransaction(txHash, traceOptions) | ||
* traceOptions: { | ||
* tracer: '', // name of tracer or custom js tracer code | ||
* config: {} // struct logger config object | ||
* tracerConfig: {} // tracer specific config object | ||
* } | ||
*/ | ||
if (!this.restful) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Restful API not supported')); | ||
} | ||
try { | ||
const txId = params[0]; | ||
const opts = params[1]; | ||
const tx = await this.connex.thor.transaction(txId).get(); | ||
if (!tx) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Target not found')); | ||
} | ||
const exec = this._methodMap[req.method]; | ||
if (!exec) { | ||
const msg = `Method ${req.method} not implemented`; | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.MethodNotFound, msg)); | ||
const blk = (await this.connex.thor.block(tx.meta.blockID).get()); | ||
const txIndex = blk.transactions.findIndex(elem => elem == txId); | ||
if (opts?.tracer) { | ||
return await this.restful.traceClause({ | ||
target: `${tx.meta.blockID}/${txIndex}/0`, | ||
name: opts?.tracer, | ||
config: opts?.tracerConfig, | ||
}); | ||
} | ||
let params; | ||
try { | ||
params = this._formatter.formatInput(req.method, req.params); | ||
else { | ||
// if tracerConfig.name not specified, it's struct logger | ||
// struct logger config is located at tracerConfig.config | ||
return await this.restful.traceClause({ | ||
target: `${tx.meta.blockID}/${txIndex}/0`, | ||
name: opts?.tracer, | ||
config: opts?.config, | ||
}); | ||
} | ||
catch (err) { | ||
return Promise.reject(err); | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
_traceCall = async (params) => { | ||
/** | ||
* debug_traceCall(callArgs, blockHashOrNumber ,tracerOptions) | ||
* tracerOptions: { | ||
* tracer: '', // name of tracer or custom js tracer code | ||
* config: {} // struct logger config object | ||
* tracerConfig: {} // tracer specific config object | ||
* } | ||
*/ | ||
if (!this.restful) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, 'Restful API not supported')); | ||
} | ||
try { | ||
const callArgs = params[0]; | ||
const revision = params[1]; | ||
const opts = params[2]; | ||
if (opts?.tracer) { | ||
return await this.restful.traceCall({ | ||
...callArgs, | ||
name: opts?.tracer, | ||
config: opts?.tracerConfig, | ||
}, revision); | ||
} | ||
return exec(params); | ||
}); | ||
} | ||
else { | ||
// if tracerConfig.name not specified, it's struct logger | ||
// struct logger config is located at tracerConfig.config | ||
return await this.restful.traceCall({ | ||
...callArgs, | ||
name: opts.tracer, | ||
config: opts.config, | ||
}, revision); | ||
} | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
} | ||
exports.Provider = Provider; | ||
//# sourceMappingURL=provider.js.map |
@@ -1,2 +0,2 @@ | ||
import { Net, ExplainArg } from './types'; | ||
import { Net, ExplainArg, TraceClauseOption, TraceCallOption } from './types'; | ||
export declare class Restful { | ||
@@ -8,7 +8,8 @@ private readonly _net; | ||
sendRawTransaction: (raw: string) => Promise<any>; | ||
getCode: (addr: string, revision?: string | undefined) => Promise<string>; | ||
getBalance: (addr: string, revision?: string | undefined) => Promise<string>; | ||
getStorageAt: (addr: string, key: string, revision?: string | undefined) => Promise<string>; | ||
call: (callObj: ExplainArg, revision?: string | undefined) => Promise<string>; | ||
getCode: (addr: string, revision?: string) => Promise<string>; | ||
getBalance: (addr: string, revision?: string) => Promise<string>; | ||
getStorageAt: (addr: string, key: string, revision?: string) => Promise<string>; | ||
call: (callObj: ExplainArg, revision?: string) => Promise<string>; | ||
traceClause: (opts: TraceClauseOption) => Promise<object>; | ||
traceCall: (opts: TraceCallOption, revision?: string) => Promise<object>; | ||
} | ||
//# sourceMappingURL=restful.d.ts.map |
'use strict'; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -17,89 +8,5 @@ exports.Restful = void 0; | ||
class Restful { | ||
_net; | ||
_genesisId; | ||
constructor(net, genesisId) { | ||
this.sendRawTransaction = (raw) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const resp = yield this._net.http("POST", "transactions", { | ||
body: { raw: raw }, | ||
validateResponseHeader: this._headerValidator | ||
}); | ||
return resp.id; | ||
} | ||
catch (err) { | ||
return Promise.reject({ | ||
code: error_1.ErrCode.Default, | ||
message: (0, utils_1.getErrMsg)(err) | ||
}); | ||
} | ||
}); | ||
this.getCode = (addr, revision) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const httpParams = { | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const code = yield this._net.http("GET", `accounts/${addr}/code`, httpParams); | ||
return code.code; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this.getBalance = (addr, revision) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const httpParams = { | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const acc = yield this._net.http("GET", `accounts/${addr}`, httpParams); | ||
return acc.balance; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this.getStorageAt = (addr, key, revision) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const httpParams = { | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const storage = yield this._net.http("GET", `accounts/${addr}/storage/${key}`, httpParams); | ||
return storage.value; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this.call = (callObj, revision) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const httpParams = { | ||
body: callObj, | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const outputs = yield this._net.http("POST", `accounts/*`, httpParams); | ||
const output = outputs[0]; | ||
if (output.reverted) { | ||
if (output.vmError === 'execution reverted') { | ||
const reason = (0, utils_1.decodeRevertReason)(output.data); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, reason ? `execution reverted: ${reason}` : output.vmError, output.data)); | ||
} | ||
else { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, output.vmError)); | ||
} | ||
} | ||
return output.data; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}); | ||
this._net = net; | ||
@@ -116,4 +23,119 @@ this._genesisId = genesisId; | ||
} | ||
sendRawTransaction = async (raw) => { | ||
try { | ||
const resp = await this._net.http("POST", "transactions", { | ||
body: { raw: raw }, | ||
validateResponseHeader: this._headerValidator | ||
}); | ||
return resp.id; | ||
} | ||
catch (err) { | ||
return Promise.reject({ | ||
code: error_1.ErrCode.Default, | ||
message: (0, utils_1.getErrMsg)(err) | ||
}); | ||
} | ||
}; | ||
getCode = async (addr, revision) => { | ||
try { | ||
const httpParams = { | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const code = await this._net.http("GET", `accounts/${addr}/code`, httpParams); | ||
return code.code; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
getBalance = async (addr, revision) => { | ||
try { | ||
const httpParams = { | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const acc = await this._net.http("GET", `accounts/${addr}`, httpParams); | ||
return acc.balance; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
getStorageAt = async (addr, key, revision) => { | ||
try { | ||
const httpParams = { | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const storage = await this._net.http("GET", `accounts/${addr}/storage/${key}`, httpParams); | ||
return storage.value; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
call = async (callObj, revision) => { | ||
try { | ||
const httpParams = { | ||
body: callObj, | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const outputs = await this._net.http("POST", `accounts/*`, httpParams); | ||
const output = outputs[0]; | ||
if (output.reverted) { | ||
if (output.vmError === 'execution reverted') { | ||
const reason = (0, utils_1.decodeRevertReason)(output.data); | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, reason ? `execution reverted: ${reason}` : output.vmError, output.data)); | ||
} | ||
else { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.Default, output.vmError)); | ||
} | ||
} | ||
return output.data; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
traceClause = async (opts) => { | ||
try { | ||
const httpParams = { | ||
body: opts, | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
const ret = await this._net.http("POST", 'debug/tracers', httpParams); | ||
return ret; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
traceCall = async (opts, revision) => { | ||
try { | ||
const httpParams = { | ||
body: opts, | ||
validateResponseHeader: this._headerValidator | ||
}; | ||
if (revision) { | ||
httpParams.query = { "revision": revision }; | ||
} | ||
const ret = await this._net.http("POST", 'debug/tracers/call', httpParams); | ||
return ret; | ||
} | ||
catch (err) { | ||
return Promise.reject(new eip1193_1.ProviderRpcError(error_1.ErrCode.InternalError, (0, utils_1.getErrMsg)(err))); | ||
} | ||
}; | ||
} | ||
exports.Restful = Restful; | ||
//# sourceMappingURL=restful.js.map |
/// <reference types="node" /> | ||
/// <reference types="@vechain/connex-types" /> | ||
import { RequestArguments } from "./eip1193"; | ||
export declare type ZeroBytes8 = '0x0000000000000000'; | ||
export declare type ZeroBytes20 = '0x0000000000000000000000000000000000000000'; | ||
export declare type ZeroBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000'; | ||
export declare type ZeroBytes256 = '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; | ||
export type ZeroBytes8 = '0x0000000000000000'; | ||
export type ZeroBytes20 = '0x0000000000000000000000000000000000000000'; | ||
export type ZeroBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000'; | ||
export type ZeroBytes256 = '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; | ||
export interface Net { | ||
@@ -57,3 +57,3 @@ /** base URL */ | ||
} | ||
export declare type ExplainArg = { | ||
export type ExplainArg = { | ||
clauses: Array<{ | ||
@@ -119,2 +119,3 @@ to: string | null; | ||
gasPrice: '0x0'; | ||
signature: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; | ||
} | ||
@@ -146,3 +147,3 @@ export interface RetReceipt { | ||
} | ||
export declare type TxObj = { | ||
export type TxObj = { | ||
to?: string; | ||
@@ -153,4 +154,6 @@ from?: string; | ||
gas?: string; | ||
gasPrice?: string; | ||
input?: string; | ||
}; | ||
export declare type FilterOpts = { | ||
export type FilterOpts = { | ||
address?: string | string[]; | ||
@@ -161,10 +164,24 @@ fromBlock?: string; | ||
}; | ||
export declare type ConvertedFilterOpts = { | ||
export type ConvertedFilterOpts = { | ||
range: Connex.Thor.Filter.Range; | ||
criteria: Connex.Thor.Filter.Criteria<'event'>[]; | ||
}; | ||
export declare type DelegateOpt = { | ||
export type DelegateOpt = { | ||
url: string; | ||
signer?: string; | ||
}; | ||
//# sourceMappingURL=types.d.ts.map | ||
export interface TracerOption { | ||
name: string; | ||
config: object; | ||
} | ||
export interface TraceClauseOption extends TracerOption { | ||
target: string; | ||
} | ||
export interface TraceCallOption extends TracerOption { | ||
to: string | null; | ||
value: string; | ||
data: string; | ||
caller?: string; | ||
gas?: number; | ||
gasPrice?: string; | ||
} |
@@ -22,2 +22,1 @@ /// <reference types="@vechain/connex-types" /> | ||
export declare function getErrMsg(err: any): string; | ||
//# sourceMappingURL=utils.d.ts.map |
'use strict'; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -57,3 +48,7 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
function hexToNumber(hex) { | ||
return web3_utils_1.default.hexToNumber(hex); | ||
const n = web3_utils_1.default.hexToNumber(hex); | ||
if (typeof n === 'number') { | ||
return n; | ||
} | ||
return parseInt(n); | ||
} | ||
@@ -180,3 +175,3 @@ exports.hexToNumber = hexToNumber; | ||
}; | ||
const signTransaction = (ethTx, key, provider) => __awaiter(void 0, void 0, void 0, function* () { | ||
const signTransaction = async (ethTx, key, provider) => { | ||
const clauses = [{ | ||
@@ -187,8 +182,8 @@ to: ethTx.to || null, | ||
}]; | ||
const gas = ethTx.gas || (yield provider.request({ | ||
const gas = ethTx.gas || await provider.request({ | ||
method: 'eth_estimateGas', | ||
params: [ethTx] | ||
})); | ||
}); | ||
const chainId = provider.chainTag; | ||
const best = yield provider.request({ | ||
const best = await provider.request({ | ||
method: 'eth_getBlockByNumber', | ||
@@ -208,5 +203,5 @@ params: ['latest'] | ||
const tx = new thor_devkit_1.Transaction(txBody); | ||
tx.signature = yield key.sign(tx.signingHash()); | ||
tx.signature = await key.sign(tx.signingHash()); | ||
return '0x' + tx.encode().toString('hex'); | ||
}); | ||
}; | ||
exports.signTransaction = signTransaction; | ||
@@ -221,3 +216,3 @@ function decodeRevertReason(data) { | ||
} | ||
catch (_a) { | ||
catch { | ||
return null; | ||
@@ -224,0 +219,0 @@ } |
{ | ||
"name": "@vechain/web3-providers-connex", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Implementation of the JSON-RPC provider for the VeChain Thor protocol, compatible with web3.js and ethers.js.", | ||
@@ -11,2 +11,3 @@ "main": "dist/index.js", | ||
"scripts": { | ||
"prepack": "npm run build", | ||
"build": "rm -rf dist/ && node_modules/.bin/tsc -d -p . ", | ||
@@ -44,3 +45,3 @@ "test": "nyc --reporter=lcov mocha --no-timeouts test/**/*.test.ts", | ||
"peerDependencies": { | ||
"ethers": "^5.7.2" | ||
"ethers": "^6.7.1" | ||
}, | ||
@@ -62,5 +63,5 @@ "devDependencies": { | ||
"tsconfig-paths": "^4.1.2", | ||
"typescript": "^4.5.5", | ||
"web3": "^1.7.3" | ||
"typescript": "^5.1.6", | ||
"web3": "^4.1.1" | ||
} | ||
} |
# web3-providers-connex | ||
This project implements the JSON-RPC provider defined in [EIP-1193](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md) for the [VeChain Thor protocol](https://github.com/vechain/thor). The provider is made to be compatible with [web3.js](https://github.com/ChainSafe/web3.js) and [ethers.js](https://github.com/ethers-io/ethers.js), allowing developers to use the two libs to interact with a Thor node. | ||
![Main (GH Actions)](https://github.com/vechain/web3-providers-connex/actions/workflows/unit-test-sonar-on-push.yml/badge.svg?branch=main) | ||
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=coverage)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=bugs)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=vechain_web3-providers-connex&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=vechain_web3-providers-connex) | ||
## Installation | ||
``` | ||
npm i web3-providers-connex | ||
npm i @vechain/web3-providers-connex | ||
``` | ||
@@ -11,3 +23,3 @@ ## Examples | ||
```ts | ||
import { Provider } from 'web3-providers-connex' | ||
import { Provider } from '@vechain/web3-providers-connex' | ||
@@ -46,4 +58,4 @@ // connexObj is an instance of Connex | ||
```ts | ||
import { ProviderWeb3 } from 'web3-providers-connex' | ||
import Web3 from 'web3' | ||
import { ProviderWeb3 } from '@vechain/web3-providers-connex' | ||
import { Web3 } from 'web3' | ||
@@ -55,12 +67,15 @@ const provider = new ProviderWeb3({ connex: connexObj }) | ||
```ts | ||
import * as thor from 'web3-providers-connex' | ||
import * as thor from '@vechain/web3-providers-connex' | ||
import { ethers } from 'ethers' | ||
const provider = thor.ethers.modifyProvider( | ||
new ethers.providers.Web3Provider( | ||
new thor.Provider({ connex: connexObj }) | ||
new ethers.BrowserProvider( | ||
new thor.Provider({ | ||
connex: connexObj, | ||
wallet: walletObj, // MUST provide to call [getSigner] method | ||
}) | ||
) | ||
) | ||
``` | ||
Obtaining a singner | ||
Obtaining a signer | ||
```ts | ||
@@ -74,12 +89,16 @@ const signer = provider.getSigner(address) | ||
) | ||
const contract = await factory.deploy(...args) | ||
const base = await factory.deploy(...args) | ||
await base.waitForDeployment() | ||
const contractAddress = await base.getAddress() | ||
const contract = new ethers.Contract(contractAddress, abi, signer) | ||
``` | ||
Methods `modifyProvider` and `modifyFactory` are used to bypass the Ethereum contract address computation that is incompatible with the Thor protocol. | ||
Methods `modifyProvider` and `modifyFactory` are used to patch the original code of [ethers.js](https://github.com/ethers-io/ethers.js) that is incompatible with the Thor protocol. | ||
### Request at a particular block hight | ||
APIs `eth_getBalance`, `eth_getCode`, `et_getStorageAt` and `eth_call` allow users to specify a particular block height [1]. To do that, we need to provide a `Net` object when creating a provider: | ||
APIs `eth_getBalance`, `eth_getCode`, `eth_getStorageAt` and `eth_call` allow users to specify a particular block height [1]. To do that, we need to provide a `Net` object when creating a provider: | ||
```ts | ||
import { SimpleNet } from '@vechain/connex-driver' | ||
import * as thor from 'web3-providers-connex' | ||
import Web3 from 'web3' | ||
import * as thor from '@vechain/web3-providers-connex' | ||
import { Web3 } from 'web3' | ||
import { ethers } from 'ethers' | ||
@@ -100,3 +119,3 @@ | ||
const providerEthers = thor.ethers.modifyProvider( | ||
new ethers.providers.Web3Provider( | ||
new ethers.BrowserProvider( | ||
new thor.Provider({ | ||
@@ -112,3 +131,3 @@ connex: connexObj, | ||
```ts | ||
import { Provider } from 'web3-providers-connex'; | ||
import { Provider } from '@vechain/web3-providers-connex'; | ||
@@ -155,2 +174,3 @@ const provider = new Provider({ | ||
##### `eth_isSyncing` | ||
##### `eth_requestAccounts` | ||
##### `eth_sendRawTransaction` | ||
@@ -166,6 +186,8 @@ Requiring passing a `Net` object when constructing an instance of `Provider` or `ProviderWeb3` | ||
Returning string `thor` | ||
##### `debug_traceTransaction` | ||
##### `debug_traceCall` | ||
## Implementation Notes | ||
1. Fields `blockHash` and `transactionHash` return the values of [`blockId`](https://docs.vechain.org/thor/learn/block.html#block) and [`transactionId`](https://docs.vechain.org/thor/learn/transaction-model.html#transaction-id) defined in the Thor protocol, respectively | ||
2. APIs `eth_estimateGas`, `eth_call` and `eth_getTransactionReceipt` only return information associated with the first [clause](https://docs.vechain.org/thor/learn/transaction-model.html#clauses) in a transaction | ||
2. APIs `eth_estimateGas`, `eth_call`, `eth_getTransactionReceipt`, `debug_traceTransaction` and `debug_traceCall` only return information associated with the first [clause](https://docs.vechain.org/thor/learn/transaction-model.html#clauses) in a transaction | ||
3. Unsupported returning fields (all set to zero): | ||
@@ -183,4 +205,4 @@ * `cumulativeGasUsed` | ||
[GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.html), also included | ||
in *LICENSE##### file in repository. | ||
in *LICENSE* file in repository. | ||
## References | ||
[1] [https://eth.wiki/json-rpc/API](https://eth.wiki/json-rpc/API). |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2005
200
175423
36
1