solana verify signature with python - python

Hello im trying to authenticate users via phantom wallet but I cannot verify signature on backend.
here's my frontend code :
const response = await solana.connect();
console.log("wallet account ", response.publicKey.toString());
setWalletKey(response.publicKey.toString());
const message = new TextEncoder().encode("hello");
const signature = await solana.signMessage(message);
const resp_backend = await Axios.post("http://localhost:8000/api/auth/",{message:"hello", pub_key:response.publicKey.toString(), signature:bs58.encode(signature.signature)})
and backend on django/python:
from nacl.signing import VerifyKey
import base58
from solders.pubkey import Pubkey
def verify_signature_for_user(public_key, signature, message):
pub_key = Pubkey(public_key)
print(len(public_key))
msg = bytes(message, encoding='utf-8')
signed = bytes(signature, 'utf-8')
result = VerifyKey(pub_key).verify(smessage=msg, signature=base58.b58decode(signed))
return result
but I'm getting error of ValueError: expected a sequence of length 32 (got 44)
any ideas how to fix it?

Related

Retrieving data from 2 python scripts

This is the first script which get's data from a website:
import requests
def get_prices():
name = "SeedifyFund"
crypto_data = requests.get("https://api.pancakeswap.info/api/tokens").json()["data"]
data = None
for i in crypto_data:
current = crypto_data[i]
if current['name'] == name:
data = {
"PriceUSD": current["price"],
"PriceBNB": current["price_BNB"],
}
return data
if __name__ == "__main__":
print(get_prices())
The code above outputs the following: {'PriceUSD': '1.022239219137518991087869433174527', 'PriceBNB': '0.002452203037583603303073246037795846'}
I'm having issue an issue with the second script. I want it to use the data that it has collected above and print it in a telegram bot when the user types /price. The code for the second script:
import telegram
from telegram.ext import Updater
from telegram.ext import CommandHandler
from tracker import get_prices
telegram_bot_token = "API TOKEN"
updater = Updater(token=telegram_bot_token, use_context=True)
dispatcher = updater.dispatcher
def price(update, context):
chat_id = update.effective_chat.id
message = ""
crypto_data = get_prices()
for i in crypto_data:
bnbprice = crypto_data[i]["pricebnb"]
usdprice = crypto_data[i]["priceusd"]
message += f"1 SFUND = \n${usdprice:,.2f} USD\n{bnbprice:.3f} BNB\n\n"
context.bot.send_message(chat_id=chat_id, text=message)
dispatcher.add_handler(CommandHandler("price", price))
updater.start_polling()
When the user types /price in the telegram chat it give this error:
coin = crypto_data[i]["pricebnb"]
TypeError: string indices must be integers
Could someone tell me what I'm doing wrong and help me solve the issue. Many thanks

Can't load JSON-type message in client

I can't load JSON-type message with dictionary inside when client receives it from server
Dictionary contains: message, sender address, time of sending
When i dump dictionary to JSON and send it to client, client tries to load this dict, so he can't use data from dictionary from server and print it to user
Also, when client sending message he can write "/r" to receive data from server, that means client can receive big data at one time.
This is only parts of code with sending and receiving data from server and in client
SERVER
def serialize_data(self, sending_time, message, address,):
message_dict = {
'sending_time': sending_time,
'message': message,
'sender_address': address
}
serialized_dict = dumps(message_dict)
return serialized_dict
def send_messages(self, data_dict, address):
if enable_log:
message = f'{self.get_time()}, {data_dict["message"]}, {address}'
self.save_log(message, 'a')
message = self.serialize_data(self.get_time(), data_dict['message'], address)
for client in self.connections_list:
message = dumps(message)
client.sendall(bytes(message, encoding='utf-8'))
CLIENT
def receive_data(self,):
while True:
try:
data = self.sock.recv(2048).decode('utf-8')
print(data)
data_dict = loads(data)
for d in data_dict:
d = loads(d)
d = f"{d['sending_time']} {d['sender_address']} - {d['message']}"
print(d)
except timeout:
break
I getting this in client when i trying to receive data from server:
"{\"sending_time\": \"2019-05-17 | 21:16:32 \", \"message\": \"connected!\", \"sender_address\": \"127.0.0.1\"}""{\"sending_time\": \"2019-05-17 | 21:16:33 \", \"message\": \"abcd\", \"sender_address\": \"127.0.0.1\"}"
That is because you are calling json.dumps() twice.
def serialize_data(self, sending_time, message, address,):
message_dict = {
'sending_time': sending_time,
'message': message,
'sender_address': address
}
serialized_dict = dumps(message_dict) # -------------> first time
return serialized_dict
def send_messages(self, data_dict, address):
if enable_log:
message = f'{self.get_time()}, {data_dict["message"]}, {address}'
self.save_log(message, 'a')
message = self.serialize_data(self.get_time(), data_dict['message'], address)
for client in self.connections_list:
message = dumps(message) # ------------------> Second time
client.sendall(bytes(message, encoding='utf-8'))
Removing either one of them should fix it.

Issue with saving OAuth request token using Tweepy as part of Facebook Messenger bot

I am developing a Facebook messenger bot using Flask and want to utilize the Twitter API for a feature of the bot. I am therefore using Tweepy to simplify the process. However, I am unable to get OAuth working in my program. I believe the source of the issue is that the request token is not saving or being received properly, because when I do auth.get_access_token I get an error - either "OAuth has no object request_token" or "string indices must be integers" depending on how I'm saving the OAuth handler instance. Sometimes, it also fails to get the request_token and doesn't send the link back to the user. I tried to check this by printing out the request token in my oauth_verification() function and it was blank. I've been stuck on this for a few hours, and any help would be greatly appreciated. My code is as follows:
PAT = '[pat here]'
auth = tweepy.OAuthHandler('[key here]', '[secret here]')
auth_req_token = ''
#app.route('/', methods=['GET'])
def handle_verification():
print("Handling Verification.")
if request.args.get('hub.verify_token', '') == '[verification token]':
print("Verification successful!")
return request.args.get('hub.challenge', '')
else:
print("Verification failed!")
return 'Error, wrong validation token'
#app.route('/', methods=['POST'])
def handle_messages():
print("Handling Messages")
payload = request.get_data()
print(payload)
for sender, message in messaging_events(payload):
print("Incoming from %s: %s" % (sender, message))
parse_message(PAT, sender, message)
return "ok"
def parse_message(PAT, sender, message):
original_message = message
message = str(message.decode('unicode_escape'))
message = message.replace("?", "")
if message.isdigit():
oauth_verification(PAT, sender, original_message.decode("utf-8"))
else:
split_msg = message.split(" ")
print(split_msg)
try:
platform = split_msg[split_msg.index("followers") - 1]
does_location = split_msg.index("does") + 1
have_location = split_msg.index("have")
name = split_msg[does_location:have_location]
name = " ".join(name)
print("Name: " +name + " Platform: " + platform)
init_oauth(name, PAT, sender)
except ValueError:
reply_error(PAT, sender)
def init_oauth(name, token, recipient):
try:
redirect_url = auth.get_authorization_url()
auth_req_token = auth.request_token
r = requests.post("https://graph.facebook.com/v2.6/me/messages",
params={"access_token": token},
data=json.dumps({
"recipient": {"id": recipient},
"message": {"text": "Please login to Twitter, and reply with your verification code " + redirect_url}
}),
headers={'Content-type': 'application/json'})
except tweepy.TweepError:
print('Error! Failed to get request token.')
def oauth_verification(token, recipient, verifier):
auth.request_token = auth_req_token
try:
auth.get_access_token(verifier) # issue is here - I am able to get authentication link, but not able to get access token
api = tweepy.API(auth)
r = requests.post("https://graph.facebook.com/v2.6/me/messages",
params={"access_token": token},
data=json.dumps({
"recipient": {"id": recipient},
"message": {"text": "Successfully authenticated Twitter!"}
}),
headers={'Content-type': 'application/json'})
except tweepy.TweepError:
print('Error! Failed to get access token.')
As auth_req_token is a global variable, you need to use the global keyword to change its value in init_oauth:
def init_oauth(name, token, recipient):
global auth_req_token
try:
redirect_url = auth.get_authorization_url()
auth_req_token = auth.request_token
# ...

Python secret key encoding from API

I've been trying to use the Poloniex APIg. I get a key and secret from my account, exactly like this. Then, following the examples, I should use one of the following forms:
import poloniex
polo = poloniex.Poloniex('yourApiKeyHere','yourSecretKeyHere123')
# or
polo.APIKey = 'yourApiKeyHere'
polo.Secret = 'yourSecretKeyHere123'
By using either one of them, I get this error:
TypeError: key: expected bytes or bytearray, but got 'str'
I've tried:
polo.Secret = b'yourSecretKeyHere123'
And get:
TypeError: Unicode-objects must be encoded before hashing
So I tried:
polo.Secret = 'yourSecretKeyHere123'.encode('utf-8')
I'm a bit out of my depth here with the encoding and would also expect the API just take my secret key as a string. What am I missing?
This code will works (assuming both your Secret & APIKey exists and also that API are not IP or withdraw-only restricted):
import urllib
import urllib2
import json
import time
import hmac,hashlib
req={}
APIKey = "<my_API_key>"
Secret = "<my_secret>"
command="returnBalances"
req['command'] = command
req['nonce'] = int(time.time()*1000)
post_data = urllib.urlencode(req)
sign = hmac.new(Secret, post_data, hashlib.sha512).hexdigest()
#print sign
headers = {
'Sign': sign,
'Key': APIKey
}
ret = urllib2.urlopen(urllib2.Request('https://poloniex.com/tradingApi', post_data, headers))
jsonRet = json.loads(ret.read())
print jsonRet

Yahoo BOSS V2 authorization troubles

I'm having an awfully hard time with Yahoo's authentication/authorization. I've enabled BOSS in my account, set up a payment method, and now I'm trying to run a search using some python code:
import urllib2
import oauth2 as oauth
import time
OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"
def oauth_request(url, params, method="GET"):
params['oauth_version'] = "1.0",
params['oauth_nonce'] = oauth.generate_nonce(),
params['oauth_timestamp'] = int(time.time())
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY,
secret=OAUTH_CONSUMER_SECRET)
params['oauth_consumer_key'] = consumer.key
req = oauth.Request(method=method, url=url, parameters=params)
req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)
return req
if __name__ == "__main__":
url = "http://yboss.yahooapis.com/ysearch/web"
req = oauth_request(url, params={"q": "cats dogs"})
req_url = req.to_url()
print req_url
result = urllib2.urlopen(req_url)
I keep getting a urllib2.HTTPError: HTTP Error 401: Unauthorized exception. I can't figure out whether there's something wrong with my key, or the method of signing, or if I'm somehow tampering with my data after signing, or what the deal is. Anyone have suggestions?
I made some small changes to make your example work. See code for comments.
import urllib2
import oauth2 as oauth
import time
OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"
def oauth_request(url, params, method="GET"):
# Removed trailing commas here - they make a difference.
params['oauth_version'] = "1.0" #,
params['oauth_nonce'] = oauth.generate_nonce() #,
params['oauth_timestamp'] = int(time.time())
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY,
secret=OAUTH_CONSUMER_SECRET)
params['oauth_consumer_key'] = consumer.key
req = oauth.Request(method=method, url=url, parameters=params)
req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)
return req
if __name__ == "__main__":
url = "http://yboss.yahooapis.com/ysearch/web"
req = oauth_request(url, params={"q": "cats dogs"})
# This one is a bit nasty. Apparently the BOSS API does not like
# "+" in its URLs so you have to replace "%20" manually.
# Not sure if the API should be expected to accept either.
# Not sure why to_url does not just return %20 instead...
# Also, oauth2.Request seems to store parameters as unicode and forget
# to encode to utf8 prior to percentage encoding them in its to_url
# method. However, it's handled correctly for generating signatures.
# to_url fails when query parameters contain non-ASCII characters. To
# work around, manually utf8 encode the request parameters.
req['q'] = req['q'].encode('utf8')
req_url = req.to_url().replace('+', '%20')
print req_url
result = urllib2.urlopen(req_url)
Here is a Python code snippet that works for me against Yahoo! BOSS:
import httplib2
import oauth2
import time
OAUTH_CONSUMER_KEY = "Blah"
OAUTH_CONSUMER_SECRET = "Blah"
if __name__ == "__main__":
url = "http://yboss.yahooapis.com/ysearch/web?q=cats%20dogs"
consumer = oauth2.Consumer(key=OAUTH_CONSUMER_KEY,secret=OAUTH_CONSUMER_SECRET)
params = {
'oauth_version': '1.0',
'oauth_nonce': oauth2.generate_nonce(),
'oauth_timestamp': int(time.time()),
}
oauth_request = oauth2.Request(method='GET', url=url, parameters=params)
oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, None)
oauth_header=oauth_request.to_header(realm='yahooapis.com')
# Get search results
http = httplib2.Http()
resp, content = http.request(url, 'GET', headers=oauth_header)
print resp
print content
Im using an Authenticate Header to submit the OAuth signature.
So I decided to ditch Python and try Perl, and it Just Worked. Here's a minimal code sample:
use strict;
use Net::OAuth;
use LWP::UserAgent;
my $CC_KEY = "blahblahblah";
my $CC_SECRET = "blah";
my $url = 'http://yboss.yahooapis.com/ysearch/web';
print make_request($url, {q => "cat dog", format => "xml", count => 5});
sub make_request {
my ($url, $args) = #_;
my $request = Net::OAuth->request("request token")
->new(
consumer_key => $CC_KEY,
consumer_secret => $CC_SECRET,
request_url => $url,
request_method => 'GET',
signature_method => 'HMAC-SHA1',
timestamp => time,
nonce => int(rand 10**6),
callback => 'oob',
extra_params => $args,
protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A,
);
$request->sign;
my $res = LWP::UserAgent->new(env_proxy=>1)->get($request->to_url);
return $res->content if $res->is_success;
die $res->status_line;
}
Here's another solution, this time back in python-land. This was put together by Tom De Smedt, author of the Pattern web-mining kit.
I'll communicate with the author of python-oauth2 to see if it can be fixed.
OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"
import urllib
import hmac
import time
import random
import base64
try:
from hashlib import sha1
from hashlib import md5
except:
import sha as sha1
import md5; md5=md5.new
def hmac_sha1(key, text):
return hmac.new(key, text, sha1).digest()
def oauth_nonce(length=40):
h = "".join([str(random.randint(0, 9)) for i in range(length)])
h = md5(str(time.time()) + h).hexdigest()
return h
def oauth_timestamp():
return str(int(time.time()))
def oauth_encode(s):
return urllib.quote(s, "~")
def oauth_signature(url, data={}, method="get", secret="", token=""):
# Signature base string: http://tools.ietf.org/html/rfc5849#section-3.4.1
base = oauth_encode(method.upper()) + "&"
base += oauth_encode(url.rstrip("?")) + "&"
base += oauth_encode("&".join(["%s=%s" % (k, v) for k, v in sorted(data.items())]))
# HMAC-SHA1 signature algorithm: http://tools.ietf.org/html/rfc5849#section-3.4.2
signature = hmac_sha1(oauth_encode(secret) + "&" + token, base)
signature = base64.b64encode(signature)
return signature
q = "cat"
url = "http://yboss.yahooapis.com/ysearch/" + "web" # web | images | news
data = {
"q": q,
"start": 0,
"count": 50, # 35 for images
"format": "xml",
"oauth_version": "1.0",
"oauth_nonce" : oauth_nonce(),
"oauth_timestamp" : oauth_timestamp(),
"oauth_consumer_key" : OAUTH_CONSUMER_KEY,
"oauth_signature_method" : "HMAC-SHA1",
}
data["oauth_signature"] = oauth_signature(url, data, secret=OAUTH_CONSUMER_SECRET)
complete_url = url + "?" + urllib.urlencode(data)
response = urllib.urlopen(complete_url)
print response.read()
Here is sample code to access Yahoo! BOSS API v2 using with python-oauth as oauth liberary.
OAUTH_CONSUMER_KEY = "<oauth consumer key>"
OAUTH_CONSUMER_SECRET = "<oauth consumer secret>"
URL = "http://yboss.yahooapis.com/ysearch/web"
import urllib
import oauth.oauth as oauth
data = {
"q": "yahoo boss search",
"start":0,
"count":2,
"format":"json"
}
consumer = oauth.OAuthConsumer(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET)
signature_method_plaintext = oauth.OAuthSignatureMethod_PLAINTEXT()
signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1()
oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=None, http_method='GET', http_url=URL, parameters=data)
oauth_request.sign_request(signature_method_hmac_sha1, consumer, "")
complete_url = oauth_request.to_url()
response = urllib.urlopen(complete_url)
print "REQUEST URL => %s" % complete_url
print ""
print "RESPONSE =>"
print response.read()
I stepped into the urllib2.open code using the debugger, and found that the response has this header:
WWW-Authenticate: OAuth oauth_problem="version_rejected", realm="yahooapis.com"
So I guess I'm having some kind of version mismatch of OAuth.

Categories