Skip to content

Commit

Permalink
Merge pull request #25 from KeystoneHQ/evm
Browse files Browse the repository at this point in the history
Support evm
  • Loading branch information
renfengshi authored Jul 18, 2023
2 parents f398455 + 8551e61 commit f952869
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 5 deletions.
10 changes: 5 additions & 5 deletions Library/URRegistryFFI.xcframework/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libur_registry_ffi.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libur_registry_ffi.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const char* parse_sol_signature(struct ExternError*, const char* ur_type, const
const char* generate_cosmos_sign_request(struct ExternError*, const char* request_id, const char* sign_data, const int data_type, const char* accounts, const char* origin);
const char* parse_cosmos_signature(struct ExternError*, const char* ur_type, const char* cbor_hex);

// Cosmos
const char* generate_evm_sign_request(struct ExternError*, const char* request_id, const char* sign_data, const int data_type, const int custom_chain_identifier, const char* account, const char* origin);
const char* parse_evm_signature(struct ExternError*, const char* ur_type, const char* cbor_hex);

// Tron
const char* generate_tron_sign_request(struct ExternError*, const char* request_id, const char* sign_data, const char* path, const char* xfp, const char* token_info, const char* origin, const int64_t timestamp);
const char* parse_tron_signature(struct ExternError*, const char* ur_type, const char* cbor_hex);
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const char* parse_sol_signature(struct ExternError*, const char* ur_type, const
const char* generate_cosmos_sign_request(struct ExternError*, const char* request_id, const char* sign_data, const int data_type, const char* accounts, const char* origin);
const char* parse_cosmos_signature(struct ExternError*, const char* ur_type, const char* cbor_hex);

// Cosmos
const char* generate_evm_sign_request(struct ExternError*, const char* request_id, const char* sign_data, const int data_type, const int custom_chain_identifier, const char* account, const char* origin);
const char* parse_evm_signature(struct ExternError*, const char* ur_type, const char* cbor_hex);

// Tron
const char* generate_tron_sign_request(struct ExternError*, const char* request_id, const char* sign_data, const char* path, const char* xfp, const char* token_info, const char* origin, const int64_t timestamp);
const char* parse_tron_signature(struct ExternError*, const char* ur_type, const char* cbor_hex);
Expand Down
Binary file not shown.
29 changes: 29 additions & 0 deletions Sources/KeystoneSDK/Chain/KeystoneEvmSDK.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// KeystoneEvmSDK.swift
//
//
// Created by Renfeng Shi on 2023/7/17.
//

import Foundation
import URRegistryFFI
import URKit


public class KeystoneEvmSDK: KeystoneBaseSDK {

public func parseSignature(ur: UR) throws -> Signature {
let signResult = handle_error(
get_result: { parse_evm_signature($0, ur.type, ur.cborData.hexEncodedString()) }
)
return try super.parseUR(urString: signResult, ofType: Signature.self, ofError: KeystoneError.parseSignatureError)
}

public func generateSignRequest(evmSignRequest: EvmSignRequest) throws -> UREncoder {
let accountsJson = String(data: try jsonEncoder.encode(evmSignRequest.account), encoding: .utf8)
let signRequest = handle_error(
get_result: { generate_evm_sign_request($0, evmSignRequest.requestId, evmSignRequest.signData, evmSignRequest.dataType.rawValue, evmSignRequest.customChainIdentifier, accountsJson, evmSignRequest.origin) }
)
return try super.generateSignRequest(signRequest: signRequest)
}
}
3 changes: 3 additions & 0 deletions Sources/KeystoneSDK/KeystoneSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class KeystoneSDK {
public lazy var cosmos: KeystoneCosmosSDK = {
return KeystoneCosmosSDK()
}()
public lazy var evm: KeystoneEvmSDK = {
return KeystoneEvmSDK()
}()
public lazy var tron: KeystoneTronSDK = {
return KeystoneTronSDK()
}()
Expand Down
45 changes: 45 additions & 0 deletions Sources/KeystoneSDK/Model/EvmSignRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// EvmSignRequest.swift
//
//
// Created by Renfeng Shi on 2023/7/17.
//

import Foundation

public struct EvmSignRequest {
let requestId: String
let signData: String
let dataType: DataType
let customChainIdentifier: Int32
let account: Account

let origin: String

public enum DataType: Int32 {
case arbitrary = 1
case cosmosAmino = 2
case cosmosDirect = 3
}

public struct Account: Encodable {
let path: String
let xfp: String
let address: String

public init(path: String, xfp: String, address: String = "") {
self.path = path
self.xfp = xfp
self.address = address
}
}

public init(requestId: String, signData: String, dataType: DataType, customChainIdentifier: Int32, account: Account, origin: String = "") {
self.requestId = requestId
self.signData = signData
self.dataType = dataType
self.customChainIdentifier = customChainIdentifier
self.account = account
self.origin = origin
}
}
73 changes: 73 additions & 0 deletions Tests/KeystoneSDKTests/Chain/KeystoneEvmSDKTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// KeystoneEvmSDKTests.swift
//
//
// Created by Renfeng Shi on 2023/7/17.
//

import XCTest
import URKit
@testable import KeystoneSDK

final class KeystoneEvmSDKTests: XCTestCase {

func testParseSignature() {
let signatureHex = "a201d82550057523355d514a64a481ff2200000000025840a0e2577ca16119a32f421c6a1c90fa2178a9382f30bf3575ff276fb820b32b3269d49d6bbfc82bae899f60c15de4b97f24a7ebb6d4712534829628ccfbef38bc"

let sdk = KeystoneEvmSDK()
let ur = try! UR(type: "evm-signature", cborData: signatureHex.hexadecimal)
let signature = try! sdk.parseSignature(ur: ur)

XCTAssertEqual(signature.requestId, "05752335-5d51-4a64-a481-ff2200000000")
XCTAssertEqual(signature.signature, "a0e2577ca16119a32f421c6a1c90fa2178a9382f30bf3575ff276fb820b32b3269d49d6bbfc82bae899f60c15de4b97f24a7ebb6d4712534829628ccfbef38bc")
}

func testParseSignatureError() {
let signatureHex = "a201d825509b1de"
let sdk = KeystoneEvmSDK()
let ur = try! UR(type: "evm-signature", cborData: signatureHex.hexadecimal)

var thrownError: Swift.Error?
XCTAssertThrowsError(try sdk.parseSignature(ur: ur)) {
thrownError = $0
}
XCTAssertEqual(thrownError as? KeystoneError, .parseSignatureError("signature is invalid"))
}

func testGenerateSignRequest() {
let signRequest = EvmSignRequest(
requestId: "05752335-5d51-4a64-a481-ff2200000000",
signData: "0A9D010A9A010A1C2F636F736D6F732E62616E6B2E763162657461312E4D736753656E64127A0A2C65766D6F73317363397975617230756E3736677235633871346A3736687572347179706A6B38336E786B7735122C65766D6F73317363397975617230756E3736677235633871346A3736687572347179706A6B38336E786B77351A1C0A07617465766D6F7312113130303030303030303030303030303030127E0A590A4F0A282F65746865726D696E742E63727970746F2E76312E657468736563703235366B312E5075624B657912230A21024F7A8D64E515CCF1E0A92A7C859262F425473CF09A50EBCAF3B06B156624145312040A020801181612210A1B0A07617465766D6F7312103236323530303030303030303030303010A8B4061A0C65766D6F735F393030302D342084C68E01",
dataType: .cosmosDirect,
customChainIdentifier: 9000,
account: EvmSignRequest.Account(path: "m/44'/60'/0'/0/0", xfp: "f23f9fd2", address: "0x860A4E746FE4FDA40E98382B2F6AFC1D4040CAC7"),
origin: "Keplr Extension"
)

let sdk = KeystoneEvmSDK()
let signRequestEncoder = try! sdk.generateSignRequest(evmSignRequest: signRequest)

let qrCode = signRequestEncoder.nextPart()

XCTAssertEqual(qrCode, "ur:evm-sign-request/1-2/lpadaocfadmocyldbbnehnhdsoosadtpdagdahkpcnechlgygeieoxlyzmcpaeaeaeaeaohkadeobkntadbknyadbkcedliajljkjnjljkdmidhsjtjedmkoehidihjyhsehdmgtjkioguihjtiebgknbkdwihkojnjljkehjkiaeskkkphsjpdykpjtemeniojpeciaetjseeimemeniskpjpeejskkjoimjeeteojtksjektecbgdwihkojnjljkehjkiaeskkkphsjpdykpjtemeniojpeciaetjseeimemeniskpjpeejskkjoimjeeteojtksjekteccycebkathsjyihkojnjljkbgbyehdydydydydydydydydydydydydydydydybgkbbkhkbkgwbkdedlihjyisihjpjninsocsleax")
}

func testGenerateSignRequestError() {
let signRequest = EvmSignRequest(
requestId: "7AFD5E09-9267-43FB-A02E-08C4A09417EC-1",
signData: "0A9D010A9A010A1C2F636F736D6F732E62616E6B2E763162657461312E4D736753656E64127A0A2C65766D6F73317363397975617230756E3736677235633871346A3736687572347179706A6B38336E786B7735122C65766D6F73317363397975617230756E3736677235633871346A3736687572347179706A6B38336E786B77351A1C0A07617465766D6F7312113130303030303030303030303030303030127E0A590A4F0A282F65746865726D696E742E63727970746F2E76312E657468736563703235366B312E5075624B657912230A21024F7A8D64E515CCF1E0A92A7C859262F425473CF09A50EBCAF3B06B156624145312040A020801181612210A1B0A07617465766D6F7312103236323530303030303030303030303010A8B4061A0C65766D6F735F393030302D342084C68E01",
dataType: .cosmosDirect,
customChainIdentifier: 9000,
account: EvmSignRequest.Account(path: "m/44'/60'/0'/0/0", xfp: "f23f9fd2", address: "0x860A4E746FE4FDA40E98382B2F6AFC1D4040CAC7"),
origin: "Keplr"
)

let sdk = KeystoneEvmSDK()

var thrownError: Swift.Error?
XCTAssertThrowsError(try sdk.generateSignRequest(evmSignRequest: signRequest)) {
thrownError = $0
}
XCTAssertEqual(thrownError as? KeystoneError, .generateSignRequestError("uuid is invalid"))
}
}

0 comments on commit f952869

Please sign in to comment.