web3 / web3.js

Collection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.
https://web3js.org/
Other
19.23k stars 4.93k forks source link

Property 'address' does not exist on type 'Wallet<Web3BaseWalletAccount>' #6397

Open Jogiter opened 1 year ago

Jogiter commented 1 year ago

Expected behavior

https://github.com/web3/web3.js/blob/4.x/docs/docs/guides/basics/sign_and_send_tx/local_wallet.md

// First step: initialize `web3` instance
import Web3 from 'web3';
const web3 = new Web3(/* PROVIDER*/);

// Second step: add an account to wallet
const privateKeyString = '0x1f953dc9b6437fb94fcafa5dabe3faa0c34315b954dd66f41bf53273339c6d26';
const account = web3.eth.accounts.wallet.add(privateKeyString);

// Make sure the account has enough eth on balance to send the transaction

// Third step: sign and send the transaction
// Magic happens behind sendTransaction. If a transaction is sent from an account that exists in a wallet, it will be automatically signed.
try {
    const receipt = await web3.eth.sendTransaction({
        from: account.address,
        to: '0xe4beef667408b99053dc147ed19592ada0d77f59',
        value: '0x1',
        gas: '300000',
        // other transaction's params
    });
} catch (error) {
    // catch transaction error
    console.error(error);
}

the above code works well

Actual behavior

from: account.address, got a typescript lint error: Property 'address' does not exist on type 'Wallet'

according to the docs Wallet should be en array object. there is no property address exist. we can use get method to get the account of the wallet

const account = web3.eth.accounts.wallet.add('0xbce9b59981303e76c4878b1a6d7b088ec6b9dd5c966b7d5f54d7a749ff683387');
> Wallet(1) [
  {
    address: '0x85D70633b90e03e0276B98880286D0D055685ed7',
    privateKey: '0xbce9b59981303e76c4878b1a6d7b088ec6b9dd5c966b7d5f54d7a749ff683387',
    signTransaction: [Function: signTransaction],
    sign: [Function: sign],
    encrypt: [Function: encrypt]
  },
  _accountProvider: {
    create: [Function: create],
    privateKeyToAccount: [Function: privateKeyToAccount],
    decrypt: [Function: decrypt]
  },
  _addressMap: Map(1) { '0x85d70633b90e03e0276b98880286d0d055685ed7' => 0 },
  _defaultKeyName: 'web3js_wallet'
]

account.get(0);

Steps to reproduce the behavior

  1. [First step]
  2. [Second step]
  3. [and so on...]

Logs

Environment

Muhammad-Altabba commented 1 year ago

Many thanks @Jogiter for opening an issue and a PR as well. We will discuss in the team whether we will keep this and update the documentation. Or to revert back to the 1.x behavior. Just a hint for your PR: do not call .get(0) as it could be a previously added wallet. But maybe use [account.address]

Jogiter commented 1 year ago

Thanks for the hint! i am new to web3.js, As the documentation is not the latest one, i will close this and waiting for the new document

Muhammad-Altabba commented 1 year ago

Hi @Jogiter , Thanks for your contribution to web3.js. Related to this issue and your good MR. I would like to discuss regarding the wallet.add(...) method. Currently, it is not easy for the user to get the index or the public key of an account after it has been added using the private key. This is in particular difficult to manage for the user if he tried to add the same account twice. Like in the following scenario:

  1. wallet.add(privateKey1).get(0) // this will work
  2. wallet.add(privateKey2).get(1) // this will work
  3. wallet.add(privateKey1).get(2) // this will not work as there is nothing at index 2 because the account was already added at is only available at index 0.

So, I would like to take the input from the team. And then someone will implement it. And it would be great if it was you to add and test... My suggestion is to go with either of those:

jdevcs commented 1 year ago

After a team discussion we decided that we will add function for backward compatibility for this without breaking 4.x.