Get user's wallet address in web3.js - blockchain

I need to call an API that requires the user's wallet address. However, I can only get wallet's accounts by web3.eth.getAccounts() but not the wallet address.
I am using WalletConnect and was able to create web3 instance.
Thanks!

You need to use requestAccounts and ask the permission from the user to access their wallet addresses.
Due to privacy reasons, the website cannot do this by default.
Also, you need to set up your Web3 properly with the wallet in the order it to work. Because your question did not contain any example code or repeatable example, it is not possible to tell if you are doing it properly.

Related

Reason for using web3 signature request

Many dapps such as opensea requests for sinature request as user's authentication.
Is this primarily for off-chain database access and gaining access token or cookie?
If my dapp does not use off-chain DB, can I skip it?
I just have a simple buy token flow and wondering if this is necessary because i've seen most of the dapps are utilising signature request.
It is not going to hurt you. You are just proving that you have access to the private keys. what happens is the server retrieves an account address from the signature and checks if the retrieved account is the same as the one sent to the server. The signature request adds trustability to the website.
In db example, if the user information is stored and retrieved by the account address, you can see the user information and have access to the private routes.
Or let's say a user uploads an unsafe image to the website and sends an arbitrary address to the server. Now website will ban this sent address not the user's address.

How to create a transaction using web3 or ethers.js without setting private_key

What i am trying to do:
Building a small app that allows a user to purchase a service for a set amount of tokens. For example, 100 tokens for service A, 500 tokens for service B. This will be for a custom token on the harmony blockchain.
What i know:
I already know how to connect to metamask and get the users address. Signer and provider are available to me.
What confuses me:
Examples and documentation all refer to a private_key and creating a wallet, i don't need to do that, i need to use the users existing wallet.
What i need to do:
Prompt a transaction in the user wallet (harmony one or metamask) for a set amount of tokens.
Check if the user has required balance (seems trivial knowing i can read their balance).
Make the transaction. Also seems ok after reading the docs.
Get a receipt, then call a callback/my code. Again, seems ok after reading the docs.
All pretty straight forward, but again - every document i read always refers to setting a private key - surely i don't need to do this?
A transaction always needs to be signed by a private key generating the sender address. Otherwise it's rejected by the network.
Examples and documentation all refer to a private_key and creating a wallet, i don't need to do that, i need to use the users existing wallet.
every document i read always refers to setting a private key - surely i don't need to do this?
A backend approach is to import the private key to the app and use it to sign the transaction.
However, there's also a frontend approach: Send a request to a wallet browser extension to sign the transaction and broadcast it to the network. The wallet extension then pops up a window and lets the user chose whether they want to sign the transaction (with their private key, not shared with the app) and broadcast it - or not.
You can find an example of such request in the MetaMask docs page.
An advantage of this approach is that your app doesn't need to ask for the user's private key. A disadvantage is that if the user haven't installed a browser wallet compatible with your app, they can't send the transaction (or at least not so easily).
Note: I'm not familiar with the Harmony wallet, but I'm assuming it works in a similar way as MetaMask - because Harmony is an EVM-compatible network, and MetaMask only supports EVM-compatible networks.

How to deal with "Only the owner of the contract can update the smart contract"

I am developing a smart contract that holds user information. The problem is that when I try to update the user information from the address that did not deployed the contract, the request is successful but there is no change in the user information. But when I change the user information from the address that deployed the contract it changes the user's information for all the users. Like the change is reflected on all the accounts regardless of the account being different.
function setUserName(string memory _userName) public {
users[msg.sender].userName = _userName;
}
This is my function that updates the user info. I believe that "msg.sender" is the one that is calling the contract and not the one that deployed the contract. I am using metamask and ganache for accounts. The first account is added to metamask in chrome browser and the second account is added to metamask in mozilla firefox.
Steps to reproduce username bug:
Open two different browsers
Start ganache server
In browser one add first address's private key to the metamask in
order to add ETH
In browser two add second address's private key to the metamask in
order to add ETH
Deploy the contracts with " truffle migrate --reset "
It will migrate the contracts with the first address in ganache
From the browser two try to update the username. You will se that
the update was successful but the username was not update (even
after refresh).
Now from browser one update the username by going to the settings
page. You will see that the username is updated and this change is
also reflected on the browser two, regardless of the address being
changed from the browser one's.
Same happens when we try to obtain points by exchanging tokens. From browser one the request is successful but from browser two it throws an error indicating that "ERC20: transfer amount exceeds balance". Even the user has token in their account.
The problem was the data was being saved correctly but when fetching the records solidity was assigning msg.sender to the creator of the contract not the one who sent the transaction. So, in order to deal with this I am sending the user address from frontend in the call function and receiving the address as a parameter in the respective functions. So instead of using the msg.sender I am using the address that I am receiving from frontend.

Verifying a crypto (BSC) address belongs to someone

I am setting up a service where users will pay by sending crypto to a particular address but i need some way to verify that the user is the owner of the address they say they sent it from without it being complicated on the users end.
If I assume the user is using Metamask, there are a variety of signature methods Metamask allows you to do to verify the user owns the address. The specific methods vary, but the basic idea is that it asks the user to sign a message with their private key for the address, and then verifies that the signature is valid. One API for this is described here:
https://medium.com/metamask/scaling-web3-with-signtypeddata-91d6efc8b290
Since Metamask supports BSC and it is generally ETH compatible, I would assume the same functions would work for a BSC address. I'm not familiar enough with every BSC wallet (such as the Trust Wallet) to know if they have similar signing features, they may. In any case, the user's wallet would need to have a feature that allows for this kind of signing for this type of verification to be done--it may not be possible if you are interacting with a user that just has a mobile light wallet with limited features for only sending/receiving.

Stripe identity verification storage

I am reading the documentation regarding stripe verification for managed accounts and I am wondering if it is a good idea to store them as well (as a backup) on a private place where my application has access (like a private bucket on S3 or in a private server)?
I'd recommend against saving any sensitive info on your end such as their SSN, a copy of their government id or their bank account details. The best solution here is to send the details to Stripe directly as they will store it on their end and not log any of it beyond tracking that you provided those info.
You then listen for account.updated events on your Connect webhook endpoint setup in your platform. This will tell you whether Stripe needs more info from that user if fields_needed is set and what delay you have to provide the required details based on verification[due_by].
You can also use properties like legal_entity[ssn_last_4_provided] to know if you've already sent that information to Stripe or if they might need it. This can be found in the docs here