Swift) 업비트(Upbit) API 이용하기
아쉬운점은 Node, Python, Ruby, Java 에 대해서만 예제를 제공하고 있어서 swift로 예제를 작성 했습니다.
업비트의 API는 크게 EXCHANGE API, QUOTATION API로 2가지가 존재합니다. QUOTATION API의 경우 큰 문제없이 GET 메소드로 request를 요청하면 됩니다. 문제는 EXCHANGE API인데 주문 API의 경우 업비트를 통해서 access key와 secret key를 이용해 토큰을 생성해 API를 요청해야하기 때문에 다소 까다롭습니다.
업비트의 토큰 경우 JWT(https://jwt.io) 형식을 따릅니다. Swift에는 타 언어처럼 jwt라이브러리를 제공하고 있지 않아서 JWT토큰을 이용하기 위해서 IBM에서 개발된 Swift-JWT(https://github.com/Kitura/Swift-JWT)를 이용하고 API 요청을 위해서 Alamofire(https://github.com/Alamofire/Alamofire)을 이용합니다.
upbit에서 사용중이 Payload의 구성은 다음과 같기 때문에 Swift-JWT에서 제공하는 Claims protocol을 이용해서 payload를 만들어줍니다.
1 2 3 4 5 6 7 | struct Payload: Claims { let access_key: String let nonce: String let query_hash: String let query_hash_alg: String } | cs |
1 2 3 4 5 6 7 8 9 10 11 1 13 14 15 16 17 | func getAccounts() { let accessKey = "UPBIT_OPEN_API_ACCESS_KEY" let secretKey = "UPBIT_OPEN_API_SECRET_KEY" let url = "https://api.upbit.com/v1/accounts" var jwt = JWT(claims: Payload(access_key: accessKey, nonce: UUID().uuidString), query_hash: "", query_hash_alg: "SHA512") let signedJWT = try! jwt.sign(using: .hs256(key: secretKey.data(using: .utf8)!)) let authenticationToken = "Bearer " + signedJWT AF.request(url, headers: ["Authorization": authenticationToken]) .responseString { response in print(response) } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | func ordersChance() { let accessKey = "UPBIT_OPEN_API_ACCESS_KEY" let secretKey = "UPBIT_OPEN_API_SECRET_KEY" let url = "https://api.upbit.com/v1/orders/chance" let query = ["market": "KRW-BTC"] var components = URLComponents() components.queryItems = query.map { URLQueryItem(name: $0, value: $1) } let requestString = components.query!.digest(using: .sha512) var jwt = JWT(claims: Payload(access_key: accessKey, nonce: UUID().uuidString, query_hash: requestString, query_hash_alg: "SHA512")) let signedJWT = try! jwt.sign(using: .hs256(key: secretKey.data(using: .utf8)!)) let authenticationToken = "Bearer " + signedJWT AF.request("https://api.upbit.com/v1/orders/chance", parameters: query, headers: ["Authorization": authenticationToken]) .responseString { response in print(response) } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | func order() { let accessKey = "UPBIT_OPEN_API_ACCESS_KEY" let secretKey = "UPBIT_OPEN_API_SECRET_KEY" let url = "https://api.upbit.com/v1/orders" let query = ["market": "KRW-BTC", "side": "bid", "volume": "0.00228319", "price": "56219000", "ord_type": "limit"] var components = URLComponents() components.queryItems = query.map { URLQueryItem(name: $0, value: $1) } let requestString = components.query!.digest(using: .sha512) var jwt = JWT(claims: Payload(access_key: accessKey, nonce: UUID().uuidString, query_hash: requestString, query_hash_alg: "SHA512")) let signedJWT = try! jwt.sign(using: .hs256(key: secretKey.data(using: .utf8)!)) let authenticationToken = "Bearer " + signedJWT var request = URLRequest(url: URL(string: url)!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue(authenticationToken, forHTTPHeaderField: "Authorization") do { try request.httpBody = JSONSerialization.data(withJSONObject: query, options: []) } catch { print("http Body Error") } AF.request(request) .responseString { response in print(response.description) } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | func orders() { let accessKey = "UPBIT_OPEN_API_ACCESS_KEY" let secretKey = "UPBIT_OPEN_API_SECRET_KEY" let url = "https://api.upbit.com/v1/orders/chance" let query = ["market": "KRW-BTC"] let uuids = ["216d955b-2f81-4776-9fc9-1b3f7af42e1a", "c0752957-d7c1-4a9c-85bc-0072651b4f9f"] let uuidsString = uuids.compactMap({ "uuids[]=" + $0}).joined(separator: "&") let queryString = query.compactMap({ $0.key + "=" + $0.value }).joined(separator: "&") let queryHashString = queryString + "&" + uuidsString let requestString = queryHashString.digest(using: .sha512) var jwt = JWT(claims: Payload(access_key: accessKey, nonce: UUID().uuidString, query_hash: requestString, query_hash_alg: "SHA512")) let signedJWT = try? jwt.sign(using: .hs256(key: secretKey.data(using: .utf8)!)) let authenticationToken = "Bearer " + signedJWT! AF.request(url + "?" + queryHashString, headers: ["Content-Type": "application/json", "Authorization": authenticationToken]) .responseString { response in print(response) } } | cs |
댓글 없음: