Need Help With Network.request() Https Post. Porting Python To Lua.

I’m having trouble implementing a POST request in Lua. I have a working python script that I am trying to port into lua but it seem that lua isn’t handling the POST request like I anticipated. My code makes the connection but the server returns “invalid nonce,” even when I know I’m submitting a proper nonce.  So I think my problem must be with passing parameters in the proper format.

Doc for the API https://btc-e.com/api/documentation (also has example PHP, java or obj-c code) 

I have verified that I am getting the same result from the lua crypro.hmac that the python script does, but am including the code incase I’m messing up more than I thought.

I’ve tried many, many things and think I’ve narrowed it down to my implementation of Lua network.request() parameters.  I think that my problem is with how lua handles tables as arrays and/or dictionaries, and passing those parameters on in the proper format, but honestly have no real clue after 2 days messing with this.

Any help will be greatly appreciated.

Below is some example python code from http://pastebin.com/ec11hxcP :

method name and nonce go into the POST parameters

params = {“method”:“getInfo”,
3.
          “nonce”: nonce}
4.
params = urllib.urlencode(params)
5.
 
6.

Hash the params string to produce the Sign header value

H = hmac.new(BTC_api_secret, digestmod=hashlib.sha512)
8.
H.update(params)
9.
sign = H.hexdigest()
10.
 
11.
headers = {“Content-type”: “application/x-www-form-urlencoded”,
12.
                   “Key”:BTC_api_key,
13.
                   “Sign”:sign}
14.
conn = httplib.HTTPSConnection(“btc-e.com”)
15.
conn.request(“POST”, “/tapi”, params, headers)
16.
response = conn.getresponse()
17.
 
18.
print response.status, response.reason
19.
print json.load(response)
20.
 
21.
conn.close()

my relevant Lua:

local function tapiListener( event ) if ( event.isError ) then print( "Network error!") else print ( "RESPONSE: " .. event.response ) end end local params = {} params.method = "getInfo" params.nonce = nonce --Hardcoded data to make HMAC happy - works stringdata = "nonce=" .. getnonce() .. "&" .. "method=getInfo" local hash = crypto.hmac(crypto.sha512, stringdata, BTC\_api\_secret) local headers = {} headers["Content-Type"] = "application/x-www-form-urlencoded" headers["Key"] = BTC\_api\_key headers["Sign"] = hash params.headers = headers network.request("https://btc-e.com/tapi", "POST", tapiListener, params)

Hi there, Yes, it looks to me like you’re not passing the URL parameters correctly, like you suspected. You’re trying to pass them via the params table, but instead you should URL encode them and then append them to the URL itself. The params table is only used for headers and body, not for URL parameters. By putting method and nonce as fields on the params table, they effectively don’t go anywhere. Hope this helps! - Andrew

Thanks, you’ve helped me track down the problem.  I need to start coding smarter and taking notes on things I’ve already tried.

Incase anyone gets confused like I did, my params table printed to string it looks like this:

{ headers = { Sign = "xxxxxxxx", ["Content-Type"] = "application/x-www-form-urlencoded", Key = "xxx-xxx-xxx-xxx" }, body = "nonce=1366168976&method=getInfo" }

It might not have been necessary, but I ended up using some of this (https://github.com/keplerproject/cgilua/blob/master/src/cgilua/urlcode.lua) code to encode my params table.

Hi there, Yes, it looks to me like you’re not passing the URL parameters correctly, like you suspected. You’re trying to pass them via the params table, but instead you should URL encode them and then append them to the URL itself. The params table is only used for headers and body, not for URL parameters. By putting method and nonce as fields on the params table, they effectively don’t go anywhere. Hope this helps! - Andrew

Thanks, you’ve helped me track down the problem.  I need to start coding smarter and taking notes on things I’ve already tried.

Incase anyone gets confused like I did, my params table printed to string it looks like this:

{ headers = { Sign = "xxxxxxxx", ["Content-Type"] = "application/x-www-form-urlencoded", Key = "xxx-xxx-xxx-xxx" }, body = "nonce=1366168976&method=getInfo" }

It might not have been necessary, but I ended up using some of this (https://github.com/keplerproject/cgilua/blob/master/src/cgilua/urlcode.lua) code to encode my params table.