iOS Question KRAKEN - API

RemoRoth

New Member
Licensed User
Hi
I was trying to use the KRAKEN-API for several days (even weeks) without success, but yesterday suddenly it worked. If someone also got stuck, here is a solution which is working:


General Usage by Kraken:

NOTE: All API URLs should use the domain api.kraken.com.

Public methods can use either GET or POST.
Private methods must use POST and be set up as follows:

HTTP header:
API-Key = API key
API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

POST data:
nonce = always increasing unsigned 64 bit integer
otp = two-factor password (if two-factor enabled, otherwise not required)



B4X:
'Code module

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
   
    Private mstrKrakenURL As String = "https://api.kraken.com"
    Private mstrPathBalance As String = "/0/private/Balance"
    Private mstrResponse As String
End Sub

Public Sub getBalance()
    PostRequest(mstrKrakenURL, mstrPathBalance, "", "jobBalance")
End Sub

Sub JobDone (Job As HttpJob)
    Dim strResponse As String
   
    If Job.Success = True Then
        mstrResponse = Job.GetString
       
        Select Job.JobName
            Case "jobBalance"
                'just parse   mstrResponse   to get what you want...
               
            Case Else
               
        End Select
    Else
        strResponse = "Failed"
        Msgbox(Job.ErrorMessage,strResponse)
    End If
    Job.Release
End Sub

Public Sub PostRequest(strURL As String, strPath As String, strPropsAdditional As String, strJobName As String )
    Dim md As MessageDigest
    Dim strAPI_Key, strAPI_Secret As String
   
    Dim strNonce As String = DateUtils.UnixTimeToTicks(DateTime.Now) & "000"
   
    Dim strURI As String = strURL & strPath
   
    Dim strProps As String = "nonce=" & strNonce & strPropsAdditional
   
    Dim strNP As String = strNonce & strProps
    Dim bytesNonce() As Byte = strNP.GetBytes("utf8")
    Dim bytesSHA256Nonce() As Byte = md.GetMessageDigest(bytesNonce, "SHA-256")
   
    Dim bytesURIpath() As Byte = strPath.GetBytes("utf8")
   
    Dim z() As Byte = JoinBytes(Array(bytesURIpath, bytesSHA256Nonce))
   
    strAPI_Key = mdlSQL.getKey(0)
    strAPI_Secret = mdlSQL.getKey(1)

    Dim strUtils As StringUtils
    Dim bytesAPI_Secret() As Byte = strUtils.DecodeBase64(strAPI_Secret)
   
    Dim byteSignature() As Byte = HMACSHA512(bytesAPI_Secret, z)
    Dim strSignature As String = strUtils.EncodeBase64(byteSignature)
   
   
    Dim jobPost As HttpJob
   
    jobPost.Initialize(strJobName, Me)
    jobPost.PostString(strURI, strProps)
    jobPost.GetRequest.SetHeader("API-Key", strAPI_Key)
    jobPost.GetRequest.SetHeader("API-Sign", strSignature)
    jobPost.GetRequest.SetContentType("application/x-www-form-urlencoded")
End Sub

Private Sub JoinBytes(ListOfArraysOfBytes As List) As Byte()
    Dim size As Int
    For Each b() As Byte In ListOfArraysOfBytes
        size = size + b.Length
    Next
    Dim result(size) As Byte
    Dim index As Int
    Dim bc As ByteConverter 'ByteConverter library
    For Each b() As Byte In ListOfArraysOfBytes
        bc.ArrayCopy(b, 0, result, index, b.Length)
        index = index + b.Length
    Next
    Return result
End Sub

Public Sub HMACSHA256(key As String, input As String, key_is_hex_string As Boolean) As String
    Dim no As NativeObject = Me
    Dim keyb() As Byte
    Dim bc As ByteConverter
   
    If key_is_hex_string Then
        keyb = bc.HexToBytes(key)
    Else
        keyb = key.GetBytes("UTF8")
    End If
   
    Dim res As Object = no.RunMethod("hmacForKeyAndData256::", Array(no.ArrayToNSData(keyb), no.ArrayToNSData(input.GetBytes("utf8"))))
    Dim resb() As Byte = no.NSDataToArray(res)
    Return bc.HexFromBytes(resb).ToLowerCase
End Sub

Public Sub HMACSHA512(keyb() As Byte, inputb() As Byte) As Byte()
    Dim no As NativeObject = Me
   
    Dim res As Object = no.RunMethod("hmacForKeyAndData512::", Array(no.ArrayToNSData(keyb), no.ArrayToNSData(inputb)))
    Dim resb() As Byte = no.NSDataToArray(res)
   
    Return resb
End Sub


#if OBJC
#import <CommonCrypto/CommonHMAC.h>

- (NSData*) hmacForKeyAndData256:(NSData*)cKey :(NSData*) cData
{
  unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
  CCHmac(kCCHmacAlgSHA256, [cKey bytes], [cKey length], [cData bytes], [cData length], cHMAC);
  return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}

- (NSData*) hmacForKeyAndData512:(NSData*)cKey :(NSData*) cData
{
  unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
  CCHmac(kCCHmacAlgSHA512, [cKey bytes], [cKey length], [cData bytes], [cData length], cHMAC);
  return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
#End If
 

claudiob4

Member
Licensed User
Longtime User
Hi
I was trying to use the KRAKEN-API for several days (even weeks) without success, but yesterday suddenly it worked. If someone also got stuck, here is a solution which is working:


General Usage by Kraken:

NOTE: All API URLs should use the domain api.kraken.com.

Public methods can use either GET or POST.
Private methods must use POST and be set up as follows:

HTTP header:
API-Key = API key
API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

POST data:
nonce = always increasing unsigned 64 bit integer
otp = two-factor password (if two-factor enabled, otherwise not required)



B4X:
'Code module

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
  
    Private mstrKrakenURL As String = "https://api.kraken.com"
    Private mstrPathBalance As String = "/0/private/Balance"
    Private mstrResponse As String
End Sub

Public Sub getBalance()
    PostRequest(mstrKrakenURL, mstrPathBalance, "", "jobBalance")
End Sub

Sub JobDone (Job As HttpJob)
    Dim strResponse As String
  
    If Job.Success = True Then
        mstrResponse = Job.GetString
      
        Select Job.JobName
            Case "jobBalance"
                'just parse   mstrResponse   to get what you want...
              
            Case Else
              
        End Select
    Else
        strResponse = "Failed"
        Msgbox(Job.ErrorMessage,strResponse)
    End If
    Job.Release
End Sub

Public Sub PostRequest(strURL As String, strPath As String, strPropsAdditional As String, strJobName As String )
    Dim md As MessageDigest
    Dim strAPI_Key, strAPI_Secret As String
  
    Dim strNonce As String = DateUtils.UnixTimeToTicks(DateTime.Now) & "000"
  
    Dim strURI As String = strURL & strPath
  
    Dim strProps As String = "nonce=" & strNonce & strPropsAdditional
  
    Dim strNP As String = strNonce & strProps
    Dim bytesNonce() As Byte = strNP.GetBytes("utf8")
    Dim bytesSHA256Nonce() As Byte = md.GetMessageDigest(bytesNonce, "SHA-256")
  
    Dim bytesURIpath() As Byte = strPath.GetBytes("utf8")
  
    Dim z() As Byte = JoinBytes(Array(bytesURIpath, bytesSHA256Nonce))
  
    strAPI_Key = mdlSQL.getKey(0)
    strAPI_Secret = mdlSQL.getKey(1)

    Dim strUtils As StringUtils
    Dim bytesAPI_Secret() As Byte = strUtils.DecodeBase64(strAPI_Secret)
  
    Dim byteSignature() As Byte = HMACSHA512(bytesAPI_Secret, z)
    Dim strSignature As String = strUtils.EncodeBase64(byteSignature)
  
  
    Dim jobPost As HttpJob
  
    jobPost.Initialize(strJobName, Me)
    jobPost.PostString(strURI, strProps)
    jobPost.GetRequest.SetHeader("API-Key", strAPI_Key)
    jobPost.GetRequest.SetHeader("API-Sign", strSignature)
    jobPost.GetRequest.SetContentType("application/x-www-form-urlencoded")
End Sub

Private Sub JoinBytes(ListOfArraysOfBytes As List) As Byte()
    Dim size As Int
    For Each b() As Byte In ListOfArraysOfBytes
        size = size + b.Length
    Next
    Dim result(size) As Byte
    Dim index As Int
    Dim bc As ByteConverter 'ByteConverter library
    For Each b() As Byte In ListOfArraysOfBytes
        bc.ArrayCopy(b, 0, result, index, b.Length)
        index = index + b.Length
    Next
    Return result
End Sub

Public Sub HMACSHA256(key As String, input As String, key_is_hex_string As Boolean) As String
    Dim no As NativeObject = Me
    Dim keyb() As Byte
    Dim bc As ByteConverter
  
    If key_is_hex_string Then
        keyb = bc.HexToBytes(key)
    Else
        keyb = key.GetBytes("UTF8")
    End If
  
    Dim res As Object = no.RunMethod("hmacForKeyAndData256::", Array(no.ArrayToNSData(keyb), no.ArrayToNSData(input.GetBytes("utf8"))))
    Dim resb() As Byte = no.NSDataToArray(res)
    Return bc.HexFromBytes(resb).ToLowerCase
End Sub

Public Sub HMACSHA512(keyb() As Byte, inputb() As Byte) As Byte()
    Dim no As NativeObject = Me
  
    Dim res As Object = no.RunMethod("hmacForKeyAndData512::", Array(no.ArrayToNSData(keyb), no.ArrayToNSData(inputb)))
    Dim resb() As Byte = no.NSDataToArray(res)
  
    Return resb
End Sub


#if OBJC
#import <CommonCrypto/CommonHMAC.h>

- (NSData*) hmacForKeyAndData256:(NSData*)cKey :(NSData*) cData
{
  unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
  CCHmac(kCCHmacAlgSHA256, [cKey bytes], [cKey length], [cData bytes], [cData length], cHMAC);
  return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}

- (NSData*) hmacForKeyAndData512:(NSData*)cKey :(NSData*) cData
{
  unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
  CCHmac(kCCHmacAlgSHA512, [cKey bytes], [cKey length], [cData bytes], [cData length], cHMAC);
  return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
#End If
 
Upvote 0

claudiob4

Member
Licensed User
Longtime User
Hi RemoRoth,
I'm also trying to use the KRAKEN-API but can't connect. I used your subs but since I use B4J I had to modify the HMACSHA512. Maybe my mistake is in this version. Could anyone tell me if it is correct? Thanks.


Your HMACSHA512:
Public Sub HMACSHA512(keyb() As Byte, inputb() As Byte) As Byte()
    Dim no As NativeObject = Me
  
    Dim res As Object = no.RunMethod("hmacForKeyAndData512::", Array(no.ArrayToNSData(keyb), no.ArrayToNSData(inputb)))
    Dim resb() As Byte = no.NSDataToArray(res)
  
    Return resb
End Sub




My HMACSHA512:
Private Sub HMACSHA512(keyb() As Byte, inputb() As Byte) As Byte()
    
    Dim m As Mac
    Dim k As KeyGenerator
    k.Initialize("HMACSHA512")
    k.KeyFromBytes(keyb)
    m.Initialise("HMACSHA512", k.Key)
    m.Update(inputb)
    Dim b() As Byte
    b = m.Sign
    Return b
    
End Sub
 
Upvote 0
Top