You might want to look into EthersJs instead of web3. It's way better for what you're trying to achieve.
One major difference between ethers.js and web3 is how they handle key
management and interaction with the ethereum blockchain. Web3 assumes
that there is a local node connected to the application. That node is
assumed to store keys, sign transactions, and interact with and read
the ethereum blockchain. In reality, this is not often the case — most
users are not running geth locally. Metamask effectively emulates that
environment through a browser application, and so most web3 apps
require Metamask to hold keys, sign transactions, and interact with
the ethereum mainnet.
Ethers.js takes a different approach that we believe gives developers
more flexibility. Ethers.js separates the “node” into two separate
roles:
A “wallet” that holds keys and signs transaction, and
A “provider” that serves as an anonymous connection to the ethereum network, checking state and sending transactions
This allows developers to manage these two roles discretely — perhaps
using Infura as the provider, and a hardware device for the wallet.