Get access to the owner tokens

Hi there!
I am trying to build a tokens trading bot. I created an account to the bot in Metamask where this account will be the (SPENDER) and the user account will be the (OWNER). Now my question is :
How can the bot get access to the owners tokens without need for the owners private key? I tried to implement the Approve function (since it gives the right for the sender to do swap for the owners tokens) on the JavaScript side using Moralis runContractFunction?
and on the server side i used the bot address and private key, but this didn’t worked. any ideas pleas??

Thanks in advance

You can use getTokenBalances.

How could this help me? could you please explain more?
The idea is i want to implement SWAP functions like SWAPEXAKTTOKENSFORTOKENS for example with using approve function and i don’t want the users private key.

Sorry I misunderstood, I thought you meant reading what tokens the user has.

The user has to approve any token use for the bot or contract so you have to implement that in some way, like through a frontend. No other way other than having access or private key as you said.

What is the goal behind the ALLOWENSE AND APPROVE functions then ?
Sorry, but I understood that Allowance returns the value that the owner allows the spender to spend and it is(the value) 0 by default and can be edit by using approve function. in this case the sender can SWAP tokens from the owner wallet! AM I right or that is wrong?

Sorry if my questions was a bit silly. but i need an answer please. Could you answer me please?

Yes you are correct, you can read more here: ERC 20 - OpenZeppelin Docs

You can’t gain access to a user’s tokens unless they give you permission. You don’t want the user’s private key yes, and they wouldn’t give you their private key.

That’s why you have to ask them for permission - they would need to sign a transaction for using their wallet. This is commonly done through a frontend. For example, your app has a button saying “Approve XYZ Token spend of 100”, when the user clicks it, their MetaMask pops up and then they would sign/approve.

Thanx for your answer!
I’ve already applied the approve function on the front end and Metamask pops up asking the user for permission, but it still doesn’t work.

I will explain the logic which i follow right now. I’ve created two accounts on meta mask one for the user and the another one for the bot and the approve function asks the user to give permission for the bot to make a swap e.g. (using the bot account to make a swap on the user account )

This is my approve function:

const abi = [
{
constant: false,
inputs: [
{ internalType: “address”, name: “spender”, type: “address” },
{ internalType: “uint256”, name: “amount”, type: “uint256” }
],
name: “approve”,
outputs: [{ internalType: “bool”, name: “”, type: “bool” }],
payable: false,
stateMutability: “nonpayable”,
type: “function”
}
const approve = {
contractAddress: fromTokenAddress,
functionName: “approve”,
abi: abi,
params: {
spender: “THE BOT ADDRESS”,
amount: amount
}
};
const app = await Moralis.Web3API.native.runContractFunction(approve);
console.log(app)

and then on the server(backend) I am using the owner address to get the balance and then the bot private key to sign the transaction like the following.

sender_address = “ONER ADDRESS”

sellTokenContract = web3.eth.contract(spend, abi=sellAbi)

    #Get Token Balance
    balance = sellTokenContract.functions.balanceOf(sender_address).call()
    symbol = sellTokenContract.functions.symbol().call()
    readable = web3.fromWei(balance,'ether')

pancakeswap2_txn = contract.functions.swapExactTokensForETH(

                amount ,0,
                [   spend, to_tokenaddress],
                sender_address,
                (int(time.time()) + 1000000)
                ).buildTransaction({
                'from': sender_address,
                'gasPrice': web3.toWei('5','gwei'),
                'nonce': web3.eth.get_transaction_count(sender_address),
                })

       

    signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn, private_key='BOT PRIVATE KEY')

    tx_token = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
    print(f"Sold {symbol}: " + web3.toHex(tx_token))

could you tell me why it givs an error pleas

Thanx in advance.

What error do you get and where are you getting it?

I got this error on the terminal

Exception occurred during processing of request from (‘127.0.0.1’, 61816)
Traceback (most recent call last):
File “C:\Program Files\Python39\lib\socketserver.py”, line 316, in _handle_request_noblock
self.process_request(request, client_address)
File “C:\Program Files\Python39\lib\socketserver.py”, line 347, in process_request
self.finish_request(request, client_address)
File “C:\Program Files\Python39\lib\socketserver.py”, line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File “C:\Program Files\Python39\lib\http\server.py”, line 653, in init
super().init(*args, **kwargs)
File “C:\Program Files\Python39\lib\socketserver.py”, line 720, in init
self.handle()
File “C:\Program Files\Python39\lib\http\server.py”, line 427, in handle
self.handle_one_request()
File “C:\Program Files\Python39\lib\http\server.py”, line 415, in handle_one_request
method()
File “c:\Users\waels\Desktop\thesiscode\thesis\server\database.py”, line 75, in do_POST
trade.swapOtherTokens(data[‘user_address’],data[‘from’],data[‘till’], data[‘inamount’])
File “c:\Users\waels\Desktop\thesiscode\thesis\server\Swapmotor.py”, line 275, in swapOtherTokens
signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn, private_key=‘325c8d37cdde3ec610a396360bc469a3f132750a84bf5a3e3bee066h37r43hc4’)
File “C:\Users\waels\Desktop\thesiscode\thesis\botenv\lib\site-packages\eth_utils\decorators.py”, line 18, in _wrapper
return self.method(obj, *args, **kwargs)
File “C:\Users\waels\Desktop\thesiscode\thesis\botenv\lib\site-packages\eth_account\account.py”, line 735, in sign_transaction
raise TypeError(“from field must match key’s %s, but it was %s” % (
TypeError: from field must match key’s 0x642ca54373E44450bC79F4239b914711D70f8h3g, but it was 0xc25C9DCb43984CD99227fA7Bc482dAF1973sk83h

Looks like an issue with the sender_address going by the last error, can you log that to make sure it’s accurate. Can you also edit out your private key from your comment please.

I inserted the sender_address manually(hard coding) and it is actually the OWNER address as i said. and I did the same for the private key and I used the private key for the bot account.

I have already edited the private key before posting it (Thanx for your note :slight_smile: )

Something that causes the last reror (from field must match key’s) is an incorrect private key - can you make sure it’s correct for the sender_address or bot address.

Yes I did it. it is for the bot.
and the sender_address is the OWNER address

Does the owner address mean the user address? The call is expecting from to have your bot address. Look at the error again (from field must match key), your private key’s address doesn’t match whatever is in from. There are two different addresses, they need to be the same.

I did that and I got the following error:

Balance: 0 Cake
Swapping 0.1 Cake for REEF

Exception occurred during processing of request from (‘127.0.0.1’, 62555)
Traceback (most recent call last):
File “C:\Program Files\Python39\lib\socketserver.py”, line 316, in _handle_request_noblock
self.process_request(request, client_address)
File “C:\Program Files\Python39\lib\socketserver.py”, line 347, in process_request
self.finish_request(request, client_address)
File “C:\Program Files\Python39\lib\socketserver.py”, line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File “C:\Program Files\Python39\lib\http\server.py”, line 653, in init
super().init(*args, **kwargs)
File “C:\Program Files\Python39\lib\socketserver.py”, line 720, in init
self.handle()
File “C:\Program Files\Python39\lib\http\server.py”, line 427, in handle
self.handle_one_request()
File “C:\Program Files\Python39\lib\http\server.py”, line 415, in handle_one_request
method()
File “c:\Users\waels\Desktop\thesiscode\thesis\server\database.py”, line 75, in do_POST
trade.swapOtherTokens(data[‘user_address’],data[‘from’],data[‘till’], data[‘inamount’])
File “c:\Users\waels\Desktop\thesiscode\thesis\server\Swapmotor.py”, line 276, in swapOtherTokens
tx_token = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
File “C:\Users\waels\Desktop\thesiscode\thesis\botenv\lib\site-packages\web3\eth.py”, line 818, in send_raw_transaction
return self._send_raw_transaction(transaction)
File “C:\Users\waels\Desktop\thesiscode\thesis\botenv\lib\site-packages\web3\module.py”, line 57, in caller
result = w3.manager.request_blocking(method_str,
File “C:\Users\waels\Desktop\thesiscode\thesis\botenv\lib\site-packages\web3\manager.py”, line 198, in request_blocking
return self.formatted_response(response,
File “C:\Users\waels\Desktop\thesiscode\thesis\botenv\lib\site-packages\web3\manager.py”, line 171, in formatted_response
raise ValueError(response[“error”])
ValueError: {‘code’: -32000, ‘message’: ‘insufficient funds for gas * price + value’}

So you need to add some funds to your bot wallet address.

In this case the bot will trade for its own account and not for the users. am I right?

could i contact you on the discord? so you may have a better overview on the code? :slight_smile:

Yes unless I am not understanding how swapExactTokensForETH works; it looks like you can set the recipient address in that function.

So correct me if I’m wrong about the logic; bot gets approved access to an amount of the user’s tokens, the bot sends these tokens to PancakeSwap to get back BNB which is sent to the user. I could be way off since I’m not familiar with this sort of thing.

You can but it would be best to keep any updates in this thread so others can help as well.

yes that is the logic unless it is not necessary that the user will get BNB. the user can choose which pair of tokens to trade with.

we can talk a bit on the discord just for you get a better overview on the code and then we can complete the conversation here.

write your discord here please if it is ok for you. :slight_smile:

this is mine anyway:
wael shikh mhd#5117