Callback in MetaMask

Hello,
Could you tell me, please, how can I get an answer about the status of the transfer?
Do you have something like a callback, how does it work in card acquiring?

The task is simple: it is necessary to implement the transfer of tokens from one wallet to another. But have a problem with obtaining the transfer status, so that on our side we could assign a successful / unsuccessful status to this transfer.

Help, please, to understand.

2 Likes

@rc_plt

Hello! Welcome to the MetaMask community !

Why complicate your life with callbacks ))
You may use promises (async/await) to handle translation status easily

try {
      transfer (await)
    } catch (error) {
      throw new Error(error.message);
      //unsuccessful
    } finally {
      immediately update state after transfer
      // successful 
    }

If you don’t quite understand how it works, I can provide more detailed code. :smirk_cat:
Cheers)

4 Likes

If not difficult, then please send more detailed code)

2 Likes

@rc_plt

Of course.

Let’s imagine that we have an asynchronous function for interacting with a contract (buying a product for example) :

const purchase = async (itemId, priceInWei) => {
    try {
      return await contract.methods
        .purchase(itemId)
        .send({ from: account.account, value: priceInWei });
    } catch (error) {
      throw new Error(error.message);
    } finally {
        // change state immediately after any tx
    }
  };

This function is a promise, so it can be in 3 states:

pending: initial state, neither fulfilled nor rejected.
fulfilled: meaning that the operation was completed successfully.
rejected: meaning that the operation failed .

Thanks to these states, you can broadcast transaction status changes directly to the UI.

3 Likes

For simplicity, you may use the “react-toastify” library, a function from which takes a promise as an argument and renders the result you need:

toast.promise(purchase, {
  pending: {
    render() {
      return <div>Waiting...</div>;
    },
  },
  success: {
    render({ data }) {
      return (
        <div>
            // data.transactionHash
        </div>
      );
    }
  },
  error: {
    render({ data }) {
      return (
        <div>
             // data.message 
        </div>
      );
    }
  }
})
2 Likes

@rc_plt

I want to add that this is an example for review, and not a working version. You need to learn more about how this library works.

So if you have any questions, I’d be happy to answer.:wink:

3 Likes

Thank you very much!
Now let’s try to deal with all this.
If we have additional questions, I will definitely ask them through the “Reply” button))

2 Likes

@rc_plt Cheers mate :clinking_glasses:

2 Likes

Hello,
I apologize for such a primitive question, but I can not find an answer to it.
How to make a transfer not in the main network currency: BNB (BEP-20), ETH (Ethereum) but in any other? For example, how to transfer BUSD currency?

Let me describe the case a bit:
It will be something like a payment page, where the user will have to pay with a certain currency, for example, busd.
Payment will not be made through a smart contract, but simply as a transfer from one wallet to another.
How to make a transfer from one wallet to another in the main currencies of the network - I figured it out, but I can’t find how to send other tokens anywhere.

Hello! Welcome to the MetaMask community !)

Are you writing your own wallet application?

For a better understanding of how tokens ‘work’ under the hood, you should familiarize yourself with the ERC-20 standard. The open source library openZeppelin is perfect for this.

You need to interact with the smart contract of the token you want to transfer to another address.

In code this look like this:

ERC20(tokenMappingInYourWallet[ticker].tokenAddress).transfer(addressTransferTo, amount)

3 Likes

We are making an interface so that users can pay for goods/services using MetaMask, but payment will be made by direct transfer of tokens to the seller’s wallet.

1 Like

Excellent. If you encounter difficulties, you can provide your code and screenshots of error logs

2 Likes

Here you were talking about this library, right?
docs. openzeppelin. com/contracts/4.x/

yes, specifically ERC-20 standard

2 Likes

Thanks for the help! Let’s try to figure it out)

2 Likes

Hello!
Could you help with such a question?
How to implement the ability to connect a wallet and other actions depending on the network ID?
For example, if the network ID is 56, then start connecting the wallet / transfer, etc., and if not, then give an error.
I am using this example web3.eth.getChainId().then(console.log);

61
but I don’t understand how to apply the result to this or that rule(

2 Likes

@rc_plt hello again )

When initializing the application, you need to determine the current web3 provider and a web3 instance:

useEffect(() => {
    const loadProvider = async () => {
      const provider = await detectEthereumProvider()

      if (provider) {
        const web3 = new Web3(provider);
        setListener(provider);

        setApi({
          provider,
          web3
        });
      } else {
        console.error("gotta be install metamask");
      }
    };
    loadProvider();
  }, []);

The listener function will help you with automatic page reloading in case of network switch in MetaMask:

  const setListener = provider => {
    provider.on("chainChanged", _ => window.location.reload());
  };

Next, you must pass the value set in setApi to the entire application (memoize this to improve performance!), For example, through the context or a convenient state manager for you.

Just for example:


<Web3.Provider value={Api}>{your application}</Web3.Provider>
1 Like

As for displaying the interface based on the current network, for convenience, you can create a hook:

const NETWORKS = {
  1: "Ethereum Main Network",
  56: "Binance Smart Chain",
};

export const handler = web3 => {
  const targetChain = NETWORKS[process.env.CHAIN_YOU_WANNA];

  const { data, error } = useSWR(
    () => (web3 ? "web3/network" : null),
    async () => {
      const chainId = await web3.eth.getChainId();
      if (!chainId) {
        throw new Error("Gotta refresh page.");
      }
      return NETWORKS[chainId];
    }
  );

  return {
      network: data,
      target: targetChain,
  };
};

Check out the requests library, it gives an amazing UI ))

Now through this hook you can access values ​​anywhere in your application:

const { network, target } = useNetwork(web3);
 {network != target && (
              <div>
                <div>Connected to wrong network.</div>
                {`Connect to: ${network}`}
                {`Gotta be Connect to: ${target}`}
              </div>
2 Likes

Thanks a lot for the detailed answer!

3 Likes