Maruta
Maruta

Reputation: 1091

How to make signed API call in Swift

I am trying to do a signed API request with HMAC SHA256 signature.

How can I make the signed request? I am not able to generate the correct signature:

{"code":-1022,"msg":"Signature for this request is not valid."}

  static func binanceAccountSnapshot(timeStamp: Int) {
        
        let semaphore = DispatchSemaphore (value: 0)
        let urlWithoutSignature = "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)"
        let secretString = "aN345refdcx78iygkhbrefdoyilhukB6prefd98uoixjk(api secret)"
        let key = SymmetricKey(data: secretString.data(using: .utf8)!)
        
        let signature = HMAC<SHA256>.authenticationCode(for: urlWithoutSignature.data(using: .utf8)!, using: key)
        let signatureString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
         
        var request = URLRequest(url: URL(string: "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)&signature=\(signatureString)")!,timeoutInterval: Double.infinity)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("p4t98weflsudichjkxwtrfsduoxhckjnwe8isdokjx(api key)", forHTTPHeaderField: "X-MBX-APIKEY")
        request.httpMethod = "GET"
         
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                print(String(describing: error))
                semaphore.signal()
                return
            }
            print(String(data: data, encoding: .utf8)!)
            semaphore.signal()
        }
        task.resume()
    }

Upvotes: 2

Views: 978

Answers (1)

Sam
Sam

Reputation: 2331

Your code almost works, the string for the signature should only be the params for the url and not the whole url though (the string should only be those characters which come after the ? in the url)

  static func binanceAccountSnapshot(timeStamp: Int) {
        
        let semaphore = DispatchSemaphore (value: 0)
        let params = timestamp=\(timeStamp)
        let urlWithoutSignature = "https://api.binance.com/sapi/v1/capital/config/getall?\(params)"
        let secretString = "aN345refdcx78iygkhbrefdoyilhukB6prefd98uoixjk(api secret)"
        let key = SymmetricKey(data: secretString.data(using: .utf8)!)
        
        let signature = HMAC<SHA256>.authenticationCode(for: params.data(using: .utf8)!, using: key)
        let signatureString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
         
        var request = URLRequest(url: URL(string: "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)&signature=\(signatureString)")!,timeoutInterval: Double.infinity)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("p4t98weflsudichjkxwtrfsduoxhckjnwe8isdokjx(api key)", forHTTPHeaderField: "X-MBX-APIKEY")
        request.httpMethod = "GET"
         
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                print(String(describing: error))
                semaphore.signal()
                return
            }
            print(String(data: data, encoding: .utf8)!)
            semaphore.signal()
        }
        task.resume()
    }

Upvotes: 2

Related Questions