solana-py icon indicating copy to clipboard operation
solana-py copied to clipboard

transfer problem

Open ctycode opened this issue 3 years ago • 24 comments

Hi,How to transfer tokens from one address to another

ctycode avatar May 07 '21 15:05 ctycode

Please try following this example here for now: https://github.com/michaelhly/solana-py/blob/815802fbfa6fa5f7c5c1ab1c481b7a7ce3666b2e/tests/integration/test_token_client.py#L110

I will try to create some new documentation on this..

michaelhly avatar May 07 '21 15:05 michaelhly

Please try following this example here for now:

https://github.com/michaelhly/solana-py/blob/815802fbfa6fa5f7c5c1ab1c481b7a7ce3666b2e/tests/integration/test_token_client.py#L110

I will try to create some new documentation on this..

Okay,so Where is the token written? like srm,ray image

ctycode avatar May 07 '21 15:05 ctycode

You initialize them here: https://github.com/michaelhly/solana-py/blob/815802fbfa6fa5f7c5c1ab1c481b7a7ce3666b2e/spl/token/client.py#L79

michaelhly avatar May 07 '21 15:05 michaelhly

solana-py/spl/token/client.py

Hi,I read docs but I don't understand, if I transfer USDC to another address

class TransferParams(NamedTuple):
    """Transfer token transaction params."""

    program_id: PublicKey
    """SPL Token program account."""
    source: PublicKey
    """Source account."""
    dest: PublicKey
    """Destination account."""
    owner: PublicKey
    """Owner of the source account."""
    amount: int
    """Number of tokens to transfer."""
    signers: List[PublicKey] = []
    """Signing accounts if `owner` is a multiSig."""

program_id What should I fill in? Token Address? or Associated Token Metadata? image dest: PublicKey like this : PublicKey(another address) ?

I look forward to hearing from you

thank you

ctycode avatar May 08 '21 14:05 ctycode

from solana.publickey import PublicKey
from solana.account import Account
from solana.rpc.api import Client
from spl.token.client import Token
from spl.token.contstants import TOKEN_PROGRAM_ID

payer = Account() # Your sol account
usdc_mint = PublicKey(...) # Public key of the usdc mint
conn = Client("https://devnet.solana.com")
usdc_token_client = Token(conn, usdc_mint, TOKEN_PROGRAM_ID, payer)

usdc_token_client.transfer(
            source=PublicKey(...), # PK of USDC token account you're transfering FROM
            dest=PublicKey(...), # PK of USDC token account you're transfering TO
            owner=payer, # Account that owns your source USDC token account
            amount=10000000,
            opts=TxOpts(skip_confirmation=False),
        )

michaelhly avatar May 08 '21 15:05 michaelhly

from solana.publickey import PublicKey
from solana.account import Account
from solana.rpc.api import Client
from spl.token.client import Token
from spl.token.contstants import TOKEN_PROGRAM_ID

payer = Account() # Your sol account
usdc_mint = PublicKey(...) # Public key of the usdc mint
conn = Client("https://devnet.solana.com")
usdc_token_client = Token(conn, usdc_mint, TOKEN_PROGRAM_ID, payer)

usdc_token_client.transfer(
            source=PublicKey(...), # PK of USDC token account you're transfering FROM
            dest=PublicKey(...), # PK of USDC token account you're transfering TO
            owner=payer, # Account that owns your source USDC token account
            amount=10000000,
            opts=TxOpts(skip_confirmation=False),
        )

Okay ,thank you

def transfer(
        self,
        source: PublicKey,
        dest: PublicKey,
        owner: Union[Account, PublicKey],
        amount: int,
        multi_signers: Optional[List[Account]] = None,
        opts: TxOpts = TxOpts(),
    ) -> RPCResponse:

Can amount be a decimal? like amount: float ?

ctycode avatar May 08 '21 15:05 ctycode

from solana.publickey import PublicKey
from solana.account import Account
from solana.rpc.api import Client
from spl.token.client import Token
from spl.token.contstants import TOKEN_PROGRAM_ID

payer = Account() # Your sol account
usdc_mint = PublicKey(...) # Public key of the usdc mint
conn = Client("https://devnet.solana.com")
usdc_token_client = Token(conn, usdc_mint, TOKEN_PROGRAM_ID, payer)

usdc_token_client.transfer(
            source=PublicKey(...), # PK of USDC token account you're transfering FROM
            dest=PublicKey(...), # PK of USDC token account you're transfering TO
            owner=payer, # Account that owns your source USDC token account
            amount=10000000,
            opts=TxOpts(skip_confirmation=False),
        )

I run this code response this:

{'code': -32002, 'message': 'Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction', 'data': {'err': {'InstructionError': [0, 'InvalidAccountData']}, 'logs': ['Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]', 'Program log: Instruction: Transfer', 'Program log: Error: InvalidAccountData', 'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1515 of 200000 compute units', 'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction']}}

ctycode avatar May 08 '21 15:05 ctycode

Can you post your code?

michaelhly avatar May 08 '21 16:05 michaelhly

Can you post your code?

This is my code

sender = Account(bytes(sender[:32]))
usdc_mint = PublicKey(base58.b58decode("2wmVCSfPxGPjrnMMn7rchp4uaeoTqN39mXFC2zhPdri9")) # Public key of the usdc mint
conn = Client("https://solana-api.projectserum.com")
usdc_token_client = Token(conn, usdc_mint, TOKEN_PROGRAM_ID, sender)

usdc_token_client.transfer(
            source=sender.public_key(), # PK of USDC token account you're transfering FROM
            dest=PublicKey(base58.b58decode('3zscPNbmgv6NCtXBSq8bTDpDnbiwKvobXBa8gxQmtXaX')), # PK of USDC token account you're transfering TO
            owner=sender, # Account that owns your source USDC token account
            amount=1000,
            opts=TxOpts(skip_confirmation=False),
        )

ctycode avatar May 08 '21 16:05 ctycode

Souce cannot be sender. It needs to be a usdc token account.

michaelhly avatar May 08 '21 16:05 michaelhly

Use this method to create an account first: https://michaelhly.github.io/solana-py/spl.html#spl.token.client.Token.create_account

michaelhly avatar May 08 '21 16:05 michaelhly

Use this method to create an account first: https://michaelhly.github.io/solana-py/spl.html#spl.token.client.Token.create_account

Okay, I change my code:

sender = Account(bytes(sender[:32]))
usdc_mint = PublicKey(base58.b58decode("2wmVCSfPxGPjrnMMn7rchp4uaeoTqN39mXFC2zhPdri9")) # Public key of the usdc mint
conn = Client("https://solana-api.projectserum.com")
source = Token(conn, usdc_mint, TOKEN_PROGRAM_ID, sender)
usdc_token_client = Token(conn, usdc_mint, TOKEN_PROGRAM_ID, sender)

usdc_token_client.transfer(
            source=source.create_account(owner=sender.public_key()), # PK of USDC token account you're transfering FROM
            dest=PublicKey(base58.b58decode('3zscPNbmgv6NCtXBSq8bTDpDnbiwKvobXBa8gxQmtXaX')), # PK of USDC token account you're transfering TO
            owner=sender, # Account that owns your source USDC token account
            amount=1,
            opts=TxOpts(skip_confirmation=False),
        )

But response this:

Transaction error: {'InstructionError': [1, {'Custom': 2}]}
{'code': -32002, 'message': 'Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction', 'data': {'err': {'InstructionError': [0, 'InvalidAccountData']}, 'logs': ['Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]', 'Program log: Instruction: Transfer', 'Program log: Error: InvalidAccountData', 'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1643 of 200000 compute units', 'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction']}}

What's wrong with me?

ctycode avatar May 08 '21 16:05 ctycode

Did this succeed? source.create_account(owner=sender.public_key()?

michaelhly avatar May 08 '21 19:05 michaelhly

Did this succeed? source.create_account(owner=sender.public_key()?

How to judge whether it is successful or not?

ctycode avatar May 17 '21 14:05 ctycode

Did this succeed? source.create_account(owner=sender.public_key()?

I run and response this: image and I look at: https://explorer.solana.com/tx/4EqtspBaAphnepZghqjp9sEdaB1syUkpQXDkb2XcrTHP4YzTeE4jbFueZr3M97Cwxbru3KoWFG24nZKrnf5iLwBf image So What’s the problem?

ctycode avatar May 17 '21 15:05 ctycode

I have the same problem. raise Exception("Unable to confirm transaction %s" % tx_sig) Exception: Unable to confirm transaction xxx

novrend avatar May 20 '21 05:05 novrend

https://www.reddit.com/r/solana/comments/npmfuq/error_send_transaction_spltoken_solana_web3/

You're probably trying to send USDC to a sol address, you'll need to get the usdc address from the corresponding sol address as the destination.

to test, attempt to send usdc to yourself. if it works than your code is fine and your destination address is wrong.

vcyleung avatar Jun 06 '21 01:06 vcyleung

The mint param is not Mint authority owner, it's just Token Address, FYI @ctycode

CryptoZ258 avatar Jul 01 '21 10:07 CryptoZ258

I get the error= "AttributeError: transaction feePayer required" How can this be? on the account is use as payer there is 2 SOL and also to the sending account their is SOL. I don't get want I'm doing wrong .

code:

_usdc_mint = PublicKey(base58.b58decode(SPLtokenProgramPubkey)) #mint account solana_client = Client("https://api.devnet.solana.com")

source = spl.token.client.Token(conn=solana_client, pubkey=usdc_mint, program_id=spl.token.constants.TOKEN_PROGRAM_ID, payer=account1) #account1 = Account(keypair1[:32]) usdc_token_client = spl.token.client.Token(pubkey=usdc_mint,conn=solana_client, program_id=spl.token.constants.TOKEN_PROGRAM_ID, payer=account1) print(usdc_token_client)

usdc_token_client.transfer(source=source.create_account(owner=account1.public_key()), # PK of USDC token account you're transfering FROM dest=publickey3, # PK of USDC token account you're transfering TO owner=usdc_mint, # Account that owns your source USDC token account amount=500000, opts=TxOpts(skip_confirmation=False), )_

spongehenk avatar Oct 06 '21 13:10 spongehenk

PS : I can transfer the SPL coin trough the phantom wallet

spongehenk avatar Oct 06 '21 13:10 spongehenk

owner=usdc_mint, # Account that owns your source USDC token account

the owner is your sol address. Your sol address owns the token you are transferring and will pay the sol tx fees not the usdc mint implied in your code.

...
from spl.token.constants import TOKEN_PROGRAM_ID
...

        keypair = self._keypair       
        payer = Account(keypair[:32])    #or publickey
        token_mint_key = PublicKey(token_mint) # Public key of the usdc mint
        conn = Client("https://api.mainnet-beta.solana.com/")
        token_client = Token(conn, token_mint_key, TOKEN_PROGRAM_ID, payer)
        try: 
            print (source,'begin sending', amount)
            resp = token_client.transfer(
                source=PublicKey(source), # PK of USDC token account you're transfering FROM
                dest=PublicKey(destination), # PK of USDC token account you're transfering TO
                owner=payer, # Account that owns your source USDC token account
                amount=amount,
                opts=TxOpts(skip_confirmation=True),
            )
            return resp
        except Exception as e: 
            print('token transfer failed for:', source)
            print(e)

vcyleung avatar Oct 06 '21 15:10 vcyleung

Heyo!

I am trying to send a custom SPL token I want to distribute to my holders. This is my code:

from solana.publickey import PublicKey
from solana.account import Account
from solana.rpc.api import Client
from solana.transaction import Transaction
from solana.keypair import Keypair
from spl.token.instructions import transfer, TransferParams
from spl.token.constants import TOKEN_PROGRAM_ID

client = Client("https://api.mainnet-beta.solana.com")

secret_key= [...]
    
sender = Keypair.from_secret_key(bytes(secret_key))
receiver = PublicKey("BkoXyZy4Poam3E97Urd7rmwAvcyC3tZFBap1GHvFCjdS") # TOKEN Account

amount = int(10e6 * 5)

chick_coin = PublicKey("3RXTenk2bvx5cTYY8JrN94EFi3AkYCz9tzJzE7oRhSgf") # Mainnet address
chick_acc = PublicKey("6u4vEaj59irczDu17ydB6E9DTM4XVXZErTVe9LvFyNUG")

# https://michaelhly.github.io/solana-py/spl/intro/
transaction = Transaction().add(transfer(TransferParams(
    source=chick_acc, # PK of token account you're transfering FROM
    dest=receiver, # PK of token account you're transfering TO
    owner=sender.public_key, # Account that owns your source token account
    program_id = TOKEN_PROGRAM_ID,
    amount=amount
)))

res = client.send_transaction(transaction, sender)

Obtaining next result:

{
  'jsonrpc': '2.0',
  'result': '9cmfZ1zHkxwwUMzHdNAc15Ld2y5Y1PDbRpeuPhLcniPAEFRPTQrHW2akt3cpiYUX5Sgi2rSgTVz3zQPk99jaf2h',
  'id': 2
}

But the tokens sometimes are transferred, most of the time no, and never got a bad/error result from the res...

Can you help me? @vcyleung @michaelhly

MarioProjects avatar Feb 28 '22 16:02 MarioProjects

I get this error:

solana.rpc.core.RPCException: {'code': -32002, 'message': 'Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.', 'data': {'accounts': Non e, 'err': 'AccountNotFound', 'logs': [], 'unitsConsumed': 0}}

so I assume my owner parameter is incorrect I am providing Keypair but it asks me Union[Keypair,PublicKey] Could you help me out please?

`async def spl_transaction(token_address,receiver_key, amount): async with AsyncClient(client_network) as client: account = dbAccounts.get_zen_wallet() byte_array = base58.b58decode(account["private_key"]) slicer = slice(32) byte_array32 = byte_array[slicer]

    # sender = Keypair.from_secret_key(account['secret_key'].encode("latin-1"))
    sender = Keypair.from_seed(byte_array32)
    token_client = AsyncToken(client,PublicKey(token_address),TOKEN_PROGRAM_ID,sender)
    source_account = await token_client.create_account(owner=sender.public_key)
    print(sender)
    try:
        response = await token_client.transfer(
            source= source_account,
            dest=PublicKey(receiver_key),
            owner=sender,
            amount=int(amount*pow(10,9)),
            opts=TxOpts(skip_confirmation=False)
        )
        print(response)
        if 'result' in response:
            message = "View the transaction here: https://explorer.solana.com/tx/{}".format(response['result'])
            return message
        else:
            return None

    except Exception as e:
        print('error:', e)
        return None`

ZenRepublic avatar Jul 29 '22 12:07 ZenRepublic

after downgrading to solana version 0.23 i am able to do token_client.create_account, but....

in transfer function, my "owner" seems to be incorrect. If i just enter the keypair, it says im missing something, incorrect account

pls help im desperate

ZenRepublic avatar Jul 29 '22 12:07 ZenRepublic

image

this is how i solved mine.

first check if we have a token account, if not we create one

we also get a the token account from the sender.

took me hours to figure this out through trial and error, I'm available for further clarification

Nacbotics-dev avatar Nov 16 '22 17:11 Nacbotics-dev