xf00f / web3x Goto Github PK
View Code? Open in Web Editor NEWEthereum TypeScript Client Library - for perfect types and tiny builds.
Ethereum TypeScript Client Library - for perfect types and tiny builds.
Please provide an example for eth_signTypedData method. I'm trying to use your library instead of web3 and so far it works great!
However I'm trying to implement signTypedData and don't know exactly how. I'm getting Method not found error. Having a working example would help a lot.
If no gas
is provided to Account.proptotype.sendTransaction
an exception is thrown, but not handled. In fact, any exception thrown here will lead to the same situation.
I guess the expected behavior would be for the Account
to estimate the gas by calling the provider. This is an opinionated alternative though. The simplest alternative is for the error to be forwarded to the returned PromiEvent
.
Here's a minimal production script:
import { HttpProvider } from 'web3x/providers';
import { Eth } from 'web3x/eth';
import { Account } from 'web3x/accounts';
async function main() {
const provider = new HttpProvider('http://localhost:8545');
const eth = Eth.fromProvider(provider);
const localAccount = Account.create(eth);
//This should throw something like "sender doesn't have enough funds to send tx"
await localAccount.sendTransaction({to: localAccount.address, value: 1});
}
main().catch(console.error);
web3x-codegen requires typescript at runtime, but it is in devDependencies
. So after installing web3x, web3x-codegen does not work out of the box.
Heho again! Thanks for building web3x!
When installing web3x on a Node.js 8 LTS system, I get the error
yarn install v1.13.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
error [email protected]: The engine "node" is incompatible with this module. Expected version ">= 10.0.0". Got "8.15.1"
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Retry 1/3 exited 1, retrying in 1 seconds...
yarn install v1.13.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
error [email protected]: The engine "node" is incompatible with this module. Expected version ">= 10.0.0". Got "8.15.1"
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Retry 2/3 exited 1, retrying in 2 seconds...
yarn install v1.13.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
error [email protected]: The engine "node" is incompatible with this module. Expected version ">= 10.0.0". Got "8.15.1"
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
because the dependency bigint-buffer requires Node.js 10+.
Looking at the web3x code it seams that native bigint
is also required. This limits the JS environments in which this library can be used to a few cutting edge engines. Would it be possible to use bn.js instead to make this work with Node.js 8 as well? In any case, I think the supported JS environments should be documented.
Unless I"m missing something, one cannot currently parse out the data inside transaction.input using a lot of the nice codegen features inside web3x. It would be really nice to have that ability.
Concrete use case: I have several scripts running that watch on new transactions and parse out input for particular actions. It's really fast right now as we can get all of the transactions for a particular block in one go: if we wanted to switch to parse out events we'd have to do N requests for each transaction in the request to get its receipt.
This library is amazing by the way: practically overnight I've significantly cleaned up our codebase, builds are much faster too. Thank you for all of the hard work you've put into it. ๐
In package.json
there is part
"main": "./index.js",
"types": "./index.d.ts",
but these two files don't actually exist. Because package is now spliited into subpackages e.g. web3x/eth
I guess those lines should be removed.
In Solidity version 0.5.11 (https://github.com/ethereum/solidity/releases/tag/v0.5.11), an internalType
key was added to the generated JSON ABI objects produced by the Solidity compiler.
When I compile contracts with version 0.5.10 of the Solidity compiler, I get entries like the following in the JSON ABI objects produced:
{
"constant": true,
"inputs": [
{
"name": "data",
"type": "uint256[]"
}
],
"name": "myFunction",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
}
When I compile contracts with version 0.5.11 of the Solidity compiler, I get entries like the following in the JSON ABI objects produced:
{
"constant": true,
"inputs": [
{
"internalType": "uint256[]",
"name": "data",
"type": "uint256[]"
}
],
"name": "myFunction",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
}
web3x-codegen appears to prepare the TypeScript ABI files (the MyContractAbi.ts
files generated from the Solidity contract MyContract
) by copying the entries from the Solidity compiler's generated ABI JSON files, regardless of which subsets of each entry exist in the corresponding TypeScript type definitions in web3x. Thus, the new internalType
field gets copied into the MyContractAbi.ts
files even though the web3x AbiInput
and AbiOutput
types (what I think are the web3x types for the objects in the inputs
and outputs
arrays above) don't have internalType
fields.
When I compile a project that uses the MyContract.ts
and MyContractAbi.ts
files produced when MyContract
was compiled with Solidity 0.5.11, the presence of the new internalType
key not mentioned in the web3x AbiInput
and AbiOutput
types causes the TypeScript compiler to output errors like the following:
Type '{ "internalType": string; "name": string; "type": string; }' is not assignable to type 'AbiInput'.
Type '{ "internalType": string; "name": string; "type": string; }' is not assignable to type 'AbiOutput'.
Since the entries of the inputs
and outputs
arrays for the smart contract functions are "not assignable" to the AbiInput
and AbiOutput
types, the TypeScript compiler throws additional "not assignable" errors with the enclosing ContractEntryDefinition
objects.
Given a standard ERC20 token, and its definition for web3x-codegen
to parse:
"Token": {
"source": "files",
"abiFile": "./node_modules/contracts/build/abi/Token.abi",
"initDataFile": "./node_modules/contracts/build/abi/Token.bin"
}
The generated TS file is incorrect:
totalSupply(): TxCall<string>;
Given that the ABI definition says the function returns a uin256, shouldn't this return a BN allowing for greater abstraction?
Account.prototype.sendTransaction
and Account.prototype.sendTransaction
receive Tx
objects as their first parameter. They should receive something like:
interface LocalAccountTx {
nonce?: string | number;
chainId?: string | number;
to?: string;
data?: string;
value?: string | number;
gas: string | number;
gasPrice?: string | number;
}
as the from
param doesn't make sense here, and the gas
param is required.
Hi all,
first of all, cool project you have here!
Recently I faced a potential bug. When trying to use the personal_unlockAccount method, I get an error saying the method does not exist.
A bit of investigation showed that somewhere along the way the method and parameters seem to disappear.
Unfortunately I have not yet had the time to dig in deep enough to exactly pinpoint the issue.
The problem occurs both with websocket and HTTP providers (those are the ones I tried).
Can you reproduce the error? Is there a workaround for this?
Error: The method _ does not exist/is not available
at provider.send (/home/benjamin/Desktop/ONECLICK/one-click-server/node_modules/web3x/providers/legacy-provider-adapter.js:37:35)
at module.exports.request.onreadystatechange (/home/benjamin/Desktop/ONECLICK/one-click-server/node_modules/web3x/providers/http.js:73:17)
at emitOne (events.js:116:13)
at module.exports.emit (events.js:211:7)
at module.exports.EventTarget.dispatchEvent (/home/benjamin/Desktop/ONECLICK/one-click-server/node_modules/node-http-xhr/lib/node-event-target.js:114:8)
at module.exports.NodeHttpXHR._setReadyState (/home/benjamin/Desktop/ONECLICK/one-click-server/node_modules/node-http-xhr/lib/index.js:339:8)
at module.exports.onEnd (/home/benjamin/Desktop/ONECLICK/one-click-server/node_modules/node-http-xhr/lib/index.js:482:12)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
Not quite sure of great naming, but the original web3 API for getting the block could be improved.
getBlock(number, true || false // if we want full transactions)
...could be split s.t. basically:
getBlockWithTransactions(number): BlockResponse<TransactionResponse>
getBlockWithoutTransactions(number): BlockResponse<Buffer>
One might be able to use some typescript wizardry too here and not split up the method, some typescript pseudocode:
function getBlock<TGetFullTransactions extends boolean>(blockNumber: number | string | ..., includeFullTransactions: TGetFullTransactions): TGetFullTransactions extends true ? BlockResponse<TransactionResponse> : BlockResponse<Buffer>;
... happy to submit a PR if we agree this would be a good optimization.
Hey @xf00f,
I'm opening this issue because between a few interested parties we had an open call today to discuss possible changes on EIP1193 and its release schedule. The call wasn't very representative, so nothing was decided, and we are scheduling another one.
I think you may be interested in joining the next call, or the discord channel where this is being discussed. There are also some interesting discussions going on on ethereum magicians provider ring, and you may want to check them.
Best,
Patricio
The 'uuid' package used by utils/encryption.ts
has no default export.
This produces the following error
Attempted import error: 'uuid' does not contain a default export (imported as 'uuid').
"typescript": "^4.0.5"
On version v3.0.1.
When creating an instance of a contract without specifying an address, I get the following output: "No contract address."
This seems to be because of buildMethods in Contract. It visits every function in the abi and creates an executor for each one. When doing this, it checks if the address has been defined.
Thank you for the great library, it has saved me a lot of time.
Constructors are optional for solidity contracts.
Expectation: Eth.getAccounts returns items of the type Address[]
Actuality: Eth.getAccounts returns checksum-formatted addresses in string[]
form.
Formatting wrong in:
web3x/src/eth/eth-request-payloads.ts
Line 122 in ef2ff65
Line 114 in a3ace7a
Hi @xf00f,
The EIP-1193 defines a standard javascript/typescript Ethereum provider API. It has already been implemented by MetaMask and Mist Browser, and is being implemented by web3.js.
The simpler way to implement it in web3x is having a special provider that wraps an EIP-1193 compatible one, exposing this interface. Users of web3x would have to use it in this way:
import { EthereumProviderAdapter } from 'web3x-es/providers';
import { Eth } from 'web3x-es/eth';
const provider = new EthereumProviderAdapter(window.ethereum);
const eth = Eth.fromProvider(provider);
From the user perspective it would be better to have native support, using it like this:
import { Eth } from 'web3x-es/eth';
const eth = Eth.fromProvider(window.ethereum);
This alternative feels more natural, specially when integrating with MetaMask or other dapp browsers. It may require a major refactor though.
Do you have any thought about? Any plan to implement it?
I am not sure if this is the right place to report this, but I have unsuccessfully tried to replicate this bug on other dapps which don't use web3x.
Last night there was a new update for metamask (7.7.0) that breaks "newBlockHeaders" subscription,
web3x/web3x/src/eth/send-tx.ts
Line 66 in 9b1fb49
I can confirm it works on previous versions, and that on my end I haven't changed my source code.
Hello,
I have possibly discovered error in web3x. I am using Metamask 6.6.1 and web3x 3.0.11. When I tried to sign a message via
const userAddress = Address.fromString('0x123...')
const eth = Eth.fromCurrentProvider()
const personal = new Personal(eth.provider)
const signature = await personal.sign('a2000ab', userAddress, '')
I got error MetaMask - RPC Error: TypeError: e.toLowerCase is not a function
, that happened inside of metamask. After some debugging I found that it works when i convert address to lowercased string like this:
const signature = await personal.sign('a2000ab', <any> userAddress.toString().toLowerCase(), '')
I assume function sign()
is missing this conversion to lowercase string. I could create pull request for this but I am not sure that wouldn't break other combination of Metamask + web3x versions. @xf00f can you have look at this, please?
The fact that a contract.methods.aTransactionMethod(args...).send()
is available but not a contract.methods.aTransactionMethod(args...).call()
is a big problem for us, as it is very common practice to run a call
"blank" before performing a real send
transaction.
The reason behind this sort of choice is that revert
messages cannot be read when they occur on a send
- they can only be read when using call
using direct bytecode ABI encoding.
An example of what this led us to do:
const REVERT_FUNCTION_ID = "0x08c379a0";
...
safeSendTx = async (state: State, opts: any) => {
if (!isInitialized(state)) {
throw new Error("The provider isn't ready to relay transactions.");
}
// First, simulate the transaction for free.
await this.simulateTxSend(state, opts);
// If we're here, it's unlikelly that a revert will occur, as the simulation
// didn't throw.
const tx = await state.eth.sendTransaction(opts);
const hash = await tx.getTxHash();
try {
return await tx.getReceipt();
} catch (ex) {
// Get some info about the failed transaction hash.
const fullTx = await state.eth.getTransaction(hash);
// As the transaction failed, we will try and simulate it again in the block
// it failed to try and retrieve a "revert" message.
await this.simulateTxSend(opts, fullTx.blockNumber || undefined);
throw new Error("The transaction failed without a revert message.");
}
};
simulateTxSend = async (state: State, opts: any, block?: BlockType) => {
if (!isInitialized(state)) {
throw new Error("The provider isn't ready to relay transactions.");
}
const txString = await state.eth.call(opts, block);
if (!txString.startsWith(REVERT_FUNCTION_ID)) {
return txString;
}
const enc = txString.substring(REVERT_FUNCTION_ID.length);
const dec = abiCoder.decodeParameter("string", enc);
throw new Error(dec);
};
We have to call it like this:
api
.safeSendTx(state, {
...utils.chainGasOpts,
data: transact.methods.approve(account, i).encodeABI(),
from: state.account,
to: utils.chainManifest.transact,
})
This is really cumbersome - it would be great to have access to call
even on transaction methods exactly like web3 and truffle do - allowing for shooting "blanks".
Please expose the option to call
methods of contracts that are transactions.
Why checking for outputs to define if a function is constant ?
web3x-codegen
defines here a function constant if there are outputs. Why not rather checking for:
if (definition.constant)
A function can be state-modifying even if it has output, right ? I just wanted to understand why. I can do a PR if that makes sense to use the constant
keyword of the ABI
.
I know it doesn't change anything since the solidity compiler outputs the stateMutability
parameters, but the vyper
compiler doesn't. So that would help to be vyper-compatible.
I think there is an issue with the way Web3x decodes return values.
From a solidity (ERC20 compliant) token, we have a totalSupply
method that returns an uint256
.
From our code, we go:
token.methods.totalSupply().call()
where token
is a new Token(eth, TOKEN_ADDRESS)
generated using web3x-codegen
.
The result looks like this:
index.js:155 Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas?
at ABICoder.decodeParameters (index.js:155)
at ContractFunctionEntry.decodeReturnValue (contract-function-entry.js:67)
at Tx._callee2$ (tx.js:106)
at tryCatch (runtime.js:63)
at Generator.invoke [as _invoke] (runtime.js:282)
at Generator.prototype.<computed> [as next] (runtime.js:116)
at asyncGeneratorStep (asyncToGenerator.js:3)
at _next (asyncToGenerator.js:25)
It is worth mentioning that the generated typescript code for Token.ts
looks like this:
interface TokenMethods {
totalSupply(): TxCall<string>;
...
}
Shouldn't this be a BigNumber
or something like that?
Contracts in web3x
have their abi
, eth
(provider), and default options
declared as private, so there is no way to get to these parameters used to construct the Contract. Web3js exposes these parameters as options
property. Could we get the same in web3x?
https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html#new-contract
I have a contract
with ERC721 ABI "loaded in it". Since some older contracts follow the initial draft of ERC721 they miss getApproved
and isApprovedForAll
methods. One such example is CryptoKitties contract, which fortunately implement getApproved
functionality via it's own kittyIndexToApproved
.
At some point in code I want to do this:
const regularERC721Contract = new Contract<void>(eth, erc721ABI, contractAddress)
... more code here ...
// then clone contract and to append ABI for CK function `kittyIndexToApproved`
const extraAbi: ContractEntryDefinition[] = [{
constant: true,
inputs: [
{
'name': '',
'type': 'uint256'
}
],
name: 'kittyIndexToApproved',
outputs: [
{
'name': '',
'type': 'address'
}
],
payable: false,
stateMutability: 'view' as 'view',
type: 'function' as 'function'
}]
const oldAbi = []
.concat((contract as any).contractAbi.functions)
.concat((contract as any).contractAbi.events)
.concat((contract as any).contractAbi.ctor)
.map(item => item.entry)
const newAbi: ContractAbi = new ContractAbi([
...oldAbi,
...abiToAppend,
])
const ckContract = new Contract<void>((contract as any).eth, newAbi, contract.address, (contract as any).defaultOptions)
Because of missing options
property, I have to hack my way to Contract's private properties (via casting contract to any
) that may be changed in the future.
With options
feature code will be reduced to:
const regularERC721Contract = new Contract<void>(eth, erc721ABI, contractAddress)
const extraAbi: ContractEntryDefinition[] = [{
...
}]
const newAbi: ContractAbi = new ContractAbi([
...regularERC721Contract.options.jsonInterface,
...extraAbi
])
Using Web3x, is it a recommended way to useEffect
and handlers for network ID and account changes? It's not clear whether the developer should rely on web3.js
directly.
I'm testing this module and here's the error I see when I try to compile the code.
error TS2497: Module '"../node_modules/@types/bn.js/index"' resolves to a non-module entity and cannot be imported using this construct.
1 import * as BN from 'bn.js';
This is awsome PJ!
I tried web3x-es
, then got compile errors.
It resolved after installing @types/ws
and net
.
ERROR in node_modules/web3x-es/providers/ws.d.ts(6,23): error TS2688: Cannot find type definition file for 'ws'.
node_modules/web3x-es/providers/ws.d.ts(7,10): error TS2305: Module '"/client/node_modules/isomorphic-ws/index"' has no exported member 'ClientOptions'.
node_modules/web3x-es/providers/ws.d.ts(7,31): error TS2497: Module '"/client/node_modules/isomorphic-ws/index"' resolves to a non-module entity and cannot be imported using this construct.
Hi @xf00f,
I analyzed all the dependencies from package.json
, and none of them is GPL. They are MIT, BSD, ISC and Apache2, all of them are permissive licenses.
I noticed that there's also some parts of ethers.js inlined here, but that's also MIT. I'm not sure if there are parts of this project copied from web3.js. If it's only the API, using another license should be fine.
I'm wondering what's the reason to license this project as GLPv3. IMO that would inhibit adoption, as it can't be used in proprietary software, nor in project that don't agree with GLP's copyleft or don't want to be in this same position (eg: me).
Contracts to reproduce:
TransferBug.sol
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC721/IERC721Full.sol";
import "openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
contract TransferBug is ERC721Full {
using SafeERC20 for ERC20;
constructor() public ERC721Full("transfer bug", "BUG") {
}
function testBug(uint256 amount, address tokenAddress) public {
ERC20 token = ERC20(tokenAddress);
token.safeTransferFrom(msg.sender, address(this), amount);
}
}
Token.sol
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
contract Token is ERC20 {
string public name;
string public symbol;
uint8 public decimals;
address public supplier;
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 totalSupply) public {
name = _name;
symbol = _symbol;
decimals = _decimals;
supplier = msg.sender;
_mint(supplier, totalSupply);
}
}
Simple test:
import { Token } from "../../src/contracts/cos/Token";
import { TransferBug } from "../../src/contracts/cos/TransferBug";
import { startLocalBlockchain } from "../../src/localBlockchain";
test("transferBug", async () => {
const { eth, accounts } = await startLocalBlockchain({ hostname: "127.0.0.1", port: 8500, findNextPort: true });
const from = accounts[0].address;
const token = new Token(eth);
await token
.deploy("test", "TEST", 18, 10000000)
.send({ from, gas: 40000000 })
.getReceipt();
const originalBalance = await token.methods.balanceOf(from).call();
console.log("Original balance", originalBalance);
const buggedContract = new TransferBug(eth);
await buggedContract
.deploy()
.send({ from, gas: 40000000 })
.getReceipt();
console.log("Test contract addr", buggedContract.address);
await token.methods
.approve(buggedContract.address!, 10)
.send({ from, gas: 40000000 })
.getReceipt();
const result = await buggedContract.methods
.testBug(10, token.address!)
.send({ from, gas: 40000000 })
.getReceipt();
console.log("Got test reuslt", result);
});
Error:
Returned values aren't valid, did it run Out of Gas?
at ABICoder.decodeParameters (node_modules/src/contract/abi-coder/index.ts:128:13)
at ABICoder.decodeParameter (node_modules/src/contract/abi-coder/index.ts:115:17)
at inputs.forEach (node_modules/src/contract/abi-coder/index.ts:177:20)
at Array.forEach (<anonymous>)
at ABICoder.decodeLog (node_modules/src/contract/abi-coder/index.ts:172:7)
at Object.decodeEvent (node_modules/src/contract/decode-event-abi.ts:36:34)
at ContractEventEntry.decodeEvent (node_modules/src/contract/abi/contract-event-entry.ts:62:12)
at ContractAbi.decodeAnyEvent (node_modules/src/contract/abi/contract-abi.ts:47:4)
at receipt.logs.map.log (node_modules/src/contract/sent-contract-tx.ts:38:25)
at Array.map (<anonymous>)
at SentContractTx.handleReceipt (node_modules/src/contract/sent-contract-tx.ts:38:25)
I logged the topics for the Transfer event:
[ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000627306090abab3a6e1400e9345bc60c78a8bef57',
'0x000000000000000000000000f12b5dd4ead5f743c6baa640b0216200e89b60da' ]
Looks like it is missing one topic. It is not anonymous, so it should have four: one for the hash of the signature and three for the parameters:
event Transfer(address indexed from, address indexed to, uint256 value);
This causes this line to fail because the 4th topic is not there: https://github.com/xf00f/web3x/blob/master/src/contract/abi-coder/index.ts#L176
I'm using the WebsocketProvider
and I want to listen to provider events like connect
, error
, etc...
Right now I'm using this:
import { WebsocketProvider } from "web3x/providers";
const provider = new WebsocketProvider(ws_provider_path);
provider.on("connect", () => console.log("Provider connected."));
But I keep getting this error:
Error: Legacy providers only support notification event.
So why is the WebsocketProvider
a legacy provider ? And how can I setup a non-legacy provider to listen to this kind of events ?
When building the web3x
package v4.0.5 with Typescript >= 3.7 following error occurs:
node_modules/web3x/ethers/bytes.d.ts(5,10): Error TS2440: Import declaration conflicts with local declaration of 'Arrayish'.
I am not exactly sure what is connection between the code in web3x/src/ethers/bytes.ts
and ether.js
project, but they were solving exactly the same error in ethers-io/ethers.js#622.
It seems like finally
is missing from the PromiEvent
class. I'm getting this error when trying to pull in this library to a react app that was created with CRA
Property 'then' in type 'PromiEvent<T>' is not assignable to the same property in base type 'Promise<T>'.
Type '<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => PromiEvent<...>' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<...>'.
Property 'finally' is missing in type 'PromiEvent<TResult1 | TResult2>' but required in type 'Promise<TResult1 | TResult2>'.
15 then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiEvent<TResult1 | TResult2>;
~~~~
node_modules/typescript/lib/lib.es2018.promise.d.ts:31:5
31 finally(onfinally?: (() => void) | undefined | null): Promise<T>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'finally' is declared here.
I think it makes since to add here, I can do this in a PR if you want
When I generate my contract types with web3x-codegen
I end up with MyContract.ts
and MyContractAbi.ts
as intended.
However, in some of my MyContractAbi.ts
, the ContractAbi
constructor should take an array of ContractEntryDefinition
. However some of my entries are set with a gas
parameter, which does not fit the ContractEntryDefinition
interface. See below:
export default new ContractAbi([
...
{
"name": "myFunction",
"outputs": [],
"inputs": [ ],
...
"gas": 175875
},
...
]);
Hence I got some compiler errors.
What does it depend on to set this gas parameter ? Should we add it to the ContractEntryDefinition
interface as an optional parameter ?
This is awesome work! However, I can't really use this as I rely on the support of the existing Web3 team; this repo will likely not port every commit and release, and isn't part of the main ethereum
organization.
Part of your 'why' in the readme is that the typings are not perfect. Why did you vote for porting all of Web3 to TypeScript instead of improving the existing DefinitelyTyped web3 typings (which in my mind is a pretty standard to get typings for several repos)? I totally get it if you just wanted to do this project for funsies, but I want to make sure the community at large benefits from your awesomeness as much as possible.
Will you be contributing to the DefinitelyTyped bindings as well to get those up to speed with your "lessons learned" from creating this port?
Thanks!! Also, thanks again for making this awesome port; I wish it was something I could use.
As started in #34 (comment), there is the idea of relicensing this project as MIT. I think this is a very valuable step and makes this library much more attractive than others in the Ethereum space.
I'm opening this issue
Hi
First off, I want to thank and congratulate you on this library. We were looking at web3 and found both the implementation lacking and started building our own typescript library on top of the json rpc interface. However, recently I found your library which is far more complete and of quite high quality. Nice job especially for a mostly solo effort.
I started Integrating this package into some of our code, which worked well, but I was wondering about the dependencies. We don't mirror the web3 api and actually work on a generic multi blockchain api, with some key differences, especially in key management. So, we only need a part of this code. But that brings a number of dependencies for parts we don't use.
In particular, eth-lib and contract/abi* are quite useful standalone.
I wondered if you considered a lerna monorepo approach to split into multiple package, with the same high level entry point.
If you are interested, I can make a series of pr doing a gradual transition. But I do not want to undertake such a task if you do not like the idea.
In any case, thank you for publishing this library.
Not sure what exactly causes this. I managed to reproduce the bug with a simple contract. It seems that the arguments to the contract are important, as a function with no arguments does not reproduce the bug.
Very simple contract to reproduce:
pragma solidity ^0.5.0;
contract ReproduceBug {
address test;
constructor(address _test) public {
}
function create(uint256 tokenId, address itemOwner, bytes32[] memory keys, bytes32[] memory values) public returns (bool) {
return true;
}
}
Gets built to:
import BN from "bn.js";
import { Address } from "web3x/address";
import { EventLog, TransactionReceipt } from "web3x/formatters";
import { Contract, ContractOptions, TxCall, TxSend, TxDeploy, EventSubscriptionFactory } from "web3x/contract";
import { Eth } from "web3x/eth";
import abi from "./ReproduceBugAbi";
interface ReproduceBugEvents {
}
interface ReproduceBugEventLogs {
}
interface ReproduceBugTxEventLogs {
}
export interface ReproduceBugTransactionReceipt extends TransactionReceipt<ReproduceBugTxEventLogs> {
}
interface ReproduceBugMethods {
create(tokenId: number | string | BN, itemOwner: Address, keys: string[], values: string[]): TxSend<ReproduceBugTransactionReceipt>;
}
export interface ReproduceBugDefinition {
methods: ReproduceBugMethods;
events: ReproduceBugEvents;
eventLogs: ReproduceBugEventLogs;
}
export class ReproduceBug extends Contract<ReproduceBugDefinition> {
constructor(eth: Eth, address?: Address, options?: ContractOptions) {
super(eth, abi, address, options);
}
deploy(_test: Address): TxSend<ReproduceBugTransactionReceipt> {
return super.deployBytecode("0x608060405234801561001057600080fd5b506040516020806102668339810180604052602081101561003057600080fd5b810190808051906020019092919050505050610215806100516000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c01000000000000000000000000000000000000000000000000000000009004806304d36f081461004d575b600080fd5b6101c16004803603608081101561006357600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100aa57600080fd5b8201836020820111156100bc57600080fd5b803590602001918460208302840111640100000000831117156100de57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561013e57600080fd5b82018360208201111561015057600080fd5b8035906020019184602083028401116401000000008311171561017257600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506101db565b604051808215151515815260200191505060405180910390f35b60006001905094935050505056fea165627a7a72305820ebaafbde68517ea43a3c7558394ababa863d10665bf22c9d05691dbb010a15cc0029", _test) as any;
}
}
export var ReproduceBugAbi = abi;
And a simple test I am using to reproduce it. The full setup works and when I change the name of the "create" function to "createTest" or anything else, it works!
import { startLocalBlockchain } from "@cos/blockchain";
import { Address } from "web3x/address";
import { formatBytes32String } from "web3x/ethers/utf8";
import { ReproduceBug } from "../../src/contracts/cos/ReproduceBug";
test("reverts when function name is create", async () => {
const { eth, blockchain } = await startLocalBlockchain({ hostname: "127.0.0.1", port: 8500, findNextPort: true });
const from = Address.fromString(Object.keys(blockchain.unlocked_accounts)[0]);
const buggedContract = new ReproduceBug(eth);
await buggedContract
.deploy(from)
.send({ from, gas: 40000000 })
.getReceipt();
console.log("Test contract addr", buggedContract.address);
const result = await buggedContract.methods
.create("1", Address.ZERO, [formatBytes32String("hallo")], [formatBytes32String("yoyo")])
.send({ from, gas: 40000000 })
.getReceipt();
console.log("Got test reuslt", result);
});
Using truffle v0.5.4 to build the contract and web3x v3.0.1. Did not have this issue on version 2.
When using recent versions of Metamask, it's not clear how Web3x can be used to retrieve the address of the default account.
Using window.ethereum.enable()
shows the Metamask authorization popup - how is this taken care of by Web3x?
Hi,
While working on adding some basic EIP-1193 compatibility I discovered a typing error here.
The correct type is:
error?: {
code: number;
message: string;
data?: any;
}
See section 5.1 of the JSONRPC 2.0 sepc for more info.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.