serum-community / pyserum

Pyserum is client library to interact with Serum DEX
MIT License
160 stars 61 forks source link

invalid public key input:', <solana.account.Account object at 0x7f34954d5f40> #89

Open hemantsirsat opened 3 years ago

hemantsirsat commented 3 years ago

I was implementing a buy function using pyserum and solana using the following code.

        payer=sender_keypair.public_key,
        owner=Account(sender_keypair),
        side=Side.BUY,
        order_type=OrderType.LIMIT,
        limit_price=0.5,
        max_quantity=abs(1),
        opts=TxOpts(skip_preflight=True)
    )

The following error occurs:

ValueError: ('invalid public key input:', '<solana.account.Account object at 0x7fac2a7c2cd0>')
leofisG commented 3 years ago

what is sender_keypair ?

On Sun, 10 Oct 2021 at 01:00, Hemant Sirsat @.***> wrote:

I was implementing a buy function using pyserum and solana using the following code.

    payer=sender_keypair.public_key,
    owner=Account(sender_keypair),
    side=Side.BUY,
    order_type=OrderType.LIMIT,
    limit_price=0.5,
    max_quantity=abs(1),
    opts=TxOpts(skip_preflight=True)
)

The following error occurs:

ValueError: ('invalid public key input:', '<solana.account.Account object at 0x7fac2a7c2cd0>')

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/serum-community/pyserum/issues/89, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACMFDUNZAIQPTS5BYMGWVODUGBYJFANCNFSM5FVPF3NA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Wang (Leonard) Ge Imperial College London 2021 @.*** +44 - 079-364-72284

hemantsirsat commented 3 years ago

Sender_keypair(<class 'solana.keypair.Keypair'>) is the keypair of the owner's wallet.

leofisG commented 3 years ago

can you also include the code snippet on how you read from that? Omit the actual key of course

On Sun, 10 Oct 2021 at 13:01, Hemant Sirsat @.***> wrote:

Sender_keypair is the keypair of the owner's wallet.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/serum-community/pyserum/issues/89#issuecomment-939407480, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACMFDULEEPF746BVO6KM2T3UGEM2XANCNFSM5FVPF3NA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Wang (Leonard) Ge Imperial College London 2021 @.*** +44 - 079-364-72284

hemantsirsat commented 3 years ago

Here's the code. Ignore the unnecessary imports.

from solana.keypair import Keypair
from solana.publickey import PublicKey
from solana.system_program import transfer, TransferParams, TransactionInstruction, AccountMeta
from solana.account import Account
from solana.transaction import Transaction
from solana.rpc.api import Client
from solana.rpc.types import TxOpts
from spl.token.client import Token
from pyserum.connection import conn
from pyserum.enums import OrderType, Side
from pyserum.market import Market
from pyserum.connection import get_live_markets, get_token_mints
import solana.system_program as sp
import time
import base58

PRIVATEKEYPHANTOM = AbCd123.....

def get_keypair(private_key):
    byte_array = base58.b58decode(private_key)
    return byte_array

def perform_transaction(owner_keypair,client,market):
    order = market.place_order(
        payer=owner_keypair.public_key,
        owner=Account(owner_keypair),
        side=Side.BUY,
        order_type=OrderType.LIMIT,
        limit_price=0.5,
        max_quantity=abs(1),
        opts=TxOpts(skip_preflight=True)
    )
    print(order)

if __name__ == '__main__':
    start = time.time()
    client = Client('https://api.mainnet-beta.solana.com')
    cc = conn('https://solana-api.projectserum.com')

    owner_key_pair = get_keypair(PRIVATEKEYPHANTOM)
    owner_keys = Keypair(owner_key_pair[:32])

    market = Market.load(cc,market_address,PublicKey(program_id))

    perform_transaction(owner_keys, client, market)
    end = time.time()
    print("Seconds required =",end-start)
vikulikov commented 3 years ago

I've got the same error with this part of the traceback:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/publickey.py", line 31, in __init__
    self._key = base58.b58decode(value)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/base58/__init__.py", line 124, in b58decode
    acc = b58decode_int(v, alphabet=alphabet, autofix=autofix)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/base58/__init__.py", line 104, in b58decode_int
    raise ValueError(
ValueError: Invalid character <<>

The above exception was the direct cause of the following exception:

The full traceback is:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/publickey.py", line 31, in __init__
    self._key = base58.b58decode(value)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/base58/__init__.py", line 124, in b58decode
    acc = b58decode_int(v, alphabet=alphabet, autofix=autofix)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/base58/__init__.py", line 104, in b58decode_int
    raise ValueError(
ValueError: Invalid character <<>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/vikulikov/projects/solana_test/main.py", line 28, in <module>
    market.place_order(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyserum/market/market.py", line 129, in place_order
    return self._conn.send_transaction(transaction, *signers, opts=opts)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/rpc/api.py", line 1059, in send_transaction
    txn.sign(*signers)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/transaction.py", line 262, in sign
    self.sign_partial(*signers)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/transaction.py", line 241, in sign_partial
    sign_data = self.serialize_message()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/transaction.py", line 222, in serialize_message
    return self.compile_message().serialize()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/transaction.py", line 207, in compile_message
    return Message(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/message.py", line 59, in __init__
    self.account_keys = [PublicKey(key) for key in args.account_keys]
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/message.py", line 59, in <listcomp>
    self.account_keys = [PublicKey(key) for key in args.account_keys]
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/publickey.py", line 33, in __init__
    raise ValueError("invalid public key input:", value) from err
ValueError: ('invalid public key input:', '<solana.account.Account object at 0x7fdacd13b7c0>')
leofisG commented 3 years ago

Interesting, let me take a closer look.

On Mon, 11 Oct 2021 at 18:02, Viktor Kulikov @.***> wrote:

I've got the same error with this part of the traceback:

Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/solana/publickey.py", line 31, in init self._key = base58.b58decode(value) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/base58/init.py", line 124, in b58decode acc = b58decode_int(v, alphabet=alphabet, autofix=autofix) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/base58/init.py", line 104, in b58decode_int raise ValueError( ValueError: Invalid character <<>

The above exception was the direct cause of the following exception:```

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/serum-community/pyserum/issues/89#issuecomment-939878024, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACMFDUOS3KR5GVYPNRXB22DUGKY4HANCNFSM5FVPF3NA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Wang (Leonard) Ge Imperial College London 2021 @.*** +44 - 079-364-72284

kwaibun commented 3 years ago

something like this change could work, that's all because in site-packages/solana/rpc/api.py", line 1059, in send_transaction     txn.sign(*signers) signers should be Keypair, not Account, this is a recent change https://github.com/michaelhly/solana-py/commit/4fcf707e593702940ce517f92244f5ea91bdf7ac

--- a/pyserum/market/market.py
+++ b/pyserum/market/market.py
@@ -5,6 +5,7 @@ from typing import List

 from solana.account import Account
 from solana.publickey import PublicKey
+from solana.keypair import Keypair
 from solana.rpc.api import Client
 from solana.rpc.types import RPCResponse, TxOpts
 from solana.transaction import Transaction
@@ -125,7 +126,14 @@ class Market(MarketCore):
             open_order_accounts=open_order_accounts,
             place_order_open_order_account=place_order_open_order_account,
         )
-        return self._conn.send_transaction(transaction, *signers, opts=opts)
+        new_signers: List[Keypair] = []
+        for item in signers:
+            if isinstance(item, Account):
+                new_signers.append(Keypair(item.secret_key()))
+            else:
+                new_signers.append(item)
+
+        return self._conn.send_transaction(transaction, *new_signers, opts=opts)

     def cancel_order_by_client_id(
         self, owner: Account, open_orders_account: PublicKey, client_id: int, opts: TxOpts = TxOpts()
Imaclean74 commented 3 years ago

probably better to patch market and the other libs to use Keypair instead of Account ?

hemantsirsat commented 3 years ago

I tried changing public_key() to public_key of pyserum/market.py and pyserum/core.py. Now there's a new error. pyserum/market/core.py line 149, in _prepare_order_transaction raise ValueError("Invalid payer account. Cannot use unwrapped SOL.") ValueError: Invalid payer account. Cannot use unwrapped SOL.

Imaclean74 commented 3 years ago

First attempt at replacing Account with Keypair in the PR referenced above

vikulikov commented 3 years ago

in _prepare_order_transaction raise ValueError("Invalid payer account. Cannot use unwrapped SOL.") ValueError: Invalid payer account. Cannot use unwrapped SOL. `

I believe it happens due to payer == SOL unwrapped public address. Does anybody know how to handle it? Or it is a bug? How can I trade instruments with SOL (such as selling SOL/USDC or buying SRM/SOL) in this case?

hemantsirsat commented 3 years ago

in _prepare_order_transaction raise ValueError("Invalid payer account. Cannot use unwrapped SOL.") ValueError: Invalid payer account. Cannot use unwrapped SOL. `

I believe it happens due to payer == SOL unwrapped public address. Does anybody know how to handle it? Or it is a bug? How can I trade instruments with SOL (such as selling SOL/USDC or buying SRM/SOL) in this case?

Did you find any solution?

Imaclean74 commented 3 years ago

is this still failing with the latest release ?

hemantsirsat commented 3 years ago

invalid public key input is solved. Although there's a new error. ValueError: Invalid payer account. Cannot use unwrapped SOL.

EnderElement commented 3 years ago

I'm also getting this same issue still. #95 looks to be a fix for this so I'm waiting for that.

EnderElement commented 3 years ago

I'm also getting this same issue still. #95 looks to be a fix for this so I'm waiting for that.

Turns out my issue can be fixed by simply settling funds before placing an order. Btw the payer account is your token account address, not your public key if you aren't dealing with SOL or USDC I think.

hemantsirsat commented 3 years ago

I'm also getting this same issue still. #95 looks to be a fix for this so I'm waiting for that.

Turns out my issue can be fixed by simply settling funds before placing an order. Btw the payer account is your token account address, not your public key if you aren't dealing with SOL or USDC I think.

And how did you achieve that? Can you share the snippet?

EnderElement commented 3 years ago

I'm also getting this same issue still. #95 looks to be a fix for this so I'm waiting for that.

Turns out my issue can be fixed by simply settling funds before placing an order. Btw the payer account is your token account address, not your public key if you aren't dealing with SOL or USDC I think.

And how did you achieve that? Can you share the snippet?

I'll show this with an example using the ATLAS/USDC pair Screen Shot 2021-11-17 at 1 24 24 pm

Say I want to buy the asset using USDC, I take my USDC address as the payer. If I wanted to sell the asset then the payer would be the address of the asset. This likely won't work if the payer address is your SOL wallet which will give the ValueError you got. If you want to buy something using SOL then idk how you would go about doing that. I just get my token address from raydium, you might want to instead do that by code.

atlas_market_address = PublicKey("Di66GTLsV64JgCCYGVcY21RZ173BHkjJVgPyezNN7P1K") # ATLAS/USDC
usdc_wallet = PublicKey("ANDAfNfg...13UG6PWd") # USDC
atlas_market = Market.load(cc, atlas_market_address)
atlas_market.place_order(payer=usdc_wallet,owner=Keypair(privateKey),order_type=OrderType.LIMIT,side=Side.BUY,limit_price=0.1,max_quantity=1,opts=TxOpts(skip_confirmation=False))