diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index a47113a5..50bbcd46 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -25,8 +25,8 @@ jobs:
platform:
- iOS
steps:
- - uses: actions/checkout@v2.3.4
- - uses: mxcl/xcodebuild@v1
+ - uses: actions/checkout@v4
+ - uses: mxcl/xcodebuild@v3.0.0
with:
platform: ${{ matrix.platform }}
action: test
diff --git a/.gitignore b/.gitignore
index b5d2630a..41ca90cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,7 +49,6 @@ playground.xcworkspace
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
-.swiftpm/
.build/
diff --git a/.periphery.yml b/.periphery.yml
new file mode 100644
index 00000000..1ffd9c5f
--- /dev/null
+++ b/.periphery.yml
@@ -0,0 +1,3 @@
+retain_public: true
+targets:
+- TorusUtils
diff --git a/.swiftpm/TorusUtils.xctestplan b/.swiftpm/TorusUtils.xctestplan
new file mode 100644
index 00000000..7a94645d
--- /dev/null
+++ b/.swiftpm/TorusUtils.xctestplan
@@ -0,0 +1,24 @@
+{
+ "configurations" : [
+ {
+ "id" : "9F2D8848-AB66-4789-A38F-C7E010657904",
+ "name" : "Test Scheme Action",
+ "options" : {
+
+ }
+ }
+ ],
+ "defaultOptions" : {
+ "testRepetitionMode" : "retryOnFailure"
+ },
+ "testTargets" : [
+ {
+ "target" : {
+ "containerPath" : "container:",
+ "identifier" : "TorusUtilsTests",
+ "name" : "TorusUtilsTests"
+ }
+ }
+ ],
+ "version" : 1
+}
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..919434a6
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/TorusUtils.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/TorusUtils.xcscheme
new file mode 100644
index 00000000..c8f8c286
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/TorusUtils.xcscheme
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Package.resolved b/Package.resolved
index 0bf696a3..99bb4888 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -1,14 +1,5 @@
{
"pins" : [
- {
- "identity" : "anycodable",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/Flight-School/AnyCodable",
- "state" : {
- "revision" : "862808b2070cd908cb04f9aafe7de83d35f81b05",
- "version" : "0.6.7"
- }
- },
{
"identity" : "bigint",
"kind" : "remoteSourceControl",
@@ -32,8 +23,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/torusresearch/fetch-node-details-swift.git",
"state" : {
- "revision" : "f085d3d85a4f36b57cfef8f0871ac8df1dd4f6f1",
- "version" : "6.0.1"
+ "revision" : "4bd96c33ba8d02d9e27190c5c7cedf09cfdfd656",
+ "version" : "6.0.3"
}
},
{
diff --git a/Package.swift b/Package.swift
index 57771d76..25e8de38 100644
--- a/Package.swift
+++ b/Package.swift
@@ -12,17 +12,14 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/tkey/curvelib.swift", from: "1.0.1"),
- .package(url: "https://github.com/torusresearch/fetch-node-details-swift", from: "6.0.1"),
- .package(url: "https://github.com/vapor/jwt-kit", from: "4.0.0"),
- .package(
- url: "https://github.com/Flight-School/AnyCodable",
- from: "0.6.0"
- ),
+ .package(url: "https://github.com/torusresearch/fetch-node-details-swift", from: "6.0.3"),
+ // NB: jwt-kit may only be a dependency in tests or it will break cocoapod support
+ .package(url: "https://github.com/vapor/jwt-kit.git", from: "4.0.0"),
],
targets: [
.target(
name: "TorusUtils",
- dependencies: ["AnyCodable",
+ dependencies: [
.product(name: "FetchNodeDetails", package: "fetch-node-details-swift"),
.product(name: "curveSecp256k1", package: "curvelib.swift"),
]),
diff --git a/README.md b/README.md
index b25be952..3cbecc7f 100644
--- a/README.md
+++ b/README.md
@@ -8,26 +8,37 @@ This utility library allows for early exits in optimistic scenarios, while handl
The general approach is to evaluate predicates against a list of (potentially incomplete) results, and exit when the predicate passes.
## 🔗 Installation
-You can install the SingleFactorAuth Swift using Swift Package Manager.
+You can install the TorusUtils using Swift Package Manager:
```
...
dependencies: [
...
- .package(url: "https://github.com/torusresearch/torus-utils-swift", from: "8.0.1")
+ .package(url: "https://github.com/torusresearch/torus-utils-swift", from: "9.0.0")
],
+targets: [
+ .target( name: "",
+ dependencies: [
+ .product(name: "TorusUtils", package: "torus-utils-swift")
+ ]
+ ) ],
+]
+...
+```
+
+Or CocoaPods:
+
+```
+...
+ pod 'Torus-utils', '~> 9.0.0'
...
```
## Getting Started
-Initialize the `TorusUtils` class by passing `TorusNetwork`, `enableOneKey`, and your `clientId`. `enableOneKey` if true, adds the nonce value to the key, to make it compaitible with v2 users. The package supports both legacy and sapphire networks.
+Initialize the `TorusUtils` class by passing `TorusOptions` as params. Params includes `TorusNetwork`, `enableOneKey`, and your `clientId`. `enableOneKey` if true, adds the nonce value to the key, to make it compatible with v2 users. The package supports both legacy and sapphire networks.
```swift
- let torus = TorusUtils(
- enableOneKey: true,
- network: .sapphire(.SAPPHIRE_DEVNET),
- clientId: "YOUR_CLIENT_ID"
- )
+ let torusUtils = TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .sapphire(.SAPPHIRE_MAINNET), enableOneKey: true))
```
@@ -39,22 +50,17 @@ Use the `getNodeDetails` function to retrive the node details for specific `veri
do {
let fnd = NodeDetailManager(network: .sapphire(.SAPPHIRE_DEVNET))
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
- let publicAddressResponse = try await torus.getPublicAddress(
- endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.torusNodePub,
- verifier: TORUS_TEST_VERIFIER,
- verifierId: TORUS_TEST_EMAIL
- )
-
- print(publicAddressResponse.oAuthKeyData!.evmAddress)
+ let publicDetails = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ print(publicDetails.oAuthKeyData!.evmAddress)
} catch let error {
// Handle error
}
```
-Use `retriveShares` function to login a user, and get the login data such as `sessionData`, `privKey`, `evmAddress`, `metaData` for user. Along with node detals, it also takes verifier, `verifierParams`, and `idToken`(JWT token).
+Use `retrieveShares` function to login a user, and get the login data such as `sessionData`, `privKey`, `evmAddress`, `metaData` for user. Along with node details, it also takes `verifier`, `verifierParams`, and `idToken`(JWT token).
```swift
// verifier_id takes the value, for instance email, sub, or custom.
@@ -62,16 +68,11 @@ let verifierParams = VerifierParams(verifier_id: "verifier_id_value")
do {
// Use nodeDetails from above step
- let data = try await torus.retrieveShares(
- endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(),
- indexes: nodeDetails.getTorusIndexes(),
- verifier: TORUS_TEST_VERIFIER,
- verifierParams: verifierParams,
- idToken: token
- )
-
- let privateKey = data.finalKeyData!.privKey
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: token)
+
let evmAddress = data.finalKeyData!.evmAddress
} catch let error {
// Handle error
@@ -85,4 +86,4 @@ do {
- Have a look at our [Community Portal](https://community.web3auth.io/) to see if anyone has any questions or issues you might be having. Feel free to reate new topics and we'll help you out as soon as possible.
- Checkout our [Troubleshooting Documentation Page](https://web3auth.io/docs/troubleshooting) to know the common issues and solutions.
-- For Priority Support, please have a look at our [Pricing Page](https://web3auth.io/pricing.html) for the plan that suits your needs.
\ No newline at end of file
+- For Priority Support, please have a look at our [Pricing Page](https://web3auth.io/pricing.html) for the plan that suits your needs.
diff --git a/Sources/TorusUtils/AbstractTorusUtils.swift b/Sources/TorusUtils/AbstractTorusUtils.swift
deleted file mode 100644
index d22f90a8..00000000
--- a/Sources/TorusUtils/AbstractTorusUtils.swift
+++ /dev/null
@@ -1,9 +0,0 @@
-import BigInt
-import FetchNodeDetails
-import Foundation
-
-public protocol AbstractTorusUtils {
- func retrieveShares(endpoints: [String], torusNodePubs: [TorusNodePubModel], indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey
-
- func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String?) async throws -> TorusPublicKey
-}
diff --git a/Sources/TorusUtils/Constants.swift b/Sources/TorusUtils/Constants.swift
index e5af863f..e88aa344 100644
--- a/Sources/TorusUtils/Constants.swift
+++ b/Sources/TorusUtils/Constants.swift
@@ -1,13 +1,8 @@
enum JRPC_METHODS {
static let GET_OR_SET_KEY = "GetPubKeyOrKeyAssign"
static let COMMITMENT_REQUEST = "CommitmentRequest"
- static let IMPORT_SHARE = "ImportShare"
+ static let IMPORT_SHARES = "ImportShares"
static let GET_SHARE_OR_KEY_ASSIGN = "GetShareOrKeyAssign"
- static let LEGACY_VERIFIER_LOOKUP_REQUEST = "VerifierLookupRequest"
- static let LEGACY_KEY_ASSIGN = "KeyAssign"
- static let LEGACY_SHARE_REQUEST = "ShareRequest"
}
let CURVE_N: String = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
-
-let LEGACY_METADATA_HOST = "https://metadata.tor.us"
diff --git a/Sources/TorusUtils/DataModels.swift b/Sources/TorusUtils/DataModels.swift
deleted file mode 100644
index 9795185f..00000000
--- a/Sources/TorusUtils/DataModels.swift
+++ /dev/null
@@ -1,173 +0,0 @@
-import BigInt
-import Foundation
-
-public struct TaskGroupResponse {
- public var data: Data
- public var urlResponse: URLResponse
- public var index: Int
-
- public init(data: Data, urlResponse: URLResponse, index: Int) {
- self.data = data
- self.urlResponse = urlResponse
- self.index = index
- }
-}
-
-public enum TypeOfUser: String {
- case v1
- case v2
-}
-
-public struct GetUserAndAddress {
- public var typeOfUser: TypeOfUser
- public var pubNonce: PubNonce?
- public var nonceResult: String?
- public var address: String
- public var x: String
- public var y: String
-
- public init(typeOfUser: TypeOfUser, address: String, x: String, y: String, pubNonce: PubNonce? = nil, nonceResult: String? = nil) {
- self.typeOfUser = typeOfUser
- self.address = address
- self.x = x
- self.y = y
- self.pubNonce = pubNonce
- self.nonceResult = nonceResult
- }
-}
-
-public struct GetPublicAddressResult {
- public var address: String
- public var typeOfUser: TypeOfUser?
- public var x: String?
- public var y: String?
- public var metadataNonce: BigUInt?
- public var pubNonce: PubNonce?
- public var nodeIndexes: [Int]?
- public var upgarded: Bool?
-
- public init(address: String, typeOfUser: TypeOfUser? = nil, x: String? = nil, y: String? = nil, metadataNonce: BigUInt? = nil, pubNonce: PubNonce? = nil, nodeIndexes: [Int]? = [], upgraded: Bool? = false) {
- self.typeOfUser = typeOfUser
- self.address = address
- self.x = x
- self.y = y
- self.metadataNonce = metadataNonce
- self.pubNonce = pubNonce
- self.nodeIndexes = nodeIndexes
- upgarded = upgraded
- }
-}
-
-public struct GetOrSetNonceResult: Codable {
- public var typeOfUser: String?
- public var nonce: String?
- public var pubNonce: PubNonce?
- public var ifps: String?
- public var upgraded: Bool?
-
- public init(typeOfUser: String, nonce: String? = nil, pubNonce: PubNonce? = nil, ifps: String? = nil, upgraded: Bool? = false) {
- self.typeOfUser = typeOfUser
- self.nonce = nonce
- self.pubNonce = pubNonce
- self.ifps = ifps
- self.upgraded = upgraded
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
-
- typeOfUser = try container.decodeIfPresent(String.self, forKey: .typeOfUser)
- nonce = try container.decodeIfPresent(String.self, forKey: .nonce)
- pubNonce = try container.decodeIfPresent(PubNonce.self, forKey: .pubNonce)
- ifps = try container.decodeIfPresent(String.self, forKey: .ifps)
- upgraded = try container.decodeIfPresent(Bool.self, forKey: .upgraded)
- }
-}
-
-public struct PubNonce: Codable, Equatable {
- public var x: String
- public var y: String
-
- public init(x: String, y: String) {
- self.x = x
- self.y = y
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- x = try container.decode(String.self, forKey: .x)
- y = try container.decode(String.self, forKey: .y)
- }
-}
-
-public struct UserTypeAndAddress {
- public var typeOfUser: String
- public var nonce: BigInt?
- public var x: String
- public var y: String
- public var address: String
-
- public init(typeOfUser: String, x: String, y: String, nonce: BigInt?, address: String) {
- self.typeOfUser = typeOfUser
- self.address = address
- self.x = x
- self.y = y
- self.nonce = nonce
- }
-}
-
-public struct NonceMetadataParams: Codable {
- public struct SetNonceData: Codable {
- public var operation: String?
- public var data: String?
- public var timestamp: String?
-
- public init(operation: String? = nil, data: String? = nil, timestamp: String? = nil) {
- self.operation = operation
- self.data = data
- self.timestamp = timestamp
- }
- }
-
- public var namespace: String?
- public var pub_key_X: String
- public var pub_key_Y: String
- public var set_data: SetNonceData
- public var signature: String
-
- public init(pub_key_X: String, pub_key_Y: String, setData: SetNonceData, signature: String, namespace: String? = nil) {
- self.namespace = namespace
- self.pub_key_X = pub_key_X
- self.pub_key_Y = pub_key_Y
- set_data = setData
- self.signature = signature
- }
-}
-
-typealias StringifiedType = [String: Codable]
-
-public struct MetadataParams: Codable {
- public struct SetData: Codable {
- public var data: String
- public var timestamp: String
-
- public init(data: String, timestamp: String) {
- self.data = data
- self.timestamp = timestamp
- }
- }
-
- public var namespace: String?
- public var pub_key_X: String
- public var pub_key_Y: String
- public var set_data: SetData
- public var signature: String
-
- public init(pub_key_X: String, pub_key_Y: String, setData: SetData, signature: String, namespace: String? = nil) {
- self.namespace = namespace
- self.pub_key_X = pub_key_X
- self.pub_key_Y = pub_key_Y
- set_data = setData
- self.signature = signature
- }
-}
diff --git a/Sources/TorusUtils/Extensions/Array+Extension.swift b/Sources/TorusUtils/Extensions/Array+Extension.swift
index 10c61bcd..ad38dc0a 100644
--- a/Sources/TorusUtils/Extensions/Array+Extension.swift
+++ b/Sources/TorusUtils/Extensions/Array+Extension.swift
@@ -14,69 +14,64 @@
//
extension Array {
- @inlinable
- init(reserveCapacity: Int) {
- self = Array()
- self.reserveCapacity(reserveCapacity)
- }
+ @inlinable
+ init(reserveCapacity: Int) {
+ self = Array()
+ self.reserveCapacity(reserveCapacity)
+ }
- @inlinable
- var slice: ArraySlice {
- self[self.startIndex ..< self.endIndex]
- }
-
- @inlinable
- subscript (safe index: Index) -> Element? {
- return indices.contains(index) ? self[index] : nil
- }
+ @inlinable
+ var slice: ArraySlice {
+ self[startIndex ..< endIndex]
+ }
}
extension Array where Element == UInt8 {
- public init(hex: String) {
- self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount)
- var buffer: UInt8?
- var skip = hex.hasPrefix("0x") ? 2 : 0
- for char in hex.unicodeScalars.lazy {
- guard skip == 0 else {
- skip -= 1
- continue
- }
- guard char.value >= 48 && char.value <= 102 else {
- removeAll()
- return
- }
- let v: UInt8
- let c: UInt8 = UInt8(char.value)
- switch c {
- case let c where c <= 57:
- v = c - 48
- case let c where c >= 65 && c <= 70:
- v = c - 55
- case let c where c >= 97:
- v = c - 87
- default:
- removeAll()
- return
- }
- if let b = buffer {
- append(b << 4 | v)
- buffer = nil
- } else {
- buffer = v
- }
- }
- if let b = buffer {
- append(b)
+ public init(hex: String) {
+ self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount)
+ var buffer: UInt8?
+ var skip = hex.hasPrefix("0x") ? 2 : 0
+ for char in hex.unicodeScalars.lazy {
+ guard skip == 0 else {
+ skip -= 1
+ continue
+ }
+ guard char.value >= 48 && char.value <= 102 else {
+ removeAll()
+ return
+ }
+ let v: UInt8
+ let c: UInt8 = UInt8(char.value)
+ switch c {
+ case let c where c <= 57:
+ v = c - 48
+ case let c where c >= 65 && c <= 70:
+ v = c - 55
+ case let c where c >= 97:
+ v = c - 87
+ default:
+ removeAll()
+ return
+ }
+ if let b = buffer {
+ append(b << 4 | v)
+ buffer = nil
+ } else {
+ buffer = v
+ }
+ }
+ if let b = buffer {
+ append(b)
+ }
}
- }
- public func toHexString() -> String {
- `lazy`.reduce(into: "") {
- var s = String($1, radix: 16)
- if s.count == 1 {
- s = "0" + s
- }
- $0 += s
+ public func toHexString() -> String {
+ lazy.reduce(into: "") {
+ var s = String($1, radix: 16)
+ if s.count == 1 {
+ s = "0" + s
+ }
+ $0 += s
+ }
}
- }
}
diff --git a/Sources/TorusUtils/Extensions/Data+Extension.swift b/Sources/TorusUtils/Extensions/Data+Extension.swift
index 5673b055..4b44a2e3 100755
--- a/Sources/TorusUtils/Extensions/Data+Extension.swift
+++ b/Sources/TorusUtils/Extensions/Data+Extension.swift
@@ -1,23 +1,23 @@
import Foundation
-public extension Data {
+extension Data {
var hexString: String {
return map { String(format: "%02x", $0) }.joined()
}
- func addLeading0sForLength64() -> Data {
+ public func addLeading0sForLength64() -> Data {
Data(hex: hexString.addLeading0sForLength64())
}
-
+
init(hex: String) {
- self.init(Array(hex: hex))
+ self.init(Array(hex: hex))
}
var bytes: Array {
- Array(self)
+ Array(self)
}
func toHexString() -> String {
- self.bytes.toHexString()
+ bytes.toHexString()
}
}
diff --git a/Sources/TorusUtils/Extensions/OSLog+categories.swift b/Sources/TorusUtils/Extensions/OSLog+categories.swift
index 795d5da7..9154afde 100644
--- a/Sources/TorusUtils/Extensions/OSLog+categories.swift
+++ b/Sources/TorusUtils/Extensions/OSLog+categories.swift
@@ -6,8 +6,6 @@ let subsystem = Bundle.main.bundleIdentifier ?? "com.torus.utils"
public struct TorusUtilsLogger {
static let inactiveLog = OSLog.disabled
static let network = OSLog(subsystem: subsystem, category: "network")
- static let parsing = OSLog(subsystem: subsystem, category: "parsing")
- static let core = OSLog(subsystem: subsystem, category: "core")
}
func getTorusLogger(log: OSLog = .default, type: OSLogType = .default) -> OSLog {
diff --git a/Sources/TorusUtils/Extensions/Sequence+Extension.swift b/Sources/TorusUtils/Extensions/Sequence+Extension.swift
deleted file mode 100644
index 8b10b1e7..00000000
--- a/Sources/TorusUtils/Extensions/Sequence+Extension.swift
+++ /dev/null
@@ -1,7 +0,0 @@
-import BigInt
-import Foundation
-
-extension Sequence where Element == UInt8 {
- var data: Data { .init(self) }
- var hexa: String { map { .init(format: "%02x", $0) }.joined() }
-}
diff --git a/Sources/TorusUtils/Extensions/String+Extension.swift b/Sources/TorusUtils/Extensions/String+Extension.swift
index c058cf37..82bf77ad 100755
--- a/Sources/TorusUtils/Extensions/String+Extension.swift
+++ b/Sources/TorusUtils/Extensions/String+Extension.swift
@@ -1,15 +1,15 @@
import Foundation
extension String {
- func hasHexPrefix() -> Bool {
- return hasPrefix("0x")
- }
-
func addHexPrefix() -> String {
- if !hasPrefix("0x") {
- return "0x" + self
+ if hasPrefix("0x") {
+ return self
}
- return self
+ return "0x" + self
+ }
+
+ func add04PrefixUnchecked() -> String {
+ return "04" + self
}
func stripHexPrefix() -> String {
@@ -20,26 +20,15 @@ extension String {
return self
}
- func has04Prefix() -> Bool {
- return hasPrefix("04")
- }
-
- func add04Prefix(targetLength: Int = 128) -> String {
- if self.count == targetLength{
- return "04" + self
- }
- return self
- }
-
- func strip04Prefix(targetLength: Int = 130) -> String {
- if hasPrefix("04") && self.count == targetLength {
+ func strip04Prefix() -> String {
+ if hasPrefix("04") {
let indexStart = index(startIndex, offsetBy: 2)
return String(self[indexStart...])
}
return self
}
- func addLeading0sForLength64() -> String {
+ public func addLeading0sForLength64() -> String {
if count < 64 {
let toAdd = String(repeating: "0", count: 64 - count)
return toAdd + self
@@ -48,35 +37,23 @@ extension String {
}
}
- func customBytes() -> Array {
- data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8)
- }
+ public func hexEncodedToString() -> String {
+ var finalString = ""
+ var chars = Array(self)
- func toChecksumAddress() -> String {
- let lowerCaseAddress = stripHexPrefix().lowercased()
- let arr = Array(lowerCaseAddress)
- let hash = keccak256Data(lowerCaseAddress.data(using: .utf8) ?? Data() ).toHexString()
+ if (chars.count % 2) != 0 { // odd number of characters in hex, pad with single zero.
+ chars.insert("0", at: 0)
+ }
- var result = String()
- for i in 0 ... lowerCaseAddress.count - 1 {
- let iIndex = hash.index(hash.startIndex, offsetBy: i)
- if let val = hash[iIndex].hexDigitValue , val >= 8 {
- result.append(arr[i].uppercased())
- } else {
- result.append(arr[i])
+ for count in stride(from: 0, to: chars.count - 1, by: 2) {
+ let firstDigit = Int("\(chars[count])", radix: 16) ?? 0
+ let lastDigit = Int("\(chars[count + 1])", radix: 16) ?? 0
+ let decimal = firstDigit * 16 + lastDigit
+ let decimalString = String(format: "%c", decimal) as String
+ if !(decimalString.isEmpty) { // lossy conversion
+ finalString.append(Character(decimalString))
}
}
- return result.addHexPrefix()
- }
-}
-
-extension StringProtocol {
- var hexa: [UInt8] {
- var startIndex = self.startIndex
- return (0 ..< count / 2).compactMap { _ in
- let endIndex = index(after: startIndex)
- defer { startIndex = index(after: endIndex) }
- return UInt8(self[startIndex ... endIndex], radix: 16)
- }
+ return finalString
}
}
diff --git a/Sources/TorusUtils/Extensions/TorusUtils+extension.swift b/Sources/TorusUtils/Extensions/TorusUtils+extension.swift
deleted file mode 100644
index b01e1eda..00000000
--- a/Sources/TorusUtils/Extensions/TorusUtils+extension.swift
+++ /dev/null
@@ -1,1335 +0,0 @@
-import Foundation
-import curveSecp256k1
-import AnyCodable
-import BigInt
-import CryptoKit
-import FetchNodeDetails
-import OSLog
-
-
-
-extension TorusUtils {
-
-
- internal func combinations(elements: ArraySlice, k: Int) -> [[T]] {
- if k == 0 {
- return [[]]
- }
-
- guard let first = elements.first else {
- return []
- }
-
- let head = [first]
- let subcombos = combinations(elements: elements.dropFirst(), k: k - 1)
- var ret = subcombos.map { head + $0 }
- ret += combinations(elements: elements.dropFirst(), k: k)
-
- return ret
- }
-
- internal func combinations(elements: [T], k: Int) -> [[T]] {
- return combinations(elements: ArraySlice(elements), k: k)
- }
-
- internal func makeUrlRequest(url: String, httpMethod: HTTPMethod = .post) throws -> URLRequest {
- guard
- let url = URL(string: url)
- else {
- throw TorusUtilError.runtime("Invalid Url \(url)")
- }
- var rq = URLRequest(url: url)
- rq.httpMethod = httpMethod.name
- rq.addValue("application/json", forHTTPHeaderField: "Content-Type")
- rq.addValue("application/json", forHTTPHeaderField: "Accept")
- return rq
- }
-
- internal func thresholdSame(arr: [T], threshold: Int) -> T? {
- var hashmap = [T: Int]()
- for (_, value) in arr.enumerated() {
- if let _ = hashmap[value] {
- hashmap[value]! += 1
- } else {
- hashmap[value] = 1
- }
- if hashmap[value] == threshold {
- return value
- }
- }
- return nil
- }
-
- internal func isLegacyNetwork() -> Bool {
- if case .legacy = network {
- return true
- }
- return false
- }
-
- internal func isMigratedLegacyNetwork() -> Bool {
- if case let .legacy(legacyNetwork) = network {
- let legacyRoute = legacyNetwork.migration_map
- if !legacyRoute.migrationCompleted {
- return true
- }
- return false
- }
- return false
- }
-
- // MARK: - metadata API
-
- internal func getMetadata(dictionary: [String: String]) async throws -> BigUInt {
- let encoded = try JSONSerialization.data(withJSONObject: dictionary, options: [.sortedKeys])
-
- var request = try makeUrlRequest(url: "\(legacyMetadataHost)/get")
- request.httpBody = encoded
- let val = try await urlSession.data(for: request)
- let data = try JSONSerialization.jsonObject(with: val.0) as? [String: Any] ?? [:]
- os_log("getMetadata: %@", log: getTorusLogger(log: TorusUtilsLogger.network, type: .info), type: .info, data)
- guard
- let msg: String = data["message"] as? String,
- let ret = BigUInt(msg, radix: 16)
- else {
- throw TorusUtilError.decodingFailed("Message value not correct or nil in \(data)")
- }
- return ret
- }
-
- internal func getOrSetNonce(x: String, y: String, privateKey: String? = nil, getOnly: Bool = false) async throws -> GetOrSetNonceResult {
- var data: Data
- let msg = getOnly ? "getNonce" : "getOrSetNonce"
- if privateKey != nil {
- let val = try generateParams(message: msg, privateKey: privateKey!)
- let encoder = JSONEncoder()
- encoder.outputFormatting = .sortedKeys
- data = try encoder.encode(val)
- } else {
- let dict: [String: Any] = ["pub_key_X": x, "pub_key_Y": y, "set_data": ["data": msg]]
- data = try JSONSerialization.data(withJSONObject: dict, options: .sortedKeys)
- }
- var request = try makeUrlRequest(url: "\(legacyMetadataHost)/get_or_set_nonce")
- request.httpBody = data
- let val = try await urlSession.data(for: request)
- let decoded = try JSONDecoder().decode(GetOrSetNonceResult.self, from: val.0)
- return decoded
- }
-
- internal func generateParams(message: String, privateKey: String) throws -> MetadataParams {
- let privKey = try SecretKey(hex: privateKey)
- let publicKey = try privKey.toPublic().serialize(compressed: false)
-
- let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16)
- let setData: MetadataParams.SetData = .init(data: message, timestamp: timeStamp)
- let encoder = JSONEncoder()
- encoder.outputFormatting = .sortedKeys
- let encodedData = try encoder
- .encode(setData)
-
- let hash = keccak256Data(encodedData).hexString
- let sigData = try ECDSA.signRecoverable(key: privKey, hash: hash).serialize()
-
- return .init(pub_key_X: String(publicKey.suffix(128).prefix(64)), pub_key_Y: String(publicKey.suffix(64)), setData: setData, signature: Data(hex: sigData).base64EncodedString())
- }
-
- // MARK: - getShareOrKeyAssign
-
- private func getShareOrKeyAssign(endpoints: [String], nodeSigs: [CommitmentRequestResponse], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String: Any] = [:]) async throws -> [URLRequest] {
- _ = createURLSession()
- _ = Int(endpoints.count / 2) + 1
- var rpcdata: Data = Data()
-
- let loadedStrings = extraParams
- let valueDict = ["idtoken": idToken,
- "nodesignatures": nodeSigs,
- "verifieridentifier": verifier,
- "verifier_id": verifierParams.verifier_id,
- "extended_verifier_id": verifierParams.extended_verifier_id,
- ] as [String: Codable]
-
- let keepingCurrent = loadedStrings.merging(valueDict) { current, _ in current }
- let finalItem = keepingCurrent.merging(verifierParams.additionalParams) { current, _ in current }
-
- let params = ["encrypted": "yes",
- "use_temp": true,
- "one_key_flow": true,
- "item": AnyCodable([finalItem]),
- ] as [String: AnyCodable]
-
- let dataForRequest = ["jsonrpc": "2.0",
- "id": 10,
- "method": AnyCodable(JRPC_METHODS.GET_SHARE_OR_KEY_ASSIGN),
- "params": AnyCodable(params),
- ] as [String: AnyCodable]
-
- // do {
- let encoder = JSONEncoder()
- encoder.outputFormatting = .sortedKeys
- rpcdata = try encoder.encode(dataForRequest)
- // } catch {
- // os_log("get share or key assign - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- // }
-
- // Create Array of URLRequest Promises
- var requestArray = [URLRequest]()
-
- for endpoint in endpoints {
- var request = try makeUrlRequest(url: endpoint, httpMethod: .post)
- request.httpBody = rpcdata
- requestArray.append(request)
- }
-
- return requestArray
- }
-
- private func reconstructKey(decryptedShares: [Int: String], thresholdPublicKey: KeyAssignment.PublicKey) throws -> String? {
- // run lagrange interpolation on all subsets, faster in the optimistic scenario than berlekamp-welch due to early exit
- let allCombis = combinations(elements: Array(0 ..< decryptedShares.count), k: 3)
- var returnedKey: String?
-
- for j in 0 ..< allCombis.count {
- let currentCombi = allCombis[j]
- let currentCombiShares = decryptedShares.enumerated().reduce(into: [Int: String]()) { acc, current in
- let (index, curr) = current
- if currentCombi.contains(index) {
- acc[curr.key] = curr.value
- }
- }
- let derivedPrivateKey = try SecretKey(hex: try lagrangeInterpolation(shares: currentCombiShares, offset: 0).addLeading0sForLength64())
-
- let decryptedPubKey = try derivedPrivateKey.toPublic().serialize(compressed: false)
- let decryptedPubKeyX = String(decryptedPubKey.suffix(128).prefix(64))
- let decryptedPubKeyY = String(decryptedPubKey.suffix(64))
- if decryptedPubKeyX == thresholdPublicKey.X.addLeading0sForLength64() && decryptedPubKeyY == thresholdPublicKey.Y.addLeading0sForLength64() {
- returnedKey = try derivedPrivateKey.serialize().addLeading0sForLength64()
- break
- }
- }
-
- return returnedKey
- }
-
- // MARK: - retrieveShare
-
- // TODO: add importShare functionality later
- internal func retrieveShare(
- legacyMetadataHost: String,
- allowHost: String,
- enableOneKey: Bool,
- network: TorusNetwork,
- clientId: String,
- endpoints: [String],
- verifier: String,
- verifierParams: VerifierParams,
- idToken: String,
- extraParams: [String: Any] = [:]
- ) async throws -> TorusKey {
- let session = createURLSession()
- let threshold = (endpoints.count / 2) + 1
-
- let sessionAuthKey = SecretKey()
- let serializedPublicKey = try sessionAuthKey.toPublic().serialize(compressed: false)
-
- // Split key in 2 parts, X and Y
- let pubKeyX = String(serializedPublicKey.suffix(128).prefix(64))
- let pubKeyY = String(serializedPublicKey.suffix(64))
-
- // Hash the token from OAuth login
- let timestamp = String(Int(getTimestamp()))
- let hashedToken = keccak256Data(idToken.data(using: .utf8) ?? Data()).toHexString()
-
-
- let nodeSigs = try await commitmentRequest(endpoints: endpoints, verifier: verifier, pubKeyX: pubKeyX, pubKeyY: pubKeyY, timestamp: timestamp, tokenCommitment: hashedToken)
- os_log("retrieveShares - data after commitment request: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, nodeSigs)
- var promiseArrRequest = [URLRequest]()
-
- // TODO: make sure we have only complete requests in promiseArrRequest?
- promiseArrRequest = try await getShareOrKeyAssign(endpoints: endpoints, nodeSigs: nodeSigs, verifier: verifier, verifierParams: verifierParams, idToken: idToken, extraParams: extraParams)
-
- var thresholdNonceData: GetOrSetNonceResult?
- var pubkeyArr = [KeyAssignment.PublicKey]()
- var isNewKeyArr: [String] = []
- var completeShareRequestResponseArr = [ShareRequestResult]()
- var thresholdPublicKey: KeyAssignment.PublicKey?
-
- try await withThrowingTaskGroup(of: Result.self, body: { group in
-
- for (i, rq) in promiseArrRequest.enumerated() {
- group.addTask {
- do {
- let val = try await session.data(for: rq)
- return .success(.init(data: val.0, urlResponse: val.1, index: i))
- } catch {
- return .failure(error)
- }
- }
- }
-
- for try await val in group {
- do {
- switch val {
- case let .success(model):
- let data = model.data
- let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data)
- os_log("retrieveShare promise - reponse: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, decoded.message ?? "")
-
- if decoded.error != nil {
- os_log("retrieveShare promise - decode error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, decoded.error?.message ?? "")
- throw TorusUtilError.runtime(decoded.error?.message ?? "")
- }
-
- // Ensure that we don't add bad data to result arrays.
- guard
- let decodedResult = decoded.result as? ShareRequestResult
- else { throw TorusUtilError.decodingFailed("ShareReqeust error decoding error : \(decoded), can't decode into shareRequestResult") }
-
- isNewKeyArr.append(decodedResult.isNewKey)
- completeShareRequestResponseArr.append(decodedResult)
- let keyObj = decodedResult.keys
- if let first = keyObj.first {
- let pubkey = first.publicKey
- let nonceData = first.nonceData
- let pubNonce = nonceData?.pubNonce?.x
-
- pubkeyArr.append(pubkey)
- if thresholdNonceData == nil && verifierParams.extended_verifier_id == nil {
- if pubNonce != "" {
- thresholdNonceData = nonceData
- }
- }
- guard let result = thresholdSame(arr: pubkeyArr, threshold: threshold)
- else {
- throw TorusUtilError.thresholdError
- }
-
- thresholdPublicKey = result
-
- if thresholdPublicKey?.X == nil {
- throw TorusUtilError.thresholdError
- }
-
- if thresholdNonceData == nil && verifierParams.extended_verifier_id == nil && !isLegacyNetwork() {
- throw TorusUtilError.metadataNonceMissing
- }
- return
- }
- case let .failure(error):
- throw error
- }
- } catch {
- os_log("retrieveShare promise - share request error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug))
- }
- }
-
- os_log("retrieveShare - invalid result from nodes, threshold number of public key results are not matching", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error)
- throw TorusUtilError.thresholdError
- })
-
- // optimistically run lagrange interpolation once threshold number of shares have been received
- // this is matched against the user public key to ensure that shares are consistent
- // Note: no need of thresholdMetadataNonce for extended_verifier_id key
- if completeShareRequestResponseArr.count >= threshold {
- if thresholdPublicKey?.X != nil && (thresholdNonceData != nil && thresholdNonceData?.pubNonce?.x != "" || verifierParams.extended_verifier_id != nil || isLegacyNetwork()) {
- // Code block to execute if all conditions are true
- var shares = [String]()
- var sessionTokenSigPromises = [String?]()
- var sessionTokenPromises = [String?]()
- var nodeIndexes = [Int]()
- var sessionTokenData = [SessionToken?]()
-
- guard let isNewKey = thresholdSame(arr: isNewKeyArr, threshold: threshold)
- else {
- os_log("retrieveShare - invalid result from nodes, threshold number of is_new_key results are not matching", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error)
- throw TorusUtilError.thresholdError
- }
-
- for currentShareResponse in completeShareRequestResponseArr {
- let sessionTokens = currentShareResponse.sessionTokens
- let sessionTokenMetadata = currentShareResponse.sessionTokenMetadata
- let sessionTokenSigs = currentShareResponse.sessionTokenSigs
- let sessionTokenSigMetadata = currentShareResponse.sessionTokenSigMetadata
- let keys = currentShareResponse.keys
-
- if sessionTokenSigs.count > 0 {
- // decrypt sessionSig if enc metadata is sent
- if sessionTokenSigMetadata.first?.ephemPublicKey != nil {
- sessionTokenSigPromises.append(try? decryptNodeData(eciesData: sessionTokenSigMetadata[0], ciphertextHex: sessionTokenSigs[0], privKey: sessionAuthKey.serialize().addLeading0sForLength64()))
- } else {
- sessionTokenSigPromises.append(sessionTokenSigs[0])
- }
- } else {
- sessionTokenSigPromises.append(nil)
- }
-
- if sessionTokens.count > 0 {
- if sessionTokenMetadata.first?.ephemPublicKey != nil {
- sessionTokenPromises.append(try? decryptNodeData(eciesData: sessionTokenMetadata[0], ciphertextHex: sessionTokens[0], privKey: sessionAuthKey.serialize().addLeading0sForLength64()))
- } else {
- sessionTokenPromises.append(sessionTokenSigs[0])
- }
- } else {
- sessionTokenPromises.append(nil)
- }
-
- if keys.count > 0 {
- let latestKey = currentShareResponse.keys[0]
- nodeIndexes.append(Int(latestKey.nodeIndex))
- let data = Data(base64Encoded: latestKey.share, options: [])!
- guard let ciphertextHex = String(data: data, encoding: .ascii) else {
- throw TorusUtilError.decodingFailed()
- }
- let decryptedShare = try decryptNodeData(eciesData: latestKey.shareMetadata, ciphertextHex: ciphertextHex, privKey: sessionAuthKey.serialize().addLeading0sForLength64())
- shares.append(decryptedShare.addLeading0sForLength64())
- } else {
- os_log("retrieveShare - 0 keys returned from nodes", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error)
- throw TorusUtilError.thresholdError
- }
- }
-
- let validTokens = sessionTokenPromises.filter { token in
- if let _ = token {
- return true
- }
- return false
- }
-
- if verifierParams.extended_verifier_id == nil && validTokens.count < threshold {
- os_log("retrieveShare - Insufficient number of session tokens from nodes, required: %@, found: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, threshold, validTokens.count)
- throw TorusUtilError.apiRequestFailed
- }
-
- let validSigs = sessionTokenSigPromises.filter { sig in
- if let _ = sig {
- return true
- }
- return false
- }
-
- if verifierParams.extended_verifier_id == nil && validSigs.count < threshold {
- os_log("retrieveShare - Insufficient number of session signatures from nodes, required: %@, found: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, threshold, validSigs.count)
- throw TorusUtilError.apiRequestFailed
- }
-
- for (index, x) in sessionTokenPromises.enumerated() {
- if x == nil {
- sessionTokenData.append(nil)
- } else {
- let token = x!
- let signature = sessionTokenSigPromises[index]
- let nodePubX = completeShareRequestResponseArr[index].nodePubX
- let nodePubY = completeShareRequestResponseArr[index].nodePubY
-
- sessionTokenData.append(SessionToken(token: token, signature: signature!, node_pubx: nodePubX, node_puby: nodePubY))
- }
- }
-
- let sharesWithIndex = shares.enumerated().reduce(into: [Int: String]()) { acc, current in
- let (index, curr) = current
- acc[nodeIndexes[index]] = curr
- }
-
- let returnedKey = try reconstructKey(decryptedShares: sharesWithIndex, thresholdPublicKey: thresholdPublicKey!)
- if returnedKey == nil {
- throw TorusUtilError.privateKeyDeriveFailed
- }
-
- guard let oAuthKey = returnedKey else {
- throw TorusUtilError.privateKeyDeriveFailed
- }
-
- let derivedPrivateKey = try SecretKey(hex: oAuthKey)
-
- let oAuthPubKey = try derivedPrivateKey.toPublic().serialize(compressed: false)
- let oAuthPubKeyX = String(oAuthPubKey.suffix(128).prefix(64))
- let oAuthPubKeyY = String(oAuthPubKey.suffix(64))
-
- var metadataNonce = BigInt(thresholdNonceData?.nonce ?? "0", radix: 16) ?? BigInt(0)
-
- var pubKeyNonceResult: PubNonce?
- var typeOfUser: UserType = .v1
-
- var finalPubKey = oAuthPubKey
- if verifierParams.extended_verifier_id != nil {
- typeOfUser = .v2
- // For TSS key, no need to add pub nonce
- finalPubKey = String(finalPubKey.suffix(128))
- } else if case .legacy = self.network {
- if self.enableOneKey {
- // get or set nonce based on isNewKey variable
- let nonceResult = try await getOrSetNonce(x: oAuthPubKeyX, y: oAuthPubKeyY, privateKey: oAuthKey, getOnly: isNewKey == "false")
- // BigInt( Data(hex: nonceResult.nonce ?? "0"))
- metadataNonce = BigInt(nonceResult.nonce ?? "0", radix: 16)!
- let usertype = nonceResult.typeOfUser
-
- if usertype == "v2" {
- let pubNonceX = nonceResult.pubNonce?.x
- let pubNonceY = nonceResult.pubNonce?.y
- typeOfUser = .v2
- let pubkey2 = (pubNonceX!.addLeading0sForLength64() + pubNonceY!.addLeading0sForLength64()).add04Prefix()
- let combined = try combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false)
- finalPubKey = combined
- pubKeyNonceResult = .init(x: pubNonceX!, y: pubNonceY!)
- } else {
- typeOfUser = .v1
- // for imported keys in legacy networks
- metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oAuthPubKeyX, "pub_key_Y": oAuthPubKeyY]))
- let privateKeyWithNonce = (BigInt(oAuthKey, radix: 16)! + BigInt(metadataNonce)).modulus(modulusValue)
- finalPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
- }
- } else {
- typeOfUser = .v1
- // for imported keys in legacy networks
- metadataNonce = BigInt(try await getMetadata(dictionary: ["pub_key_X": oAuthPubKeyX, "pub_key_Y": oAuthPubKeyY]))
- let privateKeyWithNonce = (BigInt(oAuthKey, radix: 16)! + BigInt(metadataNonce)).modulus(modulusValue)
- finalPubKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
- }
- } else {
- typeOfUser = .v2
-
- let pubNonceX = thresholdNonceData!.pubNonce!.x
- let pubNonceY = thresholdNonceData!.pubNonce!.y
- let pubkey2 = (pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64()).add04Prefix()
- let combined = try combinePublicKeys(keys: [finalPubKey, pubkey2], compressed: false)
- finalPubKey = combined
- pubKeyNonceResult = .init(x: pubNonceX, y: pubNonceY)
- }
-
- let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthPubKeyX, publicKeyY: oAuthPubKeyY)
-
- var finalPrivKey = ""
-
- if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) {
- let privateKeyWithNonce = ((BigInt(oAuthKey, radix: 16) ?? BigInt(0)) + metadataNonce).modulus(modulusValue)
- finalPrivKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
- }
-
- let (finalPubX, finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey)
- // deriving address from pub key coz pubkey is always available
- // but finalPrivKey won't be available for v2 user upgraded to 2/n
- let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY)
-
- var isUpgraded: Bool?
-
- switch typeOfUser {
- case .v1:
- isUpgraded = nil
- case .v2:
- isUpgraded = metadataNonce == BigInt(0)
- }
-
- return TorusKey(
- finalKeyData: .init(
- evmAddress: finalEvmAddress,
- X: finalPubX.addLeading0sForLength64(),
- Y: finalPubY.addLeading0sForLength64(),
- privKey: finalPrivKey
- ),
- oAuthKeyData: .init(
- evmAddress: oAuthKeyAddress,
- X: oAuthPubKeyX,
- Y: oAuthPubKeyY,
- privKey: oAuthKey
- ),
- sessionData: .init(
- sessionTokenData: sessionTokenData,
- sessionAuthKey: try sessionAuthKey.serialize().addLeading0sForLength64()
- ),
- metadata: .init(
- pubNonce: pubKeyNonceResult,
- nonce: BigUInt(metadataNonce),
- typeOfUser: typeOfUser,
- upgraded: isUpgraded
- ),
- nodesData: .init(nodeIndexes: nodeIndexes)
- )
- }
- }
- throw TorusUtilError.retrieveOrImportShareError
- }
-
- // MARK: - commitment request
-
- internal func commitmentRequest(endpoints: [String], verifier: String, pubKeyX: String, pubKeyY: String, timestamp: String, tokenCommitment: String) async throws -> [CommitmentRequestResponse] {
- let session = createURLSession()
-
- let threshold = Int(endpoints.count / 4) * 3 + 1
- let encoder = JSONEncoder()
- var failedLookUpCount = 0
- let jsonRPCRequest = JSONRPCrequest(
- method: JRPC_METHODS.COMMITMENT_REQUEST,
- params: ["messageprefix": "mug00",
- "tokencommitment": tokenCommitment,
- "temppubx": pubKeyX,
- "temppuby": pubKeyY,
- "verifieridentifier": verifier,
- "timestamp": timestamp]
- )
-
- guard let rpcdata = try? encoder.encode(jsonRPCRequest)
- else {
- throw TorusUtilError.runtime("Unable to encode request. \(jsonRPCRequest)")
- }
-
- // Build promises array
- var nodeSignatures = [CommitmentRequestResponse]()
- var requestArr = [URLRequest]()
- for (_, el) in endpoints.enumerated() {
- var rq = try makeUrlRequest(url: el)
- rq.httpBody = rpcdata
- requestArr.append(rq)
- }
- return try await withThrowingTaskGroup(of: Result.self, body: { group in
-
- for (i, rq) in requestArr.enumerated() {
- group.addTask {
- do {
- let val = try await session.data(for: rq)
- return .success(.init(data: val.0, urlResponse: val.1, index: i))
- } catch {
- return .failure(error)
- }
- }
- }
-
- for try await val in group {
- do {
- try Task.checkCancellation()
- switch val {
- case let .success(model):
- let data = model.data
- let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data)
- os_log("commitmentRequest - reponse: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, decoded.message ?? "")
-
- // TODO: this error block can't catch error
- if decoded.error != nil {
- os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, decoded.error?.message ?? "")
- throw TorusUtilError.runtime(decoded.error?.message ?? "")
- }
-
- // Ensure that we don't add bad data to result arrays.
- guard
- let response = decoded.result as? CommitmentRequestResponse
- else {
- throw TorusUtilError.decodingFailed("CommitmentRequestResponse could not be decoded")
- }
-
- // Check if k+t responses are back
- let val = CommitmentRequestResponse(data: response.data, nodepubx: response.nodepubx, nodepuby: response.nodepuby, signature: response.signature)
- nodeSignatures.append(val)
- if nodeSignatures.count >= threshold {
- os_log("commitmentRequest - nodeSignatures: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, nodeSignatures)
- session.invalidateAndCancel()
- return nodeSignatures
- }
- case let .failure(error):
- os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- }
- } catch {
- failedLookUpCount += 1
- os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- if failedLookUpCount > endpoints.count - threshold {
- os_log("commitmentRequest - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold node unavailable").localizedDescription)
- session.invalidateAndCancel()
- throw error
- }
- }
- }
- throw TorusUtilError.commitmentRequestFailed
- })
- }
-
- internal func convertMetadataToNonce(params: [String: Any]?) -> BigUInt {
- guard let params = params, let message = params["message"] as? String else {
- return BigUInt(0)
- }
- return BigUInt(message, radix: 16)!
- }
-
- internal func decryptNodeData(eciesData: EciesHex, ciphertextHex: String, privKey: String) throws -> String {
- let eciesOpts = ECIES(
- iv: eciesData.iv,
- ephemPublicKey: eciesData.ephemPublicKey,
- ciphertext: ciphertextHex,
- mac: eciesData.mac
- )
-
- let decryptedSigBuffer = try decrypt(privateKey: privKey, opts: eciesOpts).hexString
- return decryptedSigBuffer
- }
-
- public func encryptData(privkeyHex: String, _ dataToEncrypt: String) throws -> String {
- let privKey = try SecretKey(hex: privkeyHex)
- let pubKey = try privKey.toPublic().serialize(compressed: false)
- let encParams = try encrypt(publicKey: pubKey, msg: dataToEncrypt, opts: nil)
- let data = try JSONEncoder().encode(encParams)
- guard let string = String(data: data, encoding: .utf8) else { throw TorusUtilError.runtime("Invalid String from enc Params") }
- return string
- }
-
- internal func randomBytes(ofLength length: Int) throws -> [UInt8] {
- var bytes = [UInt8](repeating: 0, count: length)
- let status = SecRandomCopyBytes(kSecRandomDefault, length, &bytes)
- if status == errSecSuccess {
- return bytes
- }
- throw TorusUtilError.runtime("Failed to generate secure random bytes")
- }
-
- public func encrypt(publicKey: String, msg: String, opts: Ecies? = nil) throws -> Ecies {
- guard let data = msg.data(using: .utf8) else {
- throw TorusUtilError.runtime("Encryption: Invalid utf8 string")
- }
- let curveMsg = try Encryption.encrypt(pk: PublicKey(hex: publicKey), plainText: data)
- return try .init(iv: curveMsg.iv(), ephemPublicKey: curveMsg.ephemeralPublicKey().serialize(compressed: false), ciphertext: curveMsg.chipherText(), mac: curveMsg.mac())
- }
-
- // MARK: - decrypt shares
-
- internal func decryptIndividualShares(shares: [Int: RetrieveDecryptAndReconstuctResponseModel], privateKey: String) throws -> [Int: String] {
- var result = [Int: String]()
-
- for (_, el) in shares.enumerated() {
- let nodeIndex = el.key
-
- guard
- let data = Data(base64Encoded: el.value.share),
- let share = String(data: data, encoding: .utf8)
- else {
- throw TorusUtilError.decryptionFailed
- }
-
- let ecies: ECIES = .init(iv: el.value.iv, ephemPublicKey: el.value.ephemPublicKey, ciphertext: share, mac: el.value.mac)
- result[nodeIndex] = try decrypt(privateKey: privateKey, opts: ecies).toHexString()
-
- if shares.count == result.count {
- return result
- }
- }
- throw TorusUtilError.runtime("decryptIndividualShares func failed")
- }
-
- // MARK: - Lagrange interpolation
-
- internal func thresholdLagrangeInterpolation(data filteredData: [Int: String], endpoints: [String], lookupPubkeyX: String, lookupPubkeyY: String) throws -> (String, String, String) {
- // all possible combinations of share indexes to interpolate
- let shareCombinations = combinations(elements: Array(filteredData.keys), k: Int(endpoints.count / 2) + 1)
- for shareIndexSet in shareCombinations {
- var sharesToInterpolate: [Int: String] = [:]
- shareIndexSet.forEach { sharesToInterpolate[$0] = filteredData[$0] }
- do {
- let data = try lagrangeInterpolation(shares: sharesToInterpolate)
- let finalPrivateKey = try SecretKey(hex: data)
- let finalPublicKey = try finalPrivateKey.toPublic().serialize(compressed: false)
- // Split key in 2 parts, X and Y
- let pubKeyX = String(finalPublicKey.suffix(128).prefix(64))
- let pubKeyY = String(finalPublicKey.suffix(64))
- os_log("retrieveDecryptAndReconstuct: private key rebuild %@ %@ %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, data, pubKeyX, pubKeyY)
-
- // Verify
- if pubKeyX == lookupPubkeyX && pubKeyY == lookupPubkeyY {
- return (pubKeyX, pubKeyY, data)
- } else {
- os_log("retrieveDecryptAndReconstuct: verification failed", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error)
- }
- } catch {
- os_log("retrieveDecryptAndReconstuct: lagrangeInterpolation: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- }
- }
- throw TorusUtilError.interpolationFailed
- }
-
- internal func lagrangeInterpolation(shares: [Int: String], offset: Int = 1) throws -> String {
- let CurveSecp256k1N = modulusValue
-
- // Convert shares to BigInt(Shares)
- var shareList = [BigInt: BigInt]()
- _ = shares.map { shareList[BigInt($0.key + offset)] = BigInt($0.value.addLeading0sForLength64(), radix: 16) }
-
- var secret = BigUInt("0") // to support BigInt 4.0 dependency on cocoapods
- var sharesDecrypt = 0
-
- for (i, share) in shareList {
- var upper = BigInt(1)
- var lower = BigInt(1)
- for (j, _) in shareList {
- if i != j {
- let negatedJ = j * BigInt(-1)
- upper = upper * negatedJ
- upper = upper.modulus(CurveSecp256k1N)
-
- var temp = i - j
- temp = temp.modulus(CurveSecp256k1N)
- lower = (lower * temp).modulus(CurveSecp256k1N)
- }
- }
- guard
- let inv = lower.inverse(CurveSecp256k1N)
- else {
- throw TorusUtilError.decryptionFailed
- }
- var delta = (upper * inv).modulus(CurveSecp256k1N)
- delta = (delta * share).modulus(CurveSecp256k1N)
- secret = BigUInt((BigInt(secret) + delta).modulus(CurveSecp256k1N))
- sharesDecrypt += 1
- }
- let secretString = String(secret.serialize().hexa.suffix(64))
- if sharesDecrypt == shareList.count {
- return secretString
- } else {
- throw TorusUtilError.interpolationFailed
- }
- }
-
- // MARK: - getPubKeyOrKeyAssign
-
- internal func getPubKeyOrKeyAssign(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> KeyLookupResult {
- // Encode data
- let encoder = JSONEncoder()
- let session = createURLSession()
- let threshold = (endpoints.count / 2) + 1
- var failedLookupCount = 0
-
- // flag to check if node with index 1 is queried for metadata
- var isNodeOneVisited = false
-
- let methodName = JRPC_METHODS.GET_OR_SET_KEY
-
- let params = GetPublicAddressOrKeyAssignParams(verifier: verifier, verifier_id: verifierId, extended_verifier_id: extendedVerifierId, one_key_flow: true, fetch_node_index: true)
-
- let jsonRPCRequest = JSONRPCrequest(
- method: methodName,
- params: params
- )
-
- guard let rpcdata = try? encoder.encode(jsonRPCRequest)
-
- else {
- throw TorusUtilError.encodingFailed("\(jsonRPCRequest)")
- }
-
- // Create Array of URLRequest Promises
-
- var resultArray: [KeyLookupResponse] = []
- var requestArray = [URLRequest]()
- for endpoint in endpoints {
- var request = try makeUrlRequest(url: endpoint)
- request.httpBody = rpcdata
- requestArray.append(request)
- }
-
- var nonceResult: GetOrSetNonceResult?
- var nodeIndexesArray: [Int] = []
- var keyArray: [VerifierLookupResponse?] = []
-
- return try await withThrowingTaskGroup(of: Result.self, returning: KeyLookupResult.self) { group in
-
- for (i, rq) in requestArray.enumerated() {
- group.addTask {
- do {
- let val = try await session.data(for: rq)
- return .success(.init(data: val.0, urlResponse: val.1, index: i))
- } catch {
- return .failure(error)
- }
- }
- }
-
- // this is serial execution
- // TODO: convert this to some function implementation as we do in web
- for try await val in group {
- do {
- switch val {
- case let .success(model):
- // print( try JSONSerialization.jsonObject(with: model.data) )
- let data = model.data
- let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct
- let result = decoded.result as? VerifierLookupResponse
-
- if let _ = decoded.error {
- let error = KeyLookupError.createErrorFromString(errorString: "")
- throw error
- } else {
- let decodedResult = result!
- keyArray.append(decodedResult)
- if let k = decodedResult.keys,
- let key = k.first {
- let model = KeyLookupResponse(pubKeyX: key.pub_key_X, pubKeyY: key.pub_key_Y, address: key.address, isNewKey: decodedResult.is_new_key)
-
- resultArray.append(model)
- if let nonceData = key.nonce_data {
- let pubNonceX = nonceData.pubNonce?.x
- if pubNonceX != nil && pubNonceX != "" && nonceResult == nil {
- nonceResult = key.nonce_data
- }
- }
- }
- }
- let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied
-
- // proceed if we have key result and either of nonceResult, extendedVerifierId, isLegacyNetwork is
- // available
- if keyResult != nil && (nonceResult != nil || extendedVerifierId != nil || isLegacyNetwork()) {
- if let keyResult = keyResult {
- os_log("%@: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, methodName, keyResult.description)
- session.invalidateAndCancel()
- keyArray.forEach({ result in
-
- if result?.node_index == "1" {
- isNodeOneVisited = true
- }
- if result != nil && result?.node_index != "0" {
- nodeIndexesArray.append(Int(result!.node_index)!)
- }
-
- })
-
- return KeyLookupResult(keyResult: keyResult, nodeIndexes: nodeIndexesArray, nonceResult: nonceResult)
- }
- }
- throw NSError(domain: "condition not meet", code: 1001)
- case let .failure(error):
- throw error
- }
- } catch {
- failedLookupCount += 1
- os_log("%@: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, methodName, error.localizedDescription)
-
- if (isNodeOneVisited && failedLookupCount > (endpoints.count - threshold)) || (failedLookupCount == endpoints.count) {
- os_log("%@: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, methodName, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription)
- session.invalidateAndCancel()
- throw error
- }
- }
- }
-
- throw TorusUtilError.runtime("\(methodName) func failed")
- }
- }
-
- // MARK: - keylookup
-
- internal func awaitKeyLookup(endpoints: [String], verifier: String, verifierId: String, timeout: Int = 0) async throws -> KeyLookupResponse {
- let durationInNanoseconds = UInt64(timeout * 1000000000)
- try await Task.sleep(nanoseconds: durationInNanoseconds)
- return try await keyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId)
- }
-
- internal func awaitLegacyKeyLookup(endpoints: [String], verifier: String, verifierId: String, timeout: Int = 0) async throws -> LegacyKeyLookupResponse {
- let durationInNanoseconds = UInt64(timeout * 1000000000)
- try await Task.sleep(nanoseconds: durationInNanoseconds)
- return try await legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId)
- }
-
- internal func legacyKeyLookup(endpoints: [String], verifier: String, verifierId: String) async throws -> LegacyKeyLookupResponse {
- // Enode data
- let encoder = JSONEncoder()
- let session = createURLSession()
- let threshold = (endpoints.count / 2) + 1
- var failedLookupCount = 0
- let jsonRPCRequest = JSONRPCrequest(
- method: JRPC_METHODS.LEGACY_VERIFIER_LOOKUP_REQUEST,
- params: ["verifier": verifier, "verifier_id": verifierId])
- guard let rpcdata = try? encoder.encode(jsonRPCRequest)
- else {
- throw TorusUtilError.encodingFailed("\(jsonRPCRequest)")
- }
- var allowHostRequest = try makeUrlRequest(url: allowHost, httpMethod: .get)
- allowHostRequest.addValue("torus-default", forHTTPHeaderField: "x-api-key")
- allowHostRequest.addValue(verifier, forHTTPHeaderField: "Origin")
- do {
- _ = try await session.data(for: allowHostRequest)
- } catch {
- os_log("KeyLookup: signer allow: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- throw error
- }
-
- // Create Array of URLRequest Promises
-
- var resultArray = [LegacyKeyLookupResponse]()
- var requestArray = [URLRequest]()
- for endpoint in endpoints {
- var request = try makeUrlRequest(url: endpoint)
- request.httpBody = rpcdata
- requestArray.append(request)
- }
-
- return try await withThrowingTaskGroup(of: Result.self, body: { [unowned self] group in
- for (i, rq) in requestArray.enumerated() {
- group.addTask {
- do {
- let val = try await session.data(for: rq)
- return .success(.init(data: val.0, urlResponse: val.1, index: i))
- } catch {
- return .failure(error)
- }
- }
- }
-
- for try await val in group {
- do {
- switch val {
- case let .success(model):
- let data = model.data
- let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct
- os_log("keyLookup: API response: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decoded)")
-
- let result = decoded.result
- let error = decoded.error
- if let _ = error {
- let error = KeyLookupError.createErrorFromString(errorString: decoded.error?.data ?? "")
- throw error
- } else {
- guard
- let decodedResult = result as? [String: [[String: String]]],
- let k = decodedResult["keys"],
- let keys = k.first,
- let pubKeyX = keys["pub_key_X"],
- let pubKeyY = keys["pub_key_Y"],
- let keyIndex = keys["key_index"],
- let address = keys["address"]
- else {
- throw TorusUtilError.decodingFailed("keys not found in \(result ?? "")")
- }
- let model = LegacyKeyLookupResponse(pubKeyX: pubKeyX, pubKeyY: pubKeyY, keyIndex: keyIndex, address: address)
- resultArray.append(model)
- }
- let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied
-
- if let keyResult = keyResult {
- os_log("keyLookup: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, keyResult.description)
- session.invalidateAndCancel()
- return keyResult
- }
- case let .failure(error):
- throw error
- }
- } catch {
- failedLookupCount += 1
- os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- if failedLookupCount > (endpoints.count - threshold) {
- os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription)
- session.invalidateAndCancel()
- throw error
- }
- }
- }
- throw TorusUtilError.runtime("keyLookup func failed")
- })
- }
-
- internal func keyLookup(endpoints: [String], verifier: String, verifierId: String) async throws -> KeyLookupResponse {
- // Enode data
- let encoder = JSONEncoder()
- let session = createURLSession()
- let threshold = (endpoints.count / 2) + 1
- var failedLookupCount = 0
- let jsonRPCRequest = JSONRPCrequest(
- method: JRPC_METHODS.LEGACY_VERIFIER_LOOKUP_REQUEST,
- params: ["verifier": verifier, "verifier_id": verifierId])
- guard let rpcdata = try? encoder.encode(jsonRPCRequest)
- else {
- throw TorusUtilError.encodingFailed("\(jsonRPCRequest)")
- }
- var allowHostRequest = try makeUrlRequest(url: allowHost, httpMethod: .get)
- allowHostRequest.addValue("torus-default", forHTTPHeaderField: "x-api-key")
- allowHostRequest.addValue(verifier, forHTTPHeaderField: "Origin")
- do {
- _ = try await session.data(for: allowHostRequest)
- } catch {
- os_log("KeyLookup: signer allow: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- throw error
- }
-
- // Create Array of URLRequest Promises
-
- var resultArray = [KeyLookupResponse]()
- var requestArray = [URLRequest]()
- for endpoint in endpoints {
- var request = try makeUrlRequest(url: endpoint)
- request.httpBody = rpcdata
- requestArray.append(request)
- }
-
- return try await withThrowingTaskGroup(of: Result.self, body: { [unowned self] group in
- for (i, rq) in requestArray.enumerated() {
- group.addTask {
- do {
- let val = try await session.data(for: rq)
- return .success(.init(data: val.0, urlResponse: val.1, index: i))
- } catch {
- return .failure(error)
- }
- }
- }
-
- for try await val in group {
- do {
- switch val {
- case let .success(model):
- let data = model.data
- let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: data) // User decoder to covert to struct
- os_log("keyLookup: API response: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decoded)")
-
- // result of decoded data
- let result = decoded.result
- let error = decoded.error
- if let _ = error {
- let error = KeyLookupError.createErrorFromString(errorString: decoded.error?.data ?? "")
- throw error
- } else {
- guard
- let decodedResult = result as? [String: [[String: Any]]],
-
- let k = decodedResult["keys"],
- let keys = k.first,
- let pubKeyX = keys["pub_key_X"] as? String,
- let pubKeyY = keys["pub_key_Y"] as? String,
- let address = keys["address"] as? String
- else {
- throw TorusUtilError.decodingFailed("key not found")
- }
- let isNewKey = keys["is_new_key"] as? Bool ?? false
- let model = KeyLookupResponse(pubKeyX: pubKeyX, pubKeyY: pubKeyY, address: address, isNewKey: isNewKey)
- resultArray.append(model)
- }
- let keyResult = thresholdSame(arr: resultArray, threshold: threshold) // Check if threshold is satisfied
-
- if let keyResult = keyResult {
- os_log("keyLookup: fulfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, keyResult.description)
- session.invalidateAndCancel()
- return keyResult
- }
- case let .failure(error):
- throw error
- }
- } catch {
- failedLookupCount += 1
- os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- if failedLookupCount > (endpoints.count - threshold) {
- os_log("keyLookup: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, TorusUtilError.runtime("threshold nodes unavailable").localizedDescription)
- session.invalidateAndCancel()
- throw error
- }
- }
- }
- throw TorusUtilError.runtime("keyLookup func failed")
- })
- }
-
- // MARK: - key assignment
-
- internal func keyAssign(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, signerHost: String, network: TorusNetwork, firstPoint: Int? = nil, lastPoint: Int? = nil) async throws -> JSONRPCresponse {
- var nodeNum: Int = 0
- var initialPoint: Int = 0
- os_log("KeyAssign: endpoints: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, endpoints)
- if let safeLastPoint = lastPoint {
- nodeNum = safeLastPoint % endpoints.count
- } else {
- nodeNum = Int(floor(Double(Double(arc4random_uniform(1)) * Double(endpoints.count))))
- }
- if nodeNum == firstPoint {
- throw TorusUtilError.runtime("Looped through all")
- }
- if let safefirstPoint = firstPoint {
- initialPoint = safefirstPoint
- }
-
- let encoder = JSONEncoder()
- if #available(macOS 10.13, *) {
- encoder.outputFormatting = .sortedKeys
- } else {
- // Fallback on earlier versions
- }
- os_log("newEndpoints2 : %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, endpoints)
-
- let SignerObject = JSONRPCrequest(method: JRPC_METHODS.LEGACY_KEY_ASSIGN, params: ["verifier": verifier, "verifier_id": verifierId])
- let rpcdata = try encoder.encode(SignerObject)
- var request = try makeUrlRequest(url: signerHost)
- request.addValue(torusNodePubs[nodeNum].getX().lowercased(), forHTTPHeaderField: "pubKeyX")
- request.addValue(torusNodePubs[nodeNum].getY().lowercased(), forHTTPHeaderField: "pubKeyY")
- switch network {
- case let .legacy(network): request.addValue(network.path, forHTTPHeaderField: "network")
- case let .sapphire(network): request.addValue(network.path, forHTTPHeaderField: "network")
- }
-
- request.httpBody = rpcdata
- do {
- let responseFromSignerData: (Data, URLResponse) = try await urlSession.data(for: request)
- let decodedSignerResponse = try JSONDecoder().decode(SignerResponse.self, from: responseFromSignerData.0)
- os_log("KeyAssign: responseFromSigner: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decodedSignerResponse)")
- let keyassignRequest = KeyAssignRequest(params: ["verifier": verifier, "verifier_id": verifierId], signerResponse: decodedSignerResponse)
- // Combine signer respose and request data
- encoder.outputFormatting = .sortedKeys
- let newData = try encoder.encode(keyassignRequest)
- var request2 = try makeUrlRequest(url: endpoints[nodeNum])
- request2.httpBody = newData
- let keyAssignRequestData: (Data, URLResponse) = try await urlSession.data(for: request2)
- do {
- let decodedData = try JSONDecoder().decode(JSONRPCresponse.self, from: keyAssignRequestData.0) // User decoder to covert to struct
-
- os_log("keyAssign: fullfill: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, "\(decodedData)")
- return decodedData
- } catch let err {
- throw TorusUtilError.decodingFailed(err.localizedDescription)
- }
- } catch {
- os_log("KeyAssign: err: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, "\(error)")
- return try await keyAssign(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, signerHost: signerHost, network: network, firstPoint: initialPoint, lastPoint: nodeNum + 1)
- }
- }
-
- internal func generateNonceMetadataParams(message: String, privateKey: BigInt, nonce: BigInt?) throws -> NonceMetadataParams {
- let privKey = try SecretKey(hex: privateKey.magnitude.serialize().hexString.addLeading0sForLength64())
- let publicKey = try privKey.toPublic().serialize(compressed: false)
-
- let timeStamp = String(BigUInt(serverTimeOffset + Date().timeIntervalSince1970), radix: 16)
- var setData: NonceMetadataParams.SetNonceData = .init(data: message, timestamp: timeStamp)
- if nonce != nil {
- setData.data = String(nonce!, radix: 16).addLeading0sForLength64()
- }
- let encoder = JSONEncoder()
- encoder.outputFormatting = .sortedKeys
- let encodedData = try JSONEncoder()
- .encode(setData)
- let hash = keccak256Data(encodedData).hexString
- let sigData = try ECDSA.signRecoverable(key: privKey, hash: hash).serialize()
-
- return .init(pub_key_X: String(publicKey.suffix(128).prefix(64)), pub_key_Y: String(publicKey.suffix(64)), setData: setData, signature: Data(hex: sigData).base64EncodedString())
- }
-
- internal func getPublicKeyPointFromPubkeyString(pubKey: String) throws -> (String, String) {
- let publicKeyHashData = Data(hex: pubKey.strip04Prefix())
- if !(publicKeyHashData.count == 64) {
- throw TorusUtilError.invalidKeySize
- }
-
- let xCoordinateData = publicKeyHashData.prefix(32).toHexString()
- let yCoordinateData = publicKeyHashData.suffix(32).toHexString()
-
- return (xCoordinateData, yCoordinateData)
- }
-
- internal func combinePublicKeys(keys: [String], compressed: Bool) throws -> String {
- let collection = PublicKeyCollection()
- for item in keys {
- let pk = try PublicKey(hex: item)
- try collection.insert(key: pk)
- }
-
- let added = try PublicKey.combine(collection: collection).serialize(compressed: compressed)
- return added
- }
-
- internal func formatLegacyPublicData(finalKeyResult: KeyLookupResponse, enableOneKey: Bool, isNewKey: Bool) async throws -> TorusPublicKey {
- var finalPubKey: String = ""
- var nonce: BigUInt = 0
- var typeOfUser: TypeOfUser = .v1
- var pubNonce: PubNonce?
- var result: TorusPublicKey
- var nonceResult: GetOrSetNonceResult?
- let pubKeyX = finalKeyResult.pubKeyX
- let pubKeyY = finalKeyResult.pubKeyY
- let (oAuthX, oAuthY) = (pubKeyX.addLeading0sForLength64(), pubKeyY.addLeading0sForLength64())
- if enableOneKey {
- nonceResult = try await getOrSetNonce(x: pubKeyX, y: pubKeyY, privateKey: nil, getOnly: !isNewKey)
- nonce = BigUInt(nonceResult?.nonce ?? "0") ?? 0
- typeOfUser = .init(rawValue: nonceResult?.typeOfUser ?? ".v1") ?? .v1
- if typeOfUser == .v1 {
- finalPubKey = (pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()).add04Prefix()
- if nonce != BigInt(0) {
- let noncePrivateKey = try SecretKey(hex: BigUInt(nonce).magnitude.serialize().addLeading0sForLength64().hexString)
- let noncePublicKey = try noncePrivateKey.toPublic().serialize(compressed: false)
- finalPubKey = try combinePublicKeys(keys: [finalPubKey, noncePublicKey], compressed: false)
- } else {
- finalPubKey = String(finalPubKey)
- }
- } else if typeOfUser == .v2 {
- pubNonce = nonceResult?.pubNonce
- if nonceResult?.upgraded ?? false {
- finalPubKey = (pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()).add04Prefix()
- } else {
- guard nonceResult?.pubNonce != nil else { throw TorusUtilError.decodingFailed("No pub nonce found") }
- finalPubKey = (pubKeyX.addLeading0sForLength64() + pubKeyY.addLeading0sForLength64()).add04Prefix()
- let ecpubKeys = ((nonceResult?.pubNonce!.x.addLeading0sForLength64())! + (nonceResult?.pubNonce!.y.addLeading0sForLength64())!).add04Prefix()
- finalPubKey = try combinePublicKeys(keys: [finalPubKey, ecpubKeys], compressed: false)
- }
- finalPubKey = String(finalPubKey.suffix(128))
- } else {
- throw TorusUtilError.runtime("getOrSetNonce should always return typeOfUser.")
- }
- } else {
- typeOfUser = .v1
- let localNonce = try await getMetadata(dictionary: ["pub_key_X": pubKeyX, "pub_key_Y": pubKeyY])
- nonce = localNonce
- let localPubkeyX = finalKeyResult.pubKeyX
- let localPubkeyY = finalKeyResult.pubKeyY
- finalPubKey = (localPubkeyX.addLeading0sForLength64() + localPubkeyY.addLeading0sForLength64()).add04Prefix()
- if localNonce != BigInt(0) {
- let nonce2 = BigInt(localNonce)
- let noncePrivateKey = try SecretKey(hex: BigUInt(nonce2).magnitude.serialize().addLeading0sForLength64().hexString)
- let noncePublicKey = try noncePrivateKey.toPublic().serialize(compressed: false)
- finalPubKey = try combinePublicKeys(keys: [finalPubKey, noncePublicKey], compressed: false)
- } else {
- finalPubKey = String(finalPubKey)
- }
- }
- let finalX = String(finalPubKey.suffix(128).prefix(64))
- let finalY = String(finalPubKey.suffix(64))
-
- let oAuthAddress = generateAddressFromPubKey(publicKeyX: oAuthX, publicKeyY: oAuthY)
- let finalAddress = generateAddressFromPubKey(publicKeyX: finalX, publicKeyY: finalY)
-
- var usertype = ""
- switch typeOfUser {
- case .v1:
- usertype = "v1"
- case .v2:
- usertype = "v2"
- }
-
- result = TorusPublicKey(
- finalKeyData: .init(
- evmAddress: finalAddress,
- X: finalX.addLeading0sForLength64(),
- Y: finalY.addLeading0sForLength64()
- ),
- oAuthKeyData: .init(
- evmAddress: oAuthAddress,
- X: oAuthX.addLeading0sForLength64(),
- Y: oAuthY.addLeading0sForLength64()
- ),
- metadata: .init(
- pubNonce: pubNonce,
- nonce: nonce,
- typeOfUser: UserType(rawValue: usertype)!,
- upgraded: nonceResult?.upgraded ?? false
- ),
- nodesData: .init(nodeIndexes: [])
- )
- return result
- }
-
- internal func tupleToArray(_ tuple: Any) -> [UInt8] {
- let tupleMirror = Mirror(reflecting: tuple)
- let tupleElements = tupleMirror.children.map({ $0.value as! UInt8 })
- return tupleElements
- }
-
- public func decrypt(privateKey: String, opts: ECIES) throws -> Data {
- let secret = try SecretKey(hex: privateKey)
- let msg = try EncryptedMessage(cipherText: opts.ciphertext, ephemeralPublicKey: PublicKey(hex: opts.ephemPublicKey), iv: opts.iv, mac: opts.mac)
- let result = try Encryption.decrypt(sk: secret, encrypted: msg)
- return result
- }
-}
-
-extension Array where Element == UInt8 {
- func uint8Reverse() -> Array {
- var revArr = [Element]()
- for arrayIndex in stride(from: count - 1, through: 0, by: -1) {
- revArr.append(self[arrayIndex])
- }
- return revArr
- }
-}
diff --git a/Sources/TorusUtils/Helpers/Common.swift b/Sources/TorusUtils/Helpers/Common.swift
index bcb548d4..e62140c4 100644
--- a/Sources/TorusUtils/Helpers/Common.swift
+++ b/Sources/TorusUtils/Helpers/Common.swift
@@ -1,17 +1,96 @@
import BigInt
import Foundation
+#if canImport(curveSecp256k1)
+ import curveSecp256k1
+#endif
-import curveSecp256k1
+internal func normalizeKeysResult(result: VerifierLookupResponse) -> KeyLookupResult.KeyResult {
+ var finalResult = KeyLookupResult.KeyResult(is_new_key: result.is_new_key)
-func keccak256Data(_ data: Data) -> Data {
- let hash = try? keccak256(data: data)
- return hash ?? Data([])
+ if !result.keys.isEmpty {
+ let finalKey = result.keys[0]
+ finalResult.keys = [
+ VerifierLookupResponse.Key(
+ pub_key_X: finalKey.pub_key_X,
+ pub_key_Y: finalKey.pub_key_Y,
+ address: finalKey.address
+ ),
+ ]
+ }
+
+ return finalResult
+}
+
+internal func kCombinations(elements: ArraySlice, k: Int) -> [[T]] {
+ if k == 0 || k > elements.count {
+ return []
+ }
+
+ if k == elements.count {
+ return [Array(elements)]
+ }
+
+ if k == 1 {
+ return elements.map { [$0] }
+ }
+
+ var combs: [[T]] = []
+ var tailCombs: [[T]] = []
+
+ for i in 0 ... (elements.count - k + 1) {
+ tailCombs = kCombinations(elements: elements[(elements.startIndex + i + 1)...], k: k - 1)
+ for item in tailCombs {
+ var extended = [elements[elements.startIndex + i]]
+ extended.append(contentsOf: item)
+ combs.append(extended)
+ }
+ }
+
+ return combs
+}
+
+internal func thresholdSame(arr: [T], threshold: Int) throws -> T? {
+ var hashmap = [String: Int]()
+ let jsonEncoder = JSONEncoder()
+ jsonEncoder.outputFormatting = .sortedKeys
+ for (_, value) in arr.enumerated() {
+ guard let jsonString = String(data: try jsonEncoder.encode(value), encoding: .utf8) else { throw TorusUtilError.encodingFailed("thresholdSame")
+ }
+ if let _ = hashmap[jsonString] {
+ hashmap[jsonString]! += 1
+ } else {
+ hashmap[jsonString] = 1
+ }
+ if hashmap[jsonString] == threshold {
+ return value
+ }
+ }
+ return nil
+}
+
+internal func calculateMedian(arr: [Int]) -> Int {
+ let arrLen = arr.count
+
+ if arrLen == 0 {
+ return 0
+ }
+
+ var sortedArr = arr
+ sortedArr = arr.sorted()
+
+ if (arrLen % 2) != 0 {
+ return sortedArr[Int(floor(Double(arrLen / 2 - 1)))]
+ }
+
+ let mid1 = sortedArr[Int(floor(Double(arrLen / 2 - 1)))]
+ let mid2 = sortedArr[Int(floor(Double(arrLen / 2)))]
+
+ return (mid1 + mid2) / 2
}
-func generateAddressFromPubKey(publicKeyX: String, publicKeyY: String) -> String {
- let publicKeyHex = publicKeyX.addLeading0sForLength64() + publicKeyY.addLeading0sForLength64()
- let publicKeyData = Data(hex: publicKeyHex)
- let ethAddrData = keccak256Data(publicKeyData).suffix(20)
- let ethAddrlower = ethAddrData.toHexString().addHexPrefix()
- return ethAddrlower.toChecksumAddress()
+internal func getProxyCoordinatorEndpointIndex(endpoints: [String], verifier: String, verifierId: String) throws -> BigUInt {
+ let verifierIdString = verifier + verifierId
+ let hashedVerifierId = try KeyUtils.keccak256Data(verifierIdString)
+ let proxyEndPointNum = BigInt(hashedVerifierId, radix: 16)!.modulus(BigInt(endpoints.count))
+ return proxyEndPointNum.magnitude
}
diff --git a/Sources/TorusUtils/Helpers/Error.swift b/Sources/TorusUtils/Helpers/Error.swift
index 943dcea0..a11f87ba 100644
--- a/Sources/TorusUtils/Helpers/Error.swift
+++ b/Sources/TorusUtils/Helpers/Error.swift
@@ -2,27 +2,21 @@ import Foundation
public enum TorusUtilError: Error, Equatable {
case configurationError
- case apiRequestFailed
- case errInResponse(Any)
- case encodingFailed(String? = nil)
- case decodingFailed(String? = nil)
+ case encodingFailed(String = "")
+ case decodingFailed(String = "")
case commitmentRequestFailed
case importShareFailed
case decryptionFailed
- case thresholdError
- case promiseFulfilled
case privateKeyDeriveFailed
- case timeout
- case missingNodePubKeyError
- case unableToDerive
case interpolationFailed
- case nodesUnavailable
case invalidKeySize
+ case invalidPubKeySize
case runtime(_ msg: String)
case retrieveOrImportShareError
case metadataNonceMissing
- case gatingError(_ msg: String? = nil)
- case empty
+ case pubNonceMissing
+ case gatingError(_ msg: String = "")
+ case invalidInput
}
extension TorusUtilError: CustomDebugStringConvertible {
@@ -30,48 +24,36 @@ extension TorusUtilError: CustomDebugStringConvertible {
switch self {
case .configurationError:
return "SDK Configuration incorrect. Network is probably incorrect"
- case .apiRequestFailed:
- return "API request failed or No response from the node"
case let .decodingFailed(response):
- return "JSON Decoding error \(response ?? "")"
- case let .errInResponse(str):
- return "API response error \(str)"
+ return "JSON Decoding error" + response
case .decryptionFailed:
return "Decryption Failed"
case .commitmentRequestFailed:
return "commitment request failed"
case .importShareFailed:
return "import share failed"
- case .thresholdError:
- return "Threshold error"
- case .promiseFulfilled:
- return "Promise fulfilled"
case .privateKeyDeriveFailed:
return "could not derive private key"
- case .timeout:
- return "Timeout"
- case .missingNodePubKeyError:
- return "Missing node pub key for node index"
- case .unableToDerive:
- return "could not derive private key"
case .interpolationFailed:
return "lagrange interpolation failed"
- case .nodesUnavailable:
- return "One or more nodes unavailable"
- case .empty:
- return ""
+ case .invalidInput:
+ return "Input was found to be invalid"
case let .runtime(msg):
return msg
case .invalidKeySize:
return "Invalid key size. Expected 32 bytes"
+ case .invalidPubKeySize:
+ return "Invalid key size. Expected 64 bytes"
case let .encodingFailed(msg):
- return "Could not encode data \(msg ?? "")"
+ return "Could not encode data" + msg
case .retrieveOrImportShareError:
return "retrieve or import share failed"
case .metadataNonceMissing:
return "Unable to fetch metadata nonce"
case let .gatingError(msg):
- return "could not process request \(msg ?? "")"
+ return "could not process request" + msg
+ case .pubNonceMissing:
+ return "Public nonce is missing"
}
}
@@ -88,38 +70,24 @@ extension TorusUtilError: LocalizedError {
switch self {
case .configurationError:
return "SDK Configuration incorrect. Network is probably incorrect"
- case .apiRequestFailed:
- return "API request failed or No response from the node"
case let .decodingFailed(response):
- return "JSON Decoding error \(response ?? "")"
- case let .errInResponse(str):
- return "API response error \(str)"
+ return "JSON Decoding error" + response
case .decryptionFailed:
return "Decryption Failed"
case .commitmentRequestFailed:
return "commitment request failed"
- case .thresholdError:
- return "Threshold error"
- case .promiseFulfilled:
- return "Promise fulfilled"
- case .timeout:
- return "Timeout"
- case .unableToDerive:
- return "could not derive private key"
case .interpolationFailed:
return "lagrange interpolation failed"
- case .nodesUnavailable:
- return "One or more nodes unavailable"
- case .empty:
- return ""
+ case .invalidInput:
+ return "Input was found to be invalid"
case let .runtime(msg):
return msg
case .invalidKeySize:
return "Invalid key size. Expected 32 bytes"
case let .encodingFailed(msg):
- return "Could not encode data \(msg ?? "")"
+ return "Could not encode data " + msg
case let .gatingError(msg):
- return "\(msg ?? "")"
+ return msg
default:
return "default Error msg"
}
diff --git a/Sources/TorusUtils/Helpers/JSONRPCRequest.swift b/Sources/TorusUtils/Helpers/JSONRPCRequest.swift
deleted file mode 100644
index 32478788..00000000
--- a/Sources/TorusUtils/Helpers/JSONRPCRequest.swift
+++ /dev/null
@@ -1,238 +0,0 @@
-import BigInt
-import Foundation
-
-import AnyCodable
-public struct GetPublicAddressOrKeyAssignParams: Encodable {
- public var verifier: String
- public var verifier_id: String
- public var extended_verifier_id: String?
- public var one_key_flow: Bool
- public var fetch_node_index: Bool
-}
-
-public struct SignerResponse: Codable {
- public var torusNonce: String
- public var torusSignature: String
- public var torusTimestamp: String
-
- enum SignerResponseKeys: String, CodingKey {
- case torusNonce = "torus-nonce"
- case torusTimestamp = "torus-timestamp"
- case torusSignature = "torus-signature"
- }
-
- public func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: SignerResponseKeys.self)
- try container.encode(torusNonce, forKey: .torusNonce)
- try container.encode(torusSignature, forKey: .torusSignature)
- try container.encode(torusTimestamp, forKey: .torusTimestamp)
- }
-
- public init(torusNonce: String, torusTimestamp: String, torusSignature: String) {
- self.torusNonce = torusNonce
- self.torusTimestamp = torusTimestamp
- self.torusSignature = torusSignature
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: SignerResponseKeys.self)
- let nonce: String = try container.decode(String.self, forKey: .torusNonce)
- let signature: String = try container.decode(String.self, forKey: .torusSignature)
- let timestamp: String = try container.decode(String.self, forKey: .torusTimestamp)
- self.init(torusNonce: nonce, torusTimestamp: timestamp, torusSignature: signature)
- }
-}
-
-public struct KeyAssignRequest: Encodable {
- public var id: Int = 10
- public var jsonrpc: String = "2.0"
- public var method: String = JRPC_METHODS.LEGACY_KEY_ASSIGN
- public var params: Any
- public var torusNonce: String
- public var torusSignature: String
- public var torusTimestamp: String
-
- enum KeyAssignRequestKeys: String, CodingKey {
- case id
- case jsonrpc
- case method
- case params
- case torusNonce = "torus-nonce"
- case torusTimestamp = "torus-timestamp"
- case torusSignature = "torus-signature"
- }
-
- public func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: KeyAssignRequestKeys.self)
- try container.encode(id, forKey: .id)
-
- try container.encode(jsonrpc, forKey: .jsonrpc)
- try container.encode(method, forKey: .method)
-
- if let _ = params as? [String: String] {
- try container.encode(params as! [String: String], forKey: .params)
- }
- if let _ = params as? [String: [String: [String: String]]] {
- try container.encode(params as! [String: [String: [String: String]]], forKey: .params)
- }
-
- try container.encode(torusNonce, forKey: .torusNonce)
- try container.encode(torusTimestamp, forKey: .torusTimestamp)
- try container.encode(torusSignature, forKey: .torusSignature)
- }
-
- public init(params: Any, signerResponse: SignerResponse) {
- self.params = params
- torusNonce = signerResponse.torusNonce
- torusSignature = signerResponse.torusSignature
- torusTimestamp = signerResponse.torusTimestamp
- }
-}
-
-public indirect enum MixedValue: Codable {
- case integer(Int)
- case boolean(Bool)
- case string(String)
- case mixValue([String: MixedValue])
- case array([MixedValue])
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.singleValueContainer()
- if let value = try? container.decode(Bool.self) {
- self = .boolean(value)
- } else if let value = try? container.decode(Int.self) {
- self = .integer(value)
- } else if let value = try? container.decode(String.self) {
- self = .string(value)
- } else if let value = try? container.decode([String: MixedValue].self) {
- self = .mixValue(value)
- } else if let value = try? container.decode([MixedValue].self) {
- self = .array(value)
- } else {
- throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid mixed value")
- }
- }
-
- public func encode(to encoder: Encoder) throws {
- var container = encoder.singleValueContainer()
- switch self {
- case let .integer(value):
- try container.encode(value)
- case let .boolean(value):
- try container.encode(value)
- case let .string(value):
- try container.encode(value)
- case let .mixValue(value):
- try container.encode(value)
- case let .array(value):
- try container.encode(value)
- }
- }
-}
-
-/// JSON RPC request structure for serialization and deserialization purposes.
-public struct JSONRPCrequest: Encodable {
- public var jsonrpc: String = "2.0"
- public var method: String
- public var params: T
- public var id: Int = 10
-
- enum CodingKeys: String, CodingKey {
- case jsonrpc
- case method
- case params
- case id
- }
-}
-
-public struct JSONRPCresponse: Decodable {
- public var id: Int
- public var jsonrpc = "2.0"
- public var result: Any?
- public var error: ErrorMessage?
- public var message: String?
-
- enum JSONRPCresponseKeys: String, CodingKey {
- case id
- case jsonrpc
- case result
- case error
- case errorMessage
- }
-
- public init(id: Int, jsonrpc: String, result: Decodable?, error: ErrorMessage?) {
- self.id = id
- self.jsonrpc = jsonrpc
- self.result = result
- self.error = error
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: JSONRPCresponseKeys.self)
- let id: Int = try container.decode(Int.self, forKey: .id)
- let jsonrpc: String = try container.decode(String.self, forKey: .jsonrpc)
- let errorMessage = try container.decodeIfPresent(ErrorMessage.self, forKey: .error)
- if errorMessage != nil {
- self.init(id: id, jsonrpc: jsonrpc, result: nil, error: errorMessage)
- return
- }
-
- var result: Decodable?
- if let rawValue = try? container.decodeIfPresent(VerifierLookupResponse.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(ShareRequestResult.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(LegacyShareRequestResult.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(CommitmentRequestResponse.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(LegacyLookupResponse.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(String.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(Int.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent(Bool.self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([Bool].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([Int].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([String].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([String: String].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([String: [[String: String]]].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([String: Int].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([String: [String: [String: String]]].self, forKey: .result) {
- result = rawValue
- } else if let rawValue = try? container.decodeIfPresent([String: [String: [String: [String: String?]]]].self, forKey: .result) {
- result = rawValue
- } else {
- result = nil
- }
-
- self.init(id: id, jsonrpc: jsonrpc, result: result, error: nil)
- }
-}
-
-public struct ErrorMessage: Codable {
- public var code: Int
- public var message: String
- public var data: String
-
- enum ErrorMessageKeys: String, CodingKey {
- case code
- case message
- case data
- }
-
- public func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: ErrorMessageKeys.self)
- try container.encode(message, forKey: .message)
- try container.encode(code, forKey: .code)
- try container.encode(data, forKey: .data)
- }
-}
diff --git a/Sources/TorusUtils/Helpers/KeyUtils.swift b/Sources/TorusUtils/Helpers/KeyUtils.swift
new file mode 100644
index 00000000..51e9d45e
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/KeyUtils.swift
@@ -0,0 +1,194 @@
+import BigInt
+import Foundation
+#if canImport(curveSecp256k1)
+ import curveSecp256k1
+#endif
+
+enum TorusKeyType: String, Equatable, Hashable, Codable {
+ case secp256k1
+}
+
+public class KeyUtils {
+ public static func keccak256Data(_ input: String) throws -> String {
+ guard let data = input.data(using: .utf8) else { throw TorusUtilError.invalidInput }
+ return try keccak256(data: data).toHexString()
+ }
+
+ public static func keccak256Data(_ data: Data) throws -> Data {
+ return try keccak256(data: data)
+ }
+
+ public static func randomNonce() throws -> String {
+ return try generateSecret()
+ }
+
+ public static func generateSecret() throws -> String {
+ let secret = SecretKey()
+ return try secret.serialize().addLeading0sForLength64()
+ }
+
+ internal static func getOrderOfCurve() -> BigInt {
+ let orderHex = CURVE_N
+ let order = BigInt(orderHex, radix: 16)!
+ return order
+ }
+
+ internal static func generateAddressFromPubKey(publicKeyX: String, publicKeyY: String) throws -> String {
+ let publicKeyHex = KeyUtils.getPublicKeyFromCoords(pubKeyX: publicKeyX, pubKeyY: publicKeyY, prefixed: false)
+ let publicKeyData = Data(hex: publicKeyHex)
+ let ethAddrData = try keccak256Data(publicKeyData).suffix(20)
+ let ethAddrlower = ethAddrData.toHexString().addHexPrefix().lowercased()
+ return try toChecksumAddress(hexAddress: ethAddrlower)
+ }
+
+ internal static func toChecksumAddress(hexAddress: String) throws -> String {
+ let lowerCaseAddress = hexAddress.stripHexPrefix().lowercased()
+ let arr = Array(lowerCaseAddress)
+ let hash = try keccak256Data(lowerCaseAddress.data(using: .utf8) ?? Data()).toHexString()
+
+ var result = String()
+ for i in 0 ... lowerCaseAddress.count - 1 {
+ let iIndex = hash.index(hash.startIndex, offsetBy: i)
+ if let val = hash[iIndex].hexDigitValue, val >= 8 {
+ result.append(arr[i].uppercased())
+ } else {
+ result.append(arr[i])
+ }
+ }
+ return result.addHexPrefix()
+ }
+
+ public static func getPublicKeyCoords(pubKey: String) throws -> (String, String) {
+ var publicKeyUnprefixed = pubKey
+ if publicKeyUnprefixed.count > 128 {
+ publicKeyUnprefixed = publicKeyUnprefixed.strip04Prefix()
+ }
+
+ if !(publicKeyUnprefixed.count == 128) {
+ throw TorusUtilError.invalidPubKeySize
+ }
+
+ return (String(publicKeyUnprefixed.prefix(64)), String(publicKeyUnprefixed.suffix(64)))
+ }
+
+ public static func getPublicKeyFromCoords(pubKeyX: String, pubKeyY: String, prefixed: Bool = true) -> String {
+ let X = pubKeyX.addLeading0sForLength64()
+ let Y = pubKeyY.addLeading0sForLength64()
+
+ return prefixed ? (X + Y).add04PrefixUnchecked() : X + Y
+ }
+
+ internal static func combinePublicKeys(keys: [String], compressed: Bool = false) throws -> String {
+ var collection: [PublicKey] = []
+
+ for item in keys {
+ try collection.append(PublicKey(hex: item))
+ }
+
+ return try combinePublicKeys(keys: collection, compressed: compressed)
+ }
+
+ internal static func combinePublicKeys(keys: [PublicKey], compressed: Bool = false) throws -> String {
+ let collection = PublicKeyCollection()
+ for item in keys {
+ try collection.insert(key: item)
+ }
+
+ let added = try PublicKey.combine(collection: collection).serialize(compressed: compressed)
+ return added
+ }
+
+ internal static func generateKeyData(privateKey: String) throws -> PrivateKeyData {
+ let scalar = BigInt(privateKey, radix: 16)!
+
+ let randomNonce = BigInt(try SecretKey().serialize().addLeading0sForLength64(), radix: 16)!
+
+ let oAuthKey = (scalar - randomNonce).modulus(KeyUtils.getOrderOfCurve())
+
+ let oAuthPubKeyString = try SecretKey(hex: oAuthKey.magnitude.serialize().hexString.addLeading0sForLength64()).toPublic().serialize(compressed: false)
+
+ let finalUserPubKey = try SecretKey(hex: privateKey).toPublic().serialize(compressed: false)
+
+ return PrivateKeyData(
+ oAuthKey: oAuthKey.magnitude.serialize().hexString.addLeading0sForLength64(),
+ oAuthPubKey: oAuthPubKeyString,
+ nonce: randomNonce.magnitude.serialize().hexString.addLeading0sForLength64(),
+ signingKey: oAuthKey.magnitude.serialize().hexString.addLeading0sForLength64(),
+ signingPubKey: oAuthPubKeyString,
+ finalKey: privateKey,
+ finalPubKey: finalUserPubKey
+ )
+ }
+
+ private static func generateNonceMetadataParams(operation: String, privateKey: BigInt, nonce: BigInt?, serverTimeOffset: Int?) throws -> NonceMetadataParams {
+ let privKey = try SecretKey(hex: privateKey.magnitude.serialize().hexString.addLeading0sForLength64())
+
+ var setData = SetNonceData(operation: operation, timestamp: String(BigUInt(trunc(Double((serverTimeOffset ?? 0) + Int(Date().timeIntervalSince1970)))), radix: 16))
+
+ if nonce != nil {
+ setData.data = nonce!.magnitude.serialize().hexString.addLeading0sForLength64()
+ }
+
+ let publicKey = try privKey.toPublic().serialize(compressed: false)
+
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ let encodedData = try encoder
+ .encode(setData)
+
+ let hash = try KeyUtils.keccak256Data(encodedData).toHexString()
+ let sigData = try ECDSA.signRecoverable(key: privKey, hash: hash).serialize()
+ _ = try ECDSA.recover(signature: Signature(hex: sigData), hash: hash)
+ let (pubKeyX, pubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: publicKey)
+ return .init(pub_key_X: pubKeyX, pub_key_Y: pubKeyY, setData: setData, encodedData: encodedData.base64EncodedString(), signature: Data(hex: sigData).base64EncodedString())
+ }
+
+ internal static func generateShares(keyType: TorusKeyType = .secp256k1, serverTimeOffset: Int, nodeIndexes: [BigUInt], nodePubKeys: [INodePub], privateKey: String) throws -> [ImportedShare] {
+ if keyType != TorusKeyType.secp256k1 {
+ throw TorusUtilError.runtime("Unsupported key type")
+ }
+
+ let keyData = try generateKeyData(privateKey: privateKey)
+
+ let threshold = Int(trunc(Double((nodePubKeys.count / 2) + 1)))
+ let degree = threshold - 1
+ let nodeIndexesBN = nodeIndexes.map({ BigInt($0) })
+
+ let poly = try Lagrange.generateRandomPolynomial(degree: degree, secret: BigInt(keyData.oAuthKey, radix: 16))
+ let shares = poly.generateShares(shareIndexes: nodeIndexesBN)
+ let nonceParams = try KeyUtils.generateNonceMetadataParams(operation: "getOrSetNonce", privateKey: BigInt(keyData.signingKey, radix: 16)!, nonce: BigInt(keyData.nonce, radix: 16), serverTimeOffset: serverTimeOffset)
+
+ var encShares: [Ecies] = []
+ for i in 0 ..< nodePubKeys.count {
+ let shareInfo: Share = shares[nodeIndexes[i].magnitude.serialize().hexString.addLeading0sForLength64()]!
+
+ let nodePub = KeyUtils.getPublicKeyFromCoords(pubKeyX: nodePubKeys[i].X, pubKeyY: nodePubKeys[i].Y)
+ let nodePubKey = try PublicKey(hex: nodePub).serialize(compressed: true)
+ let encrypted = try MetadataUtils.encrypt(publicKey: nodePubKey, msg: shareInfo.share.magnitude.serialize().hexString.addLeading0sForLength64())
+ encShares.append(encrypted)
+ }
+
+ var sharesData: [ImportedShare] = []
+ for i in 0 ..< nodePubKeys.count {
+ let encrypted = encShares[i]
+ let (oAuthPubX, oAuthPubY) = try getPublicKeyCoords(pubKey: try PublicKey(hex: keyData.oAuthPubKey).serialize(compressed: false))
+ let (signingPubX, signingPubY) = try getPublicKeyCoords(pubKey: try PublicKey(hex: keyData.signingPubKey).serialize(compressed: false))
+ let (finalPubX, finalPubY) = try getPublicKeyCoords(pubKey: try PublicKey(hex: keyData.finalPubKey).serialize(compressed: false))
+ let finalPoint = try Point(x: finalPubX, y: finalPubY)
+ let importShare = ImportedShare(
+ oauth_pub_key_x: oAuthPubX,
+ oauth_pub_key_y: oAuthPubY,
+ final_user_point: finalPoint,
+ signing_pub_key_x: signingPubX,
+ signing_pub_key_y: signingPubY,
+ encryptedShare: encrypted.ciphertext,
+ encryptedShareMetadata: EciesHexOmitCiphertext(from: encrypted),
+ node_index: Int(nodeIndexes[i].magnitude.serialize().hexString.addLeading0sForLength64(), radix: 16)!,
+ nonce_data: nonceParams.encodedData,
+ nonce_signature: nonceParams.signature)
+ sharesData.append(importShare)
+ }
+
+ return sharesData
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift b/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift
index a284bc23..62df8e57 100644
--- a/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift
+++ b/Sources/TorusUtils/Helpers/LangrangeInterpolatePoly.swift
@@ -4,177 +4,174 @@ import Foundation
import curveSecp256k1
#endif
-func modInverse(_ a: BigInt, _ m: BigInt) -> BigInt? {
- var (t, newT) = (BigInt(0), BigInt(1))
- var (r, newR) = (m, a)
-
- while newR != 0 {
- let quotient = r / newR
- (t, newT) = (newT, t - quotient * newT)
- (r, newR) = (newR, r - quotient * newR)
+internal class Lagrange {
+ public static func generatePrivateExcludingIndexes(shareIndexes: [BigInt]) throws -> BigInt {
+ let key = BigInt(Data(hex: try SecretKey().serialize().addLeading0sForLength64()))
+ if shareIndexes.contains(where: { $0 == key }) {
+ return try generatePrivateExcludingIndexes(shareIndexes: shareIndexes)
+ }
+ return key
}
- if r > 1 {
- return nil // Modular inverse does not exist
- }
- if t < 0 {
- t += m
+ public static func generateEmptyBNArray(length: Int) -> [BigInt] {
+ return Array(repeating: BigInt(0), count: length)
}
- return t
-}
-
-func generatePrivateExcludingIndexes(shareIndexes: [BigInt]) throws -> BigInt {
- let key = BigInt(Data(hex: try SecretKey().serialize().addLeading0sForLength64()))
- if shareIndexes.contains(where: { $0 == key }) {
- return try generatePrivateExcludingIndexes(shareIndexes: shareIndexes)
- }
- return key
-}
-
-func generateEmptyBNArray(length: Int) -> [BigInt] {
- return Array(repeating: BigInt(0), count: length)
-}
-
-func denominator(i: Int, innerPoints: [Point]) -> BigInt {
- var result = BigInt(1)
- let xi = innerPoints[i].x
- for j in (0 ..< innerPoints.count).reversed() {
- if i != j {
- var tmp = xi
- tmp = tmp - innerPoints[j].x
- tmp %= getOrderOfCurve()
- result = result * tmp
- result %= getOrderOfCurve()
+ public static func denominator(i: Int, innerPoints: [Point]) -> BigInt {
+ var result = BigInt(1)
+ let xi = innerPoints[i].x
+ for j in (0 ..< innerPoints.count).reversed() {
+ if i != j {
+ var tmp = xi
+ tmp = (tmp - innerPoints[j].x).modulus(KeyUtils.getOrderOfCurve())
+ result = (result * tmp).modulus(KeyUtils.getOrderOfCurve())
+ }
}
+ return result
}
- return result
-}
-func interpolationPoly(i: Int, innerPoints: [Point]) -> [BigInt] {
- var coefficients = generateEmptyBNArray(length: innerPoints.count)
- let d = denominator(i: i, innerPoints: innerPoints)
- if d == BigInt(0) {
- fatalError("Denominator for interpolationPoly is 0")
- }
- coefficients[0] = d.inverse(getOrderOfCurve())!
- for k in 0 ..< innerPoints.count {
- var newCoefficients = generateEmptyBNArray(length: innerPoints.count)
- if k != i {
- var j: Int
- if k < i {
- j = k + 1
- } else {
- j = k
- }
- j -= 1
- while j >= 0 {
- newCoefficients[j + 1] = newCoefficients[j + 1] + coefficients[j] % getOrderOfCurve()
- var tmp = BigInt(innerPoints[k].x)
- tmp = tmp * coefficients[j] % getOrderOfCurve()
- newCoefficients[j] = newCoefficients[j] - tmp % getOrderOfCurve()
+ public static func interpolationPoly(i: Int, innerPoints: [Point]) -> [BigInt] {
+ var coefficients = generateEmptyBNArray(length: innerPoints.count)
+ let d = denominator(i: i, innerPoints: innerPoints)
+ if d == BigInt(0) {
+ fatalError("Denominator for interpolationPoly is 0")
+ }
+ coefficients[0] = d.inverse(KeyUtils.getOrderOfCurve())!
+ for k in 0 ..< innerPoints.count {
+ var newCoefficients = generateEmptyBNArray(length: innerPoints.count)
+ if k != i {
+ var j: Int
+ if k < i {
+ j = k + 1
+ } else {
+ j = k
+ }
j -= 1
+ while j >= 0 {
+ newCoefficients[j + 1] = (newCoefficients[j + 1] + coefficients[j]).modulus(KeyUtils.getOrderOfCurve())
+ var tmp = BigInt(innerPoints[k].x)
+ tmp = (tmp * coefficients[j]).modulus(KeyUtils.getOrderOfCurve())
+ newCoefficients[j] = (newCoefficients[j] - tmp).modulus(KeyUtils.getOrderOfCurve())
+ j -= 1
+ }
+ coefficients = newCoefficients
}
- coefficients = newCoefficients
}
+ return coefficients
}
- return coefficients
-}
-func pointSort(innerPoints: [Point]) -> [Point] {
- var pointArrClone = innerPoints
- pointArrClone.sort { $0.x < $1.x }
- return pointArrClone
-}
+ public static func pointSort(innerPoints: [Point]) -> [Point] {
+ var pointArrClone = innerPoints
+ pointArrClone.sort { $0.x < $1.x }
+ return pointArrClone
+ }
-func lagrange(unsortedPoints: [Point]) -> Polynomial {
- let sortedPoints = pointSort(innerPoints: unsortedPoints)
- var polynomial = generateEmptyBNArray(length: sortedPoints.count)
- for i in 0 ..< sortedPoints.count {
- let coefficients = interpolationPoly(i: i, innerPoints: sortedPoints)
- for k in 0 ..< sortedPoints.count {
- var tmp = BigInt(sortedPoints[i].y)
- tmp = tmp * coefficients[k] % getOrderOfCurve()
- polynomial[k] = (polynomial[k] + tmp) % getOrderOfCurve()
+ public static func lagrange(unsortedPoints: [Point]) -> Polynomial {
+ let sortedPoints = pointSort(innerPoints: unsortedPoints)
+ var polynomial = generateEmptyBNArray(length: sortedPoints.count)
+ for i in 0 ..< sortedPoints.count {
+ let coefficients = interpolationPoly(i: i, innerPoints: sortedPoints)
+ for k in 0 ..< sortedPoints.count {
+ var tmp = BigInt(sortedPoints[i].y)
+ tmp = (tmp * coefficients[k]).modulus(KeyUtils.getOrderOfCurve())
+ polynomial[k] = (polynomial[k] + tmp).modulus(KeyUtils.getOrderOfCurve())
+ }
}
+ return Polynomial(polynomial: polynomial)
}
- return Polynomial(polynomial: polynomial)
-}
-func lagrangeInterpolatePolynomial(points: [Point]) -> Polynomial {
- return lagrange(unsortedPoints: points)
-}
+ public static func lagrangeInterpolatePolynomial(points: [Point]) -> Polynomial {
+ return lagrange(unsortedPoints: points)
+ }
-func lagrangeInterpolationWithNodeIndex(shares: [BigInt], nodeIndex: [BigInt]) -> BigInt {
- let modulus = BigInt(CURVE_N, radix: 16)!
+ public static func lagrangeInterpolation(shares: [String], nodeIndex: [Int]) throws -> String {
+ let sharesList: [BigInt] = shares.map({ BigInt($0.addLeading0sForLength64(), radix: 16) }).filter({ $0 != nil }).map({ $0! })
+ let indexList: [BigInt] = nodeIndex.map({ BigInt($0) })
- if shares.count != nodeIndex.count {
- fatalError("shares not equal to nodeIndex length in lagrangeInterpolation")
- }
+ if sharesList.count != indexList.count {
+ throw TorusUtilError.runtime("sharesList not equal to indexList length in lagrangeInterpolation")
+ }
- var secret = BigInt(0)
- for i in 0 ..< shares.count {
- var upper = BigInt(1)
- var lower = BigInt(1)
- for j in 0 ..< shares.count {
- if i != j {
- upper *= -nodeIndex[j]
- upper %= modulus
- var temp = nodeIndex[i] - nodeIndex[j]
- temp %= modulus
- lower *= temp
- lower %= modulus
+ var secret = BigUInt("0")
+ var sharesDecrypt = 0
+
+ for i in 0 ..< sharesList.count {
+ var upper = BigInt(1)
+ var lower = BigInt(1)
+ for j in 0 ..< sharesList.count {
+ if i != j {
+ let negatedJ = indexList[j] * BigInt(-1)
+ upper = upper * negatedJ
+ upper = upper.modulus(KeyUtils.getOrderOfCurve())
+
+ var temp = indexList[i] - indexList[j]
+ temp = temp.modulus(KeyUtils.getOrderOfCurve())
+ lower = (lower * temp).modulus(KeyUtils.getOrderOfCurve())
+ }
}
+ guard
+ let inv = lower.inverse(KeyUtils.getOrderOfCurve())
+ else {
+ throw TorusUtilError.decryptionFailed
+ }
+ var delta = (upper * inv).modulus(KeyUtils.getOrderOfCurve())
+ delta = (delta * sharesList[i]).modulus(KeyUtils.getOrderOfCurve())
+ secret = BigUInt((BigInt(secret) + delta).modulus(KeyUtils.getOrderOfCurve()))
+ sharesDecrypt += 1
}
- var delta = upper * modInverse(lower, modulus)!
- delta %= modulus
- delta = delta * shares[i]
- delta %= modulus
- secret += delta
- }
- return secret % modulus
-}
+ if secret == BigUInt(0) {
+ throw TorusUtilError.interpolationFailed
+ }
-func generateRandomPolynomial(degree: Int, secret: BigInt? = nil, deterministicShares: [Share]? = nil) throws -> Polynomial {
- var actualS = secret
- if secret == nil {
- actualS = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)])
+ let secretString = secret.serialize().hexString.addLeading0sForLength64()
+ if sharesDecrypt == sharesList.count {
+ return secretString
+ } else {
+ throw TorusUtilError.interpolationFailed
+ }
}
- if deterministicShares == nil {
- var poly = [actualS!]
- for _ in 0 ..< degree {
- let share = try generatePrivateExcludingIndexes(shareIndexes: poly)
- poly.append(share)
+ public static func generateRandomPolynomial(degree: Int, secret: BigInt? = nil, deterministicShares: [Share]? = nil) throws -> Polynomial {
+ var actualS = secret
+ if secret == nil {
+ actualS = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)])
}
- return Polynomial(polynomial: poly)
- }
+ if deterministicShares == nil {
+ var poly = [actualS!]
+ for _ in 0 ..< degree {
+ let share = try generatePrivateExcludingIndexes(shareIndexes: poly)
+ poly.append(share)
+ }
- guard let deterministicShares = deterministicShares else {
- throw NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Deterministic shares in generateRandomPolynomial should be an array"])
- }
+ return Polynomial(polynomial: poly)
+ }
- if deterministicShares.count > degree {
- throw NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Deterministic shares in generateRandomPolynomial should be less or equal than degree to ensure an element of randomness"])
- }
+ guard let deterministicShares = deterministicShares else {
+ throw NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Deterministic shares in generateRandomPolynomial should be an array"])
+ }
- var points = [String: Point]()
- for share in deterministicShares {
- points[String(share.shareIndex, radix: 16).addLeading0sForLength64()] =
- Point(x: share.shareIndex, y: share.share)
- }
+ if deterministicShares.count > degree {
+ throw NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Deterministic shares in generateRandomPolynomial should be less or equal than degree to ensure an element of randomness"])
+ }
- let remainingDegree = degree - deterministicShares.count
- for _ in 0 ..< remainingDegree {
- var shareIndex = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)])
- while points[shareIndex.description.padding(toLength: 64, withPad: "0", startingAt: 0)] != nil {
- shareIndex = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)])
+ var points = [String: Point]()
+ for share in deterministicShares {
+ points[String(share.shareIndex, radix: 16).addLeading0sForLength64()] =
+ Point(x: share.shareIndex, y: share.share)
}
- points[String(shareIndex, radix: 16).addLeading0sForLength64()] = Point(x: shareIndex, y: BigInt(Data(hex:try SecretKey().serialize().addLeading0sForLength64())))
- }
- points["0"] = Point(x: BigInt(0), y: actualS!)
- return lagrangeInterpolatePolynomial(points: Array(points.values))
+ let remainingDegree = degree - deterministicShares.count
+ for _ in 0 ..< remainingDegree {
+ var shareIndex = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)])
+ while points[shareIndex.magnitude.serialize().hexString.addLeading0sForLength64()] != nil {
+ shareIndex = try generatePrivateExcludingIndexes(shareIndexes: [BigInt(0)])
+ }
+ points[shareIndex.magnitude.serialize().hexString.addLeading0sForLength64()] = Point(x: shareIndex, y: BigInt(Data(hex: try SecretKey().serialize().addLeading0sForLength64())))
+ }
+
+ points["0"] = Point(x: BigInt(0), y: actualS!)
+ return lagrangeInterpolatePolynomial(points: Array(points.values))
+ }
}
diff --git a/Sources/TorusUtils/Helpers/MetadataUtils.swift b/Sources/TorusUtils/Helpers/MetadataUtils.swift
new file mode 100644
index 00000000..ecb70c0c
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/MetadataUtils.swift
@@ -0,0 +1,109 @@
+import BigInt
+import FetchNodeDetails
+import Foundation
+import OSLog
+#if canImport(curveSecp256k1)
+ import curveSecp256k1
+#endif
+
+internal class MetadataUtils {
+ public static func decryptNodeData(eciesData: EciesHexOmitCiphertext, ciphertextHex: String, privKey: String) throws -> String {
+ let eciesOpts = ECIES(
+ iv: eciesData.iv,
+ ephemPublicKey: eciesData.ephemPublicKey,
+ ciphertext: ciphertextHex,
+ mac: eciesData.mac
+ )
+
+ let decryptedSigBuffer = try decrypt(privateKey: privKey, opts: eciesOpts).hexString
+ return decryptedSigBuffer
+ }
+
+ public static func decrypt(privateKey: String, opts: ECIES) throws -> Data {
+ let secret = try SecretKey(hex: privateKey)
+ var publicKey = opts.ephemPublicKey
+ if opts.ephemPublicKey.count == 128 { // missing 04 prefix
+ publicKey = publicKey.add04PrefixUnchecked()
+ }
+ let msg = try EncryptedMessage(cipherText: opts.ciphertext, ephemeralPublicKey: PublicKey(hex: publicKey), iv: opts.iv, mac: opts.mac)
+ let result = try Encryption.decrypt(sk: secret, encrypted: msg)
+ return result
+ }
+
+ public static func encrypt(publicKey: String, msg: String) throws -> Ecies {
+ let data = Data(hex: msg)
+ let curveMsg = try Encryption.encrypt(pk: PublicKey(hex: publicKey), plainText: data)
+ return try .init(iv: curveMsg.iv(), ephemPublicKey: curveMsg.ephemeralPublicKey().serialize(compressed: false), ciphertext: curveMsg.chipherText(), mac: curveMsg.mac())
+ }
+
+ internal static func makeUrlRequest(url: String, httpMethod: httpMethod = .post) throws -> URLRequest {
+ guard
+ let url = URL(string: url)
+ else {
+ throw TorusUtilError.runtime("Invalid Url \(url)")
+ }
+ var rq = URLRequest(url: url)
+ rq.httpMethod = httpMethod.name
+ rq.addValue("application/json", forHTTPHeaderField: "Content-Type")
+ rq.addValue("application/json", forHTTPHeaderField: "Accept")
+ return rq
+ }
+
+ public static func generateMetadataParams(serverTimeOffset: Int, message: String, privateKey: String, X: String, Y: String, keyType: TorusKeyType? = nil) throws -> MetadataParams {
+ let privKey = try SecretKey(hex: privateKey)
+
+ let timeStamp = String(BigUInt(TimeInterval(serverTimeOffset) + Date().timeIntervalSince1970), radix: 16)
+ let setData: MetadataParams.SetData = .init(data: message, timestamp: timeStamp)
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ let encodedData = try encoder
+ .encode(setData)
+
+ let hash = try KeyUtils.keccak256Data(encodedData).toHexString()
+ let sigData = try ECDSA.signRecoverable(key: privKey, hash: hash).serialize()
+ _ = try ECDSA.recover(signature: Signature(hex: sigData), hash: hash)
+ return .init(pub_key_X: X, pub_key_Y: Y, setData: setData, signature: Data(hex: sigData).base64EncodedString(), keyType: keyType)
+ }
+
+ public static func getMetadata(legacyMetadataHost: String, params: GetMetadataParams) async throws -> BigUInt {
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ var request = try makeUrlRequest(url: "\(legacyMetadataHost)/get")
+ request.httpBody = try encoder.encode(params)
+ let urlSession = URLSession(configuration: .default)
+ let val = try await urlSession.data(for: request)
+ let data: GetMetadataResponse = try JSONDecoder().decode(GetMetadataResponse.self, from: val.0)
+ let msg: String = data.message
+ let ret = BigUInt(msg, radix: 16)!
+ return ret
+ }
+
+ public static func getOrSetNonce(legacyMetadataHost: String, serverTimeOffset: Int, X: String, Y: String, privateKey: String? = nil, getOnly: Bool = false, keyType: TorusKeyType? = nil) async throws -> GetOrSetNonceResult {
+ var data: Data
+ let msg = getOnly ? "getNonce" : "getOrSetNonce"
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ if privateKey != nil {
+ let val = try generateMetadataParams(serverTimeOffset: serverTimeOffset, message: msg, privateKey: privateKey!, X: X, Y: Y)
+ data = try encoder.encode(val)
+ } else {
+ let val = GetNonceParams(pub_key_X: X, pub_key_Y: Y, set_data: GetNonceSetDataParams(data: msg))
+ data = try encoder.encode(val)
+ }
+ var request = try makeUrlRequest(url: "\(legacyMetadataHost)/get_or_set_nonce")
+ request.httpBody = data
+ let urlSession = URLSession(configuration: .default)
+ let val = try await urlSession.data(for: request)
+
+ let decoded = try JSONDecoder().decode(GetOrSetNonceResult.self, from: val.0)
+ return decoded
+ }
+
+ public static func getOrSetSapphireMetadataNonce(metadataHost: String, network: TorusNetwork, X: String, Y: String, serverTimeOffset: Int? = nil, privateKey: String? = nil, getOnly: Bool = false, keyType: TorusKeyType = .secp256k1) async throws -> GetOrSetNonceResult {
+ if case .sapphire = network {
+ return try await getOrSetNonce(legacyMetadataHost: metadataHost, serverTimeOffset: serverTimeOffset ?? Int(trunc(Double(0 + Int(Date().timeIntervalSince1970)))), X: X, Y: Y, privateKey: privateKey, getOnly: getOnly, keyType: keyType)
+ } else {
+ throw TorusUtilError.metadataNonceMissing
+ }
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/NodeUtils.swift b/Sources/TorusUtils/Helpers/NodeUtils.swift
new file mode 100644
index 00000000..41e2f2fe
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/NodeUtils.swift
@@ -0,0 +1,597 @@
+import BigInt
+import FetchNodeDetails
+import Foundation
+import OSLog
+#if canImport(curveSecp256k1)
+ import curveSecp256k1
+#endif
+
+internal class NodeUtils {
+ public static func getPubKeyOrKeyAssign(
+ endpoints: [String],
+ network: TorusNetwork,
+ verifier: String,
+ verifierId: String,
+ legacyMetadataHost: String,
+ serverTimeOffset: Int? = nil,
+ extendedVerifierId: String? = nil) async throws -> KeyLookupResult {
+ let threshold = Int(trunc(Double((endpoints.count / 2) + 1)))
+
+ let params = GetOrSetKeyParams(distributed_metadata: true, verifier: verifier, verifier_id: verifierId, extended_verifier_id: extendedVerifierId, one_key_flow: true, fetch_node_index: true, client_time: String(Int(trunc(Double((serverTimeOffset ?? 0) + Int(Date().timeIntervalSince1970))))))
+ let jsonRPCRequest = JRPCRequest(
+ method: JRPC_METHODS.GET_OR_SET_KEY,
+ params: params
+ )
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ let rpcdata = try encoder.encode(jsonRPCRequest)
+
+ var nonceResult: GetOrSetNonceResult?
+ var nodeIndexes: [Int] = []
+
+ let (keyResult, lookupResults, errorResult): (KeyLookupResult.KeyResult?, [JRPCResponse?], ErrorMessage?) = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: (KeyLookupResult.KeyResult?, [JRPCResponse?], ErrorMessage?).self) { group -> (KeyLookupResult.KeyResult?, [JRPCResponse?], ErrorMessage?) in
+ for endpoint in endpoints {
+ group.addTask {
+ do {
+ var request = try MetadataUtils.makeUrlRequest(url: endpoint)
+ request.httpBody = rpcdata
+ let val = try await URLSession(configuration: .default).data(for: request)
+ let decoded = try JSONDecoder().decode(JRPCResponse.self, from: val.0)
+ return decoded
+ } catch {
+ return nil
+ }
+ }
+ }
+ var collected = [JRPCResponse?]()
+ var errorResult: ErrorMessage?
+ var lookupPubKeys = [JRPCResponse?]()
+ var keyResult: KeyLookupResult.KeyResult?
+ for try await value in group {
+ collected.append(value)
+
+ lookupPubKeys = collected.filter({ $0 != nil && $0?.error == nil })
+
+ errorResult = try thresholdSame(arr: collected.filter({ $0?.error != nil }).map { $0?.error }, threshold: threshold) as? ErrorMessage
+
+ let normalizedKeyResults = lookupPubKeys.map({ normalizeKeysResult(result: ($0!.result)!) })
+
+ keyResult = try thresholdSame(arr: normalizedKeyResults, threshold: threshold)
+
+ if keyResult != nil {
+ group.cancelAll()
+ }
+ }
+ return (keyResult, lookupPubKeys, errorResult)
+ }
+
+ if keyResult != nil && nonceResult == nil && extendedVerifierId == nil && !TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ for i in 0 ..< lookupResults.count {
+ let x1 = lookupResults[i]
+ if x1 != nil && x1?.error == nil {
+ let currentNodePubKeyX = x1!.result!.keys[0].pub_key_X.addLeading0sForLength64().lowercased()
+ let thresholdPubKeyX = keyResult!.keys[0].pub_key_X.addLeading0sForLength64().lowercased()
+ let pubNonce: PubNonce? = x1!.result!.keys[0].nonce_data?.pubNonce
+ if pubNonce != nil && currentNodePubKeyX == thresholdPubKeyX {
+ nonceResult = x1?.result?.keys[0].nonce_data
+ break
+ }
+ }
+ }
+
+ if nonceResult == nil {
+ let metadataNonce = try await MetadataUtils.getOrSetSapphireMetadataNonce(metadataHost: legacyMetadataHost, network: network, X: keyResult!.keys[0].pub_key_X, Y: keyResult!.keys[0].pub_key_Y)
+ nonceResult = metadataNonce
+ if nonceResult!.nonce != nil {
+ nonceResult!.nonce = nil
+ }
+ }
+ }
+
+ var serverTimeOffsets: [Int] = []
+ if keyResult != nil && (nonceResult != nil || extendedVerifierId != nil || TorusUtils.isLegacyNetworkRouteMap(network: network) || errorResult != nil) {
+ for i in 0 ..< lookupResults.count {
+ let x1 = lookupResults[i]
+ if x1 != nil && x1?.result != nil {
+ let currentNodePubKey = x1!.result!.keys[0].pub_key_X.lowercased()
+ let thresholdPubKey = keyResult!.keys[0].pub_key_X.lowercased()
+ if currentNodePubKey == thresholdPubKey {
+ let nodeIndex = Int(x1!.result!.node_index)
+ if nodeIndex != nil {
+ nodeIndexes.append(nodeIndex!)
+ }
+ }
+ let serverTimeOffset: Int = Int(x1!.result!.server_time_offset ?? "0")!
+ serverTimeOffsets.append(serverTimeOffset)
+ }
+ }
+ }
+
+ let serverTimeOffset = (keyResult != nil) ? calculateMedian(arr: serverTimeOffsets) : 0
+
+ return KeyLookupResult(
+ keyResult: keyResult,
+ nodeIndexes: nodeIndexes,
+ serverTimeOffset: serverTimeOffset,
+ nonceResult: nonceResult,
+ errorResult: errorResult)
+ }
+
+ public static func retrieveOrImportShare(
+ legacyMetadataHost: String,
+ serverTimeOffset: Int?,
+ enableOneKey: Bool,
+ allowHost: String,
+ network: TorusNetwork,
+ clientId: String,
+ endpoints: [String],
+ verifier: String,
+ verifierParams: VerifierParams,
+ idToken: String,
+ importedShares: [ImportedShare]?,
+ apiKey: String = "torus-default",
+ extraParams: TorusUtilsExtraParams
+ ) async throws -> TorusKey {
+ let threshold = Int(trunc(Double((endpoints.count / 2) + 1)))
+
+ var allowHostRequest = try MetadataUtils.makeUrlRequest(url: allowHost, httpMethod: .get)
+ allowHostRequest.addValue(apiKey, forHTTPHeaderField: "x-api-key")
+ allowHostRequest.addValue(verifier, forHTTPHeaderField: "origin")
+ allowHostRequest.addValue(verifier, forHTTPHeaderField: "verifier")
+ allowHostRequest.addValue(verifierParams.verifier_id, forHTTPHeaderField: "verifierid")
+ allowHostRequest.addValue(network.name, forHTTPHeaderField: "network")
+ allowHostRequest.addValue(clientId, forHTTPHeaderField: "clientid")
+ allowHostRequest.addValue("true", forHTTPHeaderField: "enablegating")
+ let allowHostResult = try await URLSession(configuration: .default).data(for: allowHostRequest)
+ let allowHostResultData = try JSONDecoder().decode(AllowSuccess.self, from: allowHostResult.0)
+ if allowHostResultData.success == false {
+ let errorData = try JSONDecoder().decode(AllowRejected.self, from: allowHostResult.0)
+ throw TorusUtilError.gatingError("code: \(errorData.code), error: \(errorData.error)")
+ }
+
+ let sessionAuthKey = SecretKey()
+ let sessionAuthKeySerialized = try sessionAuthKey.serialize().addLeading0sForLength64()
+ let pubKey = try sessionAuthKey.toPublic().serialize(compressed: false)
+ let (pubX, pubY) = try KeyUtils.getPublicKeyCoords(pubKey: pubKey)
+ let tokenCommitment = try KeyUtils.keccak256Data(idToken)
+
+ var isImportShareReq = false
+ var importedShareCount = 0
+ if importedShares != nil && importedShares!.count > 0 {
+ if importedShares!.count != endpoints.count {
+ throw TorusUtilError.importShareFailed
+ }
+ isImportShareReq = true
+ importedShareCount = importedShares!.count
+ }
+
+ let params = CommitmentRequestParams(messageprefix: "mug00", tokencommitment: tokenCommitment, temppubx: pubX, temppuby: pubY, verifieridentifier: verifier, timestamp: String(BigUInt(trunc(Double((serverTimeOffset ?? 0) + Int(Date().timeIntervalSince1970)))), radix: 16))
+
+ let jsonRPCRequest = JRPCRequest(
+ method: JRPC_METHODS.COMMITMENT_REQUEST,
+ params: params
+ )
+
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ let rpcdata = try encoder.encode(jsonRPCRequest)
+
+ let nodeSigs: [CommitmentRequestResult] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [CommitmentRequestResult].self) { group -> [CommitmentRequestResult] in
+ let minRequiredCommitmments = Int(trunc(Double(endpoints.count * 3 / 4) + 1))
+ var received: Int = 0
+ for endpoint in endpoints {
+ group.addTask {
+ do {
+ var request = try MetadataUtils.makeUrlRequest(url: endpoint)
+ request.httpBody = rpcdata
+ let val = try await URLSession(configuration: .default).data(for: request)
+ let decoded = try JSONDecoder().decode(JRPCResponse.self, from: val.0)
+ return decoded
+ } catch {
+ return nil
+ }
+ }
+ }
+ var collected = [CommitmentRequestResult]()
+ for try await value in group {
+ if value != nil && value?.error == nil {
+ collected.append(value!.result!)
+ received += 1
+ if !isImportShareReq {
+ if received >= minRequiredCommitmments {
+ group.cancelAll()
+ }
+ }
+ } else {
+ if isImportShareReq {
+ // cannot continue, all must pass for import
+ group.cancelAll()
+ }
+ }
+ }
+ return collected
+ }
+
+ if importedShareCount > 0 && !(nodeSigs.count == endpoints.count) {
+ throw TorusUtilError.commitmentRequestFailed
+ }
+
+ var thresholdNonceData: GetOrSetNonceResult?
+
+ let sessionExpiry = extraParams.session_token_exp_second
+
+ var shareImportSuccess = false
+
+ var shareResponses = [ShareRequestResult]()
+ var thresholdPublicKey: KeyAssignment.PublicKey?
+
+ if isImportShareReq {
+ var importedItems: [ShareRequestParams.ShareRequestItem] = []
+ for j in 0 ..< endpoints.count {
+ let importShare = importedShares![j]
+
+ let shareRequestItem = ShareRequestParams.ShareRequestItem(
+ verifieridentifier: verifier,
+ verifier_id: verifierParams.verifier_id,
+ extended_verifier_id: verifierParams.extended_verifier_id,
+ idtoken: idToken,
+ nodesignatures: nodeSigs,
+ pub_key_x: importShare.oauth_pub_key_x,
+ pub_key_y: importShare.oauth_pub_key_y,
+ signing_pub_key_x: importShare.signing_pub_key_x,
+ signing_pub_key_y: importShare.signing_pub_key_y,
+ encrypted_share: importShare.encryptedShare,
+ encrypted_share_metadata: importShare.encryptedShareMetadata,
+ node_index: importShare.node_index,
+ key_type: importShare.key_type,
+ nonce_data: importShare.nonce_data,
+ nonce_signature: importShare.nonce_signature,
+ sub_verifier_ids: verifierParams.sub_verifier_ids,
+ session_token_exp_second: sessionExpiry,
+ verify_params: verifierParams.verify_params,
+ sss_endpoint: endpoints[j],
+
+ nonce: extraParams.nonce,
+ message: extraParams.message,
+ signature: extraParams.signature,
+ clientDataJson: extraParams.clientDataJson,
+ authenticatorData: extraParams.authenticatorData,
+ publicKey: extraParams.publicKey,
+ challenge: extraParams.challenge,
+ rpOrigin: extraParams.rpOrigin,
+ rpId: extraParams.rpId
+ )
+
+ importedItems.append(shareRequestItem)
+ }
+
+ let params = ShareRequestParams(encrypted: "yes", item: importedItems, client_time: String(Int(trunc(Double((serverTimeOffset ?? 0) + Int(Date().timeIntervalSince1970))))))
+
+ let jsonRPCRequest = JRPCRequest(
+ method: JRPC_METHODS.IMPORT_SHARES,
+ params: params
+ )
+
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ let rpcdata = try encoder.encode(jsonRPCRequest)
+ var request = try MetadataUtils.makeUrlRequest(url: endpoints[Int(try getProxyCoordinatorEndpointIndex(endpoints: endpoints, verifier: verifier, verifierId: verifierParams.verifier_id))])
+ request.httpBody = rpcdata
+ let val = try await URLSession(configuration: .default).data(for: request)
+ let decoded = try JSONDecoder().decode(JRPCResponse<[ShareRequestResult]>.self, from: val.0)
+ if decoded.error == nil {
+ shareImportSuccess = true
+ }
+
+ if isImportShareReq && !shareImportSuccess {
+ throw TorusUtilError.importShareFailed
+ }
+
+ shareResponses = decoded.result!
+
+ let pubkeys = shareResponses.filter({ $0.keys.count > 0 }).map { $0.keys[0].publicKey }
+
+ thresholdPublicKey = try thresholdSame(arr: pubkeys, threshold: threshold)
+ } else {
+ (shareResponses, thresholdPublicKey) = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: ([ShareRequestResult], KeyAssignment.PublicKey?).self) {
+ group -> ([ShareRequestResult], KeyAssignment.PublicKey?) in
+ for i in 0 ..< endpoints.count {
+ group.addTask {
+ do {
+ let shareRequestItem = ShareRequestParams.ShareRequestItem(
+ verifieridentifier: verifier,
+ verifier_id: verifierParams.verifier_id,
+ extended_verifier_id: verifierParams.extended_verifier_id,
+ idtoken: idToken,
+ nodesignatures: nodeSigs,
+ sub_verifier_ids: verifierParams.sub_verifier_ids,
+ session_token_exp_second: sessionExpiry,
+ verify_params: verifierParams.verify_params,
+
+ nonce: extraParams.nonce,
+ message: extraParams.message,
+ signature: extraParams.signature,
+ clientDataJson: extraParams.clientDataJson,
+ authenticatorData: extraParams.authenticatorData,
+ publicKey: extraParams.publicKey,
+ challenge: extraParams.challenge,
+ rpOrigin: extraParams.rpOrigin,
+ rpId: extraParams.rpId
+ )
+
+ let params = ShareRequestParams(encrypted: "yes", item: [shareRequestItem], client_time: String(Int(trunc(Double((serverTimeOffset ?? 0) + Int(Date().timeIntervalSince1970))))))
+
+ let jsonRPCRequest = JRPCRequest(
+ method: JRPC_METHODS.GET_SHARE_OR_KEY_ASSIGN,
+ params: params
+ )
+
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .sortedKeys
+ let rpcdata = try encoder.encode(jsonRPCRequest)
+ var request = try MetadataUtils.makeUrlRequest(url: endpoints[i])
+ request.httpBody = rpcdata
+ let val = try await URLSession(configuration: .default).data(for: request)
+ let decoded = try JSONDecoder().decode(JRPCResponse.self, from: val.0)
+ return decoded
+ } catch {
+ return nil
+ }
+ }
+ }
+
+ var collected = [JRPCResponse?]()
+ var shareResponses = [ShareRequestResult]()
+ var thresholdPublicKey: KeyAssignment.PublicKey?
+ for try await value in group {
+ collected.append(value)
+
+ shareResponses = collected.filter({ $0 != nil && $0!.result != nil }).map({ $0!.result! })
+
+ let pubkeys = shareResponses.filter({ $0.keys.count > 0 }).map { $0.keys[0].publicKey }
+
+ thresholdPublicKey = try thresholdSame(arr: pubkeys, threshold: threshold)
+
+ if thresholdPublicKey != nil {
+ group.cancelAll()
+ }
+ }
+
+ return (shareResponses, thresholdPublicKey)
+ }
+ }
+
+ if thresholdPublicKey == nil {
+ throw TorusUtilError.retrieveOrImportShareError
+ }
+
+ for item in shareResponses {
+ if thresholdNonceData == nil && verifierParams.extended_verifier_id == nil {
+ let currentPubKeyX = item.keys[0].publicKey.X.addLeading0sForLength64().lowercased()
+ let thesholdPubKeyX = thresholdPublicKey!.X.addLeading0sForLength64().lowercased()
+ let pubNonce: PubNonce? = item.keys[0].nonceData?.pubNonce
+ if pubNonce != nil && currentPubKeyX == thesholdPubKeyX {
+ thresholdNonceData = item.keys[0].nonceData
+ }
+ }
+ }
+
+ var serverTimeOffsets: [String] = []
+ for item in shareResponses {
+ serverTimeOffsets.append(item.serverTimeOffset)
+ }
+ let serverOffsetTimes = serverTimeOffsets.map({ Int($0) ?? 0 })
+
+ let serverTimeOffsetResponse: Int = serverTimeOffset ?? calculateMedian(arr: serverOffsetTimes)
+
+ if thresholdNonceData == nil && verifierParams.extended_verifier_id == nil && !TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ let metadataNonce = try await MetadataUtils.getOrSetSapphireMetadataNonce(metadataHost: legacyMetadataHost, network: network, X: thresholdPublicKey!.X, Y: thresholdPublicKey!.Y, serverTimeOffset: serverTimeOffsetResponse, getOnly: false)
+ thresholdNonceData = metadataNonce
+ }
+
+ let thresholdReqCount = (importedShares != nil && importedShares!.count > 0) ? endpoints.count : threshold
+
+ // Invert comparision to return error early
+ if !(shareResponses.count >= thresholdReqCount && thresholdPublicKey != nil && (thresholdNonceData != nil || verifierParams.extended_verifier_id != nil || TorusUtils.isLegacyNetworkRouteMap(network: network))) {
+ throw TorusUtilError.retrieveOrImportShareError
+ }
+
+ var shares: [String?] = []
+ var sessionTokenSigs: [String?] = []
+ var sessionTokens: [String?] = []
+ var nodeIndexes: [Int?] = []
+ var sessionTokenDatas: [SessionToken?] = []
+ var isNewKeys: [String] = []
+
+ for item in shareResponses {
+ isNewKeys.append(item.isNewKey)
+
+ if !item.sessionTokenSigs.isEmpty {
+ if !item.sessionTokenSigMetadata.isEmpty {
+ let decrypted = try MetadataUtils.decryptNodeData(eciesData: item.sessionTokenSigMetadata[0], ciphertextHex: item.sessionTokenSigs[0], privKey: sessionAuthKeySerialized)
+ sessionTokenSigs.append(decrypted)
+ } else {
+ sessionTokenSigs.append(item.sessionTokenSigs[0])
+ }
+ } else {
+ sessionTokenSigs.append(nil)
+ }
+
+ if !item.sessionTokens.isEmpty {
+ if !item.sessionTokenMetadata.isEmpty {
+ let decrypted = try MetadataUtils.decryptNodeData(eciesData: item.sessionTokenMetadata[0], ciphertextHex: item.sessionTokens[0], privKey: sessionAuthKeySerialized)
+ sessionTokens.append(decrypted)
+ } else {
+ sessionTokens.append(item.sessionTokens[0])
+ }
+ } else {
+ sessionTokens.append(nil)
+ }
+
+ if !item.keys.isEmpty {
+ let latestKey = item.keys[0]
+ nodeIndexes.append(latestKey.nodeIndex)
+ guard let cipherData = Data(base64Encoded: latestKey.share) else {
+ throw TorusUtilError.decodingFailed("cipher is not base64 encoded")
+ }
+ guard let cipherTextHex = String(data: cipherData, encoding: .utf8) else {
+ throw TorusUtilError.decodingFailed("cipherData is not utf8")
+ }
+ let decrypted = try MetadataUtils.decryptNodeData(eciesData: latestKey.shareMetadata, ciphertextHex: cipherTextHex, privKey: sessionAuthKeySerialized)
+ shares.append(decrypted)
+ } else {
+ nodeIndexes.append(nil)
+ shares.append(nil)
+ }
+ }
+
+ let validSigs = sessionTokenSigs.filter({ $0 != nil }).map({ $0! })
+
+ if verifierParams.extended_verifier_id == nil && validSigs.count < threshold {
+ throw TorusUtilError.retrieveOrImportShareError
+ }
+
+ let validTokens = sessionTokens.filter({ $0 != nil }).map({ $0! })
+
+ if verifierParams.extended_verifier_id == nil && validTokens.count < threshold {
+ throw TorusUtilError.runtime("Insufficient number of signatures from nodes")
+ }
+
+ for (i, item) in sessionTokens.enumerated() {
+ if item == nil {
+ sessionTokenDatas.append(nil)
+ } else {
+ sessionTokenDatas.append(SessionToken(token: item!.data(using: .utf8)!.base64EncodedString(), signature: sessionTokenSigs[i]!.data(using: .utf8)!.hexString, node_pubx: shareResponses[i].nodePubX, node_puby: shareResponses[i].nodePubY))
+ }
+ }
+
+ var decryptedShares: [Int: String] = [:]
+ for (i, item) in shares.enumerated() {
+ if item != nil {
+ decryptedShares.updateValue(item!, forKey: nodeIndexes[i]!)
+ }
+ }
+ let elements = Array(0 ... decryptedShares.keys.max()!) // Note: torus.js has a bug that this line resolves
+
+ let allCombis = kCombinations(elements: elements.slice, k: threshold)
+
+ var privateKey: String?
+
+ for j in 0 ..< allCombis.count {
+ let currentCombi = allCombis[j]
+ let currentCombiShares = decryptedShares.filter({ currentCombi.contains($0.key) })
+ let shares = currentCombiShares.map({ $0.value })
+ let indices = currentCombiShares.map({ $0.key })
+ let derivedPrivateKey = try? Lagrange.lagrangeInterpolation(shares: shares, nodeIndex: indices)
+ if derivedPrivateKey == nil {
+ continue
+ }
+ let decryptedPubKey = try SecretKey(hex: derivedPrivateKey!).toPublic().serialize(compressed: false)
+ let (decryptedPubKeyX, decryptedPubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: decryptedPubKey)
+ let thresholdPubKeyX = thresholdPublicKey!.X.addLeading0sForLength64().lowercased()
+ let thresholdPubKeyY = thresholdPublicKey!.Y.addLeading0sForLength64().lowercased()
+ if decryptedPubKeyX.lowercased() == thresholdPubKeyX && decryptedPubKeyY.lowercased() == thresholdPubKeyY {
+ privateKey = derivedPrivateKey
+ break
+ }
+ }
+
+ if privateKey == nil {
+ throw TorusUtilError.privateKeyDeriveFailed
+ }
+
+ let thresholdIsNewKey: String? = try thresholdSame(arr: isNewKeys, threshold: threshold)
+
+ let oAuthKey = privateKey!
+ let oAuthPublicKey = try SecretKey(hex: oAuthKey).toPublic().serialize(compressed: false)
+ let (oAuthPublicKeyX, oAuthPublicKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: oAuthPublicKey)
+ var metadataNonce = BigInt(thresholdNonceData?.nonce?.addLeading0sForLength64() ?? "0", radix: 16) ?? BigInt(0)
+ var finalPubKey: String?
+ var pubNonce: PubNonce?
+ var typeOfUser: UserType = .v1
+ if verifierParams.extended_verifier_id != nil {
+ typeOfUser = .v2
+ finalPubKey = oAuthPublicKey
+ } else if TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ if enableOneKey {
+ let isNewKey = !(thresholdIsNewKey == "true")
+ let nonce = try await MetadataUtils.getOrSetNonce(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffsetResponse, X: thresholdPublicKey!.X, Y: thresholdPublicKey!.Y, privateKey: oAuthKey, getOnly: isNewKey)
+ metadataNonce = BigInt(nonce.nonce?.addLeading0sForLength64() ?? "0", radix: 16) ?? BigInt(0)
+ typeOfUser = UserType(rawValue: nonce.typeOfUser?.lowercased() ?? "v1")!
+ if typeOfUser == .v2 {
+ pubNonce = nonce.pubNonce
+ let publicNonce = KeyUtils.getPublicKeyFromCoords(pubKeyX: pubNonce!.x, pubKeyY: pubNonce!.y)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [oAuthPublicKey, publicNonce])
+ } else {
+ typeOfUser = .v1
+ metadataNonce = BigInt(try await MetadataUtils.getMetadata(legacyMetadataHost: legacyMetadataHost, params: GetMetadataParams(pub_key_X: oAuthPublicKeyX, pub_key_Y: oAuthPublicKeyY)))
+ let privateKeyWithNonce = (BigInt(oAuthKey.addLeading0sForLength64(), radix: 16)! + BigInt(metadataNonce)).modulus(KeyUtils.getOrderOfCurve())
+ finalPubKey = try SecretKey(hex: privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()).toPublic().serialize(compressed: false)
+ }
+ } else {
+ typeOfUser = .v1
+ metadataNonce = BigInt(try await MetadataUtils.getMetadata(legacyMetadataHost: legacyMetadataHost, params: GetMetadataParams(pub_key_X: oAuthPublicKeyX, pub_key_Y: oAuthPublicKeyY)))
+ let privateKeyWithNonce = (BigInt(oAuthKey.addLeading0sForLength64(), radix: 16)! + BigInt(metadataNonce)).modulus(KeyUtils.getOrderOfCurve())
+ finalPubKey = try SecretKey(hex: privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()).toPublic().serialize(compressed: false)
+ }
+ } else {
+ typeOfUser = .v2
+ let oAuthPubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: oAuthPublicKeyX, pubKeyY: oAuthPublicKeyY)
+ finalPubKey = oAuthPubKey
+ if thresholdNonceData!.pubNonce != nil && !(thresholdNonceData!.pubNonce!.x.isEmpty || thresholdNonceData!.pubNonce!.y.isEmpty) {
+ let pubNonceKey = thresholdNonceData!.pubNonce!
+
+ let publicNonce = KeyUtils.getPublicKeyFromCoords(pubKeyX: pubNonceKey.x, pubKeyY: pubNonceKey.y)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [oAuthPubKey, publicNonce])
+ pubNonce = PubNonce(x: thresholdNonceData!.pubNonce!.x, y: thresholdNonceData!.pubNonce!.y)
+ } else {
+ throw TorusUtilError.pubNonceMissing
+ }
+ }
+
+ if finalPubKey == nil {
+ throw TorusUtilError.retrieveOrImportShareError
+ }
+
+ let oAuthKeyAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: oAuthPublicKeyX, publicKeyY: oAuthPublicKeyY)
+
+ let (finalPubX, finalPubY) = try KeyUtils.getPublicKeyCoords(pubKey: finalPubKey!)
+ let finalEvmAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY)
+
+ var finalPrivKey = ""
+ if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) {
+ let privateKeyWithNonce = ((BigInt(oAuthKey.addLeading0sForLength64(), radix: 16) ?? BigInt(0)) + metadataNonce).modulus(KeyUtils.getOrderOfCurve())
+ finalPrivKey = privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()
+ }
+
+ var isUpgraded: Bool?
+ if typeOfUser == .v2 {
+ isUpgraded = metadataNonce == BigInt(0)
+ }
+
+ return TorusKey(
+ finalKeyData: TorusKey.FinalKeyData(
+ evmAddress: finalEvmAddress,
+ X: finalPubX,
+ Y: finalPubY,
+ privKey: finalPrivKey),
+ oAuthKeyData: TorusKey.OAuthKeyData(
+ evmAddress: oAuthKeyAddress,
+ X: oAuthPublicKeyX,
+ Y: oAuthPublicKeyY,
+ privKey: oAuthKey),
+ sessionData: TorusKey.SessionData(
+ sessionTokenData: sessionTokenDatas,
+ sessionAuthKey: sessionAuthKeySerialized),
+ metadata: TorusPublicKey.Metadata(
+ pubNonce: pubNonce,
+ nonce: metadataNonce.magnitude,
+ typeOfUser: typeOfUser,
+ upgraded: isUpgraded,
+ serverTimeOffset: serverTimeOffsetResponse),
+ nodesData: TorusKey.NodesData(
+ nodeIndexes: nodeIndexes.filter({ $0 != nil }).map({ $0! })
+ )
+ )
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/NetworkingHelper.swift b/Sources/TorusUtils/Helpers/httpMethod.swift
similarity index 51%
rename from Sources/TorusUtils/Helpers/NetworkingHelper.swift
rename to Sources/TorusUtils/Helpers/httpMethod.swift
index 5bc99605..d238535d 100644
--- a/Sources/TorusUtils/Helpers/NetworkingHelper.swift
+++ b/Sources/TorusUtils/Helpers/httpMethod.swift
@@ -1,6 +1,6 @@
import Foundation
-enum HTTPMethod {
+internal enum httpMethod {
case get
case post
@@ -13,10 +13,3 @@ enum HTTPMethod {
}
}
}
-
-extension TorusUtils {
- func createURLSession() -> URLSession {
- let session = URLSession(configuration: urlSession.configuration)
- return session
- }
-}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/ErrorMessage.swift b/Sources/TorusUtils/Helpers/jsonRPC/ErrorMessage.swift
new file mode 100644
index 00000000..c878cfb3
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/ErrorMessage.swift
@@ -0,0 +1,20 @@
+import Foundation
+
+internal struct ErrorMessage: Codable {
+ public var code: Int
+ public var message: String
+ public var data: String
+
+ enum ErrorMessageKeys: String, CodingKey {
+ case code
+ case message
+ case data
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: ErrorMessageKeys.self)
+ try container.encode(message, forKey: .message)
+ try container.encode(code, forKey: .code)
+ try container.encode(data, forKey: .data)
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/JRPCRequest.swift b/Sources/TorusUtils/Helpers/jsonRPC/JRPCRequest.swift
new file mode 100644
index 00000000..15fbcd58
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/JRPCRequest.swift
@@ -0,0 +1,16 @@
+import Foundation
+
+/// JSON RPC request structure for serialization and deserialization purposes.
+internal struct JRPCRequest: Encodable {
+ public var jsonrpc: String = "2.0"
+ public var method: String
+ public var params: T
+ public var id: Int = 10
+
+ enum CodingKeys: String, CodingKey {
+ case jsonrpc
+ case method
+ case params
+ case id
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/JRPCResponse.swift b/Sources/TorusUtils/Helpers/jsonRPC/JRPCResponse.swift
new file mode 100644
index 00000000..1b79b0f9
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/JRPCResponse.swift
@@ -0,0 +1,51 @@
+import Foundation
+
+internal struct AllowSuccess: Codable {
+ public let success: Bool
+}
+
+internal struct AllowRejected: Codable {
+ public let code: Int32
+ public let error: String
+ public let success: Bool
+}
+
+internal struct JRPCResponse: Codable {
+ public var id: Int
+ public var jsonrpc = "2.0"
+ public var result: T?
+ public var error: ErrorMessage?
+ public var message: String?
+
+ enum JRPCResponseKeys: String, CodingKey {
+ case id
+ case jsonrpc
+ case result
+ case error
+ case errorMessage
+ }
+
+ public init(id: Int, jsonrpc: String, result: T?, error: ErrorMessage?) {
+ self.id = id
+ self.jsonrpc = jsonrpc
+ self.result = result
+ self.error = error
+ }
+
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: JRPCResponseKeys.self)
+ let id: Int = try container.decode(Int.self, forKey: .id)
+ let jsonrpc: String = try container.decode(String.self, forKey: .jsonrpc)
+ let errorMessage = try container.decodeIfPresent(ErrorMessage.self, forKey: .error)
+ if errorMessage != nil {
+ self.init(id: id, jsonrpc: jsonrpc, result: nil, error: errorMessage)
+ return
+ }
+
+ var result: T?
+ if let rawValue = try? container.decodeIfPresent(T.self, forKey: .result) {
+ result = rawValue
+ }
+ self.init(id: id, jsonrpc: jsonrpc, result: result, error: nil)
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Requests/CommitmentRequestParams.swift b/Sources/TorusUtils/Helpers/jsonRPC/Requests/CommitmentRequestParams.swift
new file mode 100644
index 00000000..1ca18dda
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/CommitmentRequestParams.swift
@@ -0,0 +1,10 @@
+import Foundation
+
+internal struct CommitmentRequestParams: Codable {
+ public var messageprefix: String
+ public var tokencommitment: String
+ public var temppubx: String
+ public var temppuby: String
+ public var verifieridentifier: String
+ public var timestamp: String?
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Requests/GetNonceParams.swift b/Sources/TorusUtils/Helpers/jsonRPC/Requests/GetNonceParams.swift
new file mode 100644
index 00000000..a7872433
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/GetNonceParams.swift
@@ -0,0 +1,11 @@
+import Foundation
+
+internal struct GetNonceSetDataParams: Codable {
+ public var data: String
+}
+
+internal struct GetNonceParams: Codable {
+ public var pub_key_X: String
+ public var pub_key_Y: String
+ public var set_data: GetNonceSetDataParams
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Requests/GetOrSetKeyParams.swift b/Sources/TorusUtils/Helpers/jsonRPC/Requests/GetOrSetKeyParams.swift
new file mode 100644
index 00000000..89493162
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/GetOrSetKeyParams.swift
@@ -0,0 +1,11 @@
+import Foundation
+
+internal struct GetOrSetKeyParams: Codable {
+ public var distributed_metadata: Bool
+ public var verifier: String
+ public var verifier_id: String
+ public var extended_verifier_id: String?
+ public var one_key_flow: Bool
+ public var fetch_node_index: Bool
+ public var client_time: String
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Requests/NonceMetadataParams.swift b/Sources/TorusUtils/Helpers/jsonRPC/Requests/NonceMetadataParams.swift
new file mode 100644
index 00000000..de6b00ac
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/NonceMetadataParams.swift
@@ -0,0 +1,23 @@
+import Foundation
+
+internal struct NonceMetadataParams {
+ public var namespace: String?
+ public var pub_key_X: String
+ public var pub_key_Y: String
+ public var set_data: SetNonceData
+ public var key_type: TorusKeyType
+ public var signature: String
+ public var encodedData: String
+ public var seed: String?
+
+ public init(pub_key_X: String, pub_key_Y: String, setData: SetNonceData, encodedData: String, signature: String, namespace: String? = nil, key_type: TorusKeyType = .secp256k1, seed: String? = nil) {
+ self.namespace = namespace
+ self.pub_key_X = pub_key_X
+ self.pub_key_Y = pub_key_Y
+ set_data = setData
+ self.signature = signature
+ self.seed = seed
+ self.key_type = key_type
+ self.encodedData = encodedData
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Requests/SetNonceData.swift b/Sources/TorusUtils/Helpers/jsonRPC/Requests/SetNonceData.swift
new file mode 100644
index 00000000..9d322447
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/SetNonceData.swift
@@ -0,0 +1,28 @@
+import Foundation
+
+internal struct SetNonceData: Codable {
+ public var operation: String?
+ public var data: String?
+ public var timestamp: String?
+ public var seed: String?
+
+ public init(operation: String? = nil, data: String? = nil, timestamp: String? = nil, seed: String? = nil) {
+ self.operation = operation
+ self.data = data
+ self.timestamp = timestamp
+ self.seed = seed
+ }
+
+ public func encode(to encoder: any Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+ try container.encodeIfPresent(operation, forKey: .operation)
+ try container.encodeIfPresent(data, forKey: .data)
+ try container.encodeIfPresent(timestamp, forKey: .timestamp)
+ // There is a bug in the server that expects seed to be empty and not optional, when it checks signatures. It is optional in the interface though.
+ if seed == nil {
+ try container.encode("", forKey: .seed)
+ } else {
+ try container.encode(seed, forKey: .seed)
+ }
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Requests/ShareRequestParams.swift b/Sources/TorusUtils/Helpers/jsonRPC/Requests/ShareRequestParams.swift
new file mode 100644
index 00000000..637da76c
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/ShareRequestParams.swift
@@ -0,0 +1,63 @@
+import Foundation
+
+internal struct ShareRequestParams: Codable {
+ public struct ShareRequestItem: Codable {
+ public var verifieridentifier: String
+ public var verifier_id: String?
+ public var extended_verifier_id: String?
+ public var idtoken: String
+ public var nodesignatures: [CommitmentRequestResult?]
+ public var pub_key_x: String?
+ public var pub_key_y: String?
+ public var signing_pub_key_x: String?
+ public var signing_pub_key_y: String?
+ public var encrypted_share: String?
+ public var encrypted_share_metadata: EciesHexOmitCiphertext?
+ public var node_index: Int?
+ public var key_type: TorusKeyType?
+ public var nonce_data: String?
+ public var nonce_signature: String?
+ public var sub_verifier_ids: [String]?
+ public var session_token_exp_second: Int?
+ public var verify_params: [VerifyParams?]?
+ public var sss_endpoint: String?
+
+ // TODO: This is a bit of a mess from here due to legacy reasons and should be cleaned up in future.
+ // Note: Nil values by default are excluded from serialization
+ public var enable_verifier_id_hash: Bool? // most
+ public var app_s: String? // meta
+ public var app_id: String? // meta
+ public var domain: String? // farcaster
+ public var nonce: String? // farcaster
+ public var message: String? // farcaster
+ public var signature: String? // farcaster, passkey, webauthn
+ public var clientDataJson: String? // passkey, webauthn
+ public var authenticatorData: String? // passkey, webauthn
+ public var publicKey: String? // passkey, webauthn
+ public var challenge: String? // passkey, webauthn
+ public var rpOrigin: String? // passkey, webauthn
+ public var rpId: String? // passkey, webauthn
+ public var jwk_endpoint: String? // passkey, jwt
+ public var default_node_set: [String]? // passkey, jwt
+ public var jwt_verifier_id_field: String? // passkey, jwt
+ public var jwt_verifier_id_case_sensitive: Bool? // passkey, jwt
+ public var jwk_keys: String? // passkey, jwt
+ public var jwt_validation_fields: [String]? // passkey, jwt
+ public var jwt_validation_values: [String]? // passkey, jwt
+ public var index: Int? // demo
+ public var email: String? // demo
+ public var id: String? // test, jwt, passkey
+ public var correct_id_token: String? // test
+ public var verify_param: String? // OrAggregate
+ public var threshold: Int? // SingleID
+ public var pub_k_x: String? // Signature
+ public var pub_k_y: String? // Signature
+ }
+
+ public var encrypted: String = "yes"
+ public var item: [ShareRequestItem]
+ public var use_temp: Bool = true
+ public var distributed_metadata: Bool = true
+ public var one_key_flow: Bool = true
+ public var client_time: String
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/CommitmentRequestResult.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/CommitmentRequestResult.swift
new file mode 100644
index 00000000..9fc6f376
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/CommitmentRequestResult.swift
@@ -0,0 +1,17 @@
+import Foundation
+
+internal struct CommitmentRequestResult: Codable {
+ public var signature: String
+ public var data: String
+ public var nodepubx: String
+ public var nodepuby: String
+ public var nodeindex: String
+
+ public init(data: String, nodepubx: String, nodepuby: String, signature: String, nodeindex: String) {
+ self.data = data
+ self.nodepubx = nodepubx
+ self.nodepuby = nodepuby
+ self.signature = signature
+ self.nodeindex = nodeindex
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/GetMetadataResponse.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/GetMetadataResponse.swift
new file mode 100644
index 00000000..1b5c360e
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/GetMetadataResponse.swift
@@ -0,0 +1,9 @@
+import Foundation
+
+internal struct GetMetadataResponse: Codable {
+ public var message: String
+
+ public init(message: String) {
+ self.message = message
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/GetOrSetNonceResult.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/GetOrSetNonceResult.swift
new file mode 100644
index 00000000..2daa7681
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/GetOrSetNonceResult.swift
@@ -0,0 +1,27 @@
+import Foundation
+
+internal struct GetOrSetNonceResult: Codable {
+ public var typeOfUser: String?
+ public var nonce: String?
+ public var pubNonce: PubNonce?
+ public var ifps: String?
+ public var upgraded: Bool?
+
+ public init(typeOfUser: String, nonce: String? = nil, pubNonce: PubNonce? = nil, ifps: String? = nil, upgraded: Bool? = false) {
+ self.typeOfUser = typeOfUser
+ self.nonce = nonce
+ self.pubNonce = pubNonce
+ self.ifps = ifps
+ self.upgraded = upgraded
+ }
+
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+
+ typeOfUser = try container.decodeIfPresent(String.self, forKey: .typeOfUser)
+ nonce = try container.decodeIfPresent(String.self, forKey: .nonce)
+ pubNonce = try container.decodeIfPresent(PubNonce.self, forKey: .pubNonce)
+ ifps = try container.decodeIfPresent(String.self, forKey: .ifps)
+ upgraded = try container.decodeIfPresent(Bool.self, forKey: .upgraded)
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/KeyAssignment.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/KeyAssignment.swift
new file mode 100644
index 00000000..7157fae1
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/KeyAssignment.swift
@@ -0,0 +1,49 @@
+import Foundation
+
+internal struct KeyAssignment: Codable {
+ let index: String
+ let publicKey: PublicKey
+ let threshold: Int
+ let nodeIndex: Int
+ let share: String
+ let shareMetadata: EciesHexOmitCiphertext
+ let nonceData: GetOrSetNonceResult?
+
+ struct PublicKey: Hashable, Codable {
+ let X: String
+ let Y: String
+ }
+
+ enum CodingKeys: CodingKey {
+ case index
+ case public_key
+ case threshold
+ case node_index
+ case share
+ case share_metadata
+ case nonce_data
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+ try container.encode(index, forKey: .index)
+ try container.encode(publicKey, forKey: .public_key)
+ try container.encode(threshold, forKey: .threshold)
+ try container.encode(nodeIndex, forKey: .node_index)
+ try container.encode(share, forKey: .share)
+ try container.encode(shareMetadata, forKey: .share_metadata)
+ try container.encodeIfPresent(nonceData, forKey: .nonce_data)
+ }
+
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ index = try container.decode(String.self, forKey: .index)
+
+ publicKey = try container.decode(PublicKey.self, forKey: .public_key)
+ threshold = Int(try container.decode(String.self, forKey: .threshold))!
+ nodeIndex = Int(try container.decode(String.self, forKey: .node_index))!
+ share = try container.decode(String.self, forKey: .share)
+ shareMetadata = try container.decode(EciesHexOmitCiphertext.self, forKey: .share_metadata)
+ nonceData = try container.decodeIfPresent(GetOrSetNonceResult.self, forKey: .nonce_data)
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareRequestResult.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareRequestResult.swift
new file mode 100644
index 00000000..5e72d550
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareRequestResult.swift
@@ -0,0 +1,76 @@
+import Foundation
+
+internal struct ShareRequestResult: Codable {
+ let keys: [KeyAssignment]
+ let sessionTokens: [String]
+ let sessionTokenMetadata: [EciesHexOmitCiphertext]
+ let sessionTokenSigs: [String]
+ let sessionTokenSigMetadata: [EciesHexOmitCiphertext]
+ let nodePubX: String
+ let nodePubY: String
+ let isNewKey: String
+ let serverTimeOffset: String
+
+ enum CodingKeys: CodingKey {
+ case keys
+ case session_tokens
+ case session_token_metadata
+ case session_token_sigs
+ case session_token_sig_metadata
+ case node_pubx
+ case node_puby
+ case is_new_key
+ case server_time_offset
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+ try container.encode(keys, forKey: .keys)
+ try container.encode(sessionTokens, forKey: .session_tokens)
+ try container.encode(sessionTokenMetadata, forKey: .session_token_metadata)
+ try container.encode(sessionTokenSigs, forKey: .session_token_sigs)
+ try container.encode(sessionTokenSigMetadata, forKey: .session_token_sig_metadata)
+ try container.encode(nodePubX, forKey: .node_pubx)
+ try container.encode(nodePubX, forKey: .node_puby)
+ try container.encode(isNewKey, forKey: .is_new_key)
+ try container.encode(serverTimeOffset, forKey: .server_time_offset)
+ }
+
+ init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ keys = try container.decode([KeyAssignment].self, forKey: .keys)
+ nodePubX = try container.decode(String.self, forKey: .node_pubx)
+ nodePubY = try container.decode(String.self, forKey: .node_puby)
+ isNewKey = try container.decode(String.self, forKey: .is_new_key)
+
+ if let sessionTokens = try? container.decodeIfPresent([String].self, forKey: .session_tokens) {
+ self.sessionTokens = sessionTokens
+ } else {
+ sessionTokens = []
+ }
+
+ if let sessionTokenMetadata = try? container.decodeIfPresent([EciesHexOmitCiphertext].self, forKey: .session_token_metadata) {
+ self.sessionTokenMetadata = sessionTokenMetadata
+ } else {
+ sessionTokenMetadata = []
+ }
+
+ if let sessionTokenSigs = try? container.decodeIfPresent([String].self, forKey: .session_token_sigs) {
+ self.sessionTokenSigs = sessionTokenSigs
+ } else {
+ sessionTokenSigs = []
+ }
+
+ if let sessionTokenSigMetadata = try? container.decodeIfPresent([EciesHexOmitCiphertext].self, forKey: .session_token_sig_metadata) {
+ self.sessionTokenSigMetadata = sessionTokenSigMetadata
+ } else {
+ sessionTokenSigMetadata = []
+ }
+
+ if let serverTimeOffset = try? container.decodeIfPresent(String.self, forKey: .server_time_offset) {
+ self.serverTimeOffset = serverTimeOffset
+ } else {
+ serverTimeOffset = "0"
+ }
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/LegacyVerifierLookupResponse.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/LegacyVerifierLookupResponse.swift
new file mode 100644
index 00000000..10109b53
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/LegacyVerifierLookupResponse.swift
@@ -0,0 +1,42 @@
+import Foundation
+
+internal struct LegacyVerifierLookupResponse: Codable {
+ public struct Key: Codable {
+ let pub_key_X: String
+ let pub_key_Y: String
+ let address: String
+
+ init(pub_key_X: String, pub_key_Y: String, address: String) {
+ self.pub_key_X = pub_key_X
+ self.pub_key_Y = pub_key_Y
+ self.address = address
+ }
+
+ enum JSONRPCresponseKeys: String, CodingKey {
+ case pub_key_X
+ case pub_key_Y
+ case address
+ }
+
+ public init(from: Decoder) throws {
+ let container = try from.container(keyedBy: CodingKeys.self)
+ pub_key_X = try container.decode(String.self, forKey: .pub_key_X)
+ pub_key_Y = try container.decode(String.self, forKey: .pub_key_Y)
+ address = try container.decode(String.self, forKey: .address)
+ }
+ }
+
+ var keys: [Key]
+ var server_time_offset: String?
+
+ public init(keys: [Key], serverTimeOffset: String? = nil) {
+ self.keys = keys
+ server_time_offset = serverTimeOffset
+ }
+
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ keys = try container.decode([LegacyVerifierLookupResponse.Key].self, forKey: .keys)
+ server_time_offset = try container.decodeIfPresent(String.self, forKey: .server_time_offset)
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift b/Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/VerifierLookupResponse.swift
similarity index 57%
rename from Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift
rename to Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/VerifierLookupResponse.swift
index 47b02705..a38f6d68 100644
--- a/Sources/TorusUtils/Interfaces/VerifierLookupResponse.swift
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/VerifierLookupResponse.swift
@@ -1,7 +1,7 @@
import Foundation
-struct VerifierLookupResponse: Codable {
- struct Key: Codable {
+internal struct VerifierLookupResponse: Codable {
+ public struct Key: Codable {
let pub_key_X: String
let pub_key_Y: String
let address: String
@@ -38,11 +38,12 @@ struct VerifierLookupResponse: Codable {
}
}
- var keys: [Key]?
+ var keys: [Key]
var is_new_key: Bool
var node_index: String
+ var server_time_offset: String?
- public init(keys: [Key]?, is_new_key: Bool, node_index: String) {
+ public init(keys: [Key], is_new_key: Bool, node_index: String) {
self.keys = keys
self.is_new_key = is_new_key
self.node_index = node_index
@@ -50,40 +51,9 @@ struct VerifierLookupResponse: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
- keys = try container.decodeIfPresent([VerifierLookupResponse.Key].self, forKey: .keys)
+ keys = try container.decode([VerifierLookupResponse.Key].self, forKey: .keys)
is_new_key = try container.decode(Bool.self, forKey: .is_new_key)
node_index = try container.decode(String.self, forKey: .node_index)
+ server_time_offset = try container.decodeIfPresent(String.self, forKey: .server_time_offset)
}
}
-
-public struct LegacyLookupResponse: Decodable {
- public struct KeyLookup: Decodable {
- public var index: String
- public var metadata: EciesHexOmitCiphertext
- public var publicKey: Point
- public var share: String
- public var threshold: Int
- public var verifier: [String: [String]]
-
- public enum CodingKeys: CodingKey {
- case Index
- case Metadata
- case PublicKey
- case Share
- case Threshold
- case Verifiers
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- index = try container.decode(String.self, forKey: .Index)
- metadata = try container.decode(EciesHexOmitCiphertext.self, forKey: .Metadata)
- publicKey = try container.decode(Point.self, forKey: .PublicKey)
- share = try container.decode(String.self, forKey: .Share)
- threshold = try container.decode(Int.self, forKey: .Threshold)
- verifier = try container.decode([String: [String]].self, forKey: .Verifiers)
- }
- }
-
- public var keys: [KeyLookup]
-}
diff --git a/Sources/TorusUtils/Interfaces/CommitmentRequestResponse.swift b/Sources/TorusUtils/Interfaces/CommitmentRequestResponse.swift
deleted file mode 100644
index 98b6e51e..00000000
--- a/Sources/TorusUtils/Interfaces/CommitmentRequestResponse.swift
+++ /dev/null
@@ -1,30 +0,0 @@
-import Foundation
-
-public struct CommitmentRequestResponse: Codable {
- public var data: String
- public var nodepubx: String
- public var nodepuby: String
- public var signature: String
-
- public init(data: String, nodepubx: String, nodepuby: String, signature: String) {
- self.data = data
- self.nodepubx = nodepubx
- self.nodepuby = nodepuby
- self.signature = signature
- }
-}
-
-extension Array where Element == CommitmentRequestResponse {
- public func tostringDict() -> [[String: String]] {
- var dictArr = [[String: String]]()
- for val in self {
- var dict = [String: String]()
- dict["data"] = val.data
- dict["nodepubx"] = val.nodepubx
- dict["nodepuby"] = val.nodepuby
- dict["signature"] = val.signature
- dictArr.append(dict)
- }
- return dictArr
- }
-}
diff --git a/Sources/TorusUtils/Interfaces/Ecies.swift b/Sources/TorusUtils/Interfaces/Common/Ecies.swift
similarity index 73%
rename from Sources/TorusUtils/Interfaces/Ecies.swift
rename to Sources/TorusUtils/Interfaces/Common/Ecies.swift
index cf5fc141..3ca27b9c 100644
--- a/Sources/TorusUtils/Interfaces/Ecies.swift
+++ b/Sources/TorusUtils/Interfaces/Common/Ecies.swift
@@ -7,7 +7,7 @@ protocol EciesProtocol {
var mac: Data { get }
}
-public struct ECIES: Codable {
+internal struct ECIES: Codable {
let iv: String
let ephemPublicKey: String
let ciphertext: String
@@ -23,14 +23,14 @@ public struct ECIES: Codable {
}
}
-public struct EciesHex: Codable {
+internal struct EciesHex: Codable {
let iv: String
let ephemPublicKey: String
- let ciphertext: String?
+ let ciphertext: String
let mac: String
let mode: String?
- init(iv: String, ephemPublicKey: String, ciphertext: String?, mac: String, mode: String?) {
+ init(iv: String, ephemPublicKey: String, ciphertext: String, mac: String, mode: String?) {
self.iv = iv
self.ephemPublicKey = ephemPublicKey
self.ciphertext = ciphertext
@@ -38,12 +38,20 @@ public struct EciesHex: Codable {
self.mode = mode
}
+ init(from: Ecies) {
+ ciphertext = from.ciphertext
+ iv = from.iv
+ ephemPublicKey = from.ephemPublicKey
+ mac = from.mac
+ mode = "AES256"
+ }
+
func omitCiphertext() -> EciesHexOmitCiphertext {
return EciesHexOmitCiphertext(iv: iv, ephemPublicKey: ephemPublicKey, mac: mac, mode: mode)
}
}
-public struct EciesHexOmitCiphertext: Decodable {
+internal struct EciesHexOmitCiphertext: Codable {
var iv: String
var ephemPublicKey: String
var mac: String
@@ -62,9 +70,16 @@ public struct EciesHexOmitCiphertext: Decodable {
mac = from.mac
mode = from.mode
}
+
+ init(from: Ecies) {
+ iv = from.iv
+ ephemPublicKey = from.ephemPublicKey
+ mac = from.mac
+ mode = "AES256"
+ }
}
-public struct Ecies: Codable {
+internal struct Ecies: Codable {
var iv: String
var ephemPublicKey: String
var ciphertext: String
@@ -78,7 +93,7 @@ public struct Ecies: Codable {
}
}
-struct EciesOmitCiphertext {
+internal struct EciesOmitCiphertext {
var iv: String
var ephemPublicKey: String
var mac: String
diff --git a/Sources/TorusUtils/Interfaces/Common/INodePub.swift b/Sources/TorusUtils/Interfaces/Common/INodePub.swift
new file mode 100644
index 00000000..f8021656
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/Common/INodePub.swift
@@ -0,0 +1,16 @@
+import FetchNodeDetails
+import Foundation
+
+internal class INodePub {
+ let X: String
+ let Y: String
+
+ init(X: String, Y: String) {
+ self.X = X
+ self.Y = Y
+ }
+}
+
+internal func TorusNodePubModelToINodePub(nodes: [TorusNodePubModel]) -> [INodePub] {
+ return nodes.map({ INodePub(X: $0.getX(), Y: $0.getY()) })
+}
diff --git a/Sources/TorusUtils/Interfaces/Common/ImportedShare.swift b/Sources/TorusUtils/Interfaces/Common/ImportedShare.swift
new file mode 100644
index 00000000..4218c932
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/Common/ImportedShare.swift
@@ -0,0 +1,32 @@
+import BigInt
+import Foundation
+
+internal struct ImportedShare: Codable {
+ let oauth_pub_key_x: String
+ let oauth_pub_key_y: String
+ let final_user_point: Point
+ let signing_pub_key_x: String
+ let signing_pub_key_y: String
+ let encryptedShare: String
+ let encryptedShareMetadata: EciesHexOmitCiphertext
+ let encryptedSeed: String?
+ let node_index: Int
+ let key_type: TorusKeyType
+ let nonce_data: String
+ let nonce_signature: String
+
+ public init(oauth_pub_key_x: String, oauth_pub_key_y: String, final_user_point: Point, signing_pub_key_x: String, signing_pub_key_y: String, encryptedShare: String, encryptedShareMetadata: EciesHexOmitCiphertext, encryptedSeed: String? = nil, node_index: Int, key_type: TorusKeyType = .secp256k1, nonce_data: String, nonce_signature: String) {
+ self.oauth_pub_key_x = oauth_pub_key_x
+ self.oauth_pub_key_y = oauth_pub_key_y
+ self.final_user_point = final_user_point
+ self.signing_pub_key_x = signing_pub_key_x
+ self.signing_pub_key_y = signing_pub_key_y
+ self.encryptedShare = encryptedShare
+ self.encryptedShareMetadata = encryptedShareMetadata
+ self.encryptedSeed = encryptedSeed
+ self.node_index = node_index
+ self.key_type = key_type
+ self.nonce_data = nonce_data
+ self.nonce_signature = nonce_signature
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/Common/PrivateKeyData.swift b/Sources/TorusUtils/Interfaces/Common/PrivateKeyData.swift
new file mode 100644
index 00000000..5b1fcce9
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/Common/PrivateKeyData.swift
@@ -0,0 +1,12 @@
+import BigInt
+import Foundation
+
+internal struct PrivateKeyData {
+ let oAuthKey: String
+ let oAuthPubKey: String
+ let nonce: String
+ let signingKey: String
+ let signingPubKey: String
+ let finalKey: String
+ let finalPubKey: String
+}
diff --git a/Sources/TorusUtils/Interfaces/Common/PubNonce.swift b/Sources/TorusUtils/Interfaces/Common/PubNonce.swift
new file mode 100644
index 00000000..2af7a647
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/Common/PubNonce.swift
@@ -0,0 +1,21 @@
+import Foundation
+
+public class PubNonce: Codable, Equatable {
+ public static func == (lhs: PubNonce, rhs: PubNonce) -> Bool {
+ return lhs.x == rhs.x && lhs.y == rhs.y
+ }
+
+ public var x: String
+ public var y: String
+
+ internal init(x: String, y: String) {
+ self.x = x
+ self.y = y
+ }
+
+ public required init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ x = try container.decode(String.self, forKey: .x)
+ y = try container.decode(String.self, forKey: .y)
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/Common/SessionToken.swift b/Sources/TorusUtils/Interfaces/Common/SessionToken.swift
new file mode 100644
index 00000000..ccd052bf
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/Common/SessionToken.swift
@@ -0,0 +1,15 @@
+import Foundation
+
+public class SessionToken: Codable {
+ public let token: String
+ public let signature: String
+ public let node_pubx: String
+ public let node_puby: String
+
+ internal init(token: String, signature: String, node_pubx: String, node_puby: String) {
+ self.token = token
+ self.signature = signature
+ self.node_pubx = node_pubx
+ self.node_puby = node_puby
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/Common/UserType.swift b/Sources/TorusUtils/Interfaces/Common/UserType.swift
new file mode 100644
index 00000000..b78007f7
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/Common/UserType.swift
@@ -0,0 +1,6 @@
+import Foundation
+
+public enum UserType: String, Codable, Equatable, Hashable {
+ case v1
+ case v2
+}
diff --git a/Sources/TorusUtils/Interfaces/ImportedShare.swift b/Sources/TorusUtils/Interfaces/ImportedShare.swift
deleted file mode 100644
index 22b46c99..00000000
--- a/Sources/TorusUtils/Interfaces/ImportedShare.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-import BigInt
-import Foundation
-
-struct ImportedShare {
- let pubKeyX: String
- let pubKeyY: String
- let encryptedShare: String
- let encryptedShareMetadata: EciesHex
- let nodeIndex: Int
- let keyType: String
- let nonceData: String
- let nonceSignature: String
-}
diff --git a/Sources/TorusUtils/Interfaces/KeyAssignInput.swift b/Sources/TorusUtils/Interfaces/KeyAssignInput.swift
deleted file mode 100644
index 597ca036..00000000
--- a/Sources/TorusUtils/Interfaces/KeyAssignInput.swift
+++ /dev/null
@@ -1,107 +0,0 @@
-import Foundation
-
-public struct KeyIndex: Decodable {
- let index: String
- let serviceGroupId: String
- let tag: String
-
- enum CodingKeys: CodingKey {
- case index
- case service_group_id
- case tag
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- index = try container.decode(String.self, forKey: .index)
- serviceGroupId = try container.decode(String.self, forKey: .service_group_id)
- tag = try container.decode(String.self, forKey: .tag)
- }
-}
-
-enum keyIndexTag: String {
- case imported
- case generated
-}
-
-public struct KeyAssignInput {
- let endpoints: [String]
- let torusNodePubs: [INodePub]
- let lastPoint: Int?
- let firstPoint: Int?
- let verifier: String
- let verifierId: String
- let signerHost: String
- let network: String
- let clientId: String
-}
-
-public struct KeyAssignment: Decodable {
- let index: String
- let publicKey: PublicKey
- let threshold: Int
- let nodeIndex: Int
- let share: String
- let shareMetadata: EciesHex
- let nonceData: GetOrSetNonceResult?
-
- struct PublicKey: Hashable, Codable {
- let X: String
- let Y: String
- }
-
- enum CodingKeys: CodingKey {
- case index
- case public_key
- case threshold
- case node_index
- case share
- case share_metadata
- case nonce_data
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- index = try container.decode(String.self, forKey: .index)
-
- publicKey = try container.decode(PublicKey.self, forKey: .public_key)
- threshold = Int(try container.decode(String.self, forKey: .threshold))!
- nodeIndex = Int(try container.decode(String.self, forKey: .node_index))!
- share = try container.decode(String.self, forKey: .share)
- shareMetadata = try container.decode(EciesHex.self, forKey: .share_metadata)
- nonceData = try container.decodeIfPresent(GetOrSetNonceResult.self, forKey: .nonce_data)
- }
-}
-
-public struct LegacyKeyAssignment: Decodable {
- let index: String
- let publicKey: PublicKey
- let threshold: String
- let verifiers: [String: [String]]
- let share: String
- let metadata: EciesHex
-
- struct PublicKey: Hashable, Codable {
- let X: String
- let Y: String
- }
-
- enum CodingKeys: CodingKey {
- case Index
- case PublicKey
- case Threshold
- case Verifiers
- case Share
- case Metadata
- }
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- index = try container.decode(String.self, forKey: .Index)
- publicKey = try container.decode(PublicKey.self, forKey: .PublicKey)
- threshold = try container.decode(String.self, forKey: .Threshold)
- verifiers = try container.decode([String: [String]].self, forKey: .Verifiers)
- share = try container.decode(String.self, forKey: .Share)
- metadata = try container.decode(EciesHex.self, forKey: .Metadata)
- }
-}
diff --git a/Sources/TorusUtils/Interfaces/KeyLookup/KeyLookupResult.swift b/Sources/TorusUtils/Interfaces/KeyLookup/KeyLookupResult.swift
new file mode 100644
index 00000000..4b6b01ba
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/KeyLookup/KeyLookupResult.swift
@@ -0,0 +1,32 @@
+import Foundation
+
+internal struct KeyLookupResult {
+ public struct KeyResult: Codable {
+ public var keys: [VerifierLookupResponse.Key]
+ public var is_new_key: Bool
+
+ public init(keys: [VerifierLookupResponse.Key], is_new_key: Bool) {
+ self.keys = keys
+ self.is_new_key = is_new_key
+ }
+
+ public init(is_new_key: Bool) {
+ keys = []
+ self.is_new_key = is_new_key
+ }
+ }
+
+ public let keyResult: KeyResult?
+ public let nodeIndexes: [Int]
+ public let serverTimeOffset: Int
+ public let nonceResult: GetOrSetNonceResult?
+ public let errorResult: ErrorMessage?
+
+ public init(keyResult: KeyResult?, nodeIndexes: [Int], serverTimeOffset: Int, nonceResult: GetOrSetNonceResult?, errorResult: ErrorMessage?) {
+ self.keyResult = keyResult
+ self.nodeIndexes = nodeIndexes
+ self.serverTimeOffset = serverTimeOffset
+ self.nonceResult = nonceResult
+ self.errorResult = errorResult
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift b/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift
deleted file mode 100644
index a3bcb1c7..00000000
--- a/Sources/TorusUtils/Interfaces/KeyLookupResponse.swift
+++ /dev/null
@@ -1,65 +0,0 @@
-import Foundation
-
-public struct LegacyKeyLookupResponse: CustomStringConvertible, Hashable {
- public let pubKeyX: String
- public let pubKeyY: String
- public let keyIndex: String
- public let address: String
- public var description: String {
- return "public key X is \(pubKeyX) public key Y is \(pubKeyY) address is \(address)"
- }
-
- public init(pubKeyX: String, pubKeyY: String, keyIndex: String, address: String) {
- self.pubKeyX = pubKeyX
- self.pubKeyY = pubKeyY
- self.keyIndex = keyIndex
- self.address = address
- }
-}
-
-public struct KeyLookupResponse: CustomStringConvertible, Hashable {
- public let pubKeyX: String
- public let pubKeyY: String
- public let address: String
- public let isNewKey: Bool
-
- public var description: String {
- return "public key X is \(pubKeyX) public key Y is \(pubKeyY) address is \(address)"
- }
-
- public init(pubKeyX: String, pubKeyY: String, address: String, isNewKey: Bool) {
- self.pubKeyX = pubKeyX
- self.pubKeyY = pubKeyY
- self.address = address
- self.isNewKey = isNewKey
- }
-}
-
-public enum KeyLookupError: Error {
- case verifierNotSupported
- case verifierAndVerifierIdNotAssigned
- case configError
-
- static func createErrorFromString(errorString: String) -> Self {
- if errorString.contains("Verifier not supported") {
- return .verifierNotSupported
- } else if errorString.contains("Verifier + VerifierID has not yet been assigned") {
- return .verifierAndVerifierIdNotAssigned
- } else {
- return .configError
- }
- }
-}
-
-extension KeyLookupError: LocalizedError {
- public var errorDescription: String? {
- switch self {
- case .verifierNotSupported:
- return "Verifier not supported. Check if you: \n1. Are on the right network (Torus testnet/mainnet) \n2. Have setup a verifier on dashboterard.web3auth.io?"
- case .verifierAndVerifierIdNotAssigned:
- return "Verifier + VerifierID has not yet been assigned"
- case .configError:
- return "ConfigurationError"
- }
- }
-}
diff --git a/Sources/TorusUtils/Interfaces/KeyLookupResult.swift b/Sources/TorusUtils/Interfaces/KeyLookupResult.swift
deleted file mode 100644
index ce04a3cd..00000000
--- a/Sources/TorusUtils/Interfaces/KeyLookupResult.swift
+++ /dev/null
@@ -1,7 +0,0 @@
-import Foundation
-
-struct KeyLookupResult {
- let keyResult: KeyLookupResponse
- let nodeIndexes: [Int]
- let nonceResult: GetOrSetNonceResult?
-}
diff --git a/Sources/TorusUtils/Interfaces/MetaData/MetadataParams.swift b/Sources/TorusUtils/Interfaces/MetaData/MetadataParams.swift
new file mode 100644
index 00000000..06ff6440
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/MetaData/MetadataParams.swift
@@ -0,0 +1,39 @@
+import Foundation
+
+internal struct GetMetadataParams: Codable {
+ public var pub_key_X: String
+ public var pub_key_Y: String
+
+ public init(pub_key_X: String, pub_key_Y: String) {
+ self.pub_key_X = pub_key_X
+ self.pub_key_Y = pub_key_Y
+ }
+}
+
+internal struct MetadataParams: Codable {
+ public struct SetData: Codable {
+ public var data: String // "getNonce" || "getOrSetNonce" || String
+ public var timestamp: String
+
+ public init(data: String, timestamp: String) {
+ self.data = data
+ self.timestamp = timestamp
+ }
+ }
+
+ public var namespace: String?
+ public var pub_key_X: String
+ public var pub_key_Y: String
+ public var key_type: TorusKeyType?
+ public var set_data: SetData
+ public var signature: String
+
+ public init(pub_key_X: String, pub_key_Y: String, setData: SetData, signature: String, namespace: String? = nil, keyType: TorusKeyType? = nil) {
+ self.namespace = namespace
+ self.pub_key_X = pub_key_X
+ self.pub_key_Y = pub_key_Y
+ key_type = keyType
+ set_data = setData
+ self.signature = signature
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/RetrieveDecryptAndReconstuctResponse.swift b/Sources/TorusUtils/Interfaces/RetrieveDecryptAndReconstuctResponse.swift
deleted file mode 100644
index a1981aeb..00000000
--- a/Sources/TorusUtils/Interfaces/RetrieveDecryptAndReconstuctResponse.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-import Foundation
-
-public struct RetrieveDecryptAndReconstuctResponse {
- public let iv: String
- public let ephemPublicKey: String
- public let share: String
- public let pubKeyX: String
- public let pubKeyY: String
-
- public init(iv: String, ephemPublicKey: String, share: String, pubKeyX: String, pubKeyY: String) {
- self.iv = iv
- self.ephemPublicKey = ephemPublicKey
- self.share = share
- self.pubKeyX = pubKeyX
- self.pubKeyY = pubKeyY
- }
-}
diff --git a/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift b/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift
deleted file mode 100644
index b9c4dfec..00000000
--- a/Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift
+++ /dev/null
@@ -1,28 +0,0 @@
-import BigInt
-import Foundation
-
-public struct RetrieveSharesResponse {
- public let ethAddress: String
- public let privKey: String
- public let sessionTokenData: [SessionToken?]
- public let X: String
- public let Y: String
- public let metadataNonce: BigInt
- public let postboxPubKeyX: String
- public let postboxPubKeyY: String
- public let sessionAuthKey: String
- public let nodeIndexes: [Int]
-
- public init(ethAddress: String, privKey: String, sessionTokenData: [SessionToken?], X: String, Y: String, metadataNonce: BigInt, postboxPubKeyX: String, postboxPubKeyY: String, sessionAuthKey: String, nodeIndexes: [Int]) {
- self.ethAddress = ethAddress
- self.privKey = privKey
- self.sessionTokenData = sessionTokenData
- self.X = X
- self.Y = Y
- self.metadataNonce = metadataNonce
- self.postboxPubKeyX = postboxPubKeyX
- self.postboxPubKeyY = postboxPubKeyY
- self.sessionAuthKey = sessionAuthKey
- self.nodeIndexes = nodeIndexes
- }
-}
diff --git a/Sources/TorusUtils/Interfaces/SessionToken.swift b/Sources/TorusUtils/Interfaces/SessionToken.swift
deleted file mode 100644
index 98297a94..00000000
--- a/Sources/TorusUtils/Interfaces/SessionToken.swift
+++ /dev/null
@@ -1,8 +0,0 @@
-import Foundation
-
-public struct SessionToken {
- public let token: String
- public let signature: String
- public let node_pubx: String
- public let node_puby: String
-}
diff --git a/Sources/TorusUtils/Interfaces/ShareRequestResult.swift b/Sources/TorusUtils/Interfaces/ShareRequestResult.swift
deleted file mode 100644
index 89446f92..00000000
--- a/Sources/TorusUtils/Interfaces/ShareRequestResult.swift
+++ /dev/null
@@ -1,108 +0,0 @@
-import Foundation
-
-struct ShareRequestResult: Decodable {
- let keys: [KeyAssignment]
- let sessionTokens: [String]
- let sessionTokenMetadata: [EciesHex]
- let sessionTokenSigs: [String]
- let sessionTokenSigMetadata: [EciesHex]
- let nodePubX: String
- let nodePubY: String
- let isNewKey: String
-
- enum CodingKeys: CodingKey {
- case keys
- case session_tokens
- case session_token_metadata
- case session_token_sigs
- case session_token_sig_metadata
- case node_pubx
- case node_puby
- case is_new_key
- }
-
- init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- keys = try container.decode([KeyAssignment].self, forKey: .keys)
- nodePubX = try container.decode(String.self, forKey: .node_pubx)
- nodePubY = try container.decode(String.self, forKey: .node_puby)
- isNewKey = try container.decode(String.self, forKey: .is_new_key)
-
- if let sessionTokens = try? container.decodeIfPresent([String].self, forKey: .session_tokens) {
- self.sessionTokens = sessionTokens
- } else {
- sessionTokens = []
- }
-
- if let sessionTokenMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_metadata) {
- self.sessionTokenMetadata = sessionTokenMetadata
- } else {
- sessionTokenMetadata = []
- }
-
- if let sessionTokenSigs = try? container.decodeIfPresent([String].self, forKey: .session_token_sigs) {
- self.sessionTokenSigs = sessionTokenSigs
- } else {
- sessionTokenSigs = []
- }
-
- if let sessionTokenSigMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_sig_metadata) {
- self.sessionTokenSigMetadata = sessionTokenSigMetadata
- } else {
- sessionTokenSigMetadata = []
- }
- }
-}
-
-typealias ImportShareRequestResult = ShareRequestResult
-
-struct LegacyShareRequestResult: Decodable {
- let keys: [LegacyKeyAssignment]
- let sessionTokens: [String]
- let sessionTokenMetadata: [EciesHex]
- let sessionTokenSigs: [String]
- let sessionTokenSigMetadata: [EciesHex]
- let nodePubX: String
- let nodePubY: String
-
- enum CodingKeys: CodingKey {
- case keys
- case session_tokens
- case session_token_metadata
- case session_token_sigs
- case session_token_sig_metadata
- case node_pubx
- case node_puby
- }
-
- init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- keys = try container.decode([LegacyKeyAssignment].self, forKey: .keys)
- nodePubX = try container.decode(String.self, forKey: .node_pubx)
- nodePubY = try container.decode(String.self, forKey: .node_puby)
-
- if let sessionTokens = try? container.decodeIfPresent([String].self, forKey: .session_tokens) {
- self.sessionTokens = sessionTokens
- } else {
- sessionTokens = []
- }
-
- if let sessionTokenMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_metadata) {
- self.sessionTokenMetadata = sessionTokenMetadata
- } else {
- sessionTokenMetadata = []
- }
-
- if let sessionTokenSigs = try? container.decodeIfPresent([String].self, forKey: .session_token_sigs) {
- self.sessionTokenSigs = sessionTokenSigs
- } else {
- sessionTokenSigs = []
- }
-
- if let sessionTokenSigMetadata = try? container.decodeIfPresent([EciesHex].self, forKey: .session_token_sig_metadata) {
- self.sessionTokenSigMetadata = sessionTokenSigMetadata
- } else {
- sessionTokenSigMetadata = []
- }
- }
-}
diff --git a/Sources/TorusUtils/Interfaces/TorusConstants.swift b/Sources/TorusUtils/Interfaces/TorusConstants.swift
deleted file mode 100644
index 4b8bb4fc..00000000
--- a/Sources/TorusUtils/Interfaces/TorusConstants.swift
+++ /dev/null
@@ -1,29 +0,0 @@
-import BigInt
-import FetchNodeDetails
-import Foundation
-
-enum TORUS_SAPPHIRE_NETWORK_TYPE {
- case SAPPHIRE_DEVNET
- case SAPPHIRE_TESTNET
- case SAPPHIRE_MAINNET
-}
-
-struct TORUS_SAPPHIRE_NETWORK {
- static let SAPPHIRE_DEVNET = "sapphire_devnet"
- static let SAPPHIRE_TESTNET = "sapphire_testnet"
- static let SAPPHIRE_MAINNET = "sapphire_mainnet"
-}
-
-public class INodePub {
- let X: String
- let Y: String
-
- init(X: String, Y: String) {
- self.X = X
- self.Y = Y
- }
-}
-
-public func TorusNodePubModelToINodePub(node: TorusNodePubModel) -> INodePub {
- return INodePub(X: node.getX(), Y: node.getY())
-}
diff --git a/Sources/TorusUtils/Interfaces/TorusKey.swift b/Sources/TorusUtils/Interfaces/TorusKey.swift
new file mode 100644
index 00000000..dbf9c007
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/TorusKey.swift
@@ -0,0 +1,68 @@
+import BigInt
+import Foundation
+
+public class TorusKey: Codable {
+ public class FinalKeyData: Codable {
+ public let evmAddress: String
+ public let X: String
+ public let Y: String
+ public let privKey: String
+
+ internal init(evmAddress: String, X: String, Y: String, privKey: String) {
+ self.evmAddress = evmAddress
+ self.X = X
+ self.Y = Y
+ self.privKey = privKey
+ }
+ }
+
+ public class OAuthKeyData: Codable {
+ public let evmAddress: String
+ public let X: String
+ public let Y: String
+ public let privKey: String
+
+ internal init(evmAddress: String, X: String, Y: String, privKey: String) {
+ self.evmAddress = evmAddress
+ self.X = X
+ self.Y = Y
+ self.privKey = privKey
+ }
+ }
+
+ public class SessionData: Codable {
+ public let sessionTokenData: [SessionToken?]
+ public let sessionAuthKey: String
+
+ internal init(sessionTokenData: [SessionToken?], sessionAuthKey: String) {
+ self.sessionTokenData = sessionTokenData
+ self.sessionAuthKey = sessionAuthKey
+ }
+ }
+
+ public class NodesData: Codable {
+ public let nodeIndexes: [Int]
+
+ internal init(nodeIndexes: [Int]) {
+ self.nodeIndexes = nodeIndexes
+ }
+ }
+
+ internal init(finalKeyData: FinalKeyData,
+ oAuthKeyData: OAuthKeyData,
+ sessionData: SessionData,
+ metadata: TorusPublicKey.Metadata,
+ nodesData: NodesData) {
+ self.finalKeyData = finalKeyData
+ self.oAuthKeyData = oAuthKeyData
+ self.sessionData = sessionData
+ self.metadata = metadata
+ self.nodesData = nodesData
+ }
+
+ public let finalKeyData: FinalKeyData
+ public let oAuthKeyData: OAuthKeyData
+ public let sessionData: SessionData
+ public let metadata: TorusPublicKey.Metadata
+ public let nodesData: NodesData
+}
diff --git a/Sources/TorusUtils/Interfaces/TorusOptions.swift b/Sources/TorusUtils/Interfaces/TorusOptions.swift
new file mode 100644
index 00000000..2dd1795e
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/TorusOptions.swift
@@ -0,0 +1,29 @@
+import FetchNodeDetails
+import Foundation
+
+/// TorusOptions is a configuration class that is used to initialize `TorusUtils`.
+public class TorusOptions {
+ public var enableOneKey: Bool
+ public var clientId: String
+ public var network: TorusNetwork
+ public var serverTimeOffset: Int
+ public var legacyMetadataHost: String?
+
+ /// Initializes TorusOptions
+ ///
+ /// - Parameters:
+ /// - clientId: The client identity.
+ /// - network: `TorusNetwork`. Please note that new users should be using .sapphire(.SAPPHIRE_MAINNET).
+ /// - legacyMetadataHost: The url of the metadata server, this only needs to be supplied if the default is not being used.
+ /// - serverTimeOffset: The offset from Coordinated Universal Time (UCT).
+ /// - enableOneKey: Use the oneKey flow.
+ ///
+ /// - Returns: `TorusOptions`
+ public init(clientId: String, network: TorusNetwork, legacyMetadataHost: String? = nil, serverTimeOffset: Int = 0, enableOneKey: Bool = false) {
+ self.clientId = clientId
+ self.enableOneKey = enableOneKey
+ self.network = network
+ self.serverTimeOffset = serverTimeOffset
+ self.legacyMetadataHost = legacyMetadataHost
+ }
+}
diff --git a/Sources/TorusUtils/Interfaces/TorusPublicKey.swift b/Sources/TorusUtils/Interfaces/TorusPublicKey.swift
index 7ff5d783..189f0d08 100644
--- a/Sources/TorusUtils/Interfaces/TorusPublicKey.swift
+++ b/Sources/TorusUtils/Interfaces/TorusPublicKey.swift
@@ -1,51 +1,64 @@
import BigInt
import Foundation
-public enum UserType: String {
- case v1
- case v2
-}
-
-public struct TorusPublicKey {
- public struct FinalKeyData {
+public class TorusPublicKey: Codable {
+ public class OAuthKeyData: Codable {
public let evmAddress: String
public let X: String
public let Y: String
+
+ internal init(evmAddress: String, X: String, Y: String) {
+ self.evmAddress = evmAddress
+ self.X = X
+ self.Y = Y
+ }
}
- public struct OAuthKeyData {
+ public class FinalKeyData: Codable {
public let evmAddress: String
public let X: String
public let Y: String
+
+ internal init(evmAddress: String, X: String, Y: String) {
+ self.evmAddress = evmAddress
+ self.X = X
+ self.Y = Y
+ }
}
- public struct Metadata {
+ public class Metadata: Codable {
public let pubNonce: PubNonce?
public let nonce: BigUInt?
public let typeOfUser: UserType
public let upgraded: Bool?
+ public let serverTimeOffset: Int
+
+ internal init(pubNonce: PubNonce?, nonce: BigUInt?, typeOfUser: UserType, upgraded: Bool?, serverTimeOffset: Int) {
+ self.pubNonce = pubNonce
+ self.nonce = nonce
+ self.typeOfUser = typeOfUser
+ self.upgraded = upgraded
+ self.serverTimeOffset = serverTimeOffset
+ }
}
- public struct NodesData {
+ public class NodesData: Codable {
public let nodeIndexes: [Int]
+
+ internal init(nodeIndexes: [Int]) {
+ self.nodeIndexes = nodeIndexes
+ }
}
- public init(finalKeyData: FinalKeyData?, oAuthKeyData: OAuthKeyData?, metadata: Metadata?, nodesData: NodesData?) {
+ internal init(oAuthKeyData: OAuthKeyData?, finalKeyData: FinalKeyData?, metadata: Metadata?, nodesData: NodesData?) {
self.finalKeyData = finalKeyData
self.oAuthKeyData = oAuthKeyData
self.metadata = metadata
self.nodesData = nodesData
}
- public let finalKeyData: FinalKeyData?
public let oAuthKeyData: OAuthKeyData?
+ public let finalKeyData: FinalKeyData?
public let metadata: Metadata?
public let nodesData: NodesData?
}
-
-public typealias V2NonceResultType = GetOrSetNonceResult
-
-struct V1NonceResultType {
- let typeOfUser: UserType
- let nonce: String?
-}
diff --git a/Sources/TorusUtils/Interfaces/Toruskey.swift b/Sources/TorusUtils/Interfaces/Toruskey.swift
deleted file mode 100644
index 4e38df6d..00000000
--- a/Sources/TorusUtils/Interfaces/Toruskey.swift
+++ /dev/null
@@ -1,65 +0,0 @@
-import BigInt
-import Foundation
-
-public struct TorusKey {
- public struct FinalKeyData {
- public let evmAddress: String
- public let X: String
- public let Y: String
- public let privKey: String?
- }
-
- public struct OAuthKeyData {
- public let evmAddress: String
- public let X: String
- public let Y: String
- public let privKey: String
- }
-
- public struct SessionData {
- public let sessionTokenData: [SessionToken?]
- public let sessionAuthKey: String
- }
-
- public struct Metadata {
- public let pubNonce: PubNonce?
- public let nonce: BigUInt?
- public let typeOfUser: UserType
- public let upgraded: Bool?
- }
-
- public struct NodesData {
- public let nodeIndexes: [Int]
- }
-
- public init(finalKeyData: FinalKeyData?,
- oAuthKeyData: OAuthKeyData?,
- sessionData: SessionData?,
- metadata: Metadata?,
- nodesData: NodesData?) {
- self.finalKeyData = finalKeyData
- self.oAuthKeyData = oAuthKeyData
- self.sessionData = sessionData
- self.metadata = metadata
- self.nodesData = nodesData
- }
-
- public let finalKeyData: FinalKeyData?
- public let oAuthKeyData: OAuthKeyData?
- public let sessionData: SessionData?
- public let metadata: Metadata?
- public let nodesData: NodesData?
-}
-
-
-// allow response
-public struct AllowSuccess : Codable {
- public let success: Bool
-}
-
-public struct AllowRejected : Codable {
- public let code: Int32
- public let error: String
- public let success: Bool
-}
-
diff --git a/Sources/TorusUtils/Interfaces/VerifierParams.swift b/Sources/TorusUtils/Interfaces/VerifierParams.swift
deleted file mode 100644
index 18f2800d..00000000
--- a/Sources/TorusUtils/Interfaces/VerifierParams.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-import Foundation
-
-public struct VerifierParams {
- public let verifier_id: String
- public let extended_verifier_id: String?
- public let additionalParams: [String: Codable]
-
- public init(verifier_id: String, extended_verifier_id: String? = nil, additionalParams: [String: Codable] = [:]) {
- self.verifier_id = verifier_id
- self.extended_verifier_id = extended_verifier_id
- self.additionalParams = additionalParams
- }
-}
diff --git a/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift b/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift
deleted file mode 100644
index d1ccefff..00000000
--- a/Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift
+++ /dev/null
@@ -1,30 +0,0 @@
-import Foundation
-
-public struct RetrieveSharesResponseModel {
- public let publicAddress: String
- public let privateKey: String
-
- public init(publicKey: String, privateKey: String) {
- publicAddress = publicKey
- self.privateKey = privateKey
- }
-}
-
-// legacy
-public struct RetrieveDecryptAndReconstuctResponseModel {
- public let iv: String
- public let ephemPublicKey: String
- public let share: String
- public let pubKeyX: String
- public let pubKeyY: String
- public let mac: String
-
- public init(iv: String, ephemPublicKey: String, share: String, pubKeyX: String, pubKeyY: String, mac: String) {
- self.iv = iv
- self.ephemPublicKey = ephemPublicKey
- self.share = share
- self.pubKeyX = pubKeyX
- self.pubKeyY = pubKeyY
- self.mac = mac
- }
-}
diff --git a/Sources/TorusUtils/Point.swift b/Sources/TorusUtils/Point.swift
index f4414ce3..942f2e84 100644
--- a/Sources/TorusUtils/Point.swift
+++ b/Sources/TorusUtils/Point.swift
@@ -1,14 +1,31 @@
import BigInt
import Foundation
import Security
+#if canImport(curveSecp256k1)
+ import curveSecp256k1
+#endif
-public class Point: Decodable {
+enum PointError: Error {
+ case encodingNotSupported
+ case compressedPublicKeyGenerationFailed
+}
+
+internal struct Point: Codable {
let x: BigInt
let y: BigInt
- init(x: String, y: String) {
- self.x = BigInt(x, radix: 16)!
- self.y = BigInt(y, radix: 16)!
+ init(x: String, y: String) throws {
+ if let xCoord = BigInt(x, radix: 16) {
+ self.x = xCoord
+ } else {
+ throw TorusUtilError.invalidInput
+ }
+
+ if let yCoord = BigInt(y, radix: 16) {
+ self.y = yCoord
+ } else {
+ throw TorusUtilError.invalidInput
+ }
}
init(x: BigInt, y: BigInt) {
@@ -16,12 +33,12 @@ public class Point: Decodable {
self.y = y
}
- public enum CodingKeys: CodingKey {
+ enum CodingKeys: CodingKey {
case X
case Y
}
- public required init(from decoder: Decoder) throws {
+ init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let hexX = try container.decode(String.self, forKey: .X)
let hexY = try container.decode(String.self, forKey: .Y)
@@ -33,20 +50,24 @@ public class Point: Decodable {
func encode(enc: String) throws -> Data {
switch enc {
case "arr":
- let prefix = Data(hex: String().add04Prefix())
- let xData = Data(hex: x.description)
- let yData = Data(hex: y.description)
- return prefix + xData + yData
-// case "elliptic-compressed":
-// let publicKey = try getCompressedPublicKey()
-// return publicKey
+ return Data(hex: KeyUtils.getPublicKeyFromCoords(pubKeyX: x.magnitude.serialize().hexString, pubKeyY: y.magnitude.serialize().hexString))
+ case "elliptic-compressed":
+ let keyData = KeyUtils.getPublicKeyFromCoords(pubKeyX: x.magnitude.serialize().hexString, pubKeyY: y.magnitude.serialize().hexString)
+ let pubKey = try PublicKey(hex: keyData)
+ return Data(hex: try pubKey.serialize(compressed: true))
default:
throw PointError.encodingNotSupported
}
}
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+ try container.encode(x.magnitude.serialize().hexString.addLeading0sForLength64(), forKey: .X)
+ try container.encode(y.magnitude.serialize().hexString.addLeading0sForLength64(), forKey: .Y)
+ }
}
-public struct PointHex: Decodable, Hashable, Equatable {
+internal struct PointHex: Decodable, Hashable, Equatable {
let x: String
let y: String
@@ -55,8 +76,3 @@ public struct PointHex: Decodable, Hashable, Equatable {
y = String(from.y, radix: 16)
}
}
-
-enum PointError: Error {
- case encodingNotSupported
- case compressedPublicKeyGenerationFailed
-}
diff --git a/Sources/TorusUtils/Polynomial.swift b/Sources/TorusUtils/Polynomial.swift
index 4ed66971..92d32ae8 100644
--- a/Sources/TorusUtils/Polynomial.swift
+++ b/Sources/TorusUtils/Polynomial.swift
@@ -1,10 +1,9 @@
import BigInt
-import CryptoKit
import Foundation
typealias ShareMap = [String: Share]
-public struct Polynomial {
+internal struct Polynomial {
let polynomial: [BigInt]
init(polynomial: [BigInt]) {
@@ -16,15 +15,14 @@ public struct Polynomial {
}
func polyEval(x: BigInt) -> BigInt {
- var xi = BigInt(x)
+ let tmpX = x
+ var xi = BigInt(tmpX)
var sum = BigInt(0)
sum += polynomial[0]
for i in 1 ..< polynomial.count {
- let tmp = xi * polynomial[i]
- sum += tmp
- sum %= getOrderOfCurve()
- xi *= x
- xi %= getOrderOfCurve()
+ let tmp = (xi * polynomial[i])
+ sum = (sum + tmp).modulus(KeyUtils.getOrderOfCurve())
+ xi = (xi * tmpX).modulus(KeyUtils.getOrderOfCurve())
}
return sum
}
@@ -32,15 +30,9 @@ public struct Polynomial {
func generateShares(shareIndexes: [BigInt]) -> ShareMap {
var shares: ShareMap = [:]
for x in 0 ..< shareIndexes.count {
- let hexString = shareIndexes[x].serialize().toHexString()
+ let hexString = shareIndexes[x].magnitude.serialize().hexString.addLeading0sForLength64()
shares[hexString] = Share(shareIndex: shareIndexes[x], share: polyEval(x: shareIndexes[x]))
}
return shares
}
}
-
-public func getOrderOfCurve() -> BigInt {
- let orderHex = CURVE_N
- let order = BigInt(orderHex, radix: 16)!
- return order
-}
diff --git a/Sources/TorusUtils/Share.swift b/Sources/TorusUtils/Share.swift
index 11e1498f..1a96d63b 100644
--- a/Sources/TorusUtils/Share.swift
+++ b/Sources/TorusUtils/Share.swift
@@ -1,13 +1,22 @@
import BigInt
import Foundation
-public class Share: Codable {
+internal class Share: Codable {
var share: BigInt
var shareIndex: BigInt
- public init(shareIndex: String, share: String) {
- self.share = BigInt(share, radix: 16)!
- self.shareIndex = BigInt(shareIndex, radix: 16)!
+ public init(shareIndex: String, share: String) throws {
+ if let si = BigInt(shareIndex, radix: 16) {
+ self.shareIndex = si
+ } else {
+ throw TorusUtilError.invalidInput
+ }
+
+ if let s = BigInt(share, radix: 16) {
+ self.share = s
+ } else {
+ throw TorusUtilError.invalidInput
+ }
}
public init(shareIndex: BigInt, share: BigInt) {
diff --git a/Sources/TorusUtils/TorusUtils.swift b/Sources/TorusUtils/TorusUtils.swift
index b431e2d7..aa1af7cf 100644
--- a/Sources/TorusUtils/TorusUtils.swift
+++ b/Sources/TorusUtils/TorusUtils.swift
@@ -2,500 +2,375 @@ import BigInt
import FetchNodeDetails
import Foundation
import OSLog
-import AnyCodable
#if canImport(curveSecp256k1)
import curveSecp256k1
#endif
var utilsLogType = OSLogType.default
-open class TorusUtils: AbstractTorusUtils {
- private var timeout: Int = 30
- var urlSession: URLSession
- var serverTimeOffset: TimeInterval = 0
+public class TorusUtils {
+ private var sessionTime: Int = 86400 // 24 hour
+
var allowHost: String
+
+ var serverTimeOffset: Int?
+
var network: TorusNetwork
- var modulusValue = BigInt(CURVE_N, radix: 16)!
+
var clientId: String
- var signerHost: String
+
var enableOneKey: Bool
+
+ var signerHost: String
+
var legacyMetadataHost: String
- public init(loglevel: OSLogType = .default,
- urlSession: URLSession = URLSession(configuration: .default),
- enableOneKey: Bool = false,
- serverTimeOffset: TimeInterval = 0,
- network: TorusNetwork,
- clientId: String,
- legacyMetadataHost: String = "https://metadata.tor.us"
- ) {
- self.urlSession = urlSession
+ var apiKey: String = "torus-default"
+
+ /// Initializes TorusUtils with the provided options
+ ///
+ /// - Parameters:
+ /// - params: `TorusOptions`
+ /// - logLevel: `OSLogType`, only needs to be provided if the default logging level should be changed
+ ///
+ /// - Returns: `TorusUtils`
+ ///
+ /// - Throws: `TorusUtilError.invalidInput`
+ public init(params: TorusOptions, loglevel: OSLogType = .default) throws {
+ var defaultHost = ""
+ if params.legacyMetadataHost == nil {
+ if case let .legacy(urlHost) = params.network {
+ defaultHost = urlHost.metadataMap
+ } else {
+ // TODO: Move this into fetchNodeDetails metadataMap
+ if case let .sapphire(sapphireNetwork) = params.network {
+ if sapphireNetwork == .SAPPHIRE_MAINNET {
+ defaultHost = "https://node-1.node.web3auth.io/metadata"
+ } else {
+ defaultHost = "https://node-1.dev-node.web3auth.io/metadata"
+ }
+ } else {
+ throw TorusUtilError.invalidInput
+ }
+ }
+ } else {
+ defaultHost = params.legacyMetadataHost!
+ }
+
+ serverTimeOffset = params.serverTimeOffset
+ network = params.network
+ clientId = params.clientId
+ allowHost = params.network.signerMap + "/api/allow"
utilsLogType = loglevel
- self.enableOneKey = enableOneKey
- self.allowHost = network.signerMap + "/api/allow"
- self.signerHost = network.signerMap + "/api/sign"
- self.network = network
- self.serverTimeOffset = serverTimeOffset
- self.clientId = clientId
- self.legacyMetadataHost = legacyMetadataHost
+ enableOneKey = params.enableOneKey
+ legacyMetadataHost = defaultHost
+ signerHost = params.network.signerMap + "/api/sign"
+ }
+
+ internal static func isLegacyNetworkRouteMap(network: TorusNetwork) -> Bool {
+ if case .legacy = network {
+ return true
+ }
+ return false
+ }
+
+ /// Sets the apiKey
+ ///
+ /// - Parameters:
+ /// - apiKey: The api key to be assigned
+ public func setApiKey(apiKey: String) {
+ self.apiKey = apiKey
}
- // MARK: - getPublicAddress
+ /// Reverts the apiKey for `TorusUtils` to the default value
+ public func removeApiKey() {
+ apiKey = "torus-default"
+ }
- public func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> TorusPublicKey {
- if isLegacyNetwork() {
- return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, enableOneKey: enableOneKey)
- } else {
- return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: enableOneKey)
+ /// Sets the sessionTime
+ ///
+ /// - Parameters:
+ /// - sessionTime: The amount of time a session should be valid for in seconds, default is 24 hours.
+ public func setSessionTime(sessionTime: Int) {
+ self.sessionTime = sessionTime
+ }
+
+ /// Convenience function to quickly retrieve the postbox key from `TorusKey`
+ ///
+ /// - Parameters:
+ /// - torusKey: `TorusKey`
+ ///
+ /// - Returns: `String`
+ public static func getPostboxKey(torusKey: TorusKey) -> String {
+ if torusKey.metadata.typeOfUser == .v1 {
+ return torusKey.finalKeyData.privKey
}
+ return torusKey.oAuthKeyData.privKey
}
+ /// Login for the provided user
+ ///
+ /// - Parameters:
+ /// - endpoints: The endpoints to be queried for the relevant network.
+ /// - verifier: The verifier to query, this can be a single verifier or an aggregate verifier.
+ /// - verifier_id: The identity of the user to be queried against the verifier, this is usually an emal.
+ /// - verifierParams: `VerifierParams`
+ /// - idToken: This is the identity token of the user. For single verifiers this will be a jwt, in the case of an aggregate verifier, this will be a keccak256 hash of the jwt.
+ ///
+ /// - Returns: `TorusKey`
+ ///
+ /// - Throws: `TorusUtilError`
public func retrieveShares(
endpoints: [String],
- torusNodePubs: [TorusNodePubModel],
- indexes: [BigUInt],
verifier: String,
verifierParams: VerifierParams,
idToken: String,
- extraParams: [String: Codable] = [:]
+ extraParams: TorusUtilsExtraParams = TorusUtilsExtraParams()
) async throws -> TorusKey {
- let session = createURLSession()
- var allowHostRequest = try makeUrlRequest(url: allowHost, httpMethod: .get)
- allowHostRequest.addValue("torus-default", forHTTPHeaderField: "x-api-key")
- allowHostRequest.addValue(verifier, forHTTPHeaderField: "origin")
- allowHostRequest.addValue(verifier, forHTTPHeaderField: "verifier")
- allowHostRequest.addValue(verifierParams.verifier_id, forHTTPHeaderField: "verifierid")
- allowHostRequest.addValue(clientId, forHTTPHeaderField: "clientid")
- allowHostRequest.addValue(network.name, forHTTPHeaderField: "network")
- allowHostRequest.addValue("true", forHTTPHeaderField: "enablegating")
- do {
- let result = try await session.data(for: allowHostRequest)
- let responseData = try JSONDecoder().decode(AllowSuccess.self, from: result.0)
- if (responseData.success == false ) {
- let errorData = try JSONDecoder().decode(AllowRejected.self, from: result.0)
- throw TorusUtilError.gatingError("code: \(errorData.code), error: \(errorData.error)")
- }
- } catch {
- os_log("retrieveShares: signer allow: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- throw error
+ if extraParams.session_token_exp_second == nil {
+ extraParams.session_token_exp_second = sessionTime
}
- if isLegacyNetwork() {
- let result = try await legacyRetrieveShares(torusNodePubs: torusNodePubs, indexes: indexes, endpoints: endpoints, verifier: verifier, verifierId: verifierParams.verifier_id, idToken: idToken, extraParams: extraParams)
- return result
- } else {
- let result = try await retrieveShare(
- legacyMetadataHost: legacyMetadataHost,
- allowHost: allowHost,
- enableOneKey: enableOneKey,
- network: network,
- clientId: clientId,
- endpoints: endpoints,
- verifier: verifier,
- verifierParams: verifierParams,
- idToken: idToken,
- extraParams: extraParams
- )
- return result
- }
+ return try await NodeUtils.retrieveOrImportShare(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffset, enableOneKey: enableOneKey, allowHost: allowHost, network: network, clientId: clientId, endpoints: endpoints, verifier: verifier, verifierParams: verifierParams, idToken: idToken, importedShares: [], apiKey: apiKey, extraParams: extraParams)
}
- public func getUserTypeAndAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> TorusPublicKey {
- if isLegacyNetwork() {
- return try await getLegacyPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, enableOneKey: true)
- } else {
- return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: true)
- }
+ /// Retrieves user information, defaulting the user type to .v2
+ ///
+ /// - Parameters:
+ /// - endpoints: The endpoints to be queried for the relevant network.
+ /// - verifier: The verifier to query, this can be a single verifier or an aggregate verifier.
+ /// - verifier_id: The identity of the user to be queried against the verifier, this is usually an emal.
+ /// - extended_verifier_id: This is only used if querying a tss verifier, otherwise it is not supplied. Format is (verifierId + "\u{0015}" + tssTag + "\u{0016}" + randomNonce)
+ ///
+ /// - Returns: `TorusPublicKey`
+ ///
+ /// - Throws: `TorusUtilError
+ public func getPublicAddress(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId: String? = nil) async throws -> TorusPublicKey {
+ return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: enableOneKey)
}
- private func getNewPublicAddress(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId: String? = nil, enableOneKey: Bool) async throws -> TorusPublicKey {
- do {
- let result = try await getPubKeyOrKeyAssign(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId)
- let keyResult = result.keyResult
- let nodeIndexes = result.nodeIndexes
- let (X, Y) = (keyResult.pubKeyX, keyResult.pubKeyY)
+ /// Imports a private key for the provided user
+ ///
+ /// - Parameters:
+ /// - endpoints: The endpoints to be queried for the relevant network.
+ /// - nodeIndexes: The node indexes for the endpoints.
+ /// - nodePubKeys: The public keys for the endpoints. `TorusNodePubModel`
+ /// - verifier: The verifier to query, this can be a single verifier or an aggregate verifier.
+ /// - verifier_id: The identity of the user to be queried against the verifier, this is usually an emal.
+ /// - verifierParams: `VerifierParams`
+ /// - idToken: This is the identity token of the user. For single verifiers this will be a jwt, in the case of an aggregate verifier, this will be a keccak256 hash of the jwt.
+ /// - newPrivateKey: The private key that is being imported.
+ ///
+ /// - Returns: `TorusKey`
+ ///
+ /// - Throws: `TorusUtilError`
+ public func importPrivateKey(
+ endpoints: [String],
+ nodeIndexes: [BigUInt],
+ nodePubKeys: [TorusNodePubModel],
+ verifier: String,
+ verifierParams: VerifierParams,
+ idToken: String,
+ newPrivateKey: String,
+ extraParams: TorusUtilsExtraParams = TorusUtilsExtraParams()
+ ) async throws -> TorusKey {
+ let nodePubs = TorusNodePubModelToINodePub(nodes: nodePubKeys)
+ if endpoints.count != nodeIndexes.count {
+ throw TorusUtilError.runtime("Length of endpoints must be the same as length of nodeIndexes")
+ }
- let nonceResult = result.nonceResult
+ let sharesData = try KeyUtils.generateShares(serverTimeOffset: serverTimeOffset ?? 0, nodeIndexes: nodeIndexes, nodePubKeys: nodePubs, privateKey: newPrivateKey)
- if nonceResult?.pubNonce?.x == nil && extendedVerifierId == nil && !isLegacyNetwork() { throw TorusUtilError.runtime("metadata nonce is missing in share response")
- }
+ if extraParams.session_token_exp_second == nil {
+ extraParams.session_token_exp_second = sessionTime
+ }
+
+ return try await NodeUtils.retrieveOrImportShare(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffset ?? 0, enableOneKey: enableOneKey, allowHost: allowHost, network: network, clientId: clientId, endpoints: endpoints, verifier: verifier, verifierParams: verifierParams, idToken: idToken, importedShares: sharesData, extraParams: extraParams)
+ }
- var modifiedPubKey: String
- var oAuthPubKeyString: String
- var pubNonce: PubNonce?
+ /// Retrieves user information
+ ///
+ /// - Parameters:
+ /// - endpoints: The endpoints to be queried for the relevant network.
+ /// - verifier: The verifier to query, this can be a single verifier or an aggregate verifier.
+ /// - verifier_id: The identity of the user to be queried against the verifier, this is usually an emal.
+ /// - extended_verifier_id: This is only used if querying a tss verifier, otherwise it is not supplied. Format is (verifierId + "\u{0015}" + tssTag + "\u{0016}" + randomNonce)
+ ///
+ /// - Returns: `TorusPublicKey`
+ ///
+ /// - Throws: `TorusUtilError`
+ public func getUserTypeAndAddress(
+ endpoints: [String],
+ verifier: String,
+ verifierId: String,
+ extendedVerifierId: String? = nil
+ ) async throws -> TorusPublicKey {
+ return try await getNewPublicAddress(endpoints: endpoints, verifier: verifier, verifierId: verifierId, extendedVerifierId: extendedVerifierId, enableOneKey: true)
+ }
- if extendedVerifierId != nil {
- modifiedPubKey = (X.addLeading0sForLength64() + Y.addLeading0sForLength64()).add04Prefix()
- oAuthPubKeyString = modifiedPubKey
- } else if isLegacyNetwork() {
- return try await formatLegacyPublicData(finalKeyResult: result.keyResult, enableOneKey: enableOneKey, isNewKey: result.keyResult.isNewKey)
+ private func getNewPublicAddress(endpoints: [String], verifier: String, verifierId: String, extendedVerifierId: String? = nil, enableOneKey: Bool) async throws -> TorusPublicKey {
+ let keyAssignResult = try await NodeUtils.getPubKeyOrKeyAssign(endpoints: endpoints, network: network, verifier: verifier, verifierId: verifierId, legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffset, extendedVerifierId: extendedVerifierId)
+
+ if keyAssignResult.errorResult != nil {
+ let error = keyAssignResult.errorResult!.message
+ if error.lowercased().contains("verifier not supported") {
+ throw TorusUtilError.runtime("Verifier not supported. Check if you: 1. Are on the right network (Torus testnet/mainnet) 2. Have setup a verifier on dashboard.web3auth.io?")
} else {
- modifiedPubKey = (X.addLeading0sForLength64() + Y.addLeading0sForLength64()).add04Prefix()
- oAuthPubKeyString = modifiedPubKey
-
- let pubNonceX = (nonceResult?.pubNonce?.x ?? "0")
- let pubNonceY = (nonceResult?.pubNonce?.y ?? "0")
- let noncePub = (pubNonceX.addLeading0sForLength64() + pubNonceY.addLeading0sForLength64()).add04Prefix()
- modifiedPubKey = try combinePublicKeys(keys: [modifiedPubKey, noncePub], compressed: false)
- pubNonce = nonceResult?.pubNonce
+ throw TorusUtilError.runtime(error)
}
+ }
- let (oAuthX, oAuthY) = try getPublicKeyPointFromPubkeyString(pubKey: oAuthPubKeyString)
- let (finalX, finalY) = try getPublicKeyPointFromPubkeyString(pubKey: modifiedPubKey)
-
- let oAuthAddress = generateAddressFromPubKey(publicKeyX: oAuthX, publicKeyY: oAuthY)
- let finalAddress = generateAddressFromPubKey(publicKeyX: finalX, publicKeyY: finalY)
-
- return .init(
- finalKeyData: .init(
- evmAddress: finalAddress,
- X: finalX,
- Y: finalY
- ),
- oAuthKeyData: .init(
- evmAddress: oAuthAddress,
- X: oAuthX,
- Y: oAuthY
- ),
- metadata: .init(
- pubNonce: pubNonce,
- nonce: BigUInt(nonceResult?.nonce ?? "0", radix: 16),
- typeOfUser: UserType(rawValue: "v2")!,
- upgraded: nonceResult?.upgraded ?? false
- ),
- nodesData: .init(nodeIndexes: nodeIndexes)
- )
+ if keyAssignResult.keyResult == nil || keyAssignResult.keyResult?.keys.count == 0 {
+ throw TorusUtilError.runtime("node results do not match at final lookup")
+ }
- } catch {
- throw error
+ if keyAssignResult.nonceResult == nil && extendedVerifierId == nil && !TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ throw TorusUtilError.runtime("metadata nonce is missing in share response")
}
- }
- // Legacy
- private func getLegacyPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, enableOneKey: Bool) async throws -> TorusPublicKey {
- do {
- var data: LegacyKeyLookupResponse
- var isNewKey = false
-
- do {
- data = try await legacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId)
- } catch {
- if let keyLookupError = error as? KeyLookupError, keyLookupError == .verifierAndVerifierIdNotAssigned {
- do {
- _ = try await keyAssign(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId, signerHost: signerHost, network: network)
- data = try await awaitLegacyKeyLookup(endpoints: endpoints, verifier: verifier, verifierId: verifierId, timeout: 1)
- isNewKey = true
- } catch {
- throw TorusUtilError.configurationError
- }
- } else {
- throw error
- }
+ let pubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: keyAssignResult.keyResult!.keys[0].pub_key_X, pubKeyY: keyAssignResult.keyResult!.keys[0].pub_key_Y)
+
+ var pubNonce: PubNonce?
+ let nonce: BigUInt = BigUInt(keyAssignResult.nonceResult?.nonce ?? "0", radix: 16) ?? BigUInt(0)
+
+ var oAuthPubKey: String?
+ var finalPubKey: String?
+
+ let finalServerTimeOffset = serverTimeOffset ?? keyAssignResult.serverTimeOffset
+
+ if extendedVerifierId != nil {
+ finalPubKey = pubKey
+ oAuthPubKey = finalPubKey
+ } else if TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ let legacyKeysResult = keyAssignResult.keyResult!.keys.map({
+ LegacyVerifierLookupResponse.Key(pub_key_X: $0.pub_key_X, pub_key_Y: $0.pub_key_Y, address: $0.address)
+ })
+ let legacyResult = LegacyVerifierLookupResponse(keys: legacyKeysResult, serverTimeOffset: String(finalServerTimeOffset))
+ return try await formatLegacyPublicKeyData(finalKeyResult: legacyResult, enableOneKey: enableOneKey, isNewKey: keyAssignResult.keyResult!.is_new_key, serverTimeOffset: finalServerTimeOffset)
+ } else {
+ let (X, Y) = try KeyUtils.getPublicKeyCoords(pubKey: pubKey)
+ oAuthPubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: X, pubKeyY: Y)
+ finalPubKey = oAuthPubKey!
+ if keyAssignResult.nonceResult!.pubNonce != nil && !(keyAssignResult.nonceResult!.pubNonce!.x.isEmpty || keyAssignResult.nonceResult!.pubNonce!.y.isEmpty) {
+ let pubNonceResult = keyAssignResult.nonceResult!.pubNonce!
+ let pubNonceKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: pubNonceResult.x, pubKeyY: pubNonceResult.y)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [oAuthPubKey!, pubNonceKey])
+ pubNonce = pubNonceResult
+ } else {
+ throw TorusUtilError.pubNonceMissing
}
- let keyLookupData = KeyLookupResponse(pubKeyX: data.pubKeyX, pubKeyY: data.pubKeyY, address: data.address, isNewKey: isNewKey)
- let result = try await formatLegacyPublicData(finalKeyResult: keyLookupData, enableOneKey: enableOneKey, isNewKey: isNewKey)
- return result
- } catch {
- throw error
}
- }
- private func legacyRetrieveShares(torusNodePubs: [TorusNodePubModel],
- indexes: [BigUInt],
- endpoints: [String], verifier: String, verifierId: String, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey {
- return try await withThrowingTaskGroup(of: TorusKey.self, body: { [unowned self] group in
- group.addTask { [unowned self] in
- try await handleRetrieveShares(torusNodePubs: torusNodePubs,
- indexes: indexes,
- endpoints: endpoints, verifier: verifier, verifierId: verifierId, idToken: idToken, extraParams: extraParams)
- }
- group.addTask { [unowned self] in
- // 60 second timeout for login
- try await _Concurrency.Task.sleep(nanoseconds: UInt64(timeout * 60000000000))
- throw TorusUtilError.timeout
- }
+ if oAuthPubKey == nil || finalPubKey == nil {
+ throw TorusUtilError.privateKeyDeriveFailed
+ }
- do {
- for try await val in group {
- try Task.checkCancellation()
- group.cancelAll()
- return val
- }
- } catch {
- group.cancelAll()
- throw error
- }
- throw TorusUtilError.timeout
- })
+ let (oAuthPubKeyX, oAuthPubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: oAuthPubKey!)
+ let oAuthAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: oAuthPubKeyX, publicKeyY: oAuthPubKeyY)
+
+ let (finalPubKeyX, finalPubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: finalPubKey!)
+ let finalAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: finalPubKeyX, publicKeyY: finalPubKeyY)
+
+ return TorusPublicKey(
+ oAuthKeyData: TorusPublicKey.OAuthKeyData(
+ evmAddress: oAuthAddress,
+ X: oAuthPubKeyX,
+ Y: oAuthPubKeyY
+ ),
+ finalKeyData: TorusPublicKey.FinalKeyData(
+ evmAddress: finalAddress,
+ X: finalPubKeyX,
+ Y: finalPubKeyY
+ ),
+ metadata: TorusPublicKey.Metadata(
+ pubNonce: pubNonce,
+ nonce: nonce,
+ typeOfUser: .v2,
+ upgraded: keyAssignResult.nonceResult?.upgraded ?? false,
+ serverTimeOffset: finalServerTimeOffset
+ ),
+ nodesData: TorusPublicKey.NodesData(
+ nodeIndexes: keyAssignResult.nodeIndexes
+ )
+ )
}
- private func handleRetrieveShares(torusNodePubs: [TorusNodePubModel],
- indexes: [BigUInt],
- endpoints: [String], verifier: String, verifierId: String, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey {
- let privateKey = SecretKey()
- let serializedPublicKey = try privateKey.toPublic().serialize(compressed: false)
-
- // Split key in 2 parts, X and Y
- // let publicKeyHex = publicKey.toHexString()
- let pubKeyX = String(serializedPublicKey.suffix(128).prefix(64))
- let pubKeyY = String(serializedPublicKey.suffix(64))
-
- // Hash the token from OAuth login
-
- let timestamp = String(Int(getTimestamp()))
-
- let hashedToken = keccak256Data(idToken.data(using: .utf8) ?? Data()).toHexString()
- var lookupPubkeyX: String = ""
- var lookupPubkeyY: String = ""
- do {
- let getPublicAddressData = try await getPublicAddress(endpoints: endpoints, torusNodePubs: torusNodePubs, verifier: verifier, verifierId: verifierId)
- guard (getPublicAddressData.finalKeyData?.evmAddress) != nil
- else {
- throw TorusUtilError.runtime("Unable to provide evmAddress")
- }
- let localPubkeyX = getPublicAddressData.finalKeyData!.X.addLeading0sForLength64()
- let localPubkeyY = getPublicAddressData.finalKeyData!.Y.addLeading0sForLength64()
- lookupPubkeyX = localPubkeyX
- lookupPubkeyY = localPubkeyY
- let commitmentRequestData = try await commitmentRequest(endpoints: endpoints, verifier: verifier, pubKeyX: pubKeyX, pubKeyY: pubKeyY, timestamp: timestamp, tokenCommitment: hashedToken)
- os_log("retrieveShares - data after commitment request: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, commitmentRequestData)
-
- let (oAuthKeyX, oAuthKeyY, oAuthKey) = try await retrieveDecryptAndReconstruct(
- endpoints: endpoints,
- indexes: indexes,
- extraParams: extraParams, verifier: verifier, tokenCommitment: idToken, nodeSignatures: commitmentRequestData, verifierId: verifierId, lookupPubkeyX: lookupPubkeyX, lookupPubkeyY: lookupPubkeyY, privateKey: privateKey.serialize().addLeading0sForLength64())
-
- var metadataNonce: BigUInt
- var typeOfUser: UserType = .v1
- var pubKeyNonceResult: PubNonce?
- var finalPubKey: String = ""
-
- if enableOneKey {
- let nonceResult = try await getOrSetNonce(x: oAuthKeyX, y: oAuthKeyY, privateKey: oAuthKey, getOnly: true)
- metadataNonce = BigUInt(nonceResult.nonce ?? "0", radix: 16) ?? 0
- let nonceType = nonceResult.typeOfUser ?? "v1"
- typeOfUser = UserType(rawValue: nonceType) ?? UserType.v1
- if typeOfUser == .v2 {
- finalPubKey = (oAuthKeyX.addLeading0sForLength64() + oAuthKeyY.addLeading0sForLength64()).add04Prefix()
- let newkey = ((nonceResult.pubNonce?.x.addLeading0sForLength64())! + (nonceResult.pubNonce?.y.addLeading0sForLength64())!).add04Prefix()
- finalPubKey = try combinePublicKeys(keys: [finalPubKey, newkey], compressed: false)
- pubKeyNonceResult = .init(x: nonceResult.pubNonce!.x, y: nonceResult.pubNonce!.y)
- } else {
- // for imported keys in legacy networks
- metadataNonce = try await getMetadata(dictionary: ["pub_key_X": oAuthKeyX, "pub_key_Y": oAuthKeyY])
- var privateKeyWithNonce = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)!
- privateKeyWithNonce = privateKeyWithNonce.modulus(modulusValue)
- let serializedKey = privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()
- let finalPrivateKey = try
- SecretKey(hex: serializedKey)
- finalPubKey = try finalPrivateKey.toPublic().serialize(compressed: false)
- }
- } else {
- // for imported keys in legacy networks
- metadataNonce = try await getMetadata(dictionary: ["pub_key_X": oAuthKeyX, "pub_key_Y": oAuthKeyY])
- var privateKeyWithNonce = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)!
- privateKeyWithNonce = privateKeyWithNonce.modulus(modulusValue)
- let finalPrivateKey = try SecretKey(hex: privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64())
- finalPubKey = try finalPrivateKey.toPublic().serialize(compressed: false)
- }
+ internal func formatLegacyPublicKeyData(finalKeyResult: LegacyVerifierLookupResponse, enableOneKey: Bool, isNewKey: Bool, serverTimeOffset: Int) async throws -> TorusPublicKey {
+ let firstResult = finalKeyResult.keys[0]
+ let X = firstResult.pub_key_X
+ let Y = firstResult.pub_key_Y
- let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthKeyX, publicKeyY: oAuthKeyY)
- let (finalPubX, finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey)
- let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY)
+ var nonceResult: GetOrSetNonceResult?
+ var finalPubKey: String?
+ var nonce: BigUInt?
+ var typeOfUser: UserType
+ var pubNonce: PubNonce?
- var finalPrivKey = ""
- if typeOfUser == .v1 || (typeOfUser == .v2 && metadataNonce > BigInt(0)) {
- let tempNewKey = BigInt(metadataNonce) + BigInt(oAuthKey, radix: 16)!
- let privateKeyWithNonce = tempNewKey.modulus(modulusValue)
- finalPrivKey = String(privateKeyWithNonce, radix: 16).addLeading0sForLength64()
- }
+ let oAuthPubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: X, pubKeyY: Y)
+
+ let finalServertimeOffset = self.serverTimeOffset ?? serverTimeOffset
+
+ if enableOneKey {
+ nonceResult = try await MetadataUtils.getOrSetNonce(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: finalServertimeOffset, X: X, Y: Y, getOnly: !isNewKey)
+ nonce = BigUInt(nonceResult!.nonce ?? "0", radix: 16)
+ typeOfUser = UserType(rawValue: nonceResult?.typeOfUser?.lowercased() ?? "v1")!
- var isUpgraded: Bool? = false
if typeOfUser == .v1 {
- isUpgraded = nil
+ finalPubKey = oAuthPubKey
+ nonce = try await MetadataUtils.getMetadata(legacyMetadataHost: legacyMetadataHost, params: GetMetadataParams(pub_key_X: X, pub_key_Y: Y))
+
+ if nonce! > BigUInt(0) {
+ let noncePrivateKey = try SecretKey(hex: nonce!.magnitude.serialize().hexString.addLeading0sForLength64())
+ let noncePublicKey = try noncePrivateKey.toPublic().serialize(compressed: false)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [finalPubKey!, noncePublicKey])
+ }
} else if typeOfUser == .v2 {
- isUpgraded = metadataNonce == BigUInt(0)
+ let pubNonceKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: nonceResult!.pubNonce!.x, pubKeyY: nonceResult!.pubNonce!.y)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [oAuthPubKey, pubNonceKey])
+ pubNonce = nonceResult!.pubNonce!
+ } else {
+ throw TorusUtilError.metadataNonceMissing
+ }
+ } else {
+ typeOfUser = .v1
+ finalPubKey = oAuthPubKey
+ nonce = try await MetadataUtils.getMetadata(legacyMetadataHost: legacyMetadataHost, params: GetMetadataParams(pub_key_X: X, pub_key_Y: Y))
+
+ if nonce! > BigUInt(0) {
+ let noncePrivateKey = try SecretKey(hex: nonce!.magnitude.serialize().hexString.addLeading0sForLength64())
+ let noncePublicKey = try noncePrivateKey.toPublic().serialize(compressed: false)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [finalPubKey!, noncePublicKey])
}
-
- return TorusKey(
- finalKeyData: .init(
- evmAddress: finalEvmAddress,
- X: finalPubX,
- Y: finalPubY,
- privKey: finalPrivKey
- ),
- oAuthKeyData: .init(
- evmAddress: oAuthKeyAddress,
- X: oAuthKeyX,
- Y: oAuthKeyY,
- privKey: oAuthKey
- ),
- sessionData: .init(
- sessionTokenData: [],
- sessionAuthKey: ""
- ),
- metadata: .init(
- pubNonce: pubKeyNonceResult,
- nonce: BigUInt(metadataNonce),
- typeOfUser: typeOfUser,
- upgraded: isUpgraded
- ),
- nodesData: .init(nodeIndexes: [])
- )
- } catch {
- os_log("Error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- throw error
}
- }
-
- open func getTimestamp() -> TimeInterval {
- return Date().timeIntervalSince1970
- }
- // MARK: - retreiveDecryptAndReconstuct
-
- private func retrieveDecryptAndReconstruct(endpoints: [String],
- indexes: [BigUInt],
- extraParams: [String: Codable], verifier: String, tokenCommitment: String, nodeSignatures: [CommitmentRequestResponse], verifierId: String, lookupPubkeyX: String, lookupPubkeyY: String, privateKey: String) async throws -> (String, String, String) {
- // Rebuild extraParams
- let session = createURLSession()
- let threshold = Int(endpoints.count / 2) + 1
- var rpcdata: Data = Data()
-
- let loadedStrings = extraParams
- let valueDict = ["verifieridentifier": verifier,
- "verifier_id": verifierId,
- "nodesignatures": nodeSignatures.tostringDict(),
- "idtoken": tokenCommitment,
- ] as [String: Codable]
- let finalItem = loadedStrings.merging(valueDict) { current, _ in current }
- let params = ["encrypted": "yes",
- "item": AnyCodable([finalItem]),
- ] as [String: AnyCodable]
-
- let dataForRequest = ["jsonrpc": "2.0",
- "id": 10,
- "method": AnyCodable(JRPC_METHODS.LEGACY_SHARE_REQUEST),
- "params": AnyCodable(params),
- ] as [String: AnyCodable]
- do {
- rpcdata = try JSONEncoder().encode(dataForRequest)
- } catch {
- os_log("import share - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- }
+ let oAuthAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: X, publicKeyY: Y)
- var shareResponses: [PointHex?] = []
- var resultArray = [Int: RetrieveDecryptAndReconstuctResponseModel]()
- var errorStack = [Error]()
- var requestArr = [URLRequest]()
- for (_, el) in endpoints.enumerated() {
- do {
- var rq = try makeUrlRequest(url: el)
- rq.httpBody = rpcdata
- requestArr.append(rq)
- } catch {
- throw error
- }
+ if typeOfUser == .v2 && finalPubKey == nil {
+ throw TorusUtilError.privateKeyDeriveFailed
}
- return try await withThrowingTaskGroup(of: Result.self, body: { [unowned self] group in
- for (i, rq) in requestArr.enumerated() {
- group.addTask {
- do {
- let val = try await session.data(for: rq)
- return .success(.init(data: val.0, urlResponse: val.1, index: i))
- } catch {
- return .failure(error)
- }
- }
- }
- for try await val in group {
- do {
- try Task.checkCancellation()
- switch val {
- case let .success(model):
- let _data = model.data
- let i = Int(indexes[model.index]) - 1
-
- let decoded = try JSONDecoder().decode(JSONRPCresponse.self, from: _data)
-
- if decoded.error != nil {
- throw TorusUtilError.decodingFailed(decoded.error?.data)
- }
- os_log("retrieveDecryptAndReconstuct: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, "\(decoded)")
- var X = lookupPubkeyX.addLeading0sForLength64()
- var Y = lookupPubkeyY.addLeading0sForLength64()
- if let decodedResult = decoded.result as? LegacyLookupResponse {
- // case non migration
- let keyObj = decodedResult.keys
- if let first = keyObj.first {
- let pointHex = PointHex(from: first.publicKey)
- shareResponses.append(pointHex)
- let metadata = first.metadata
- let model = RetrieveDecryptAndReconstuctResponseModel(iv: metadata.iv, ephemPublicKey: metadata.ephemPublicKey, share: first.share, pubKeyX: pointHex.x, pubKeyY: pointHex.y, mac: metadata.mac)
- resultArray[i] = model
- }
- } else if let decodedResult = decoded.result as? LegacyShareRequestResult {
- // case migration
- let keyObj = decodedResult.keys
- if let first = keyObj.first {
- let pointHex = PointHex(from: .init(x: first.publicKey.X, y: first.publicKey.Y))
- shareResponses.append(pointHex)
- let metadata = first.metadata
- X = pointHex.x
- Y = pointHex.y
- let model = RetrieveDecryptAndReconstuctResponseModel(iv: metadata.iv, ephemPublicKey: metadata.ephemPublicKey, share: first.share, pubKeyX: pointHex.x, pubKeyY: pointHex.y, mac: metadata.mac)
- resultArray[i] = model
- }
- } else {
- throw TorusUtilError.runtime("decode fail")
- }
-
- // Due to multiple keyAssign
-
- let lookupShares = shareResponses.filter { $0 != nil } // Nonnil elements
-
- // Comparing dictionaries, so the order of keys doesn't matter
- let keyResult = thresholdSame(arr: lookupShares.map { $0 }, threshold: threshold) // Check if threshold is satisfied
- var data: [Int: String] = [:]
- if keyResult != nil {
- os_log("retreiveIndividualNodeShares - result: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .info), type: .info, resultArray)
- data = try decryptIndividualShares(shares: resultArray, privateKey: privateKey)
- } else {
- throw TorusUtilError.empty
- }
- os_log("retrieveDecryptAndReconstuct - data after decryptIndividualShares: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .debug), type: .debug, data)
- let filteredData = data.filter { $0.value != TorusUtilError.decodingFailed(nil).debugDescription }
-
- if filteredData.count < threshold { throw TorusUtilError.thresholdError }
- let thresholdLagrangeInterpolationData = try thresholdLagrangeInterpolation(data: filteredData, endpoints: endpoints, lookupPubkeyX: X.addLeading0sForLength64(), lookupPubkeyY: Y.addLeading0sForLength64())
- session.invalidateAndCancel()
- return thresholdLagrangeInterpolationData
- case let .failure(error):
- throw error
- }
- } catch {
- errorStack.append(error)
- let nsErr = error as NSError
- let userInfo = nsErr.userInfo as [String: Any]
- if error as? TorusUtilError == .timeout {
- group.cancelAll()
- session.invalidateAndCancel()
- throw error
- }
- if nsErr.code == -1003 {
- // In case node is offline
- os_log("retrieveDecryptAndReconstuct: DNS lookup failed, node %@ is probably offline.", log: getTorusLogger(log: TorusUtilsLogger.network, type: .error), type: .error, userInfo["NSErrorFailingURLKey"].debugDescription)
- } else if let err = (error as? TorusUtilError) {
- if err == TorusUtilError.thresholdError {
- os_log("retrieveDecryptAndReconstuct - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- }
- } else {
- os_log("retrieveDecryptAndReconstuct - error: %@", log: getTorusLogger(log: TorusUtilsLogger.core, type: .error), type: .error, error.localizedDescription)
- }
- }
- }
- throw TorusUtilError.runtime("retrieveDecryptAndReconstuct func failed")
- })
+ let (finalPubKeyX, finalPubKeyY) = try KeyUtils.getPublicKeyCoords(pubKey: finalPubKey!)
+
+ let finalAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: finalPubKeyX, publicKeyY: finalPubKeyY)
+
+ return TorusPublicKey(
+ oAuthKeyData: TorusPublicKey.OAuthKeyData(
+ evmAddress: oAuthAddress,
+ X: X.addLeading0sForLength64(),
+ Y: Y.addLeading0sForLength64()
+ ),
+ finalKeyData: TorusPublicKey.FinalKeyData(
+ evmAddress: finalAddress,
+ X: finalPubKeyX,
+ Y: finalPubKeyY
+ ),
+ metadata: TorusPublicKey.Metadata(
+ pubNonce: pubNonce,
+ nonce: nonce,
+ typeOfUser: typeOfUser,
+ upgraded: nonceResult?.upgraded ?? false,
+ serverTimeOffset: finalServertimeOffset),
+ nodesData: TorusPublicKey.NodesData(nodeIndexes: [])
+ )
}
}
diff --git a/Sources/TorusUtils/TorusUtilsExtraParams.swift b/Sources/TorusUtils/TorusUtilsExtraParams.swift
new file mode 100644
index 00000000..d2280b1f
--- /dev/null
+++ b/Sources/TorusUtils/TorusUtilsExtraParams.swift
@@ -0,0 +1,33 @@
+import Foundation
+
+// TODO: This class is a bit of a mess for legacy reasons and should be cleaned up in future.
+
+public class TorusUtilsExtraParams: Codable {
+ var nonce: String? // farcaster
+ var message: String? // farcaster
+ var signature: String? // farcaster, passkey, webauthn
+ var clientDataJson: String? // passkey, webauthn
+ var authenticatorData: String? // passkey, webauthn
+ var publicKey: String? // passkey, webauthn
+ var challenge: String? // passkey, webauthn
+ var rpOrigin: String? // passkey, webauthn
+ var rpId: String? // passkey, webauthn
+ var session_token_exp_second: Int?
+ var timestamp: Int? // Signature
+
+ public init() {}
+
+ public init(nonce: String? = nil, message: String? = nil, signature: String? = nil, clientDataJson: String? = nil, authenticatorData: String? = nil, publicKey: String? = nil, challenge: String? = nil, rpOrigin: String? = nil, rpId: String? = nil, session_token_exp_second: Int? = nil, timestamp: Int? = nil) {
+ self.nonce = nonce
+ self.message = message
+ self.signature = signature
+ self.clientDataJson = clientDataJson
+ self.authenticatorData = authenticatorData
+ self.publicKey = publicKey
+ self.challenge = challenge
+ self.rpOrigin = rpOrigin
+ self.rpId = rpId
+ self.session_token_exp_second = session_token_exp_second
+ self.timestamp = timestamp
+ }
+}
diff --git a/Sources/TorusUtils/VerifierParams.swift b/Sources/TorusUtils/VerifierParams.swift
new file mode 100644
index 00000000..7c335043
--- /dev/null
+++ b/Sources/TorusUtils/VerifierParams.swift
@@ -0,0 +1,26 @@
+import Foundation
+
+public class VerifyParams: Codable {
+ public var verifier_id: String?
+ public var idtoken: String?
+
+ public init(verifier_id: String?, idtoken: String?) {
+ self.verifier_id = verifier_id
+ self.idtoken = idtoken
+ }
+}
+
+public class VerifierParams {
+ // [key: string]: unknown; This should be strongly typed
+ public let verifier_id: String
+ public let extended_verifier_id: String?
+ public let sub_verifier_ids: [String]?
+ public let verify_params: [VerifyParams]?
+
+ public init(verifier_id: String, extended_verifier_id: String? = nil, sub_verifier_ids: [String]? = nil, verify_params: [VerifyParams]? = nil) {
+ self.verifier_id = verifier_id
+ self.extended_verifier_id = extended_verifier_id
+ self.sub_verifier_ids = sub_verifier_ids
+ self.verify_params = verify_params
+ }
+}
diff --git a/Tests/TorusUtilsTests/AquaTest.swift b/Tests/TorusUtilsTests/AquaTest.swift
index 90ec485f..69359a20 100644
--- a/Tests/TorusUtilsTests/AquaTest.swift
+++ b/Tests/TorusUtilsTests/AquaTest.swift
@@ -1,167 +1,180 @@
import BigInt
import FetchNodeDetails
import JWTKit
+import TorusUtils
import XCTest
-import CoreMedia
-@testable import TorusUtils
-
class AquaTest: XCTestCase {
var TORUS_TEST_EMAIL = "hello@tor.us"
var TORUS_TEST_VERIFIER = "torus-test-health"
var TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
var fnd: NodeDetailManager!
- var tu: TorusUtils!
+ var torus: TorusUtils!
override func setUp() {
super.setUp()
fnd = NodeDetailManager(network: .legacy(.AQUA))
- }
-
- func getFNDAndTUData(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- tu = TorusUtils(enableOneKey: enableOneKey, network: .legacy(.AQUA), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .legacy(.AQUA)))
}
func test_should_fetch_public_address() async throws {
let verifier: String = "tkey-google-aqua"
let verifierID: String = TORUS_TEST_EMAIL
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
XCTAssertEqual(val.finalKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d")
- XCTAssertEqual(val.finalKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d")
- XCTAssertEqual(val.finalKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d")
XCTAssertEqual(val.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d")
XCTAssertEqual(val.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c")
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d")
+ XCTAssertEqual(val.finalKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d")
+ XCTAssertEqual(val.finalKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c")
XCTAssertNil(val.metadata?.pubNonce)
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1"))
+ XCTAssertEqual(val.metadata?.typeOfUser, .v1)
}
func test_should_fetch_user_type_and_public_addresses() async throws {
var verifier: String = "tkey-google-aqua"
var verifierID: String = TORUS_TEST_EMAIL
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- var val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d")
- XCTAssertEqual(val.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d")
- XCTAssertEqual(val.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c")
- XCTAssertEqual(val.finalKeyData!.evmAddress, "0x79F06350eF34Aeed4BE68e26954D405D573f1438")
- XCTAssertEqual(val.finalKeyData!.X, "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3")
- XCTAssertEqual(val.finalKeyData!.Y, "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16")
- XCTAssertEqual(val.metadata!.pubNonce!.x, "dc5a031fd2e0b55dbaece314ea125bac9da5f0a916bf156ff36b5ad71380ea32")
- XCTAssertEqual(val.metadata!.pubNonce!.y, "affd749b98c209d2f9cf4dacb145d7897f82f1e2924a47b07874302ecc0b8ef1")
- XCTAssertEqual(val.metadata?.nonce, 0)
- XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let result1 = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+ XCTAssertLessThan(result1.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(result1.oAuthKeyData!.evmAddress, "0xDfA967285AC699A70DA340F60d00DB19A272639d")
+ XCTAssertEqual(result1.oAuthKeyData!.X, "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d")
+ XCTAssertEqual(result1.oAuthKeyData!.Y, "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c")
+ XCTAssertEqual(result1.finalKeyData!.evmAddress, "0x79F06350eF34Aeed4BE68e26954D405D573f1438")
+ XCTAssertEqual(result1.finalKeyData!.X, "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3")
+ XCTAssertEqual(result1.finalKeyData!.Y, "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16")
+ XCTAssertEqual(result1.metadata!.pubNonce!.x, "dc5a031fd2e0b55dbaece314ea125bac9da5f0a916bf156ff36b5ad71380ea32")
+ XCTAssertEqual(result1.metadata!.pubNonce!.y, "affd749b98c209d2f9cf4dacb145d7897f82f1e2924a47b07874302ecc0b8ef1")
+ XCTAssertEqual(result1.metadata?.nonce, 0)
+ XCTAssertEqual(result1.metadata?.upgraded, false)
+ XCTAssertEqual(result1.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(result1.nodesData)
+ // 1/1 user
verifier = "tkey-google-aqua"
verifierID = "somev2user@gmail.com"
- val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828")
- XCTAssertEqual(val.oAuthKeyData!.X, "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337")
- XCTAssertEqual(val.oAuthKeyData!.Y, "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d")
- XCTAssertEqual(val.finalKeyData!.evmAddress, "0xBc32f315515AdE7010cabC5Fd68c966657A570BD")
- XCTAssertEqual(val.finalKeyData!.X, "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022")
- XCTAssertEqual(val.finalKeyData!.Y, "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968")
- XCTAssertEqual(val.finalKeyData!.evmAddress, "0xBc32f315515AdE7010cabC5Fd68c966657A570BD")
- XCTAssertEqual(val.metadata?.nonce, 0)
- XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ let result2 = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertLessThan(result2.metadata!.serverTimeOffset, 20)
+ XCTAssertEqual(result2.oAuthKeyData!.evmAddress, "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828")
+ XCTAssertEqual(result2.oAuthKeyData!.X, "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337")
+ XCTAssertEqual(result2.oAuthKeyData!.Y, "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d")
+ XCTAssertEqual(result2.finalKeyData!.evmAddress, "0xBc32f315515AdE7010cabC5Fd68c966657A570BD")
+ XCTAssertEqual(result2.finalKeyData!.X, "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022")
+ XCTAssertEqual(result2.finalKeyData!.Y, "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968")
+ XCTAssertEqual(result2.finalKeyData!.evmAddress, "0xBc32f315515AdE7010cabC5Fd68c966657A570BD")
+ XCTAssertEqual(result2.metadata?.pubNonce?.x, "1601cf4dc4362b219260663d5ec5119699fbca185d08b7acb2e36cad914340d5")
+ XCTAssertEqual(result2.metadata?.pubNonce?.y, "c2f7871f61ee71b4486ac9fb40ec759099800e737139dc5dfaaaed8c9d77c3c1")
+ XCTAssertEqual(result2.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(result2.metadata?.upgraded, false)
+ XCTAssertEqual(result2.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(result2.nodesData)
+
+ // 2/n user
verifierID = "caspertorus@gmail.com"
- val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD")
- XCTAssertEqual(val.oAuthKeyData!.X, "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281")
- XCTAssertEqual(val.oAuthKeyData!.Y, "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f")
- XCTAssertEqual(val.finalKeyData!.evmAddress, "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D")
- XCTAssertEqual(val.finalKeyData!.X, "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539")
- XCTAssertEqual(val.finalKeyData!.Y, "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21")
- XCTAssertEqual(val.metadata?.nonce, 0)
- XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ let result3 = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertLessThan(result2.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(result3.oAuthKeyData!.evmAddress, "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD")
+ XCTAssertEqual(result3.oAuthKeyData!.X, "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281")
+ XCTAssertEqual(result3.oAuthKeyData!.Y, "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f")
+ XCTAssertEqual(result3.finalKeyData!.evmAddress, "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D")
+ XCTAssertEqual(result3.finalKeyData!.X, "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539")
+ XCTAssertEqual(result3.finalKeyData!.Y, "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21")
+ XCTAssertEqual(result3.metadata?.pubNonce?.x, "17b1ebce1fa874452a96d0c6d74c1445b78f16957c7decc5d2a202b0ce4662f5")
+ XCTAssertEqual(result3.metadata?.pubNonce?.y, "b5432cb593753e1b3ecf98b05dc03e57bc02c415e1b80a1ffc5a401ec1f0abd6")
+ XCTAssertEqual(result3.metadata?.nonce, 0)
+ XCTAssertEqual(result3.metadata?.upgraded, false)
+ XCTAssertEqual(result3.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(result3.nodesData)
}
- func test_key_assign() async throws {
+ func test_should_be_able_to_key_assign() async throws {
let fakeEmail = generateRandomEmail(of: 6)
let verifier: String = "tkey-google-aqua"
let verifierID: String = fakeEmail
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertNotNil(data.finalKeyData)
- XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertNotNil(data.finalKeyData?.evmAddress)
+ XCTAssertNotNil(data.oAuthKeyData?.evmAddress)
XCTAssertEqual(data.metadata?.typeOfUser, .v1)
XCTAssertEqual(data.metadata?.upgraded, false)
+ XCTAssertNotNil(data.nodesData)
}
- func test_login() async throws {
+ func test_should_be_able_to_login() async throws {
let verifier: String = TORUS_TEST_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
let verifierParams = VerifierParams(verifier_id: verifierID)
let jwt = try! generateIdToken(email: verifierID)
- let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195")
- XCTAssertEqual(data.finalKeyData?.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664")
- XCTAssertEqual(data.finalKeyData?.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f")
- XCTAssertEqual(data.finalKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195")
- XCTAssertEqual(data.oAuthKeyData?.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664")
- XCTAssertEqual(data.oAuthKeyData?.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce, nil)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser, .v1)
- XCTAssertEqual(data.metadata?.upgraded, nil)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195")
+ XCTAssertEqual(data.finalKeyData.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664")
+ XCTAssertEqual(data.finalKeyData.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f")
+ XCTAssertEqual(data.finalKeyData.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195")
+ XCTAssertEqual(data.oAuthKeyData.X, "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664")
+ XCTAssertEqual(data.oAuthKeyData.Y, "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
- func test_aggregate_login() async throws {
+ func test_should_be_able_to_aggregate_login() async throws {
let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
- let verifierParams = VerifierParams(verifier_id: verifierID)
let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
- let hashedIDToken = keccak256Data(jwt.data(using: .utf8) ?? Data()).toHexString();
-
- let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D")
- XCTAssertEqual(data.finalKeyData?.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d")
- XCTAssertEqual(data.finalKeyData?.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10")
- XCTAssertEqual(data.finalKeyData?.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D")
- XCTAssertEqual(data.oAuthKeyData?.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d")
- XCTAssertEqual(data.oAuthKeyData?.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce == nil, true)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser == UserType.v1, true)
- XCTAssertEqual(data.metadata?.upgraded == nil, true)
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: TORUS_TEST_EMAIL, idtoken: jwt)])
+
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken)
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D")
+ XCTAssertEqual(data.finalKeyData.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d")
+ XCTAssertEqual(data.finalKeyData.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10")
+ XCTAssertEqual(data.finalKeyData.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D")
+ XCTAssertEqual(data.oAuthKeyData.X, "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d")
+ XCTAssertEqual(data.oAuthKeyData.Y, "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355")
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
-}
-extension AquaTest {
func test_retrieveShares_some_nodes_down() async throws {
let verifier: String = TORUS_TEST_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
let verifierParams = VerifierParams(verifier_id: verifierID)
let jwt = try! generateIdToken(email: verifierID)
- let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
var endpoints = nodeDetails.getTorusNodeEndpoints()
- endpoints[0] = "https://ndjnfjbfrj/random"
- // should fail if un-commented threshold 4/5
- // endpoints[1] = "https://ndjnfjbfrj/random"
- let data = try await tu.retrieveShares(endpoints: endpoints, torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d")
+ endpoints[endpoints.count - 1] = "https://ndjnfjbfrj/random"
+ let data = try await torus.retrieveShares(endpoints: endpoints, verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+ XCTAssertEqual(data.finalKeyData.privKey, "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d")
}
}
diff --git a/Tests/TorusUtilsTests/BaseTests/Combinations.swift b/Tests/TorusUtilsTests/BaseTests/Combinations.swift
new file mode 100644
index 00000000..6a2c6a9f
--- /dev/null
+++ b/Tests/TorusUtilsTests/BaseTests/Combinations.swift
@@ -0,0 +1,39 @@
+import Foundation
+@testable import TorusUtils
+import XCTest
+
+class Combinations: XCTestCase {
+ func test_kCombinations() throws {
+ let input = [0, 1, 2, 3, 4, 5]
+ let zero = kCombinations(elements: input.slice, k: 0)
+ XCTAssertEqual(zero, [])
+ let greater = kCombinations(elements: input.slice, k: 10)
+ XCTAssertEqual(greater, [])
+ let equal = kCombinations(elements: input.slice, k: 6)
+ XCTAssertEqual(equal, [[0, 1, 2, 3, 4, 5]])
+ let one = kCombinations(elements: input.slice, k: 1)
+ XCTAssertEqual(one, [[0], [1], [2], [3], [4], [5]])
+ let two = kCombinations(elements: input.slice, k: 2)
+ XCTAssertEqual(two, [
+ [0, 1], [0, 2], [0, 3], [0, 4], [0, 5],
+ [1, 2], [1, 3], [1, 4], [1, 5],
+ [2, 3], [2, 4], [2, 5],
+ [3, 4], [3, 5],
+ [4, 5],
+ ])
+ let input2 = [1, 2, 3, 4, 5]
+ let next = kCombinations(elements: input2.slice, k: 3)
+ XCTAssertEqual(next, [
+ [1, 2, 3],
+ [1, 2, 4],
+ [1, 2, 5],
+ [1, 3, 4],
+ [1, 3, 5],
+ [1, 4, 5],
+ [2, 3, 4],
+ [2, 3, 5],
+ [2, 4, 5],
+ [3, 4, 5],
+ ])
+ }
+}
diff --git a/Tests/TorusUtilsTests/Helpers/EtherAddress.swift b/Tests/TorusUtilsTests/BaseTests/EtherAddress.swift
similarity index 61%
rename from Tests/TorusUtilsTests/Helpers/EtherAddress.swift
rename to Tests/TorusUtilsTests/BaseTests/EtherAddress.swift
index 552a395d..585c9b35 100644
--- a/Tests/TorusUtilsTests/Helpers/EtherAddress.swift
+++ b/Tests/TorusUtilsTests/BaseTests/EtherAddress.swift
@@ -3,11 +3,10 @@ import Foundation
import XCTest
class EtherTest: XCTestCase {
- func testPublicToEtherAddress() {
+ func testPublicToEtherAddress() throws {
let fullAddress = String("04238569d5e12caf57d34fb5b2a0679c7775b5f61fd18cd69db9cc600a651749c3ec13a9367380b7a024a67f5e663f3afd40175c3223da63f6024b05d0bd9f292e")
- let X: String = String(fullAddress.suffix(128).prefix(64))
- let Y: String = String(fullAddress.suffix(64))
- let etherAddress = generateAddressFromPubKey(publicKeyX: X, publicKeyY: Y)
+ let (X, Y) = try KeyUtils.getPublicKeyCoords(pubKey: fullAddress)
+ let etherAddress = try KeyUtils.generateAddressFromPubKey(publicKeyX: X, publicKeyY: Y)
let finalAddress = "0x048975d4997D7578A3419851639c10318db430b6"
XCTAssertEqual(etherAddress, finalAddress)
}
diff --git a/Tests/TorusUtilsTests/BaseTests/HexEncodedString.swift b/Tests/TorusUtilsTests/BaseTests/HexEncodedString.swift
new file mode 100644
index 00000000..162a664c
--- /dev/null
+++ b/Tests/TorusUtilsTests/BaseTests/HexEncodedString.swift
@@ -0,0 +1,19 @@
+import Foundation
+@testable import TorusUtils
+import XCTest
+
+class HexEndodedTest: XCTestCase {
+ func testOddAndEvenStrings() throws {
+ let odd = "6F6464".hexEncodedToString()
+ let even = "6576656E".hexEncodedToString()
+ let extra_zero_padded = "06576656E".hexEncodedToString()
+ let double_padded = "00006576656E".hexEncodedToString()
+ let unpadded = "56E".hexEncodedToString()
+
+ XCTAssertEqual(odd, "odd") // 6F 64 64
+ XCTAssertEqual(even, "even") // 65 76 65 6E
+ XCTAssertEqual(extra_zero_padded, "even") // 00 65 76 65 6E
+ XCTAssertEqual(double_padded, "even") // 00 00 65 76 65 6E
+ XCTAssertEqual(unpadded, "\u{5}n") // 05 6E
+ }
+}
diff --git a/Tests/TorusUtilsTests/Helpers/Lagrange.swift b/Tests/TorusUtilsTests/BaseTests/Lagrange.swift
similarity index 75%
rename from Tests/TorusUtilsTests/Helpers/Lagrange.swift
rename to Tests/TorusUtilsTests/BaseTests/Lagrange.swift
index 1a2366c5..bcdd90a1 100644
--- a/Tests/TorusUtilsTests/Helpers/Lagrange.swift
+++ b/Tests/TorusUtilsTests/BaseTests/Lagrange.swift
@@ -1,8 +1,8 @@
import BigInt
import Foundation
+@testable import TorusUtils
import XCTest
-@testable import TorusUtils
class LagrangeTest: XCTestCase {
var tu: TorusUtils!
@@ -13,7 +13,7 @@ class LagrangeTest: XCTestCase {
Point(x: BigInt(3), y: BigInt(10)),
]
- let polynomial = lagrangeInterpolatePolynomial(points: points)
+ let polynomial = Lagrange.lagrangeInterpolatePolynomial(points: points)
let xValues: [BigInt] = [BigInt(1), BigInt(2), BigInt(3)]
let expectedYValues: [BigInt] = [BigInt(2), BigInt(5), BigInt(10)]
@@ -24,9 +24,9 @@ class LagrangeTest: XCTestCase {
let y = polynomial.polyEval(x: x)
- assert(y == expectedY, "Point (\(x), \(y)) does not match the expected value of (\(x), \(expectedY)).")
+ XCTAssertEqual(y, expectedY)
}
-
- print("All assertions passed.")
}
+
+ // TODO: Test other methods
}
diff --git a/Tests/TorusUtilsTests/Celeste.swift b/Tests/TorusUtilsTests/Celeste.swift
new file mode 100644
index 00000000..8f4c3a88
--- /dev/null
+++ b/Tests/TorusUtilsTests/Celeste.swift
@@ -0,0 +1,171 @@
+import BigInt
+import FetchNodeDetails
+import Foundation
+import TorusUtils
+import XCTest
+
+class CelesteTest: XCTestCase {
+ var TORUS_TEST_EMAIL = "hello@tor.us"
+ var TORUS_TEST_VERIFIER = "torus-test-health"
+ var TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
+ var fnd: NodeDetailManager!
+ var torus: TorusUtils!
+
+ override func setUp() {
+ super.setUp()
+ fnd = NodeDetailManager(network: .legacy(.CELESTE))
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .legacy(.CELESTE)))
+ }
+
+ func test_should_fetch_public_address() async throws {
+ let verifier = "tkey-google-celeste"
+ let verifierID = TORUS_TEST_EMAIL
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.torusNodeEndpoints, verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113")
+ XCTAssertEqual(val.finalKeyData!.X, "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9")
+ XCTAssertEqual(val.finalKeyData!.Y, "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb")
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113")
+ XCTAssertEqual(val.oAuthKeyData!.X, "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb")
+ XCTAssertNil(val.metadata?.pubNonce)
+ XCTAssertEqual(val.metadata?.nonce, 0)
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v1)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_fetch_user_type_and_public_address() async throws {
+ var verifier: String = "tkey-google-celeste"
+ var verifierID: String = TORUS_TEST_EMAIL
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ var val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113")
+ XCTAssertEqual(val.oAuthKeyData!.X, "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb")
+ XCTAssertEqual(val.finalKeyData!.X, "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9")
+ XCTAssertEqual(val.finalKeyData!.Y, "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb")
+ XCTAssertNil(val.metadata!.pubNonce)
+ XCTAssertEqual(val.metadata?.nonce, 0)
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v1)
+
+ verifier = "tkey-google-celeste"
+ verifierID = "somev2user@gmail.com"
+ val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xda4afB35493094Dd2C05b186Ca0FABAD96491B21")
+ XCTAssertEqual(val.oAuthKeyData!.X, "cfa646a2949ebe559205c5c407d734d1b6927f2ea5fbeabfcbc31ab9a985a336")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "8f988eb8b59515293820aa38af172b153e8d25307db8d5f410407c20e062b6e6")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x8d69CE354DA39413f205FdC8680dE1F3FBBb36e2")
+ XCTAssertEqual(val.finalKeyData!.X, "5962144e03b993b0e503eb4e6e0196427f9fc9472f0dfd1be2ca5d4939f91680")
+ XCTAssertEqual(val.finalKeyData!.Y, "f6e81f01f483110badab18371237d15834f9ecf31c3588c165dae32ec446ac38")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "2f630074151394ba1f715986a9215f4e36c9f22fc264ff880ef6d162c1300aa8")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "704cb63e5f7a291735c54e22242ef53673642ec1660da00f1abc2e7909da03d7")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "2f630074151394ba1f715986a9215f4e36c9f22fc264ff880ef6d162c1300aa8")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "704cb63e5f7a291735c54e22242ef53673642ec1660da00f1abc2e7909da03d7")
+ XCTAssertEqual(val.metadata?.nonce, 0)
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+
+ verifier = "tkey-google-celeste"
+ verifierID = "caspertorus@gmail.com"
+ val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x8108c29976C458e76f797AD55A3715Ce80a3fe78")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xc8c4748ec135196fb482C761da273C31Ec48B099")
+ XCTAssertEqual(val.oAuthKeyData!.X, "0cc857201e6c304dd893b243e323fe95982e5a99c0994cf902efa2432a672eb4")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "37a2f53c250b3e1186e38ece3dfcbcb23e325913038703531831b96d3e7b54cc")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x8108c29976C458e76f797AD55A3715Ce80a3fe78")
+ XCTAssertEqual(val.finalKeyData!.X, "e95fe2d595ade03f56d9c9a147fbb67705041704f147576fa4a8afbe7dc69470")
+ XCTAssertEqual(val.finalKeyData!.Y, "3e20e4b331466769c4dd78f4561bfb2849010b4005b09c2ed082380326724ebe")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "f8ff2c44cc0abf512d35b35c3c5cbc0eda700d49bc13b72c5492b0cdb2ca3619")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "88fb3087cec269c8c39d25b04f15298d33712f13b0f9665821328dfc7a567afb")
+ XCTAssertEqual(val.metadata?.nonce, 0)
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_key_assign() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let verifier: String = "tkey-google-celeste"
+ let verifierID: String = fakeEmail
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+ XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ XCTAssertEqual(data.metadata?.typeOfUser, .v1)
+ XCTAssertEqual(data.metadata?.upgraded, false)
+ }
+
+ func test_should_be_able_to_login() async throws {
+ let verifier: String = TORUS_TEST_VERIFIER
+ let verifierID: String = TORUS_TEST_EMAIL
+ let jwt = try! generateIdToken(email: verifierID)
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x58420FB83971C4490D8c9B091f8bfC890D716617")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x58420FB83971C4490D8c9B091f8bfC890D716617")
+ XCTAssertEqual(data.oAuthKeyData.X, "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74")
+ XCTAssertEqual(data.oAuthKeyData.Y, "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914")
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x58420FB83971C4490D8c9B091f8bfC890D716617")
+ XCTAssertEqual(data.finalKeyData.X, "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74")
+ XCTAssertEqual(data.finalKeyData.Y, "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1")
+ XCTAssertEqual(data.finalKeyData.privKey, "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
+ }
+
+ func test_should_be_able_to_aggregate_login() async throws {
+ let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
+ let verifierID: String = TORUS_TEST_EMAIL
+ let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: verifierID, idtoken: jwt)])
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.torusNodeEndpoints, verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564")
+ XCTAssertEqual(data.oAuthKeyData.X, "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca")
+ XCTAssertEqual(data.oAuthKeyData.Y, "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e")
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564")
+ XCTAssertEqual(data.finalKeyData.X, "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca")
+ XCTAssertEqual(data.finalKeyData.Y, "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb")
+ XCTAssertEqual(data.finalKeyData.privKey, "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
+ }
+}
diff --git a/Tests/TorusUtilsTests/CyanTest.swift b/Tests/TorusUtilsTests/CyanTest.swift
index f1b9982b..8c29c847 100644
--- a/Tests/TorusUtilsTests/CyanTest.swift
+++ b/Tests/TorusUtilsTests/CyanTest.swift
@@ -1,51 +1,53 @@
import BigInt
import FetchNodeDetails
import JWTKit
+import TorusUtils
import XCTest
-import CoreMedia
-@testable import TorusUtils
-
class CyanTest: XCTestCase {
var TORUS_TEST_EMAIL = "hello@tor.us"
var TORUS_TEST_VERIFIER = "torus-test-health"
var TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
var fnd: NodeDetailManager!
- var tu: TorusUtils!
+ var torus: TorusUtils!
override func setUp() {
super.setUp()
fnd = NodeDetailManager(network: .legacy(.CYAN))
- }
-
- func getFNDAndTUData(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- tu = TorusUtils(enableOneKey: enableOneKey, network: .legacy(.CYAN), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .legacy(.CYAN)))
}
func test_should_fetch_public_address() async throws {
let verifier: String = "tkey-google-cyan"
let verifierID: String = TORUS_TEST_EMAIL
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
XCTAssertEqual(val.finalKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825")
- XCTAssertEqual(val.finalKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a")
- XCTAssertEqual(val.finalKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825")
XCTAssertEqual(val.oAuthKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a")
XCTAssertEqual(val.oAuthKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825")
+ XCTAssertEqual(val.finalKeyData!.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a")
+ XCTAssertEqual(val.finalKeyData!.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1")
XCTAssertNil(val.metadata?.pubNonce)
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1"))
+ XCTAssertNotNil(val.nodesData)
}
- func test_get_user_type_and_addresses() async throws {
+ func test_should_fetch_user_type_and_addresses() async throws {
var verifier: String = "tkey-google-cyan"
var verifierID: String = TORUS_TEST_EMAIL
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- var data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ var data = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(data.finalKeyData!.evmAddress, "0x3507F0d192a44E436B8a6C32a37d57D022861b1a")
+ XCTAssertLessThan(data.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xA3767911A84bE6907f26C572bc89426dDdDB2825")
XCTAssertEqual(data.oAuthKeyData?.X, "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a")
XCTAssertEqual(data.oAuthKeyData?.Y, "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1")
@@ -57,11 +59,15 @@ class CyanTest: XCTestCase {
XCTAssertEqual(data.metadata?.nonce, BigUInt.zero)
XCTAssertEqual(data.metadata?.upgraded, false)
XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- XCTAssertEqual(data.nodesData?.nodeIndexes, [])
+ XCTAssertNotNil(data.nodesData)
verifier = "tkey-google-cyan"
verifierID = "somev2user@gmail.com"
- data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ data = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(data.finalKeyData!.evmAddress, "0x8EA83Ace86EB414747F2b23f03C38A34E0217814")
+ XCTAssertLessThan(data.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e")
XCTAssertEqual(data.oAuthKeyData?.X, "8b6f2048aba8c7833e3b02c5b6522bb18c484ad0025156e428f17fb8d8c34021")
XCTAssertEqual(data.oAuthKeyData?.Y, "cd9ba153ff89d665f655d1be4c6912f3ff93996e6fe580d89e78bf1476fef2aa")
@@ -73,11 +79,15 @@ class CyanTest: XCTestCase {
XCTAssertEqual(data.metadata?.nonce, BigUInt.zero)
XCTAssertEqual(data.metadata?.upgraded, false)
XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- XCTAssertEqual(data.nodesData?.nodeIndexes, [])
+ XCTAssertNotNil(data.nodesData?.nodeIndexes)
verifier = "tkey-google-cyan"
verifierID = "caspertorus@gmail.com"
- data = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ data = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(data.finalKeyData!.evmAddress, "0xCC1f953f6972a9e3d685d260399D6B85E2117561")
+ XCTAssertLessThan(data.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b")
XCTAssertEqual(data.oAuthKeyData?.X, "c491ba39155594896b27cf71a804ccf493289d918f40e6ba4d590f1c76139e9e")
XCTAssertEqual(data.oAuthKeyData?.Y, "d4649ed9e46461e1af00399a4c65fabb1dc219b3f4af501a7d635c17f57ab553")
@@ -89,68 +99,73 @@ class CyanTest: XCTestCase {
XCTAssertEqual(data.metadata?.nonce, BigUInt.zero)
XCTAssertEqual(data.metadata?.upgraded, false)
XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- XCTAssertEqual(data.nodesData?.nodeIndexes, [])
+ XCTAssertNotNil(data.nodesData)
}
- func test_key_assign() async throws {
+ func test_should_be_able_to_key_assign() async throws {
let fakeEmail = generateRandomEmail(of: 6)
let verifier: String = "tkey-google-cyan"
let verifierID: String = fakeEmail
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
XCTAssertEqual(data.metadata?.typeOfUser, .v1)
XCTAssertEqual(data.metadata?.upgraded, false)
}
- func test_login() async throws {
+ func test_should_be_able_to_login() async throws {
let verifier: String = TORUS_TEST_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
let jwt = try! generateIdToken(email: verifierID)
let verifierParams = VerifierParams(verifier_id: verifierID)
- let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9")
- XCTAssertEqual(data.finalKeyData?.X, "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1")
- XCTAssertEqual(data.finalKeyData?.Y, "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359")
- XCTAssertEqual(data.finalKeyData?.privKey, "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9")
- XCTAssertEqual(data.oAuthKeyData?.X, "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1")
- XCTAssertEqual(data.oAuthKeyData?.Y, "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce, nil)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser, .v1)
- XCTAssertEqual(data.metadata?.upgraded, nil)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9")
+ XCTAssertEqual(data.finalKeyData.X, "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1")
+ XCTAssertEqual(data.finalKeyData.Y, "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359")
+ XCTAssertEqual(data.finalKeyData.privKey, "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9")
+ XCTAssertEqual(data.oAuthKeyData.X, "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1")
+ XCTAssertEqual(data.oAuthKeyData.Y, "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8")
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
- func test_aggregate_login() async throws {
+ func test_should_be_able_to_aggregate_login() async throws {
let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
- let verifierParams = VerifierParams(verifier_id: verifierID)
- let hashedIDToken = keccak256Data(jwt.data(using: .utf8) ?? Data() ).toHexString()
- let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04")
- XCTAssertEqual(data.finalKeyData?.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223")
- XCTAssertEqual(data.finalKeyData?.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd")
- XCTAssertEqual(data.finalKeyData?.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04")
- XCTAssertEqual(data.oAuthKeyData?.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223")
- XCTAssertEqual(data.oAuthKeyData?.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce == nil, true)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser == UserType.v1, true)
- XCTAssertEqual(data.metadata?.upgraded == nil, true)
+ let verifierParams = VerifierParams(verifier_id: verifierID, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: TORUS_TEST_EMAIL, idtoken: jwt)])
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04")
+ XCTAssertEqual(data.finalKeyData.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223")
+ XCTAssertEqual(data.finalKeyData.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd")
+ XCTAssertEqual(data.finalKeyData.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04")
+ XCTAssertEqual(data.oAuthKeyData.X, "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223")
+ XCTAssertEqual(data.oAuthKeyData.Y, "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
}
diff --git a/Tests/TorusUtilsTests/Utils/JWTUtils.swift b/Tests/TorusUtilsTests/Helpers/JWTUtils.swift
similarity index 76%
rename from Tests/TorusUtilsTests/Utils/JWTUtils.swift
rename to Tests/TorusUtilsTests/Helpers/JWTUtils.swift
index 8a9e2a67..fe4c066c 100644
--- a/Tests/TorusUtilsTests/Utils/JWTUtils.swift
+++ b/Tests/TorusUtilsTests/Helpers/JWTUtils.swift
@@ -12,6 +12,7 @@ struct TestPayload: JWTPayload, Equatable {
case iat
case email
case audience = "aud"
+ case name
}
var subject: SubjectClaim
@@ -22,6 +23,7 @@ struct TestPayload: JWTPayload, Equatable {
var issuer: IssuerClaim
var iat: IssuedAtClaim
var email: String
+ var name: String
// call its verify method.
func verify(using signer: JWTSigner) throws {
@@ -53,12 +55,21 @@ func generateIdToken(email: String) throws -> String {
// Parses the JWT and verifies its signature.
let today = Date()
- let modifiedDate = Calendar.current.date(byAdding: .hour, value: 1, to: today)!
+ let modifiedDate = Calendar.current.date(byAdding: .minute, value: 2, to: today)!
let emailComponent = email.components(separatedBy: "@")[0]
let subject = "email|" + emailComponent
- let payload = TestPayload(subject: SubjectClaim(stringLiteral: subject), expiration: ExpirationClaim(value: modifiedDate), audience: "torus-key-test", isAdmin: false, emailVerified: true, issuer: "torus-key-test", iat: IssuedAtClaim(value: Date()), email: email)
+ let payload = TestPayload(
+ subject: SubjectClaim(stringLiteral: subject),
+ expiration: ExpirationClaim(value: modifiedDate), // eat
+ audience: "torus-key-test",
+ isAdmin: false,
+ emailVerified: true,
+ issuer: "torus-key-test",
+ iat: IssuedAtClaim(value: today),
+ email: email,
+ name: email)
let jwt = try signers.sign(payload)
return jwt
} catch {
diff --git a/Tests/TorusUtilsTests/IntegrationTest.swift b/Tests/TorusUtilsTests/IntegrationTest.swift
deleted file mode 100644
index 8617d165..00000000
--- a/Tests/TorusUtilsTests/IntegrationTest.swift
+++ /dev/null
@@ -1,129 +0,0 @@
-import BigInt
-import FetchNodeDetails
-import JWTKit
-import XCTest
-
-@testable import TorusUtils
-
-class IntegrationTests: XCTestCase {
- static var fetchNodeDetails: AllNodeDetailsModel?
- // static var nodeDetails: NodeDetails?
- static var utils: TorusUtils?
- static var endpoints: [String] = []
- static var nodePubKeys: [TorusNodePubModel] = []
- static var privKey: String = ""
-
- let TORUS_TEST_VERIFIER = "torus-test-health"
- let TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
- let TORUS_TEST_EMAIL = "hello@tor.us"
-
- // Fake data
- let TORUS_TEST_VERIFIER_FAKE = "google-lrc-fakes"
- var fnd: NodeDetailManager!
- var tu: TorusUtils!
-
- override func setUp() {
- super.setUp()
- fnd = NodeDetailManager(network: .legacy(.TESTNET))
- }
-
- override func setUpWithError() throws {
- continueAfterFailure = false
- }
-
- func get_fnd_and_tu_data(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- tu = TorusUtils(enableOneKey: enableOneKey, network: .legacy(.TESTNET), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
- }
-
- func test_getPublicAddress() async throws {
- var nodeDetails = try await get_fnd_and_tu_data(verifer: "google-lrc", veriferID: TORUS_TEST_EMAIL)
- let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: "google-lrc", verifierId: "hello@tor.us")
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x872eEfa7495599A6983d396fE8dcf542457CF33f")
-
- do {
- nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER_FAKE, veriferID: TORUS_TEST_EMAIL)
- _ = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER_FAKE, verifierId: TORUS_TEST_EMAIL)
- } catch _ {
- }
- }
-
- func test_getUserTypeAndAddress() async throws {
- let verifier: String = "tkey-google-lrc"
- let verifierID: String = "somev2user@gmail.com"
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- let val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
-
- XCTAssertEqual(val.finalKeyData?.evmAddress, "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D")
- }
-
-/* TODO: Investigate this further
- func test_keyAssign() async throws {
- let email = generateRandomEmail(of: 6)
-
- let nodeDetails = try await get_fnd_and_tu_data(verifer: "google-lrc", veriferID: email)
- let val = try await tu.keyAssign(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: email, signerHost: tu.signerHost, network: .legacy(.TESTNET))
- guard let result = val.result as? [String: Any] else {
- throw TorusUtilError.empty
- }
- let keys = result["keys"] as! [[String: String]]
- _ = keys[0]["address"]
-
- // Add more check to see if address is valid
- }
-*/
-
- func test_keyLookup() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- let val = try await tu.keyLookup(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: "google-lrc", verifierId: TORUS_TEST_EMAIL)
- XCTAssertEqual(val.address, "0x872eEfa7495599A6983d396fE8dcf542457CF33f")
-
- do {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- _ = try await tu.keyLookup(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: "google-lrc-fake", verifierId: TORUS_TEST_EMAIL)
- XCTFail()
- } catch let error {
- if let keylookupError = error as? KeyLookupError {
- XCTAssertEqual(keylookupError, KeyLookupError.verifierNotSupported)
- }
- }
- }
-
- // MARK: Aggregate tests
-
- func test_getPublicAddressAggregateLogin() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL)
- XCTAssertEqual(val.finalKeyData?.evmAddress, "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2")
- }
-
- /* TODO: Investigate this test further
- func test_keyAssignAggregateLogin() async throws {
- let email = generateRandomEmail(of: 6)
-
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- let val = try await tu.keyAssign(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: email, signerHost: signerHost, network: .legacy(.TESTNET))
- guard let result = val.result as? [String: Any] else {
- throw TorusUtilError.empty
- }
- let keys = result["keys"] as! [[String: String]]
- _ = keys[0]["address"]
-
- // Add more check to see if address is valid
- }
- */
-
- func test_keyLookupAggregateLogin() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- let val = try await tu.keyLookup(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL)
- XCTAssertEqual(val.address, "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2")
- }
-}
-
-extension IntegrationTests {}
-
-struct ROPSTEN_CONSTANTS {
- static let endpoints = ["https://teal-15-1.torusnode.com/jrpc", "https://teal-15-3.torusnode.com/jrpc", "https://teal-15-4.torusnode.com/jrpc", "https://teal-15-5.torusnode.com/jrpc", "https://teal-15-2.torusnode.com/jrpc"]
- static let nodePubKeys = [TorusNodePubModel(_X: "1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3", _Y: "d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"), TorusNodePubModel(_X: "7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d", _Y: "b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636"), TorusNodePubModel(_X: "8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f", _Y: "9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"), TorusNodePubModel(_X: "25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c", _Y: "f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249"), TorusNodePubModel(_X: "d908f41f8e06324a8a7abcf702adb6a273ce3ae63d86a3d22723e1bbf1438c9a", _Y: "f977530b3ec0e525438c72d1e768380cbc5fb3b38a760ee925053b2e169428ce")]
-}
diff --git a/Tests/TorusUtilsTests/MainnetTest.swift b/Tests/TorusUtilsTests/MainnetTest.swift
index 3c42bd74..2c2382b8 100644
--- a/Tests/TorusUtilsTests/MainnetTest.swift
+++ b/Tests/TorusUtilsTests/MainnetTest.swift
@@ -1,13 +1,11 @@
import BigInt
import FetchNodeDetails
import JWTKit
+import TorusUtils
import XCTest
-@testable import TorusUtils
-
class MainnetTests: XCTestCase {
static var fetchNodeDetails: AllNodeDetailsModel?
- // static var nodeDetails: NodeDetails?
static var utils: TorusUtils?
static var endpoints: [String] = []
static var nodePubKeys: [TorusNodePubModel] = []
@@ -16,28 +14,25 @@ class MainnetTests: XCTestCase {
let TORUS_TEST_VERIFIER = "torus-test-health"
let TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
let TORUS_TEST_EMAIL = "hello@tor.us"
- var signerHost = "https://signer.tor.us/api/sign"
- var allowHost = "https://signer.tor.us/api/allow"
- // Fake data
- let TORUS_TEST_VERIFIER_FAKE = "google-lrc-fakes"
var fnd: NodeDetailManager!
- var tu: TorusUtils!
+ var torus: TorusUtils!
override func setUp() {
super.setUp()
fnd = NodeDetailManager(network: .legacy(.MAINNET))
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .legacy(.MAINNET)))
}
- func get_fnd_and_tu_data(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- tu = TorusUtils(enableOneKey: enableOneKey, network: .legacy(.MAINNET), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
- }
+ func test_should_fetch_public_address() async throws {
+ let verifier = "google"
+ let verifierID = TORUS_TEST_EMAIL
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.torusNodeEndpoints, verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
- func test_get_public_address() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: "google", veriferID: TORUS_TEST_EMAIL)
- let val = try await tu.getPublicAddress(endpoints: nodeDetails.torusNodeEndpoints, torusNodePubs: nodeDetails.torusNodePub, verifier: "google", verifierId: TORUS_TEST_EMAIL)
XCTAssertEqual(val.finalKeyData!.evmAddress, "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A")
XCTAssertEqual(val.finalKeyData!.X, "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4")
XCTAssertEqual(val.finalKeyData!.Y, "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1")
@@ -47,30 +42,38 @@ class MainnetTests: XCTestCase {
XCTAssertNil(val.metadata?.pubNonce)
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1"))
+ XCTAssertEqual(val.metadata?.typeOfUser, .v1)
+ XCTAssertNotNil(val.nodesData)
}
- func test_fetch_user_type_and_addresses() async throws {
- let verifier1: String = "google"
- let verifierID1: String = TORUS_TEST_EMAIL
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- var val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier1, verifierId: verifierID1)
+ func test_should_fetch_user_type_and_public_address() async throws {
+ var verifier: String = "google"
+ var verifierID: String = TORUS_TEST_EMAIL
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ var val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
XCTAssertEqual(val.finalKeyData!.evmAddress, "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E")
- XCTAssertEqual(val.finalKeyData!.X, "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55")
- XCTAssertEqual(val.finalKeyData!.Y, "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E")
+
XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A")
XCTAssertEqual(val.oAuthKeyData!.X, "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4")
XCTAssertEqual(val.oAuthKeyData!.Y, "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1")
+ XCTAssertEqual(val.finalKeyData!.X, "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55")
+ XCTAssertEqual(val.finalKeyData!.Y, "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5")
XCTAssertEqual(val.metadata!.pubNonce!.x, "eb22d93244acf7fcbeb6566da722bc9c8e5433cd28da25ca0650d9cb32806c39")
XCTAssertEqual(val.metadata!.pubNonce!.y, "765541e214f067cfc44dcf41e582ae09b71c2e607a301cc8a45e1f316a6ba91c")
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
XCTAssertEqual(val.metadata?.typeOfUser, .v2)
- let verifier2: String = "tkey-google"
- let verifierID2: String = "somev2user@gmail.com"
- val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier2, verifierId: verifierID2)
+ verifier = "tkey-google"
+ verifierID = "somev2user@gmail.com"
+ val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xA9c6829e4899b6D630130ebf59D046CA868D7f83")
XCTAssertEqual(val.oAuthKeyData!.X, "5566cd940ea540ba1a3ba2ff0f5fd3d9a3a74350ac3baf47b811592ae6ea1c30")
@@ -82,92 +85,95 @@ class MainnetTests: XCTestCase {
XCTAssertEqual(val.metadata?.pubNonce?.y, "da3aed7f7e9d612052beb1d92ec68a8dcf60faf356985435b424af2423f66672")
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v2"))
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
- let verifier3: String = "tkey-google"
- let verifierID3: String = "caspertorus@gmail.com"
- val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier3, verifierId: verifierID3)
+ verifier = "tkey-google"
+ verifierID = "caspertorus@gmail.com"
+ val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
XCTAssertEqual(val.finalKeyData!.evmAddress, "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD")
- XCTAssertEqual(val.finalKeyData!.X, "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc")
- XCTAssertEqual(val.finalKeyData!.Y, "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53")
XCTAssertEqual(val.oAuthKeyData!.X, "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8")
XCTAssertEqual(val.oAuthKeyData!.Y, "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD")
+ XCTAssertEqual(val.finalKeyData!.X, "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc")
+ XCTAssertEqual(val.finalKeyData!.Y, "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff")
XCTAssertEqual(val.metadata?.pubNonce?.x, "16214bf232167258fb5f98fa9d84968ffec3236aaf0994fc366940c4bc07a5b1")
XCTAssertEqual(val.metadata?.pubNonce?.y, "475e8c09d2cc8f6c12a767f51c052b1bf8e8d3a2a2b6818d4b199dc283e80ac4")
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
}
- func test_key_assign() async throws {
- let email = generateRandomEmail(of: 6)
- let nodeDetails = try await get_fnd_and_tu_data(verifer: "google", veriferID: email)
- let val = try await tu.keyAssign(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: email, signerHost: tu.signerHost, network: .legacy(.MAINNET))
- guard let result = val.result as? [String: Any] else {
- throw TorusUtilError.empty
- }
- let keys = result["keys"] as! [[String: String]]
- _ = keys[0]["address"]
-
- // Add more check to see if address is valid
+ func test_should_be_able_to_key_assign() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let verifier: String = "google"
+ let verifierID: String = fakeEmail
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+ XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ XCTAssertEqual(data.metadata?.typeOfUser, .v1)
+ XCTAssertEqual(data.metadata?.upgraded, false)
}
- func test_login() async throws {
- let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
- let verifierParams = VerifierParams(verifier_id: TORUS_TEST_EMAIL)
- let extraParams = ["verifieridentifier": TORUS_TEST_VERIFIER, "verifier_id": TORUS_TEST_EMAIL] as [String: Codable]
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
- let data = try await tu.retrieveShares(
- endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(),
- indexes: nodeDetails.getTorusIndexes(),
- verifier: TORUS_TEST_VERIFIER,
- verifierParams: verifierParams,
- idToken: jwt,
- extraParams: extraParams)
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x90A926b698047b4A87265ba1E9D8b512E8489067")
- XCTAssertEqual(data.finalKeyData?.X, "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f")
- XCTAssertEqual(data.finalKeyData?.Y, "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1")
- XCTAssertEqual(data.finalKeyData?.privKey, "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x90A926b698047b4A87265ba1E9D8b512E8489067")
- XCTAssertEqual(data.oAuthKeyData?.X, "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f")
- XCTAssertEqual(data.oAuthKeyData?.Y, "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce, nil)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser, .v1)
- XCTAssertEqual(data.metadata?.upgraded, nil)
+ func test_should_be_able_to_login() async throws {
+ let verifier: String = TORUS_TEST_VERIFIER
+ let verifierID: String = TORUS_TEST_EMAIL
+ let jwt = try! generateIdToken(email: verifierID)
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x90A926b698047b4A87265ba1E9D8b512E8489067")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x90A926b698047b4A87265ba1E9D8b512E8489067")
+ XCTAssertEqual(data.oAuthKeyData.X, "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f")
+ XCTAssertEqual(data.oAuthKeyData.Y, "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44")
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x90A926b698047b4A87265ba1E9D8b512E8489067")
+ XCTAssertEqual(data.finalKeyData.X, "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f")
+ XCTAssertEqual(data.finalKeyData.Y, "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1")
+ XCTAssertEqual(data.finalKeyData.privKey, "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
- func test_aggregate_login() async throws {
+ func test_should_be_able_to_aggregate_login() async throws {
let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
- let hashedIDToken = keccak256Data(jwt.data(using: .utf8) ?? Data()).toHexString()
- let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable]
- let verifierParams = VerifierParams(verifier_id: verifierID)
- let nodeDetails = try await get_fnd_and_tu_data(verifer: verifier, veriferID: verifierID)
-
- let data = try await tu.retrieveShares(endpoints: nodeDetails.torusNodeEndpoints, torusNodePubs: nodeDetails.torusNodePub, indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams)
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x621a4d458cFd345dAE831D9E756F10cC40A50381")
- XCTAssertEqual(data.finalKeyData?.X, "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236")
- XCTAssertEqual(data.finalKeyData?.Y, "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e")
- XCTAssertEqual(data.finalKeyData?.privKey, "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x621a4d458cFd345dAE831D9E756F10cC40A50381")
- XCTAssertEqual(data.oAuthKeyData?.X, "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236")
- XCTAssertEqual(data.oAuthKeyData?.Y, "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce, nil)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser, .v1)
- XCTAssertEqual(data.metadata?.upgraded, nil)
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: verifierID, idtoken: jwt)])
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.torusNodeEndpoints, verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x621a4d458cFd345dAE831D9E756F10cC40A50381")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x621a4d458cFd345dAE831D9E756F10cC40A50381")
+ XCTAssertEqual(data.oAuthKeyData.X, "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236")
+ XCTAssertEqual(data.oAuthKeyData.Y, "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534")
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x621a4d458cFd345dAE831D9E756F10cC40A50381")
+ XCTAssertEqual(data.finalKeyData.X, "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236")
+ XCTAssertEqual(data.finalKeyData.Y, "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e")
+ XCTAssertEqual(data.finalKeyData.privKey, "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
}
diff --git a/Tests/TorusUtilsTests/SapphireDevnetTest.swift b/Tests/TorusUtilsTests/SapphireDevnetTest.swift
new file mode 100644
index 00000000..900c2b3b
--- /dev/null
+++ b/Tests/TorusUtilsTests/SapphireDevnetTest.swift
@@ -0,0 +1,307 @@
+import BigInt
+import curveSecp256k1
+import FetchNodeDetails
+import JWTKit
+import TorusUtils
+import XCTest
+
+final class SapphireDevnetTest: XCTestCase {
+ let TORUS_TEST_VERIFIER = "torus-test-health"
+ let TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
+
+ let TORUS_TEST_EMAIL = "devnettestuser@tor.us"
+ let TORUS_HASH_ENABLED_TEST_EMAIL = "saasas@tr.us"
+ let TORUS_IMPORT_EMAIL = "Sydnie.Lehner73@yahoo.com"
+ let TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"
+ let HASH_ENABLED_VERIFIER = "torus-test-verifierid-hash"
+
+ var fnd: NodeDetailManager!
+ var torus: TorusUtils!
+
+ override func setUp() {
+ super.setUp()
+ fnd = NodeDetailManager(network: .sapphire(.SAPPHIRE_DEVNET))
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .sapphire(.SAPPHIRE_DEVNET)))
+ }
+
+ func test_should_fetch_public_address() async throws {
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa")
+ XCTAssertEqual(val.oAuthKeyData!.X, "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x462A8BF111A55C9354425F875F89B22678c0Bc44")
+ XCTAssertEqual(val.finalKeyData!.X, "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1")
+ XCTAssertEqual(val.finalKeyData!.Y, "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed")
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_import_key_for_a_new_user() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ var jwt = try generateIdToken(email: fakeEmail)
+ let privateKey = try KeyUtils.generateSecret()
+
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = fakeEmail
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let val = try await torus.importPrivateKey(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), nodeIndexes: nodeDetails.getTorusIndexes(), nodePubKeys: nodeDetails.getTorusNodePub(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, newPrivateKey: privateKey)
+ XCTAssertEqual(val.finalKeyData.privKey, privateKey)
+
+ jwt = try generateIdToken(email: fakeEmail)
+ let shareRetrieval = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+ XCTAssertEqual(shareRetrieval.finalKeyData.privKey, privateKey)
+
+ let addressRetrieval = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+ let publicAddress = try SecretKey(hex: privateKey).toPublic().serialize(compressed: false)
+ let retrievedAddress = KeyUtils.getPublicKeyFromCoords(pubKeyX: addressRetrieval.finalKeyData!.X, pubKeyY: addressRetrieval.finalKeyData!.Y)
+ XCTAssertEqual(publicAddress, retrievedAddress)
+ }
+
+ func test_should_be_able_to_key_assign() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = fakeEmail
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ XCTAssertEqual(data.metadata?.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata?.upgraded, false)
+ }
+
+ func test_should_be_able_to_key_assign_to_tss_verifier_id() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let nonce = 0
+ let tssTag = "default"
+ let tssVerifierID: String = fakeEmail + "\u{0015}" + tssTag + "\u{0016}" + String(nonce)
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = fakeEmail
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID, extendedVerifierId: tssVerifierID)
+
+ XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ XCTAssertEqual(data.metadata?.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata?.upgraded, false)
+ }
+
+ func test_should_fetch_public_address_of_tss_verifier_id() async throws {
+ let email = TORUS_EXTENDED_VERIFIER_EMAIL
+ let nonce = 0
+ let tssTag = "default"
+ let tssVerifierID: String = email + "\u{0015}" + tssTag + "\u{0016}" + String(nonce)
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = email
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID, extendedVerifierId: tssVerifierID)
+
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30")
+ XCTAssertEqual(val.oAuthKeyData!.X, "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30")
+ XCTAssertEqual(val.finalKeyData!.X, "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c")
+ XCTAssertEqual(val.finalKeyData!.Y, "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e")
+ XCTAssertNil(val.metadata?.pubNonce)
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_allow_test_tss_verifier_to_fetch_shares() async throws {
+ let email = generateRandomEmail(of: 6)
+ let nonce = 0
+ let tssTag = "default"
+ let tssVerifierID: String = email + "\u{0015}" + tssTag + "\u{0016}" + String(nonce)
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = email
+ let token = try generateIdToken(email: email)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID, extended_verifier_id: tssVerifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: token)
+
+ XCTAssertNotNil(data.finalKeyData.privKey)
+ XCTAssertNotNil(data.oAuthKeyData.evmAddress)
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.upgraded, true)
+ }
+
+ func test_should_fetch_public_address_when_verifier_is_hash_enabled() async throws {
+ let verifier = HASH_ENABLED_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C")
+ XCTAssertEqual(val.oAuthKeyData!.X, "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x8a7e297e20804786767B1918a5CFa11683e5a3BB")
+ XCTAssertEqual(val.finalKeyData!.X, "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a")
+ XCTAssertEqual(val.finalKeyData!.Y, "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0")
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_fetch_user_type_and_public_address_when_verifier_is_hash_enabled() async throws {
+ // duplicated test
+ let verifier = HASH_ENABLED_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C")
+ XCTAssertEqual(val.oAuthKeyData!.X, "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x8a7e297e20804786767B1918a5CFa11683e5a3BB")
+ XCTAssertEqual(val.finalKeyData!.X, "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a")
+ XCTAssertEqual(val.finalKeyData!.Y, "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0")
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_login_when_verifier_is_hash_enabled() async throws {
+ let verifier = HASH_ENABLED_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+ let jwt = try generateIdToken(email: verifierID)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let val = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(val.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.finalKeyData.evmAddress, "0x8a7e297e20804786767B1918a5CFa11683e5a3BB")
+ XCTAssertEqual(val.finalKeyData.X, "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a")
+ XCTAssertEqual(val.finalKeyData.Y, "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da")
+ XCTAssertEqual(val.finalKeyData.privKey, "f161f63a84f1c935525ec0bda74bc5a15de6a9a7be28fad237ef6162df335fe6")
+ XCTAssertEqual(val.oAuthKeyData.evmAddress, "0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C")
+ XCTAssertEqual(val.oAuthKeyData.X, "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986")
+ XCTAssertEqual(val.oAuthKeyData.Y, "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa")
+ XCTAssertEqual(val.oAuthKeyData.privKey, "62e110d9d698979c1966d14b2759006cf13be7dfc86a63ff30812e2032163f2f")
+ XCTAssertEqual(val.metadata.pubNonce!.x, "5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b")
+ XCTAssertEqual(val.metadata.pubNonce!.y, "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0")
+ XCTAssertEqual(val.metadata.nonce, BigUInt("8e80e560ae59319938f7ef727ff2c5346caac1c7f5be96d3076e3342ad1d20b7", radix: 16))
+ XCTAssertEqual(val.metadata.upgraded, false)
+ XCTAssertEqual(val.metadata.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_login() async throws {
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+ let jwt = try generateIdToken(email: verifierID)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let val = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(val.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.finalKeyData.evmAddress, "0x462A8BF111A55C9354425F875F89B22678c0Bc44")
+ XCTAssertEqual(val.finalKeyData.X, "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1")
+ XCTAssertEqual(val.finalKeyData.Y, "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507")
+ XCTAssertEqual(val.finalKeyData.privKey, "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203")
+ XCTAssertEqual(val.oAuthKeyData.evmAddress, "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa")
+ XCTAssertEqual(val.oAuthKeyData.X, "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b")
+ XCTAssertEqual(val.oAuthKeyData.Y, "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5")
+ XCTAssertEqual(val.oAuthKeyData.privKey, "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa")
+ XCTAssertEqual(val.metadata.pubNonce!.x, "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc")
+ XCTAssertEqual(val.metadata.pubNonce!.y, "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed")
+
+ XCTAssertEqual(val.metadata.nonce, BigUInt("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", radix: 16))
+ XCTAssertEqual(val.metadata.upgraded, false)
+ XCTAssertEqual(val.metadata.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_aggregate_login() async throws {
+ let email: String = generateRandomEmail(of: 6)
+ let jwt = try! generateIdToken(email: email)
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let verifierParams = VerifierParams(verifier_id: email, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: email, idtoken: jwt)])
+ let nodeDetails = try await fnd.getNodeDetails(verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierID: email)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+ XCTAssertNotNil(data.finalKeyData.privKey)
+ XCTAssertNotNil(data.oAuthKeyData.evmAddress)
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ }
+
+ func test_should_be_able_to_update_sessiontime_of_the_token_signature_data() async throws {
+ let verifier: String = TORUS_TEST_VERIFIER
+ let verifierID: String = TORUS_TEST_EMAIL
+ let jwt = try! generateIdToken(email: verifierID)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let customSessionTime = Int(3600)
+ torus.setSessionTime(sessionTime: customSessionTime)
+
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ let signatures = data.sessionData.sessionTokenData.map({ $0!.token })
+ let parsedSignatures = signatures.map({
+ let data = Data(base64Encoded: $0.data(using: .utf8)!)!
+ let hexString = String(data: data, encoding: .utf8)!
+ let json = hexString.hexEncodedToString()
+ return json
+ })
+ let now = Int(Date().timeIntervalSince1970)
+ for item in parsedSignatures {
+ let json = try JSONSerialization.jsonObject(with: item.data(using: .utf8)!) as? [String: Any]
+ let exp = json!["exp"] as! Int
+ let sessionTime = exp - now
+ XCTAssertGreaterThanOrEqual(sessionTime, customSessionTime - 30)
+ XCTAssertLessThanOrEqual(sessionTime, customSessionTime + 30)
+ }
+ }
+}
diff --git a/Tests/TorusUtilsTests/SapphireMainnetTests.swift b/Tests/TorusUtilsTests/SapphireMainnetTests.swift
new file mode 100644
index 00000000..ac29a202
--- /dev/null
+++ b/Tests/TorusUtilsTests/SapphireMainnetTests.swift
@@ -0,0 +1,286 @@
+import BigInt
+import curveSecp256k1
+import FetchNodeDetails
+import JWTKit
+import TorusUtils
+import XCTest
+
+class SapphireMainnetTests: XCTestCase {
+ static var fetchNodeDetails: AllNodeDetailsModel?
+ static var utils: TorusUtils?
+ static var endpoints: [String] = []
+ static var nodePubKeys: [TorusNodePubModel] = []
+ static var privKey: String = ""
+
+ let TORUS_TEST_EMAIL = "hello@tor.us"
+ let TORUS_TEST_VERIFIER = "torus-test-health"
+ let TORUS_TEST_AGGREGATE_VERIFIER = "torus-aggregate-sapphire-mainnet"
+ let HASH_ENABLED_VERIFIER = "torus-test-verifierid-hash"
+ let TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"
+
+ var fnd: NodeDetailManager!
+ var torus: TorusUtils!
+
+ override func setUp() {
+ super.setUp()
+ fnd = NodeDetailManager(network: .sapphire(.SAPPHIRE_MAINNET))
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .sapphire(.SAPPHIRE_MAINNET), enableOneKey: true))
+ }
+
+ func test_should_fetch_public_address() async throws {
+ let verifier = "tkey-google-sapphire-mainnet"
+ let verifierID = TORUS_TEST_EMAIL
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xb1a49C6E50a1fC961259a8c388EAf5953FA5152b")
+ XCTAssertEqual(val.oAuthKeyData!.X, "a9f5a463aefb16e90f4cbb9de4a5b6b7f6c6a3831cefa0f20cccb9e7c7b01c20")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "3376c6734da57ab3a67c7792eeea20707d16992dd2c827a59499f4c056b00d08")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x327b2742768B436d09153429E762FADB54413Ded")
+ XCTAssertEqual(val.finalKeyData!.X, "1567e030ca76e520c180c50bc6baed07554ebc35c3132495451173e9310d8be5")
+ XCTAssertEqual(val.finalKeyData!.Y, "123c0560757ffe6498bf2344165d0f295ea74eb8884683675e5f17ae7bb41cdb")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "56e803db7710adbfe0ecca35bc6a3ad27e966df142e157e76e492773c88e8433")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "f4168594c1126ca731756dd480f992ee73b0834ba4b787dd892a9211165f50a3")
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_key_assign() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let verifier = "tkey-google-sapphire-mainnet"
+ let verifierID = fakeEmail
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ XCTAssertEqual(data.metadata?.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata?.upgraded, false)
+ }
+
+ func test_should_be_able_to_key_assign_to_tss_verifier_id() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let nonce = 0
+ let tssTag = "default"
+ let tssVerifierID: String = fakeEmail + "\u{0015}" + tssTag + "\u{0016}" + String(nonce)
+ let verifier = "tkey-google-sapphire-mainnet"
+ let verifierID = fakeEmail
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID, extendedVerifierId: tssVerifierID)
+
+ XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ XCTAssertEqual(data.metadata?.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata?.upgraded, false)
+ }
+
+ func test_should_fetch_public_address_of_tss_verifier_id() async throws {
+ let email = TORUS_EXTENDED_VERIFIER_EMAIL
+ let nonce = 0
+ let tssTag = "default"
+ let tssVerifierID: String = email + "\u{0015}" + tssTag + "\u{0016}" + String(nonce)
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = email
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID, extendedVerifierId: tssVerifierID)
+
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A")
+ XCTAssertEqual(val.oAuthKeyData!.X, "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A")
+ XCTAssertEqual(val.finalKeyData!.X, "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29")
+ XCTAssertEqual(val.finalKeyData!.Y, "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb")
+ XCTAssertNil(val.metadata?.pubNonce)
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_allow_test_tss_verifier_to_fetch_shares() async throws {
+ let email = generateRandomEmail(of: 6)
+ let nonce = 0
+ let tssTag = "default"
+ let tssVerifierID: String = email + "\u{0015}" + tssTag + "\u{0016}" + String(nonce)
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = email
+ let token = try generateIdToken(email: email)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID, extended_verifier_id: tssVerifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: token)
+
+ XCTAssertNotNil(data.finalKeyData.privKey)
+ XCTAssertNotNil(data.oAuthKeyData.evmAddress)
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.upgraded, true)
+ }
+
+ func test_should_fetch_public_address_when_verifier_is_hash_enabled() async throws {
+ let verifier = HASH_ENABLED_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC")
+ XCTAssertEqual(val.oAuthKeyData!.X, "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB")
+ XCTAssertEqual(val.finalKeyData!.X, "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8")
+ XCTAssertEqual(val.finalKeyData!.Y, "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f")
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_fetch_user_type_and_public_address_when_verifier_is_hash_enabled() async throws {
+ // duplicated test
+ let verifier = HASH_ENABLED_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC")
+ XCTAssertEqual(val.oAuthKeyData!.X, "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB")
+ XCTAssertEqual(val.finalKeyData!.X, "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8")
+ XCTAssertEqual(val.finalKeyData!.Y, "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f")
+ XCTAssertEqual(val.metadata?.nonce, BigUInt(0))
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_login_when_verifier_is_hash_enabled() async throws {
+ let verifier = HASH_ENABLED_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+ let jwt = try generateIdToken(email: verifierID)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let val = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(val.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.finalKeyData.evmAddress, "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB")
+ XCTAssertEqual(val.finalKeyData.X, "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8")
+ XCTAssertEqual(val.finalKeyData.Y, "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90")
+ XCTAssertEqual(val.finalKeyData.privKey, "13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6")
+ XCTAssertEqual(val.oAuthKeyData.evmAddress, "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC")
+ XCTAssertEqual(val.oAuthKeyData.X, "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8")
+ XCTAssertEqual(val.oAuthKeyData.Y, "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c")
+ XCTAssertEqual(val.oAuthKeyData.privKey, "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478")
+ XCTAssertEqual(val.metadata.pubNonce!.x, "498ed301af25a3b7136f478fa58677c79a6d6fe965bc13002a6f459b896313bd")
+ XCTAssertEqual(val.metadata.pubNonce!.y, "d6feb9a1e0d6d0627fbb1ce75682bc09ab4cf0e2da4f0f7fcac0ba9d07596c8f")
+ XCTAssertEqual(val.metadata.nonce, BigUInt("3c2b6ba5b54ca0ba4ae978eb48429a84c47b7b3e526b35e7d46dd716887f52bf", radix: 16))
+ XCTAssertEqual(val.metadata.upgraded, false)
+ XCTAssertEqual(val.metadata.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_login() async throws {
+ let verifier = TORUS_TEST_VERIFIER
+ let verifierID = TORUS_TEST_EMAIL
+ let jwt = try generateIdToken(email: verifierID)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let val = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(val.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.finalKeyData.evmAddress, "0x70520A7F04868ACad901683699Fa32765C9F6871")
+ XCTAssertEqual(val.finalKeyData.X, "adff099b5d3b1e238b43fba1643cfa486e8d9e8de22c1e6731d06a5303f9025b")
+ XCTAssertEqual(val.finalKeyData.Y, "21060328e7889afd303acb63201b6493e3061057d1d81279931ab4a6cabf94d4")
+ XCTAssertEqual(val.finalKeyData.privKey, "dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419")
+ XCTAssertEqual(val.oAuthKeyData.evmAddress, "0x925c97404F1aBdf4A8085B93edC7B9F0CEB3C673")
+ XCTAssertEqual(val.oAuthKeyData.X, "5cd8625fc01c7f7863a58c914a8c43b2833b3d0d5059350bab4acf6f4766a33d")
+ XCTAssertEqual(val.oAuthKeyData.Y, "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391")
+ XCTAssertEqual(val.oAuthKeyData.privKey, "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906")
+ XCTAssertEqual(val.metadata.pubNonce!.x, "ab4d287c263ab1bb83c37646d0279764e50fe4b0c34de4da113657866ddcf318")
+ XCTAssertEqual(val.metadata.pubNonce!.y, "ad35db2679dfad4b62d77cf753d7b98f73c902e5d101cc2c3c1209ece6d94382")
+ XCTAssertEqual(val.metadata.nonce, BigUInt("4f1181d8689f0d0960f1a6f9fe26e03e557bdfba11f4b6c8d7b1285e9c271b13", radix: 16))
+ XCTAssertEqual(val.metadata.upgraded, false)
+ XCTAssertEqual(val.metadata.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+ }
+
+ func test_should_be_able_to_aggregate_login() async throws {
+ let email: String = generateRandomEmail(of: 6)
+ let jwt = try! generateIdToken(email: email)
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let verifierParams = VerifierParams(verifier_id: email, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: email, idtoken: jwt)])
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierID: email)
+
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+ XCTAssertNotNil(data.finalKeyData.privKey)
+ XCTAssertNotNil(data.oAuthKeyData.evmAddress)
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ }
+
+ func test_should_be_able_to_update_sessiontime_of_the_token_signature_data() async throws {
+ let verifier: String = TORUS_TEST_VERIFIER
+ let verifierID: String = TORUS_TEST_EMAIL
+ let jwt = try! generateIdToken(email: verifierID)
+
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+
+ let customSessionTime = Int(3600)
+ torus.setSessionTime(sessionTime: customSessionTime)
+
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ let signatures = data.sessionData.sessionTokenData.map({ $0!.token })
+ let parsedSignatures = signatures.map({
+ let data = Data(base64Encoded: $0.data(using: .utf8)!)!
+ let hexString = String(data: data, encoding: .utf8)!
+ let json = hexString.hexEncodedToString()
+ return json
+ })
+ let now = Int(Date().timeIntervalSince1970)
+ for item in parsedSignatures {
+ let json = try JSONSerialization.jsonObject(with: item.data(using: .utf8)!) as? [String: Any]
+ let exp = json!["exp"] as! Int
+ let sessionTime = exp - now
+ XCTAssertGreaterThanOrEqual(sessionTime, customSessionTime - 30)
+ XCTAssertLessThanOrEqual(sessionTime, customSessionTime + 30)
+ }
+ }
+}
diff --git a/Tests/TorusUtilsTests/SapphireTest.swift b/Tests/TorusUtilsTests/SapphireTest.swift
deleted file mode 100644
index 94114c34..00000000
--- a/Tests/TorusUtilsTests/SapphireTest.swift
+++ /dev/null
@@ -1,381 +0,0 @@
-import BigInt
-import FetchNodeDetails
-import JWTKit
-import XCTest
-import curveSecp256k1
-
-@testable import TorusUtils
-
-final class SapphireTest: XCTestCase {
- static var fetchNodeDetails: AllNodeDetailsModel?
- // static var nodeDetails: NodeDetails?
- static var utils: TorusUtils?
- static var endpoints: [String] = []
- static var nodePubKeys: [TorusNodePubModel] = []
- static var privKey: String = ""
-
- let TORUS_TEST_VERIFIER = "torus-test-health"
- let TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
- let TORUS_TEST_EMAIL = "devnettestuser@tor.us"
- let TORUS_HASH_ENABLED_TEST_EMAIL = "saasas@tr.us";
- let TORUS_IMPORT_EMAIL = "Sydnie.Lehner73@yahoo.com"
- let TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"
- let HashEnabledVerifier = "torus-test-verifierid-hash"
-
- var fnd: NodeDetailManager!
- var torus: TorusUtils!
-
- override func setUp() {
- super.setUp()
- fnd = NodeDetailManager(network: .sapphire(.SAPPHIRE_DEVNET))
- }
-
- func get_fnd_and_tu_data(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- torus = TorusUtils(enableOneKey: enableOneKey, network: .sapphire(.SAPPHIRE_DEVNET), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
- }
-
- func testFetchPublicAddress() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
-
- let val = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.torusNodePub, verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL)
- XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa")
- XCTAssertEqual(val.oAuthKeyData!.X, "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b")
- XCTAssertEqual(val.oAuthKeyData!.Y, "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5")
- XCTAssertEqual(val.finalKeyData!.evmAddress, "0x462A8BF111A55C9354425F875F89B22678c0Bc44")
- XCTAssertEqual(val.finalKeyData!.X, "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1")
- XCTAssertEqual(val.finalKeyData!.Y, "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507")
- XCTAssertEqual(val.metadata?.pubNonce?.x, "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc")
- XCTAssertEqual(val.metadata?.pubNonce?.y, "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed")
- XCTAssertEqual(val.metadata?.nonce, BigUInt.zero)
- XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v2"))
- }
-
- func testKeepPublicAddressSame() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
-
- let publicAddress = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL)
- let publicAddress2 = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL)
-
- XCTAssertEqual(publicAddress.finalKeyData?.evmAddress, publicAddress2.finalKeyData?.evmAddress)
- XCTAssertNotEqual(publicAddress.finalKeyData?.evmAddress, nil)
- XCTAssertNotEqual(publicAddress2.finalKeyData?.evmAddress, "")
- }
-
- func testFetchPublicAddressAndUserType() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
-
- let result = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL)
-
- XCTAssertEqual(result.finalKeyData?.evmAddress.lowercased(), "0x462a8bf111a55c9354425f875f89b22678c0bc44".lowercased())
-
- XCTAssertEqual(result.metadata?.typeOfUser, .v2)
-
- XCTAssertEqual(result.metadata?.pubNonce?.x, "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc")
-
- XCTAssertEqual(result.metadata?.pubNonce?.y, "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed")
- }
-
- func testKeyAssignSapphireDevnet() async throws {
- let fakeEmail = generateRandomEmail(of: 6)
- let verifier: String = TORUS_TEST_VERIFIER
- let verifierID: String = fakeEmail
- let nodeDetails = try await get_fnd_and_tu_data(verifer: verifier, veriferID: verifierID)
- let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertNotNil(data.finalKeyData)
- XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
- XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- }
-
- func testAbleToLogin() async throws {
- let token = try generateIdToken(email: TORUS_TEST_EMAIL)
-
- let verifierParams = VerifierParams(verifier_id: TORUS_TEST_EMAIL)
-
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
-
- let data = try await torus.retrieveShares(
- endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(),
- indexes: nodeDetails.getTorusIndexes(),
- verifier: TORUS_TEST_VERIFIER,
- verifierParams: verifierParams,
- idToken: token
- )
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x462A8BF111A55C9354425F875F89B22678c0Bc44")
- XCTAssertEqual(data.finalKeyData?.X, "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1")
- XCTAssertEqual(data.finalKeyData?.Y, "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507")
- XCTAssertEqual(data.finalKeyData?.privKey, "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa")
- XCTAssertEqual(data.oAuthKeyData?.X, "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b")
- XCTAssertEqual(data.oAuthKeyData?.Y, "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa")
- XCTAssertNotEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertNotEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce?.x, "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc")
- XCTAssertEqual(data.metadata?.pubNonce?.y, "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed")
- XCTAssertEqual(data.metadata?.nonce?.serialize().toHexString(), "b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a")
- XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- XCTAssertEqual(data.metadata?.upgraded, false)
- }
-
- func testNewUserLogin() async throws {
- let fakeEmail = generateRandomEmail(of: 6)
- let verifierId = fakeEmail // faker random address
- let token = try generateIdToken(email: verifierId)
-
- let verifierParams = VerifierParams(verifier_id: verifierId)
-
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: verifierId)
-
- let data = try await torus.retrieveShares(
- endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(),
- indexes: nodeDetails.getTorusIndexes(),
- verifier: TORUS_TEST_VERIFIER,
- verifierParams: verifierParams,
- idToken: token
- )
-
- XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- XCTAssertEqual(data.metadata?.upgraded, false)
- XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
- XCTAssertNotEqual(data.finalKeyData?.X, "")
- XCTAssertNotEqual(data.finalKeyData?.Y, "")
- XCTAssertNotEqual(data.finalKeyData?.privKey, "")
- XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
- XCTAssertNotEqual(data.oAuthKeyData?.X, "")
- XCTAssertNotEqual(data.oAuthKeyData?.Y, "")
- XCTAssertNotEqual(data.oAuthKeyData?.privKey, "")
- XCTAssertNotEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertNotEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertNotEqual(data.metadata?.pubNonce?.x, "")
- XCTAssertNotEqual(data.metadata?.pubNonce?.y, "")
- }
-
- func testNodeDownAbleToLogin() async throws {
- let token = try generateIdToken(email: TORUS_TEST_EMAIL)
-
- let verifierParams = VerifierParams(verifier_id: TORUS_TEST_EMAIL)
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: TORUS_TEST_EMAIL)
-
- var torusNodeEndpoints = nodeDetails.getTorusNodeSSSEndpoints()
- torusNodeEndpoints[1] = "https://example.com"
-
- let data = try await torus.retrieveShares(endpoints: torusNodeEndpoints,
- torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(),
- verifier: TORUS_TEST_VERIFIER, verifierParams: verifierParams, idToken: token)
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x462A8BF111A55C9354425F875F89B22678c0Bc44")
- XCTAssertEqual(data.finalKeyData?.X, "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1")
- XCTAssertEqual(data.finalKeyData?.Y, "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507")
- XCTAssertEqual(data.finalKeyData?.privKey, "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa")
- XCTAssertEqual(data.oAuthKeyData?.X, "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b")
- XCTAssertEqual(data.oAuthKeyData?.Y, "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa")
- XCTAssertNotEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertNotEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce?.x, "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc")
- XCTAssertEqual(data.metadata?.pubNonce?.y, "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed")
- XCTAssertEqual(data.metadata?.nonce?.serialize().toHexString(), "b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a")
- XCTAssertEqual(data.metadata?.typeOfUser, .v2)
- XCTAssertEqual(data.metadata?.upgraded, false)
- }
-
- func testPubAdderessOfTssVerifierId() async throws {
- let email = TORUS_EXTENDED_VERIFIER_EMAIL
- let nonce = 0
- let tssTag = "default"
- let tssVerifierId = "\(email)\u{0015}\(tssTag)\u{0016}\(nonce)"
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: email)
-
- let pubAddress = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL, extendedVerifierId: tssVerifierId)
-
- XCTAssertEqual(pubAddress.oAuthKeyData!.evmAddress, "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30")
- XCTAssertEqual(pubAddress.oAuthKeyData!.X, "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c")
- XCTAssertEqual(pubAddress.oAuthKeyData!.Y, "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e")
- XCTAssertEqual(pubAddress.finalKeyData!.evmAddress, "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30")
- XCTAssertEqual(pubAddress.finalKeyData!.X, "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c")
- XCTAssertEqual(pubAddress.finalKeyData!.Y, "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e")
- XCTAssertEqual(pubAddress.metadata?.pubNonce?.x, nil)
- XCTAssertEqual(pubAddress.metadata?.pubNonce?.y, nil)
- XCTAssertEqual(pubAddress.metadata?.nonce, BigUInt("0"))
- XCTAssertEqual(pubAddress.metadata?.upgraded, false)
- XCTAssertEqual(pubAddress.metadata?.typeOfUser, UserType(rawValue: "v2"))
- }
-
- func testAssignKeyToTssVerifier() async throws {
- let fakeEmail = generateRandomEmail(of: 6)
- let verifierId = fakeEmail // faker random address
- let nonce = 0
- let tssTag = "default"
- let tssVerifierId = "\(verifierId)\u{0015}\(tssTag)\u{0016}\(nonce)"
-
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: verifierId)
- let keyData = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: TORUS_TEST_VERIFIER, verifierId: verifierId, extendedVerifierId: tssVerifierId)
- XCTAssertNotEqual(keyData.finalKeyData?.evmAddress, nil)
- XCTAssertNotEqual(keyData.finalKeyData?.evmAddress, "")
- XCTAssertEqual(keyData.metadata?.typeOfUser, .v2)
- XCTAssertEqual(keyData.metadata?.nonce, BigUInt("0"))
- XCTAssertEqual(keyData.metadata?.upgraded, false)
- }
-
- func testAllowTssVerifierIdFetchShare() async throws {
- let email = generateRandomEmail(of: 6) // faker random address ???
- let verifierId = TORUS_TEST_EMAIL
- let nonce = 0
- let tssTag = "default"
- let tssVerifierId = "\(email)\u{0015}\(tssTag)\u{0016}\(nonce)"
-
- let token = try generateIdToken(email: email)
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: verifierId)
- let verifierParams = VerifierParams(verifier_id: verifierId, extended_verifier_id: tssVerifierId)
-
- let result = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(),
- verifier: TORUS_TEST_VERIFIER, verifierParams: verifierParams, idToken: token)
-
- XCTAssertNotEqual(result.finalKeyData?.privKey, nil)
- XCTAssertNotEqual(result.finalKeyData?.evmAddress, nil)
- XCTAssertEqual(result.metadata?.typeOfUser, .v2)
- XCTAssertEqual(result.metadata?.nonce, BigUInt("0"))
- XCTAssertEqual(result.metadata?.upgraded, true)
- }
-
- func testFetchPubAdderessWhenHashEnabled() async throws {
- let nodeDetails = try await get_fnd_and_tu_data(verifer: TORUS_TEST_VERIFIER, veriferID: HashEnabledVerifier)
- let pubAddress = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeSSSEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(),
- verifier: HashEnabledVerifier, verifierId: TORUS_HASH_ENABLED_TEST_EMAIL)
- XCTAssertEqual(pubAddress.oAuthKeyData!.evmAddress, "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219")
- XCTAssertEqual(pubAddress.oAuthKeyData!.X, "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67")
- XCTAssertEqual(pubAddress.oAuthKeyData!.Y, "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0")
- XCTAssertEqual(pubAddress.finalKeyData!.evmAddress, "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03")
- XCTAssertEqual(pubAddress.finalKeyData!.X, "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a")
- XCTAssertEqual(pubAddress.finalKeyData!.Y, "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e")
- XCTAssertEqual(pubAddress.metadata?.pubNonce?.x, "d6404befc44e3ab77a8387829d77e9c77a9c2fb37ae314c3a59bdc108d70349d")
- XCTAssertEqual(pubAddress.metadata?.pubNonce?.y, "1054dfe297f1d977ccc436109cbcce64e95b27f93efc0f1dab739c9146eda2e")
- XCTAssertEqual(pubAddress.metadata?.nonce, BigUInt.zero)
- XCTAssertEqual(pubAddress.metadata?.upgraded, false)
- XCTAssertEqual(pubAddress.metadata?.typeOfUser, UserType(rawValue: "v2"))
- }
-
- func testLoginWhenHashEnabled() async throws {
- let email = TORUS_TEST_EMAIL
- let token = try generateIdToken(email: email)
- let verifierParams = VerifierParams(verifier_id: email)
- let nodeDetails = try await get_fnd_and_tu_data(verifer: HashEnabledVerifier, veriferID: HashEnabledVerifier)
- let result = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeSSSEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(),
- verifier: HashEnabledVerifier, verifierParams: verifierParams, idToken: token)
- XCTAssertEqual(result.finalKeyData?.evmAddress, "0x8a7e297e20804786767B1918a5CFa11683e5a3BB")
- XCTAssertEqual(result.finalKeyData?.X, "7927d5281aea24fd93f41696f79c91370ec0097ff65e83e95691fffbde6d733a")
- XCTAssertEqual(result.finalKeyData?.Y, "f22735f0e72ff225274cf499d50b240b7571063e0584471b2b4dab337ad5d8da")
- XCTAssertEqual(result.finalKeyData?.privKey, "f161f63a84f1c935525ec0bda74bc5a15de6a9a7be28fad237ef6162df335fe6")
- XCTAssertEqual(result.oAuthKeyData?.evmAddress, "0xaEafa3Fc7349E897F8fCe981f55bbD249f12aC8C")
- XCTAssertEqual(result.oAuthKeyData?.X, "72d9172d7edc623266d6c625db91505e6b64a5524e6d7c7c0184b1bbdea1e986")
- XCTAssertEqual(result.oAuthKeyData?.Y, "8c26d557a0a9cb22dc2a30d36bf67de93a0eb6d4ef503a849c7de2d14dcbdaaa")
- XCTAssertEqual(result.oAuthKeyData?.privKey, "62e110d9d698979c1966d14b2759006cf13be7dfc86a63ff30812e2032163f2f")
- XCTAssertNotEqual(result.sessionData?.sessionTokenData.count, 0)
- XCTAssertNotEqual(result.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(result.metadata?.pubNonce?.x, "5712d789f7ecf3435dd9bf1136c2daaa634f0222d64e289d2abe30a729a6a22b")
- XCTAssertEqual(result.metadata?.pubNonce?.y, "2d2b4586fd5fd9d15c22f66b61bc475742754a8b96d1edb7b2590e4c4f97b3f0")
- XCTAssertEqual(result.metadata?.nonce?.serialize().toHexString(), "8e80e560ae59319938f7ef727ff2c5346caac1c7f5be96d3076e3342ad1d20b7")
- XCTAssertEqual(result.metadata?.typeOfUser, .v2)
- XCTAssertEqual(result.metadata?.upgraded, false)
- }
-
- func testAggregrateLoginWithEmail(email: String) async throws {
- let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
- let verifierID: String = email
- let jwt = try! generateIdToken(email: email)
- let hashedIDToken = keccak256Data(jwt.data(using: .utf8) ?? Data()).toHexString()
- let extraParams = ["verifier_id": email, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": email, "idtoken": jwt]]] as [String: Codable]
-
- let nodeManager = NodeDetailManager(network: .sapphire(.SAPPHIRE_DEVNET))
- let endpoint = try await nodeManager.getNodeDetails(verifier: HashEnabledVerifier, verifierID: verifierID)
-
- let verifierParams = VerifierParams(verifier_id: verifierID)
- let nodeDetails = try await get_fnd_and_tu_data(verifer: verifier, veriferID: verifierID)
-
- let data = try await torus.retrieveShares(endpoints: endpoint.torusNodeEndpoints, torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams)
-
- XCTAssertNotNil(data.finalKeyData?.evmAddress)
- XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
- XCTAssertNotNil(data.oAuthKeyData?.evmAddress)
- XCTAssertEqual(data.metadata?.typeOfUser == UserType.v2, true)
- XCTAssertNotNil(data.metadata?.nonce)
- XCTAssertEqual(data.metadata?.upgraded, false)
- }
-
- func testAggregateLoginWithFixedEmail() async throws {
- // This fixed email was previously known to trigger an edge case that
- // revealed a bug in our share decryption implementation.
- let email = "hEJTRg@gmail.com"
- try await testAggregrateLoginWithEmail(email: email)
- }
-
- /* TODO: Investigate further
- func testAggregateLoginWithRandomEmail() async throws {
- let email = generateRandomEmail(of: 6)
- try await testAggregrateLoginWithEmail(email: email)
- }
- */
-
-
- func testGating() async throws {
- let torus = TorusUtils(enableOneKey: true, network: .sapphire(.SAPPHIRE_MAINNET), clientId: "YOUR_CLIENT_ID")
- let token = try generateIdToken(email: TORUS_TEST_EMAIL)
-
- let verifierParams = VerifierParams(verifier_id: TORUS_TEST_EMAIL)
-
- let nodeDetails = try await get_fnd_and_tu_data(verifer: "w3a-auth0-demo", veriferID: TORUS_TEST_EMAIL)
-
- do {
- _ = try await torus.retrieveShares(
- endpoints: nodeDetails.getTorusNodeEndpoints(),
- torusNodePubs: nodeDetails.getTorusNodePub(),
- indexes: nodeDetails.getTorusIndexes(),
- verifier: "w3a-auth0-demo",
- verifierParams: verifierParams,
- idToken: token
- )
- XCTAssert(false, "Should not pass")
- } catch {
- XCTAssertEqual(error.localizedDescription.errorDescription!,"code: 1001, error: Invalid Web3Auth client id, obtain a client ID at https://dashboard.web3auth.io")
- }
-
- }
-
- func testencryption() async throws {
- let torus = TorusUtils(enableOneKey: true, network: .sapphire(.SAPPHIRE_MAINNET), clientId: "YOUR_CLIENT_ID")
-
- let pk = curveSecp256k1.SecretKey()
- let pk_str = try pk.serialize()
-
- let msg = "hello test data"
- let encryptData = try torus.encrypt(publicKey: pk.toPublic().serialize(compressed: false), msg: msg)
-
- let curveMsg = try Encryption.encrypt(pk: pk.toPublic(), plainText: msg.data(using: .utf8)!)
- let em = try EncryptedMessage(cipherText: encryptData.ciphertext, ephemeralPublicKey: PublicKey(hex: encryptData.ephemPublicKey) , iv: encryptData.iv, mac: encryptData.mac)
-
- let eciesData = ECIES(iv: encryptData.iv, ephemPublicKey: encryptData.ephemPublicKey, ciphertext: encryptData.ciphertext, mac: encryptData.mac)
- let emp = try curveMsg.ephemeralPublicKey().serialize(compressed: false);
- let eciesData2 = try ECIES(iv: curveMsg.iv(), ephemPublicKey: emp, ciphertext: curveMsg.chipherText(), mac: curveMsg.mac())
-
- _ = try torus.decrypt(privateKey: pk_str, opts: eciesData)
- _ = try torus.decrypt(privateKey: pk_str, opts: eciesData2)
-
- let result = try Encryption.decrypt(sk: pk, encrypted: em)
- let result2 = try Encryption.decrypt(sk: pk, encrypted: curveMsg)
-
- XCTAssertEqual(msg.data(using: .utf8)!, result)
- XCTAssertEqual(msg.data(using: .utf8)!, result2)
-
- }
-
-}
diff --git a/Tests/TorusUtilsTests/StubURLProtocolTest.swift b/Tests/TorusUtilsTests/StubURLProtocolTest.swift
deleted file mode 100644
index 4b48764f..00000000
--- a/Tests/TorusUtilsTests/StubURLProtocolTest.swift
+++ /dev/null
@@ -1,19 +0,0 @@
-import FetchNodeDetails
-import Foundation
-import OSLog
-import TorusUtils
-import XCTest
-
-final class StubURLProtocolTests: XCTestCase {}
-
-public class StubMockTorusUtils: TorusUtils {
- override open func getTimestamp() -> TimeInterval {
- let ret = 0.0
- print("[StubMockTorusUtils] getTimeStamp(): ", ret)
- return ret
- }
-}
-
-let endpoints = ["https://teal-15-1.torusnode.com/jrpc", "https://teal-15-3.torusnode.com/jrpc", "https://teal-15-4.torusnode.com/jrpc", "https://teal-15-5.torusnode.com/jrpc", "https://teal-15-2.torusnode.com/jrpc"]
-
-let nodePubKeys = [TorusNodePubModel(_X: "1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3", _Y: "d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"), TorusNodePubModel(_X: "7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d", _Y: "b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636"), TorusNodePubModel(_X: "8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f", _Y: "9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"), TorusNodePubModel(_X: "25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c", _Y: "f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249"), TorusNodePubModel(_X: "d908f41f8e06324a8a7abcf702adb6a273ce3ae63d86a3d22723e1bbf1438c9a", _Y: "f977530b3ec0e525438c72d1e768380cbc5fb3b38a760ee925053b2e169428ce")]
diff --git a/Tests/TorusUtilsTests/TestnetTest.swift b/Tests/TorusUtilsTests/TestnetTest.swift
index 003b5a88..9b1c9f9e 100644
--- a/Tests/TorusUtilsTests/TestnetTest.swift
+++ b/Tests/TorusUtilsTests/TestnetTest.swift
@@ -1,34 +1,31 @@
import BigInt
import FetchNodeDetails
import JWTKit
+import TorusUtils
import XCTest
-import CoreMedia
-@testable import TorusUtils
-
class TestnetTest: XCTestCase {
var TORUS_TEST_EMAIL = "archit1@tor.us"
var TORUS_TEST_VERIFIER = "torus-test-health"
var TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
var fnd: NodeDetailManager!
- var tu: TorusUtils!
+ var torus: TorusUtils!
override func setUp() {
super.setUp()
fnd = NodeDetailManager(network: .legacy(.TESTNET))
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .legacy(.TESTNET)))
}
- func getFNDAndTUData(verifer: String, veriferID: String, enableOneKey: Bool = false) async throws -> AllNodeDetailsModel {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- tu = TorusUtils(enableOneKey: enableOneKey, network: .legacy(.TESTNET), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
- }
+ func test_should_fetch_public_address() async throws {
+ let verifier = "google-lrc"
+ let verifierID = TORUS_TEST_EMAIL
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let val = try await torus.getPublicAddress(endpoints: nodeDetails.torusNodeEndpoints, verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
- func test_get_public_address() async throws {
- let verifier: String = "google-lrc"
- let verifierID: String = TORUS_TEST_EMAIL
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let val = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
XCTAssertEqual(val.finalKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506")
XCTAssertEqual(val.finalKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5")
XCTAssertEqual(val.finalKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438")
@@ -38,104 +35,138 @@ class TestnetTest: XCTestCase {
XCTAssertNil(val.metadata?.pubNonce)
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
- XCTAssertEqual(val.metadata?.typeOfUser, UserType(rawValue: "v1"))
+ XCTAssertEqual(val.metadata?.typeOfUser, .v1)
+ XCTAssertNotNil(val.nodesData)
}
- func test_getUserTypeAndAddress_testnet() async throws {
- let verifier: String = "google-lrc"
- let verifierID: String = TORUS_TEST_EMAIL
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let val = try await tu.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
+ func test_should_fetch_user_type_and_public_address() async throws {
+ var verifier: String = "google-lrc"
+ var verifierID: String = TORUS_TEST_EMAIL
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ var val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xf5804f608C233b9cdA5952E46EB86C9037fd6842")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x9bcBAde70546c0796c00323CD1b97fa0a425A506")
XCTAssertEqual(val.oAuthKeyData!.X, "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5")
XCTAssertEqual(val.oAuthKeyData!.Y, "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438")
- XCTAssertEqual(val.finalKeyData!.evmAddress, "0xf5804f608C233b9cdA5952E46EB86C9037fd6842")
XCTAssertEqual(val.finalKeyData!.X, "ed737569a557b50722a8b5c0e4e5ca30cef1ede2f5674a0616b78246bb93dfd0")
XCTAssertEqual(val.finalKeyData!.Y, "d9e8e6c54c12c4da38c2f0d1047fcf6089036127738f4ef72a83431339586ca9")
- XCTAssertEqual(val.metadata?.pubNonce?.x, "f3f7caefd6540d923c9993113f34226371bd6714a5be6882dedc95a6a929a8")
- XCTAssertEqual(val.metadata?.pubNonce?.y, "f28620603601ce54fa0d70fd691fb72ff52f5bf164bf1a91617922eaad8cc7a5")
+ XCTAssertEqual(val.metadata!.pubNonce!.x, "f3f7caefd6540d923c9993113f34226371bd6714a5be6882dedc95a6a929a8")
+ XCTAssertEqual(val.metadata!.pubNonce!.y, "f28620603601ce54fa0d70fd691fb72ff52f5bf164bf1a91617922eaad8cc7a5")
XCTAssertEqual(val.metadata?.nonce, 0)
XCTAssertEqual(val.metadata?.upgraded, false)
XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+
+ verifier = "tkey-google-lrc"
+ verifierID = "somev2user@gmail.com"
+ val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0x376597141d8d219553378313d18590F373B09795")
+ XCTAssertEqual(val.oAuthKeyData!.X, "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D")
+ XCTAssertEqual(val.finalKeyData!.X, "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e")
+ XCTAssertEqual(val.finalKeyData!.Y, "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "ad121b67fa550da814bbbd54ec7070705d058c941e04c03e07967b07b2f90345")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "bfe2395b177a72ebb836aaf24cedff2f14cd9ed49047990f5cdb99e4981b5753")
+ XCTAssertEqual(val.metadata?.nonce, 0)
+ XCTAssertEqual(val.metadata?.upgraded, false)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
+
+ verifier = "tkey-google-lrc"
+ verifierID = "caspertorus@gmail.com"
+ val = try await torus.getUserTypeAndAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456")
+ XCTAssertLessThan(val.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(val.oAuthKeyData!.evmAddress, "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544")
+ XCTAssertEqual(val.oAuthKeyData!.X, "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8")
+ XCTAssertEqual(val.oAuthKeyData!.Y, "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5")
+ XCTAssertEqual(val.finalKeyData!.evmAddress, "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456")
+ XCTAssertEqual(val.finalKeyData!.X, "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7")
+ XCTAssertEqual(val.finalKeyData!.Y, "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222")
+ XCTAssertEqual(val.metadata?.pubNonce?.x, "4f86b0e69992d1551f1b16ceb0909453dbe17b9422b030ee6c5471c2e16b65d0")
+ XCTAssertEqual(val.metadata?.pubNonce?.y, "640384f3d39debb04c4e9fe5a5ec6a1b494b0ad66d00ac9be6f166f21d116ca4")
+ XCTAssertEqual(val.metadata?.nonce, 0)
+ XCTAssertEqual(val.metadata?.upgraded, true)
+ XCTAssertEqual(val.metadata?.typeOfUser, .v2)
+ XCTAssertNotNil(val.nodesData)
}
- /* TODO: Investigate further
- func test_key_assign_testnet() async throws {
+ func test_should_be_able_to_key_assign() async throws {
let fakeEmail = generateRandomEmail(of: 6)
let verifier: String = "google-lrc"
let verifierID: String = fakeEmail
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertNotNil(data.finalKeyData)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
XCTAssertEqual(data.metadata?.typeOfUser, .v1)
+ XCTAssertEqual(data.metadata?.upgraded, false)
}
- */
- func test_login_testnet() async throws {
+ func test_should_be_able_to_login() async throws {
let verifier: String = TORUS_TEST_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
- let verifierParams = VerifierParams(verifier_id: verifierID)
let jwt = try! generateIdToken(email: verifierID)
- let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
-
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6")
- XCTAssertEqual(data.finalKeyData?.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd")
- XCTAssertEqual(data.finalKeyData?.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9")
- XCTAssertEqual(data.finalKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6")
- XCTAssertEqual(data.oAuthKeyData?.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd")
- XCTAssertEqual(data.oAuthKeyData?.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce, nil)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser, .v1)
- XCTAssertEqual(data.metadata?.upgraded, nil)
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6")
+ XCTAssertEqual(data.oAuthKeyData.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd")
+ XCTAssertEqual(data.oAuthKeyData.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3")
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6")
+ XCTAssertEqual(data.finalKeyData.X, "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd")
+ XCTAssertEqual(data.finalKeyData.Y, "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9")
+ XCTAssertEqual(data.finalKeyData.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
- func test_aggregate_login_testnet() async throws {
+ func test_should_be_able_to_aggregate_login() async throws {
let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
- let verifierParams = VerifierParams(verifier_id: verifierID)
let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
- let hashedIDToken = keccak256Data(jwt.data(using: .utf8) ?? Data() ).toHexString()
- let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965")
- XCTAssertEqual(data.finalKeyData?.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95")
- XCTAssertEqual(data.finalKeyData?.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6")
- XCTAssertEqual(data.finalKeyData?.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965")
- XCTAssertEqual(data.oAuthKeyData?.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95")
- XCTAssertEqual(data.oAuthKeyData?.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6")
- XCTAssertEqual(data.oAuthKeyData?.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1")
- XCTAssertEqual(data.sessionData?.sessionTokenData.count, 0)
- XCTAssertEqual(data.sessionData?.sessionAuthKey, "")
- XCTAssertEqual(data.metadata?.pubNonce, nil)
- XCTAssertEqual(data.metadata?.nonce, BigUInt(0))
- XCTAssertEqual(data.metadata?.typeOfUser, .v1)
- XCTAssertEqual(data.metadata?.upgraded, nil)
- }
-}
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
-extension TestnetTest {
- func test_retrieveShares_some_nodes_down() async throws {
- let verifier: String = TORUS_TEST_VERIFIER
- let verifierID: String = TORUS_TEST_EMAIL
- let verifierParams = VerifierParams(verifier_id: verifierID)
- let jwt = try! generateIdToken(email: verifierID)
- let extraParams = ["verifieridentifier": verifier, "verifier_id": verifierID] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- var endpoints = nodeDetails.getTorusNodeEndpoints()
- endpoints[0] = "https://ndjnfjbfrj/random"
- // should fail if un-commented threshold 4/5
- // endpoints[1] = "https://ndjnfjbfrj/random"
- let data = try await tu.retrieveShares(endpoints: endpoints, torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.privKey, "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3")
+ let verifierParams = VerifierParams(verifier_id: verifierID,
+ sub_verifier_ids: [TORUS_TEST_VERIFIER],
+ verify_params: [VerifyParams(verifier_id: verifierID, idtoken: jwt)])
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.torusNodeEndpoints, verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965")
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965")
+ XCTAssertEqual(data.oAuthKeyData.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95")
+ XCTAssertEqual(data.oAuthKeyData.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1")
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x938a40E155d118BD31E439A9d92D67bd55317965")
+ XCTAssertEqual(data.finalKeyData.X, "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95")
+ XCTAssertEqual(data.finalKeyData.Y, "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6")
+ XCTAssertEqual(data.finalKeyData.privKey, "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1")
+ XCTAssertNotNil(data.sessionData)
+ XCTAssertNil(data.metadata.pubNonce)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.typeOfUser, .v1)
+ XCTAssertNil(data.metadata.upgraded)
+ XCTAssertNotNil(data.nodesData)
}
}
diff --git a/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift b/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift
deleted file mode 100644
index 3dccf9cf..00000000
--- a/Tests/TorusUtilsTests/Utils/MockTorusUtils.swift
+++ /dev/null
@@ -1,41 +0,0 @@
-import BigInt
-import FetchNodeDetails
-import Foundation
-import TorusUtils
-
-class MockTorusUtils: AbstractTorusUtils {
- func retrieveShares(endpoints: [String], torusNodePubs: [TorusNodePubModel], indexes: [BigUInt], verifier: String, verifierParams: VerifierParams, idToken: String, extraParams: [String: Codable]) async throws -> TorusKey {
- return TorusKey(finalKeyData: nil, oAuthKeyData: nil, sessionData: nil, metadata: nil, nodesData: nil)
- }
-
- func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, extendedVerifierId: String?) async throws -> TorusPublicKey {
-// GetPublicAddressResult(address: "")
- return TorusPublicKey(finalKeyData: nil, oAuthKeyData: nil, metadata: nil, nodesData: nil)
- }
-
- var nodePubKeys: [TorusNodePubModel]
-
- init() {
- nodePubKeys = []
- }
-
- func setTorusNodePubKeys(nodePubKeys: [TorusNodePubModel]) {
- self.nodePubKeys = nodePubKeys
- }
-
- func retrieveShares(torusNodePubs: [TorusNodePubModel], endpoints: [String], verifier: String, verifierId: String, idToken: String, extraParams: Data) async throws -> RetrieveSharesResponseModel {
- return .init(publicKey: "", privateKey: "")
- }
-
- func getPublicAddress(endpoints: [String], torusNodePubs: [TorusNodePubModel], verifier: String, verifierId: String, isExtended: Bool) async throws -> GetPublicAddressResult {
- return .init(address: "")
- }
-
- func getUserTypeAndAddress(endpoints: [String], torusNodePub: [TorusNodePubModel], verifier: String, verifierID: String, doesKeyAssign: Bool) async throws -> GetUserAndAddress {
- return .init(typeOfUser: .v1, address: "", x: "", y: "")
- }
-
- func getOrSetNonce(x: String, y: String, privateKey: String?, getOnly: Bool) async throws -> GetOrSetNonceResult {
- return GetOrSetNonceResult(typeOfUser: "v1")
- }
-}
diff --git a/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift b/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift
deleted file mode 100644
index 13204c0a..00000000
--- a/Tests/TorusUtilsTests/Utils/StubURLProtocol.swift
+++ /dev/null
@@ -1,518 +0,0 @@
-import Foundation
-
-private func mustDecodeJSON(_ s: String) -> [String: Any] {
- return try! JSONSerialization.jsonObject(with: Data(s.utf8), options: []) as! [String: Any]
-}
-
-private func httpBodyStreamToData(stream: InputStream?) -> Data? {
- guard let bodyStream = stream else { return nil }
- bodyStream.open()
-
- // Will read 16 chars per iteration. Can use bigger buffer if needed
- let bufferSize: Int = 16
-
- let buffer = UnsafeMutablePointer.allocate(capacity: bufferSize)
-
- var dat = Data()
-
- while bodyStream.hasBytesAvailable {
- let readDat = bodyStream.read(buffer, maxLength: bufferSize)
- dat.append(buffer, count: readDat)
- }
-
- buffer.deallocate()
-
- bodyStream.close()
-
- return dat
-}
-
-private func stubMatcher(host: String, scheme: String, path: String, method: String, requestHeaders: [String: String]) -> (URLRequest) -> Bool {
- return { (req: URLRequest) -> Bool in
- if req.url?.host != host || req.url?.scheme != scheme || req.url?.path != path || req.httpMethod != method {
- return false
- }
- for (name, value) in requestHeaders {
- if req.value(forHTTPHeaderField: name) != value {
- return false
- }
- }
- return true
- }
-}
-
-private func stubMatcherWithBody(host: String, scheme: String, path: String, method: String, requestHeaders: [String: String], body: [String: Any]) -> (URLRequest) -> Bool {
- return { (req: URLRequest) -> Bool in
- if !stubMatcher(host: host, scheme: scheme, path: path, method: method, requestHeaders: requestHeaders)(req) {
- return false
- }
- guard
- let bodyData = StubURLProtocol.property(forKey: httpBodyKey, in: req) as? Data,
- let jsonBody = (try? JSONSerialization.jsonObject(with: bodyData, options: [])) as? [String: Any]
- else {
- return false
- }
- return NSDictionary(dictionary: jsonBody).isEqual(to: body)
- }
-}
-
-private let injectedURLs: Set = [
- URL(string: "https://www.googleapis.com/userinfo/v2/me"),
- URL(string: "https://ropsten.infura.io/v3/b8cdb0e4cff24599a286bf8e87ff1c96"),
- URL(string: "https://teal-15-4.torusnode.com/jrpc"),
- URL(string: "https://teal-15-2.torusnode.com/jrpc"),
- URL(string: "https://teal-15-1.torusnode.com/jrpc"),
- URL(string: "https://teal-15-3.torusnode.com/jrpc"),
- URL(string: "https://teal-15-5.torusnode.com/jrpc"),
- URL(string: "https://metadata.tor.us/get"),
- URL(string: "https://signer.tor.us/api/allow"),
-]
-
-private let httpBodyKey = "StubURLProtocolHTTPBody"
-
-private struct Stub {
- let requestMatcher: (URLRequest) -> Bool
- let responseBody: Data?
- let statusCode: Int
- let responseHeaders: [String: String]
-}
-
-public class StubURLProtocol: URLProtocol {
- private static let terminateUnknownRequest = true
-
- private static let stubs = injectedStubs
-
- private static let urls = injectedURLs
-
- // Match and return
- private class func matchStub(req: URLRequest) -> Stub? {
- var inputReq: URLRequest
- if let httpBodyData = httpBodyStreamToData(stream: req.httpBodyStream) {
- let mutableReq = (req as NSURLRequest).mutableCopy() as! NSMutableURLRequest
- setProperty(httpBodyData, forKey: httpBodyKey, in: mutableReq)
- inputReq = mutableReq as URLRequest
- } else {
- inputReq = req
- }
- for stub in stubs {
- if stub.requestMatcher(inputReq) {
- return stub
- }
- }
- return nil
- }
-
- // To check if this protocol can handle the given request.
- override public class func canInit(with request: URLRequest) -> Bool {
- var cleanURL: URL? {
- var comp = URLComponents()
- comp.scheme = request.url?.scheme
- comp.host = request.url?.host
- comp.path = request.url?.path ?? "/"
- return comp.url
- }
- if urls.contains(cleanURL) {
- return true
- }
- return terminateUnknownRequest
- }
-
- override public class func canonicalRequest(for request: URLRequest) -> URLRequest {
- return request
- }
-
- // This is where you create the mock response as per your test case and send it to the URLProtocolClient.
- override public func startLoading() {
- guard let url = request.url else {
- fatalError("Request has no URL")
- }
- var cleanURL: URL? {
- var comp = URLComponents()
- comp.scheme = url.scheme
- comp.host = url.host
- comp.path = url.path
- return comp.url
- }
- if !StubURLProtocol.urls.contains(cleanURL) {
- fatalError("URL not mocked, inconsistent injectedURLs: \(url.absoluteString)")
- }
- if let stub = StubURLProtocol.matchStub(req: request) {
- let res = HTTPURLResponse(url: url, statusCode: stub.statusCode, httpVersion: nil, headerFields: stub.responseHeaders)!
- client?.urlProtocol(self, didReceive: res, cacheStoragePolicy: .notAllowed)
- if let d = stub.responseBody {
- client?.urlProtocol(self, didLoad: d)
- }
- } else {
- fatalError("URL not mocked: \(url.absoluteString)")
- }
- client?.urlProtocolDidFinishLoading(self)
- }
-
- // This is called if the request gets canceled or completed.
- override public func stopLoading() {
- }
-}
-
-private let injectedStubs: [Stub] = [
- Stub(
- requestMatcher: stubMatcher(
- host: "www.googleapis.com",
- scheme: "https",
- path: "/userinfo/v2/me",
- method: "GET",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Authorization":"Bearer ya29.a0ARrdaM96u3PfVhg9xbkCPuecmF6YaylxRcJwKJTlHY8kwwuSyKbqme2qBbTdLoVORMZy4n8Al5Wr1HCnfjCesU38W1xkSgFNoPhRgTen6Zqxyr_tOddJw6-TUUbe45z6Zvkbx8DzBHShQkm-KbbNzh_M00kh","Accept":"application/json"}"#) as! [String: String]
- ),
- responseBody: Data(#"{"id":"109111953856031799639","email":"michael@tor.us","verified_email":true,"name":"Michael Lee","given_name":"Michael","family_name":"Lee","picture":"https://lh3.googleusercontent.com/a/AATXAJwsBb98gSYjVNlBBAhXJjvqNOw2GDSeTf0I6SJh=s96-c","locale":"en","hd":"tor.us"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Date":"Sun, 17 Oct 2021 10:57:29 GMT","x-frame-options":"SAMEORIGIN","Pragma":"no-cache","x-xss-protection":"0","Content-Encoding":"gzip","Server":"ESF","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","Vary":"Origin, X-Origin, Referer","Alt-Svc":"h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"","x-content-type-options":"nosniff","Content-Length":"234","Content-Type":"application/json; charset=UTF-8","Expires":"Mon, 01 Jan 1990 00:00:00 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0x76671808"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000000f"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Accept-Encoding, Origin","Date":"Sun, 17 Oct 2021 10:57:30 GMT","Content-Length":"102","Content-Type":"application/json"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0x135022c2000000000000000000000000000000000000000000000000000000000000000f"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000005000000000000000000000000455d2ba3f20fa83b9f824e665dd201d908c79dce000000000000000000000000b452bbd6f4d52d87f33336aad921538bf8dfdf67000000000000000000000000e3c0493536f20d090c8f9427d8fdfe548af3266200000000000000000000000054ac312ed9ba51cdd65f182487f29a3999dbf4e200000000000000000000000057f7a525608dc540fefc3e851700a4189d19142d"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Content-Length":"870","Vary":"Accept-Encoding, Origin","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:31 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0xbafb358100000000000000000000000054ac312ed9ba51cdd65f182487f29a3999dbf4e2"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000425a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9cf63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb695824900000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001b7465616c2d31352d352e746f7275736e6f64652e636f6d3a343433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Date":"Sun, 17 Oct 2021 10:57:31 GMT","Content-Type":"application/json","Content-Length":"678","Vary":"Accept-Encoding, Origin"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0xbafb3581000000000000000000000000455d2ba3f20fa83b9f824e665dd201d908c79dce"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000011363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001b7465616c2d31352d312e746f7275736e6f64652e636f6d3a343433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Accept-Encoding, Origin","Date":"Sun, 17 Oct 2021 10:57:31 GMT","Content-Length":"678","Content-Type":"application/json"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0xbafb3581000000000000000000000000b452bbd6f4d52d87f33336aad921538bf8dfdf67"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000027c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029db359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d53963600000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001b7465616c2d31352d332e746f7275736e6f64652e636f6d3a343433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Date":"Sun, 17 Oct 2021 10:57:31 GMT","Vary":"Accept-Encoding, Origin","Content-Type":"application/json","Content-Length":"678"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0xbafb358100000000000000000000000057f7a525608dc540fefc3e851700a4189d19142d"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000005d908f41f8e06324a8a7abcf702adb6a273ce3ae63d86a3d22723e1bbf1438c9af977530b3ec0e525438c72d1e768380cbc5fb3b38a760ee925053b2e169428ce00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001b7465616c2d31352d322e746f7275736e6f64652e636f6d3a343433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Accept-Encoding, Origin","Content-Length":"678","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:31 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "ropsten.infura.io",
- scheme: "https",
- path: "/v3/b8cdb0e4cff24599a286bf8e87ff1c96",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"eth_call","id":1,"params":[{"to":"0x4023d2a0d330bf11426b12c6144cfb96b7fa6183","data":"0xbafb3581000000000000000000000000e3c0493536f20d090c8f9427d8fdfe548af32662"},"latest"]}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000038a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da70189100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001b7465616c2d31352d342e746f7275736e6f64652e636f6d3a343433000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Date":"Sun, 17 Oct 2021 10:57:31 GMT","Content-Length":"678","Content-Type":"application/json","Vary":"Accept-Encoding, Origin"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-4.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"VerifierLookupRequest","id":10,"params":{"verifier":"torus-direct-mock-ios","verifier_id":"michael@tor.us"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"key_index":"1c724","pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64","address":"0x22f2Ce611cE0d0ff4DA661d3a4C4B7A60B2b13F8"}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Server":"nginx/1.19.9","Content-Length":"281","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-2.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"VerifierLookupRequest","id":10,"params":{"verifier":"torus-direct-mock-ios","verifier_id":"michael@tor.us"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"key_index":"1c724","pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64","address":"0x22f2Ce611cE0d0ff4DA661d3a4C4B7A60B2b13F8"}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Server":"nginx/1.19.9","Content-Length":"281","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-1.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"VerifierLookupRequest","id":10,"params":{"verifier":"torus-direct-mock-ios","verifier_id":"michael@tor.us"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"key_index":"1c724","pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64","address":"0x22f2Ce611cE0d0ff4DA661d3a4C4B7A60B2b13F8"}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Content-Length":"281","Vary":"Origin","Content-Type":"application/json","Server":"nginx/1.19.9","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-3.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"VerifierLookupRequest","id":10,"params":{"verifier":"torus-direct-mock-ios","verifier_id":"michael@tor.us"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"key_index":"1c724","pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64","address":"0x22f2Ce611cE0d0ff4DA661d3a4C4B7A60B2b13F8"}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Date":"Sun, 17 Oct 2021 10:57:32 GMT","Content-Length":"281","Content-Type":"application/json","Server":"nginx/1.19.9","Vary":"Origin"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcher(
- host: "signer.tor.us",
- scheme: "https",
- path: "/api/allow",
- method: "GET",
- requestHeaders: mustDecodeJSON(#"{"Origin":"torus-direct-mock-ios","Accept":"application/json","Content-Type":"application/json","x-api-key":"torus-default"}"#) as! [String: String]
- ),
- responseBody: Data(#"{"success":true}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Content-Length":"16","access-control-allow-headers":"pubkeyx,pubkeyy,x-api-key,x-embed-host,content-type,authorization,verifier,verifier_id","access-control-max-age":"86400","access-control-allow-methods":"GET,OPTIONS","Access-Control-Allow-Origin":"*","Date":"Sun, 17 Oct 2021 10:57:32 GMT","Content-Type":"application/json"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-5.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"VerifierLookupRequest","id":10,"params":{"verifier":"torus-direct-mock-ios","verifier_id":"michael@tor.us"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"key_index":"1c724","pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64","address":"0x22f2Ce611cE0d0ff4DA661d3a4C4B7A60B2b13F8"}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Content-Length":"281","Server":"nginx/1.19.9","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "metadata.tor.us",
- scheme: "https",
- path: "/get",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"}"#)
- ),
- responseBody: Data(#"{"message":""}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"x-download-options":"noopen","x-permitted-cross-domain-policies":"none","x-content-type-options":"nosniff","Strict-Transport-Security":"max-age=15552000; includeSubDomains","x-dns-prefetch-control":"off","x-xss-protection":"0","content-security-policy":"default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests","x-frame-options":"SAMEORIGIN","referrer-policy":"no-referrer","Date":"Sun, 17 Oct 2021 10:57:32 GMT","Content-Type":"application/json; charset=utf-8","expect-ct":"max-age=0","Etag":"W/\"e-JWOqSwGs6lhRJiUZe/mVb6Mua74\"","Content-Length":"14","Vary":"Origin, Accept-Encoding"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-1.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"CommitmentRequest","id":10,"params":{"messageprefix":"mug00","temppuby":"03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e","temppubx":"3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025","tokencommitment":"f9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b","timestamp":"0","verifieridentifier":"torus-direct-mock-ios"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"signature":"f94f88b5a2fff06463fe0cb4569a652a11f351061dcd5b15e466274e374eb2992632153bda0c017d9c83916b82f1daa3ee5ac9990201d73a18915224a828b6a41b","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepubx":"1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3","nodepuby":"d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Server":"nginx/1.19.9","Content-Type":"application/json","Vary":"Origin","Date":"Sun, 17 Oct 2021 10:57:32 GMT","Content-Length":"606"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-3.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"CommitmentRequest","id":10,"params":{"messageprefix":"mug00","temppuby":"03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e","temppubx":"3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025","tokencommitment":"f9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b","timestamp":"0","verifieridentifier":"torus-direct-mock-ios"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"signature":"ee5b3560bc5b394326ddb784970eb27c995b77ceac9ce04ddffe72a52542dffd7b90b30c50b69481b43f04a0373b632798bac8fcdf8d695ead606200e0a24fc41c","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepubx":"7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d","nodepuby":"b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636"},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Server":"nginx/1.19.9","Content-Type":"application/json","Vary":"Origin","Date":"Sun, 17 Oct 2021 10:57:32 GMT","Content-Length":"606"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-4.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"CommitmentRequest","id":10,"params":{"messageprefix":"mug00","temppuby":"03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e","temppubx":"3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025","tokencommitment":"f9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b","timestamp":"0","verifieridentifier":"torus-direct-mock-ios"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"signature":"739487dab15bc238d32db83faf7b0aeb57f6863ac079aa331605eee9e076567c5cfa588978128af9d2c160d92a30197ccec8ab8c24ea68a3ac540a2534f65e261c","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepubx":"8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f","nodepuby":"9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Server":"nginx/1.19.9","Content-Length":"606","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-5.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"CommitmentRequest","id":10,"params":{"messageprefix":"mug00","temppuby":"03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e","temppubx":"3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025","tokencommitment":"f9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b","timestamp":"0","verifieridentifier":"torus-direct-mock-ios"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"signature":"d24ccf58546df41bc8506b467e017ec64d941feb442a02001bea1c014dbe4d6b01317473884284d038ea116e6040ab25dad9901ee94d41dd33674cd105bc32151b","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepubx":"25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c","nodepuby":"f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249"},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Server":"nginx/1.19.9","Content-Length":"606","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-2.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"jsonrpc":"2.0","method":"CommitmentRequest","id":10,"params":{"messageprefix":"mug00","temppuby":"03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e","temppubx":"3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025","tokencommitment":"f9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b","timestamp":"0","verifieridentifier":"torus-direct-mock-ios"}}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"signature":"ed5d0191d91c02b427d6482cec5d5380026218a1adecfefd6f892903577abb5d43f303302b1eac90b7d225beeb66c8c9ed9ebde8ccfe5994b3fb5f028cf571411c","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepubx":"d908f41f8e06324a8a7abcf702adb6a273ce3ae63d86a3d22723e1bbf1438c9a","nodepuby":"f977530b3ec0e525438c72d1e768380cbc5fb3b38a760ee925053b2e169428ce"},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Server":"nginx/1.19.9","Content-Length":"606","Content-Type":"application/json","Vary":"Origin","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-3.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"params":{"encrypted":"yes","item":[{"verifieridentifier":"torus-direct-mock-ios","nodesignatures":[{"signature":"f94f88b5a2fff06463fe0cb4569a652a11f351061dcd5b15e466274e374eb2992632153bda0c017d9c83916b82f1daa3ee5ac9990201d73a18915224a828b6a41b","nodepubx":"1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"},{"nodepubx":"7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d","nodepuby":"b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"ee5b3560bc5b394326ddb784970eb27c995b77ceac9ce04ddffe72a52542dffd7b90b30c50b69481b43f04a0373b632798bac8fcdf8d695ead606200e0a24fc41c"},{"signature":"739487dab15bc238d32db83faf7b0aeb57f6863ac079aa331605eee9e076567c5cfa588978128af9d2c160d92a30197ccec8ab8c24ea68a3ac540a2534f65e261c","nodepubx":"8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"},{"data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"d24ccf58546df41bc8506b467e017ec64d941feb442a02001bea1c014dbe4d6b01317473884284d038ea116e6040ab25dad9901ee94d41dd33674cd105bc32151b","nodepuby":"f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249","nodepubx":"25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c"}],"verifier_id":"michael@tor.us","idtoken":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImFkZDhjMGVlNjIzOTU0NGFmNTNmOTM3MTJhNTdiMmUyNmY5NDMzNTIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDkxMTE5NTM4NTYwMzE3OTk2MzkiLCJoZCI6InRvci51cyIsImVtYWlsIjoibWljaGFlbEB0b3IudXMiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InRUNDhSck1vdGFFbi1UN3dzc2U3QnciLCJub25jZSI6InZSU2tPZWwyQTkiLCJuYW1lIjoiTWljaGFlbCBMZWUiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUFUWEFKd3NCYjk4Z1NZalZObEJCQWhYSmp2cU5PdzJHRFNlVGYwSTZTSmg9czk2LWMiLCJnaXZlbl9uYW1lIjoiTWljaGFlbCIsImZhbWlseV9uYW1lIjoiTGVlIiwibG9jYWxlIjoiZW4iLCJpYXQiOjE2MzQ0NjgyNDksImV4cCI6MTYzNDQ3MTg0OX0.XGu1tm_OqlSrc5BMDMzOrlhxLZo1YnpCUT0_j2U1mQt86nJzf_Hp85JfapZj2QeeUz91H6-Ei8FR1i4ICEfjMcoZOW1Azc89qUNfUgWeyjqZ7wCHSsbHAwabE74RFAS9YAja8_ynUvCARfDEtoqcreNgmbw3ZntzAqpuuNBXYfbr87kMvu_wZ7fWjLKM91CvuXytQBwtieTyjAFnTXmEL60Pdu-JSQfHCbS5H39ZHlnYxEO6qztIjvbnQokhjHDGc4PMCx0wfzrEet1ojNOCnbfmaYE5NQudquzQNZtqZfn8f4B-sQhECElnOXagHlafWO5RayS0dCb1mTfr8orcCA"}]},"id":10,"method":"ShareRequest","jsonrpc":"2.0"}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"Index":"1c724","PublicKey":{"X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"},"Threshold":1,"Verifiers":{"torus-direct-mock-ios":["michael@tor.us"]},"Share":"NGNmMDY4M2M0ZjVlMzAzZTE1YWE0YWU3NDQwZjJiNWQ2ZWVkN2U2MjcxZGQ3MjVjMTA2OGY5Njk3MTM0ODRmNmFmYjQwNjhhYjkyMGM3MTY0MWFjNWZjYTBiMGVhMTQw","Metadata":{"iv":"95d1859aa5f86d87f13ed672d12e2d10","ephemPublicKey":"0403aa155f2605555d7399378e71146420e8d4eac9fd911ee57134da846f0e1e60702397386f0ec1226c2e7616283739922d9b654570bce4fd775021ee7bfb6451","mac":"aabadefa3f0d1d7530425595e2b54faaafb9ee3e3ff7c8ad14f8f8572095ba4e","mode":"AES256"}}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Content-Length":"722","Date":"Sun, 17 Oct 2021 10:57:32 GMT","Content-Type":"application/json","Server":"nginx/1.19.9"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-1.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Content-Type":"application/json","Accept":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"params":{"encrypted":"yes","item":[{"verifieridentifier":"torus-direct-mock-ios","nodesignatures":[{"signature":"f94f88b5a2fff06463fe0cb4569a652a11f351061dcd5b15e466274e374eb2992632153bda0c017d9c83916b82f1daa3ee5ac9990201d73a18915224a828b6a41b","nodepubx":"1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"},{"nodepubx":"7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d","nodepuby":"b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"ee5b3560bc5b394326ddb784970eb27c995b77ceac9ce04ddffe72a52542dffd7b90b30c50b69481b43f04a0373b632798bac8fcdf8d695ead606200e0a24fc41c"},{"signature":"739487dab15bc238d32db83faf7b0aeb57f6863ac079aa331605eee9e076567c5cfa588978128af9d2c160d92a30197ccec8ab8c24ea68a3ac540a2534f65e261c","nodepubx":"8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"},{"data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"d24ccf58546df41bc8506b467e017ec64d941feb442a02001bea1c014dbe4d6b01317473884284d038ea116e6040ab25dad9901ee94d41dd33674cd105bc32151b","nodepuby":"f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249","nodepubx":"25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c"}],"verifier_id":"michael@tor.us","idtoken":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImFkZDhjMGVlNjIzOTU0NGFmNTNmOTM3MTJhNTdiMmUyNmY5NDMzNTIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDkxMTE5NTM4NTYwMzE3OTk2MzkiLCJoZCI6InRvci51cyIsImVtYWlsIjoibWljaGFlbEB0b3IudXMiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InRUNDhSck1vdGFFbi1UN3dzc2U3QnciLCJub25jZSI6InZSU2tPZWwyQTkiLCJuYW1lIjoiTWljaGFlbCBMZWUiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUFUWEFKd3NCYjk4Z1NZalZObEJCQWhYSmp2cU5PdzJHRFNlVGYwSTZTSmg9czk2LWMiLCJnaXZlbl9uYW1lIjoiTWljaGFlbCIsImZhbWlseV9uYW1lIjoiTGVlIiwibG9jYWxlIjoiZW4iLCJpYXQiOjE2MzQ0NjgyNDksImV4cCI6MTYzNDQ3MTg0OX0.XGu1tm_OqlSrc5BMDMzOrlhxLZo1YnpCUT0_j2U1mQt86nJzf_Hp85JfapZj2QeeUz91H6-Ei8FR1i4ICEfjMcoZOW1Azc89qUNfUgWeyjqZ7wCHSsbHAwabE74RFAS9YAja8_ynUvCARfDEtoqcreNgmbw3ZntzAqpuuNBXYfbr87kMvu_wZ7fWjLKM91CvuXytQBwtieTyjAFnTXmEL60Pdu-JSQfHCbS5H39ZHlnYxEO6qztIjvbnQokhjHDGc4PMCx0wfzrEet1ojNOCnbfmaYE5NQudquzQNZtqZfn8f4B-sQhECElnOXagHlafWO5RayS0dCb1mTfr8orcCA"}]},"id":10,"method":"ShareRequest","jsonrpc":"2.0"}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"Index":"1c724","PublicKey":{"X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"},"Threshold":1,"Verifiers":{"torus-direct-mock-ios":["michael@tor.us"]},"Share":"ZjBjNTEyNDI1MTBmOThiMGJjNDhhZjdhOTgwZjNkYTM0YjhmYmVkYzRjZTA2NzI1ZmI4MDExYWQ1MTc3YTUwNzFkYjNmNDNhYzA2NGNjYjkzYWIxYjY0YWZkY2I2NzMy","Metadata":{"iv":"e72d1cbaef1868cfbe241c3a84bb0a26","ephemPublicKey":"048b20e455385773ea58f59b0da8bde5cbe07f46155f6793fb120cd0fac8113ecf31adfcf5c07a8457d0973b93902c59fd156496ccf3746b9d44ce3de671360109","mac":"d9e7d9b565dc815a4969928296630bbc8102f080d3bcabb8f91df08f6cdb3f74","mode":"AES256"}}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Server":"nginx/1.19.9","Content-Length":"722","Vary":"Origin","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-5.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"params":{"encrypted":"yes","item":[{"verifieridentifier":"torus-direct-mock-ios","nodesignatures":[{"signature":"f94f88b5a2fff06463fe0cb4569a652a11f351061dcd5b15e466274e374eb2992632153bda0c017d9c83916b82f1daa3ee5ac9990201d73a18915224a828b6a41b","nodepubx":"1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"},{"nodepubx":"7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d","nodepuby":"b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"ee5b3560bc5b394326ddb784970eb27c995b77ceac9ce04ddffe72a52542dffd7b90b30c50b69481b43f04a0373b632798bac8fcdf8d695ead606200e0a24fc41c"},{"signature":"739487dab15bc238d32db83faf7b0aeb57f6863ac079aa331605eee9e076567c5cfa588978128af9d2c160d92a30197ccec8ab8c24ea68a3ac540a2534f65e261c","nodepubx":"8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"},{"data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"d24ccf58546df41bc8506b467e017ec64d941feb442a02001bea1c014dbe4d6b01317473884284d038ea116e6040ab25dad9901ee94d41dd33674cd105bc32151b","nodepuby":"f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249","nodepubx":"25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c"}],"verifier_id":"michael@tor.us","idtoken":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImFkZDhjMGVlNjIzOTU0NGFmNTNmOTM3MTJhNTdiMmUyNmY5NDMzNTIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDkxMTE5NTM4NTYwMzE3OTk2MzkiLCJoZCI6InRvci51cyIsImVtYWlsIjoibWljaGFlbEB0b3IudXMiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InRUNDhSck1vdGFFbi1UN3dzc2U3QnciLCJub25jZSI6InZSU2tPZWwyQTkiLCJuYW1lIjoiTWljaGFlbCBMZWUiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUFUWEFKd3NCYjk4Z1NZalZObEJCQWhYSmp2cU5PdzJHRFNlVGYwSTZTSmg9czk2LWMiLCJnaXZlbl9uYW1lIjoiTWljaGFlbCIsImZhbWlseV9uYW1lIjoiTGVlIiwibG9jYWxlIjoiZW4iLCJpYXQiOjE2MzQ0NjgyNDksImV4cCI6MTYzNDQ3MTg0OX0.XGu1tm_OqlSrc5BMDMzOrlhxLZo1YnpCUT0_j2U1mQt86nJzf_Hp85JfapZj2QeeUz91H6-Ei8FR1i4ICEfjMcoZOW1Azc89qUNfUgWeyjqZ7wCHSsbHAwabE74RFAS9YAja8_ynUvCARfDEtoqcreNgmbw3ZntzAqpuuNBXYfbr87kMvu_wZ7fWjLKM91CvuXytQBwtieTyjAFnTXmEL60Pdu-JSQfHCbS5H39ZHlnYxEO6qztIjvbnQokhjHDGc4PMCx0wfzrEet1ojNOCnbfmaYE5NQudquzQNZtqZfn8f4B-sQhECElnOXagHlafWO5RayS0dCb1mTfr8orcCA"}]},"id":10,"method":"ShareRequest","jsonrpc":"2.0"}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"Index":"1c724","PublicKey":{"X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"},"Threshold":1,"Verifiers":{"torus-direct-mock-ios":["michael@tor.us"]},"Share":"MzUyMTg4ZjEyMzc1NDAwZjk0MDIxOTgyNGJjNjZkM2U1MmZmM2Y0YjJjZWFkOTQzN2M0N2ZjMjMxMDFkYzQ5YzY5NjZiZTUzM2MwMDg2NTE1OGRlNThiNDc5N2M5Yjgy","Metadata":{"iv":"c73e422b8c1ca9bbe10caa04d8d6e79d","ephemPublicKey":"046ac88f638dc83e4eef85b9bea2de984449ad7587cc5c652451632d2ecc1509b1fa43180768d9c6e5e513d48f2bd8c69d450a4e279a0dbbdb5e7d917e54405e84","mac":"eb941f9a9317d7b27f7bda11988b6478a87bed80d644ccf6b09131e4a488bcd4","mode":"AES256"}}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Content-Length":"722","Vary":"Origin","Date":"Sun, 17 Oct 2021 10:57:32 GMT","Server":"nginx/1.19.9","Content-Type":"application/json"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-2.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"params":{"encrypted":"yes","item":[{"verifieridentifier":"torus-direct-mock-ios","nodesignatures":[{"signature":"f94f88b5a2fff06463fe0cb4569a652a11f351061dcd5b15e466274e374eb2992632153bda0c017d9c83916b82f1daa3ee5ac9990201d73a18915224a828b6a41b","nodepubx":"1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"},{"nodepubx":"7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d","nodepuby":"b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"ee5b3560bc5b394326ddb784970eb27c995b77ceac9ce04ddffe72a52542dffd7b90b30c50b69481b43f04a0373b632798bac8fcdf8d695ead606200e0a24fc41c"},{"signature":"739487dab15bc238d32db83faf7b0aeb57f6863ac079aa331605eee9e076567c5cfa588978128af9d2c160d92a30197ccec8ab8c24ea68a3ac540a2534f65e261c","nodepubx":"8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"},{"data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"d24ccf58546df41bc8506b467e017ec64d941feb442a02001bea1c014dbe4d6b01317473884284d038ea116e6040ab25dad9901ee94d41dd33674cd105bc32151b","nodepuby":"f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249","nodepubx":"25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c"}],"verifier_id":"michael@tor.us","idtoken":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImFkZDhjMGVlNjIzOTU0NGFmNTNmOTM3MTJhNTdiMmUyNmY5NDMzNTIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDkxMTE5NTM4NTYwMzE3OTk2MzkiLCJoZCI6InRvci51cyIsImVtYWlsIjoibWljaGFlbEB0b3IudXMiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InRUNDhSck1vdGFFbi1UN3dzc2U3QnciLCJub25jZSI6InZSU2tPZWwyQTkiLCJuYW1lIjoiTWljaGFlbCBMZWUiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUFUWEFKd3NCYjk4Z1NZalZObEJCQWhYSmp2cU5PdzJHRFNlVGYwSTZTSmg9czk2LWMiLCJnaXZlbl9uYW1lIjoiTWljaGFlbCIsImZhbWlseV9uYW1lIjoiTGVlIiwibG9jYWxlIjoiZW4iLCJpYXQiOjE2MzQ0NjgyNDksImV4cCI6MTYzNDQ3MTg0OX0.XGu1tm_OqlSrc5BMDMzOrlhxLZo1YnpCUT0_j2U1mQt86nJzf_Hp85JfapZj2QeeUz91H6-Ei8FR1i4ICEfjMcoZOW1Azc89qUNfUgWeyjqZ7wCHSsbHAwabE74RFAS9YAja8_ynUvCARfDEtoqcreNgmbw3ZntzAqpuuNBXYfbr87kMvu_wZ7fWjLKM91CvuXytQBwtieTyjAFnTXmEL60Pdu-JSQfHCbS5H39ZHlnYxEO6qztIjvbnQokhjHDGc4PMCx0wfzrEet1ojNOCnbfmaYE5NQudquzQNZtqZfn8f4B-sQhECElnOXagHlafWO5RayS0dCb1mTfr8orcCA"}]},"id":10,"method":"ShareRequest","jsonrpc":"2.0"}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"Index":"1c724","PublicKey":{"X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"},"Threshold":1,"Verifiers":{"torus-direct-mock-ios":["michael@tor.us"]},"Share":"OTNhMzBjODY1YjM4OTNiNWQxOWQ2MmNmZmY1YjUzNTE1NzViZjZiMmM3ZmM0YWFmZTRiYzY0ZjA3YjkzNjU0MzczYzhjNmIyYjQ0ZjIzNTIyZWUwOGRmZWVjNzFlMjVk","Metadata":{"iv":"6e8150c48e9eaae7f03d71fe339e8ddf","ephemPublicKey":"048a363e0572bb294e979e5588488d3f702ea99df104b1b9a82e52505d85983d6ea11061a70a9bd99b2e77a0dc5e816eb1080618f96865ef318129711cd9f6634c","mac":"94d7c5a01d2a01379abb3a3a7c604910f8d58ac0f75c427392ea7c8c8085509c","mode":"AES256"}}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Vary":"Origin","Server":"nginx/1.19.9","Content-Length":"722","Content-Type":"application/json","Date":"Sun, 17 Oct 2021 10:57:32 GMT"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "teal-15-4.torusnode.com",
- scheme: "https",
- path: "/jrpc",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"params":{"encrypted":"yes","item":[{"verifieridentifier":"torus-direct-mock-ios","nodesignatures":[{"signature":"f94f88b5a2fff06463fe0cb4569a652a11f351061dcd5b15e466274e374eb2992632153bda0c017d9c83916b82f1daa3ee5ac9990201d73a18915224a828b6a41b","nodepubx":"1363aad8868cacd7f8946c590325cd463106fb3731f08811ab4302d2deae35c3","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"d77eebe5cdf466b475ec892d5b4cffbe0c1670525debbd97eee6dae2f87a7cbe"},{"nodepubx":"7c8cc521c48690f016bea593f67f88ad24f447dd6c31bbab541e59e207bf029d","nodepuby":"b359f0a82608db2e06b953b36d0c9a473a00458117ca32a5b0f4563a7d539636","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"ee5b3560bc5b394326ddb784970eb27c995b77ceac9ce04ddffe72a52542dffd7b90b30c50b69481b43f04a0373b632798bac8fcdf8d695ead606200e0a24fc41c"},{"signature":"739487dab15bc238d32db83faf7b0aeb57f6863ac079aa331605eee9e076567c5cfa588978128af9d2c160d92a30197ccec8ab8c24ea68a3ac540a2534f65e261c","nodepubx":"8a86543ca17df5687719e2549caa024cf17fe0361e119e741eaee668f8dd0a6f","data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","nodepuby":"9cdb254ff915a76950d6d13d78ef054d5d0dc34e2908c00bb009a6e4da701891"},{"data":"mug00\u001cf9a9e61d68072c950e5dc8baf824b810d52073e9e3748e35f9a534502bac8a5b\u001c3b695585f9c5ac4a4f036757c8873d01f51b68d5e8f0274e2dc4ebbc7daa7025\u001c03b18e36aa6c864091cd7d6536d30a3808c772f18479d753e12847266144c10e\u001ctorus-direct-mock-ios\u001c1634468252","signature":"d24ccf58546df41bc8506b467e017ec64d941feb442a02001bea1c014dbe4d6b01317473884284d038ea116e6040ab25dad9901ee94d41dd33674cd105bc32151b","nodepuby":"f63d40df480dacf68922004ed36dbab9e2969181b047730a5ce0797fb6958249","nodepubx":"25a98d9ae006aed1d77e81d58be8f67193d13d01a9888e2923841894f4b0bf9c"}],"verifier_id":"michael@tor.us","idtoken":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImFkZDhjMGVlNjIzOTU0NGFmNTNmOTM3MTJhNTdiMmUyNmY5NDMzNTIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI2MzYxOTk0NjUyNDItZmQ3dWp0b3JwdnZ1ZHRzbDN1M2V2OTBuaWplY3RmcW0uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDkxMTE5NTM4NTYwMzE3OTk2MzkiLCJoZCI6InRvci51cyIsImVtYWlsIjoibWljaGFlbEB0b3IudXMiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InRUNDhSck1vdGFFbi1UN3dzc2U3QnciLCJub25jZSI6InZSU2tPZWwyQTkiLCJuYW1lIjoiTWljaGFlbCBMZWUiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUFUWEFKd3NCYjk4Z1NZalZObEJCQWhYSmp2cU5PdzJHRFNlVGYwSTZTSmg9czk2LWMiLCJnaXZlbl9uYW1lIjoiTWljaGFlbCIsImZhbWlseV9uYW1lIjoiTGVlIiwibG9jYWxlIjoiZW4iLCJpYXQiOjE2MzQ0NjgyNDksImV4cCI6MTYzNDQ3MTg0OX0.XGu1tm_OqlSrc5BMDMzOrlhxLZo1YnpCUT0_j2U1mQt86nJzf_Hp85JfapZj2QeeUz91H6-Ei8FR1i4ICEfjMcoZOW1Azc89qUNfUgWeyjqZ7wCHSsbHAwabE74RFAS9YAja8_ynUvCARfDEtoqcreNgmbw3ZntzAqpuuNBXYfbr87kMvu_wZ7fWjLKM91CvuXytQBwtieTyjAFnTXmEL60Pdu-JSQfHCbS5H39ZHlnYxEO6qztIjvbnQokhjHDGc4PMCx0wfzrEet1ojNOCnbfmaYE5NQudquzQNZtqZfn8f4B-sQhECElnOXagHlafWO5RayS0dCb1mTfr8orcCA"}]},"id":10,"method":"ShareRequest","jsonrpc":"2.0"}"#)
- ),
- responseBody: Data(#"{"jsonrpc":"2.0","result":{"keys":[{"Index":"1c724","PublicKey":{"X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"},"Threshold":1,"Verifiers":{"torus-direct-mock-ios":["michael@tor.us"]},"Share":"M2U2OGMxYzg0ODFhMDAxNTFkOWE1MTMyMmZjNjlkOWQ0MWUzZjgzZDQ0NGJlNmQ1YzdlMDEwNzliZTRhYjg4OTdmM2Y3YWRiNjcwZDZhMTA5MDk4NjE2OGI2OTBlZWM2","Metadata":{"iv":"29a6a7bb27cd3a9a13cfb47818e894a0","ephemPublicKey":"0489299b0ccc867e2596e2069dce3c129e163f9e8c47c51c2dd2ea5aa56af88b4cfa4cfab34ece86512dc0995fcbab1fe9206609cafa648a66bc35d95c1795dd41","mac":"541759eb560a77517057c452b11113630e2ac32de7ba2addab8643ff52a19f59","mode":"AES256"}}]},"id":10}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Date":"Sun, 17 Oct 2021 10:57:33 GMT","Content-Type":"application/json","Content-Length":"722","Vary":"Origin","Server":"nginx/1.19.9"}"#) as! [String: String]
- ),
-
- Stub(
- requestMatcher: stubMatcherWithBody(
- host: "metadata.tor.us",
- scheme: "https",
- path: "/get",
- method: "POST",
- requestHeaders: mustDecodeJSON(#"{"Accept":"application/json","Content-Type":"application/json"}"#) as! [String: String],
- body: mustDecodeJSON(#"{"pub_key_X":"22d225892d5d149c0486bfb358b143568d1a951c39d5ada061a48c06c48afe39","pub_key_Y":"fcd9074bff4b5097489b79f951146d66bbcd05dc6acf68b8d0afc271fb73cf64"}"#)
- ),
- responseBody: Data(#"{"message":""}"#.utf8),
- statusCode: 200,
- responseHeaders: mustDecodeJSON(#"{"Content-Type":"application/json; charset=utf-8","Etag":"W/\"e-JWOqSwGs6lhRJiUZe/mVb6Mua74\"","x-xss-protection":"0","x-content-type-options":"nosniff","Vary":"Origin, Accept-Encoding","x-frame-options":"SAMEORIGIN","referrer-policy":"no-referrer","content-security-policy":"default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests","Date":"Sun, 17 Oct 2021 10:57:33 GMT","x-dns-prefetch-control":"off","x-permitted-cross-domain-policies":"none","Strict-Transport-Security":"max-age=15552000; includeSubDomains","x-download-options":"noopen","Content-Length":"14","expect-ct":"max-age=0"}"#) as! [String: String]
- ),
-]
diff --git a/Tests/TorusUtilsTests/oneKeyTest.swift b/Tests/TorusUtilsTests/oneKeyTest.swift
index 9a85d823..dd679d1b 100644
--- a/Tests/TorusUtilsTests/oneKeyTest.swift
+++ b/Tests/TorusUtilsTests/oneKeyTest.swift
@@ -1,88 +1,151 @@
import BigInt
import FetchNodeDetails
import JWTKit
+import TorusUtils
import XCTest
-import CoreMedia
-@testable import TorusUtils
-
class OneKeyTest: XCTestCase {
var TORUS_TEST_EMAIL = "hello@tor.us"
var TORUS_TEST_VERIFIER = "torus-test-health"
var TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"
var fnd: NodeDetailManager!
- var tu: TorusUtils!
+ var torus: TorusUtils!
override func setUp() {
super.setUp()
fnd = NodeDetailManager(network: .legacy(.TESTNET))
+ torus = try! TorusUtils(params: TorusOptions(clientId: "YOUR_CLIENT_ID", network: .legacy(.TESTNET), enableOneKey: true))
}
- func getFNDAndTUData(verifer: String, veriferID: String, enableOneKey: Bool = true) async throws -> AllNodeDetailsModel {
- do {
- let nodeDetails = try await fnd.getNodeDetails(verifier: verifer, verifierID: veriferID)
- tu = TorusUtils(enableOneKey: enableOneKey, network: .legacy(.TESTNET), clientId: "YOUR_CLIENT_ID")
- return nodeDetails
- } catch {
- throw error
- }
- }
-
- func test_fetch_public_address() async throws {
+ func test_should_still_fetch_v1_address_correctly() async throws {
let verifier = "google-lrc"
let verifierID = "himanshu@tor.us"
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E")
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+ XCTAssertLessThan(data.metadata!.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData?.evmAddress, "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1")
+
+ XCTAssertEqual(data.oAuthKeyData!.evmAddress, "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E")
+ XCTAssertEqual(data.oAuthKeyData!.X, "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b")
+ XCTAssertEqual(data.oAuthKeyData!.Y, "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a")
+ XCTAssertEqual(data.finalKeyData!.evmAddress, "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1")
+ XCTAssertEqual(data.finalKeyData!.X, "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425")
+ XCTAssertEqual(data.finalKeyData!.Y, "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224")
+ XCTAssertNil(data.metadata!.pubNonce)
+ XCTAssertEqual(data.metadata!.nonce, BigUInt("186a20d9b00315855ff5622a083aca6b2d34ef66ef6e0a4de670f5b2fde37e0d", radix: 16))
+ XCTAssertEqual(data.metadata!.typeOfUser, .v1)
+ XCTAssertEqual(data.metadata!.upgraded, false)
+ XCTAssertNotNil(data.nodesData)
}
- func test_login() async throws {
- let verifier: String = TORUS_TEST_VERIFIER
+ func test_should_still_login_v1_account_correctly() async throws {
let email = TORUS_TEST_EMAIL
- let verifierID: String = email
let jwt = try! generateIdToken(email: email)
- let verifierParams = VerifierParams(verifier_id: verifierID)
- let extraParams = ["verifier_id": email] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4")
- }
-
- func test_login_v2() async throws {
let verifier: String = TORUS_TEST_VERIFIER
- let verifierID: String = TORUS_TEST_EMAIL
- let jwt = try! generateIdToken(email: verifierID)
+ let verifierID: String = email
let verifierParams = VerifierParams(verifier_id: verifierID)
- let extraParams = ["verifier_id": verifierID] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: jwt, extraParams: extraParams)
- XCTAssertEqual(data.oAuthKeyData?.privKey, "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25")
- XCTAssertEqual(data.oAuthKeyData?.evmAddress, "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4")
- XCTAssertEqual(data.finalKeyData?.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4")
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7")
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7")
+ XCTAssertEqual(data.finalKeyData.X, "3fa78a0bfb9ec48810bf1ee332360def2600c4aef528ff8b1e49a0d304722c91")
+ XCTAssertEqual(data.finalKeyData.Y, "46aaca39fc00c0f88f63a79989697c70eeeeec6489300c493dd07a5608ded0d4")
+ XCTAssertEqual(data.finalKeyData.privKey, "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4")
+ XCTAssertEqual(data.oAuthKeyData.X, "18409385c38e9729eb6b7837dc8f234256233ffab1ed7eeb1c23b230333396b4")
+ XCTAssertEqual(data.oAuthKeyData.Y, "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25")
+ XCTAssertEqual(data.metadata.pubNonce!.x, "8e8c399d8ba00ff88e6c42eb40c10661f822868ba2ad8fe12a8830e996b1e25d")
+ XCTAssertEqual(data.metadata.pubNonce!.y, "554b12253694bf9eb98485441bba7ba220b78cb78ee21664e96f934d10b1494d")
+ XCTAssertEqual(data.metadata.nonce, BigUInt("22d160abe5320fe2be52a57c7aca8fe5d7e5eff104ff4d2b32767e3344e040bf", radix: 16))
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata.upgraded, false)
+ XCTAssertNotNil(data.nodesData)
}
- func test_aggregate_login() async throws {
+ func test_should_still_aggregate_v1_user_correctly() async throws {
let verifier: String = TORUS_TEST_AGGREGATE_VERIFIER
let verifierID: String = TORUS_TEST_EMAIL
let jwt = try! generateIdToken(email: TORUS_TEST_EMAIL)
- let verifierParams = VerifierParams(verifier_id: verifierID)
- let hashedIDToken = keccak256Data( jwt.data(using: .utf8) ?? Data() ).toHexString()
- let extraParams = ["verifier_id": TORUS_TEST_EMAIL, "sub_verifier_ids": [TORUS_TEST_VERIFIER], "verify_params": [["verifier_id": TORUS_TEST_EMAIL, "idtoken": jwt]]] as [String: Codable]
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), indexes: nodeDetails.getTorusIndexes(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken, extraParams: extraParams)
- XCTAssertEqual(data.finalKeyData?.evmAddress, "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B")
+ let verifierParams = VerifierParams(verifier_id: verifierID, sub_verifier_ids: [TORUS_TEST_VERIFIER], verify_params: [VerifyParams(verifier_id: TORUS_TEST_EMAIL, idtoken: jwt)])
+ let hashedIDToken = try KeyUtils.keccak256Data(jwt)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: hashedIDToken)
+
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B")
+ XCTAssertEqual(data.finalKeyData.X, "78658b2671f1bd6a488baf2afb8ce6f8d8b9a1a70842130b3c8756a9d51d9723")
+ XCTAssertEqual(data.finalKeyData.Y, "2e5840f47d645afa4bfe93c3715e65974051080d7a1e474eef8d68752924f4fb")
+ XCTAssertEqual(data.finalKeyData.privKey, "ad47959db4cb2e63e641bac285df1b944f54d1a1cecdaeea40042b60d53c35d2")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2")
+ XCTAssertEqual(data.oAuthKeyData.X, "aba2b085ae6390b3eb26802c3239bb7e3b9ed8ea6e1dcc28aeb67432571f20fc")
+ XCTAssertEqual(data.oAuthKeyData.Y, "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a")
+ XCTAssertEqual(data.metadata.pubNonce!.x, "376c0ac5e15686633061cf5833dd040365f91377686d7ab5338c5202bd963a2f")
+ XCTAssertEqual(data.metadata.pubNonce!.y, "794d7edb6a5ec0307dd40789274b377f37f293b0410a6cbd303db309536099b7")
+ XCTAssertEqual(data.metadata.nonce, BigUInt("d3d455dcab49dc700319244e9e187f443596f2acbce238cff1c215d8809fa1f9", radix: 16))
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata.upgraded, false)
+ XCTAssertNotNil(data.nodesData)
}
- /* TODO: Investigate this further
- func test_key_assign() async throws {
+ func test_should_be_able_to_key_assign() async throws {
let fakeEmail = generateRandomEmail(of: 6)
- let verifier: String = "google-lrc"
+ let verifier: String = TORUS_TEST_VERIFIER
let verifierID: String = fakeEmail
- let nodeDetails = try await getFNDAndTUData(verifer: verifier, veriferID: verifierID)
- let data = try await tu.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), torusNodePubs: nodeDetails.getTorusNodePub(), verifier: verifier, verifierId: verifierID)
- XCTAssertNotNil(data)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.getPublicAddress(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierId: verifierID)
+
+ XCTAssertEqual(data.metadata?.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata?.upgraded, false)
XCTAssertNotEqual(data.finalKeyData?.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData?.evmAddress, "")
+ }
+
+ func test_should_be_able_to_key_assign_via_login() async throws {
+ let fakeEmail = generateRandomEmail(of: 6)
+ let verifier: String = TORUS_TEST_VERIFIER
+ let verifierID: String = fakeEmail
+ let jwt = try! generateIdToken(email: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertNotEqual(data.metadata.nonce, BigUInt(0))
+ XCTAssertEqual(data.metadata.upgraded, false)
+ XCTAssertNotEqual(data.finalKeyData.evmAddress, "")
+ XCTAssertNotEqual(data.oAuthKeyData.evmAddress, "")
+ }
+
+ func test_should_still_login_v2_account_correctly() async throws {
+ let email = "Jonathan.Nolan@hotmail.com"
+ let jwt = try! generateIdToken(email: email)
+ let verifier: String = TORUS_TEST_VERIFIER
+ let verifierID: String = email
+ let verifierParams = VerifierParams(verifier_id: verifierID)
+ let nodeDetails = try await fnd.getNodeDetails(verifier: verifier, verifierID: verifierID)
+ let data = try await torus.retrieveShares(endpoints: nodeDetails.getTorusNodeEndpoints(), verifier: verifier, verifierParams: verifierParams, idToken: jwt)
+
+ XCTAssertLessThan(data.metadata.serverTimeOffset, 20)
+
+ XCTAssertEqual(data.finalKeyData.evmAddress, "0x2876820fd9536BD5dd874189A85d71eE8bDf64c2")
+ XCTAssertEqual(data.finalKeyData.X, "ad4c223520aac9bc3ec72399869601fd59f29363471131914e2ed2bc4ba46e54")
+ XCTAssertEqual(data.finalKeyData.Y, "802c6e40b22b49b5ef73fa49b194c2037267215fa01683aa86746907aab37ae1")
+ XCTAssertEqual(data.finalKeyData.privKey, "9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075")
+ XCTAssertEqual(data.oAuthKeyData.evmAddress, "0x54de3Df0CA76AAe3e171FB410F0626Ab759f3c24")
+ XCTAssertEqual(data.oAuthKeyData.X, "49d69b8550bb0eba77595c73bf57f0463ff96adf6b50d44f9e1bcf2b3fb7976e")
+ XCTAssertEqual(data.oAuthKeyData.Y, "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc")
+ XCTAssertEqual(data.oAuthKeyData.privKey, "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a")
+ XCTAssertEqual(data.metadata.pubNonce!.x, "f494a5bf06a2f0550aafb6aabeb495bd6ea3ef92eaa736819b5b0ad6bfbf1aab")
+ XCTAssertEqual(data.metadata.pubNonce!.y, "35df3d3a14f88cbba0cfd092a1e5a0e4e725ba52a8d45719614555542d701f18")
+ XCTAssertEqual(data.metadata.nonce, BigUInt("aa0dcf552fb5be7a5c52b783c1b61c1aca7113872e172a5818994715c8a5497c", radix: 16))
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata.upgraded, false)
+ XCTAssertNotNil(data.nodesData)
}
- */
}
diff --git a/Torus-utils.podspec b/Torus-utils.podspec
index e5b249bd..2dd1b3ec 100644
--- a/Torus-utils.podspec
+++ b/Torus-utils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "Torus-utils"
- spec.version = "8.1.2"
+ spec.version = "9.0.0"
spec.ios.deployment_target = "13.0"
spec.summary = "Retrieve user shares"
spec.homepage = "https://github.com/torusresearch/torus-utils-swift"
@@ -10,7 +10,6 @@ Pod::Spec.new do |spec|
spec.module_name = "TorusUtils"
spec.source = { :git => "https://github.com/torusresearch/torus-utils-swift.git", :tag => spec.version }
spec.source_files = "Sources/TorusUtils/*.{swift,json}","Sources/TorusUtils/**/*.{swift,json}"
- spec.dependency 'Torus-fetchNodeDetails', '~> 6.0.1'
+ spec.dependency 'Torus-fetchNodeDetails', '~> 6.0.3'
spec.dependency 'curvelib.swift', '~> 1.0.1'
- spec.dependency 'AnyCodable-FlightSchool', '~> 0.6.0'
end
diff --git a/cocoapods/Podfile.lock b/cocoapods/Podfile.lock
index a05e6c42..b2c3d277 100644
--- a/cocoapods/Podfile.lock
+++ b/cocoapods/Podfile.lock
@@ -1,20 +1,17 @@
PODS:
- - AnyCodable-FlightSchool (0.6.7)
- BigInt (5.2.0)
- curvelib.swift (1.0.1)
- - Torus-fetchNodeDetails (6.0.0):
+ - Torus-fetchNodeDetails (6.0.3):
- BigInt (~> 5.2.0)
- - Torus-utils (8.0.3):
- - AnyCodable-FlightSchool (~> 0.6.0)
+ - Torus-utils (9.0.0):
- curvelib.swift (~> 1.0.1)
- - Torus-fetchNodeDetails (~> 6.0.0)
+ - Torus-fetchNodeDetails (~> 6.0.3)
DEPENDENCIES:
- Torus-utils (from `../`)
SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
- - AnyCodable-FlightSchool
- BigInt
- curvelib.swift
- Torus-fetchNodeDetails
@@ -24,11 +21,10 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
- AnyCodable-FlightSchool: 261cbe76757802b17d471b9059b21e6fa5edf57b
BigInt: f668a80089607f521586bbe29513d708491ef2f7
curvelib.swift: d0746ae82bee34016c06da3567a97e493b3c979f
- Torus-fetchNodeDetails: e27940bc2151f80b76e3732987a52ea802eb34be
- Torus-utils: ce29be461bc6ae9a946d23188d1d3a50bfa4c667
+ Torus-fetchNodeDetails: 6c349f47cbca36a4b3f276fe26d03c1b39b20949
+ Torus-utils: 0f993fffd66a66a0423092c9ddea2cbff4d298df
PODFILE CHECKSUM: 2d35466879f2d32f53c6ccbca958796c381f0e62
diff --git a/cocoapods/TestApplication.xcodeproj/project.pbxproj b/cocoapods/TestApplication.xcodeproj/project.pbxproj
index 86cb4c38..bdccd572 100644
--- a/cocoapods/TestApplication.xcodeproj/project.pbxproj
+++ b/cocoapods/TestApplication.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 52;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -11,8 +11,6 @@
515E7B19247E652F0092EA9F /* TestApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515E7B18247E652F0092EA9F /* TestApplicationTests.swift */; };
515E7B1B247E652F0092EA9F /* TestApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 515E7B0D247E652F0092EA9F /* TestApplication.h */; settings = {ATTRIBUTES = (Public, ); }; };
C002FB4B4921F3B884E56B53 /* Pods_TestApplication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33DD5637C4B93179658AF996 /* Pods_TestApplication.framework */; };
- FB036776285F59AC004DEA97 /* TestApplicationTests.xctest in Resources */ = {isa = PBXBuildFile; fileRef = 515E7B13247E652F0092EA9F /* TestApplicationTests.xctest */; };
- FB8C5CAE28759F5800CB3C54 /* TestApplication.framework in Resources */ = {isa = PBXBuildFile; fileRef = 515E7B0A247E652F0092EA9F /* TestApplication.framework */; platformFilter = ios; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -31,7 +29,7 @@
33DD5637C4B93179658AF996 /* Pods_TestApplication.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TestApplication.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3E2D7627985D802D622C4CDA /* Pods-TestApplication-TestApplicationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestApplication-TestApplicationTests.release.xcconfig"; path = "Target Support Files/Pods-TestApplication-TestApplicationTests/Pods-TestApplication-TestApplicationTests.release.xcconfig"; sourceTree = ""; };
4A05A45AD7D3DA9579477D6D /* Pods_TestApplication_TestApplicationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TestApplication_TestApplicationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 515E7B0A247E652F0092EA9F /* TestApplication.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestApplication.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 515E7B0A247E652F0092EA9F /* TestApplication.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TestApplication.framework; sourceTree = BUILT_PRODUCTS_DIR; };
515E7B0D247E652F0092EA9F /* TestApplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestApplication.h; sourceTree = ""; };
515E7B0E247E652F0092EA9F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
515E7B13247E652F0092EA9F /* TestApplicationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestApplicationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -177,8 +175,9 @@
515E7B01247E652F0092EA9F /* Project object */ = {
isa = PBXProject;
attributes = {
+ BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1150;
- LastUpgradeCheck = 1150;
+ LastUpgradeCheck = 1540;
ORGANIZATIONNAME = torus;
TargetAttributes = {
515E7B09247E652F0092EA9F = {
@@ -213,7 +212,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- FB8C5CAE28759F5800CB3C54 /* TestApplication.framework in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -221,7 +219,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- FB036776285F59AC004DEA97 /* TestApplicationTests.xctest in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -322,6 +319,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@@ -344,6 +342,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -355,6 +354,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -385,6 +385,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@@ -407,6 +408,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -418,6 +420,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -442,12 +445,14 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 991B2F67E76DF3DBF4500D2D /* Pods-TestApplication.debug.xcconfig */;
buildSettings = {
+ CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 2Q63NCPY55;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_MODULE_VERIFIER = YES;
INFOPLIST_FILE = TestApplication/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
@@ -456,6 +461,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
+ MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
PRODUCT_BUNDLE_IDENTIFIER = torus.TestApplication;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
@@ -469,12 +475,14 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 1CC8F5CD8A6C11076C7B9EA2 /* Pods-TestApplication.release.xcconfig */;
buildSettings = {
+ CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 2Q63NCPY55;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_MODULE_VERIFIER = YES;
INFOPLIST_FILE = TestApplication/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
@@ -483,6 +491,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
+ MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
PRODUCT_BUNDLE_IDENTIFIER = torus.TestApplication;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;