From af687dbe0e2d28befd858f91c9e4e061ef24299a Mon Sep 17 00:00:00 2001
From: metalurgical <97008724+metalurgical@users.noreply.github.com>
Date: Mon, 29 Apr 2024 06:34:46 +0200
Subject: [PATCH] re-align torus-utils-swift
Re-align the current implementation of torus-utils-swift to that of the web implementation of torus.js.
This will reduce the overhead of differences a developer would need to remember between the two and provide an overall better experience.
This will also provide better long term maintainability and make feature parity simpler to implement between the two.
The are also numerous bug fixes implemented in this PR as well, one of which allowed the package AnyCodable as a dependency to be removed.
Should be feature-complete up until tag v12.3.5 on torus.js
---
.github/workflows/main.yml | 4 +-
.gitignore | 1 -
.periphery.yml | 3 +
.swiftpm/TorusUtils.xctestplan | 24 +
.../contents.xcworkspacedata | 7 +
.../xcschemes/TorusUtils.xcscheme | 84 ++
Package.resolved | 13 +-
Package.swift | 11 +-
README.md | 52 +-
Sources/TorusUtils/AbstractTorusUtils.swift | 9 -
Sources/TorusUtils/Constants.swift | 7 +-
Sources/TorusUtils/DataModels.swift | 173 ---
.../Extensions/Array+Extension.swift | 111 +-
.../Extensions/Data+Extension.swift | 12 +-
.../Extensions/OSLog+categories.swift | 2 -
.../Extensions/Sequence+Extension.swift | 7 -
.../Extensions/String+Extension.swift | 60 +-
.../Extensions/TorusUtils+extension.swift | 1326 -----------------
Sources/TorusUtils/Helpers/Common.swift | 99 +-
Sources/TorusUtils/Helpers/Error.swift | 69 +-
.../TorusUtils/Helpers/JSONRPCRequest.swift | 238 ---
Sources/TorusUtils/Helpers/KeyUtils.swift | 190 +++
.../Helpers/LangrangeInterpolatePoly.swift | 277 ++--
.../TorusUtils/Helpers/MetadataUtils.swift | 111 ++
Sources/TorusUtils/Helpers/NodeUtils.swift | 592 ++++++++
...etworkingHelper.swift => httpMethod.swift} | 9 +-
.../Helpers/jsonRPC/ErrorMessage.swift | 20 +
.../Helpers/jsonRPC/JRPCRequest.swift | 16 +
.../Helpers/jsonRPC/JRPCResponse.swift | 51 +
.../Requests/CommitmentRequestParams.swift | 10 +
.../jsonRPC/Requests/GetOrSetKeyParams.swift | 11 +
.../Requests/NonceMetadataParams.swift | 23 +
.../jsonRPC/Requests/SetNonceData.swift | 28 +
.../jsonRPC/Requests/ShareRequestParams.swift | 33 +
.../Responses/CommitmentRequestResult.swift | 17 +
.../Responses/GetOrSetNonceResult.swift | 27 +
.../jsonRPC/Responses/KeyAssignment.swift | 49 +
.../Responses/ShareRequestResult.swift | 76 +
.../LegacyVerifierLookupResponse.swift | 42 +
.../VerifierLookupResponse.swift | 44 +-
.../CommitmentRequestResponse.swift | 30 -
.../Interfaces/{ => Common}/Ecies.swift | 29 +-
.../Interfaces/Common/INodePub.swift | 16 +
.../Interfaces/Common/ImportedShare.swift | 32 +
.../Interfaces/Common/PrivateKeyData.swift | 12 +
.../Interfaces/Common/PubNonce.swift | 21 +
.../Interfaces/Common/SessionToken.swift | 15 +
.../Interfaces/Common/UserType.swift | 6 +
.../TorusUtils/Interfaces/ImportedShare.swift | 13 -
.../Interfaces/KeyAssignInput.swift | 107 --
.../KeyLookup/KeyLookupResult.swift | 32 +
.../Interfaces/KeyLookupResponse.swift | 65 -
.../Interfaces/KeyLookupResult.swift | 7 -
.../Interfaces/MetaData/MetadataParams.swift | 29 +
...RetrieveDecryptAndReconstuctResponse.swift | 17 -
.../Interfaces/RetrieveSharesResponse.swift | 28 -
.../TorusUtils/Interfaces/SessionToken.swift | 8 -
.../Interfaces/ShareRequestResult.swift | 108 --
.../Interfaces/TorusConstants.swift | 29 -
Sources/TorusUtils/Interfaces/TorusKey.swift | 68 +
.../TorusUtils/Interfaces/TorusOptions.swift | 29 +
.../Interfaces/TorusPublicKey.swift | 51 +-
Sources/TorusUtils/Interfaces/Toruskey.swift | 65 -
.../Interfaces/VerifierParams.swift | 13 -
.../Models/RetrieveSharesResponseModel.swift | 30 -
Sources/TorusUtils/Point.swift | 51 +-
Sources/TorusUtils/Polynomial.swift | 22 +-
Sources/TorusUtils/Share.swift | 17 +-
Sources/TorusUtils/TorusUtils.swift | 731 ++++-----
Sources/TorusUtils/VerifierParams.swift | 26 +
Tests/TorusUtilsTests/AquaTest.swift | 219 +--
.../BaseTests/Combinations.swift | 39 +
.../{Helpers => BaseTests}/EtherAddress.swift | 7 +-
.../{Helpers => BaseTests}/Lagrange.swift | 10 +-
Tests/TorusUtilsTests/Celeste.swift | 171 +++
Tests/TorusUtilsTests/CyanTest.swift | 143 +-
.../{Utils => Helpers}/JWTUtils.swift | 15 +-
Tests/TorusUtilsTests/IntegrationTest.swift | 129 --
Tests/TorusUtilsTests/MainnetTest.swift | 194 +--
.../TorusUtilsTests/SapphireDevnetTest.swift | 310 ++++
.../SapphireMainnetTests.swift | 286 ++++
Tests/TorusUtilsTests/SapphireTest.swift | 381 -----
.../TorusUtilsTests/StubURLProtocolTest.swift | 19 -
Tests/TorusUtilsTests/TestnetTest.swift | 201 +--
.../Utils/MockTorusUtils.swift | 41 -
.../Utils/StubURLProtocol.swift | 518 -------
Tests/TorusUtilsTests/oneKeyTest.swift | 178 ++-
Torus-utils.podspec | 5 +-
cocoapods/Podfile.lock | 14 +-
.../TestApplication.xcodeproj/project.pbxproj | 23 +-
90 files changed, 3854 insertions(+), 4694 deletions(-)
create mode 100644 .periphery.yml
create mode 100644 .swiftpm/TorusUtils.xctestplan
create mode 100644 .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
create mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/TorusUtils.xcscheme
delete mode 100644 Sources/TorusUtils/AbstractTorusUtils.swift
delete mode 100644 Sources/TorusUtils/DataModels.swift
delete mode 100644 Sources/TorusUtils/Extensions/Sequence+Extension.swift
delete mode 100644 Sources/TorusUtils/Extensions/TorusUtils+extension.swift
delete mode 100644 Sources/TorusUtils/Helpers/JSONRPCRequest.swift
create mode 100644 Sources/TorusUtils/Helpers/KeyUtils.swift
create mode 100644 Sources/TorusUtils/Helpers/MetadataUtils.swift
create mode 100644 Sources/TorusUtils/Helpers/NodeUtils.swift
rename Sources/TorusUtils/Helpers/{NetworkingHelper.swift => httpMethod.swift} (51%)
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/ErrorMessage.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/JRPCRequest.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/JRPCResponse.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Requests/CommitmentRequestParams.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Requests/GetOrSetKeyParams.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Requests/NonceMetadataParams.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Requests/SetNonceData.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Requests/ShareRequestParams.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Responses/CommitmentRequestResult.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Responses/GetOrSetNonceResult.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Responses/KeyAssignment.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Responses/ShareRequestResult.swift
create mode 100644 Sources/TorusUtils/Helpers/jsonRPC/Responses/VerifierLookupResponse/LegacyVerifierLookupResponse.swift
rename Sources/TorusUtils/{Interfaces => Helpers/jsonRPC/Responses/VerifierLookupResponse}/VerifierLookupResponse.swift (57%)
delete mode 100644 Sources/TorusUtils/Interfaces/CommitmentRequestResponse.swift
rename Sources/TorusUtils/Interfaces/{ => Common}/Ecies.swift (73%)
create mode 100644 Sources/TorusUtils/Interfaces/Common/INodePub.swift
create mode 100644 Sources/TorusUtils/Interfaces/Common/ImportedShare.swift
create mode 100644 Sources/TorusUtils/Interfaces/Common/PrivateKeyData.swift
create mode 100644 Sources/TorusUtils/Interfaces/Common/PubNonce.swift
create mode 100644 Sources/TorusUtils/Interfaces/Common/SessionToken.swift
create mode 100644 Sources/TorusUtils/Interfaces/Common/UserType.swift
delete mode 100644 Sources/TorusUtils/Interfaces/ImportedShare.swift
delete mode 100644 Sources/TorusUtils/Interfaces/KeyAssignInput.swift
create mode 100644 Sources/TorusUtils/Interfaces/KeyLookup/KeyLookupResult.swift
delete mode 100644 Sources/TorusUtils/Interfaces/KeyLookupResponse.swift
delete mode 100644 Sources/TorusUtils/Interfaces/KeyLookupResult.swift
create mode 100644 Sources/TorusUtils/Interfaces/MetaData/MetadataParams.swift
delete mode 100644 Sources/TorusUtils/Interfaces/RetrieveDecryptAndReconstuctResponse.swift
delete mode 100644 Sources/TorusUtils/Interfaces/RetrieveSharesResponse.swift
delete mode 100644 Sources/TorusUtils/Interfaces/SessionToken.swift
delete mode 100644 Sources/TorusUtils/Interfaces/ShareRequestResult.swift
delete mode 100644 Sources/TorusUtils/Interfaces/TorusConstants.swift
create mode 100644 Sources/TorusUtils/Interfaces/TorusKey.swift
create mode 100644 Sources/TorusUtils/Interfaces/TorusOptions.swift
delete mode 100644 Sources/TorusUtils/Interfaces/Toruskey.swift
delete mode 100644 Sources/TorusUtils/Interfaces/VerifierParams.swift
delete mode 100644 Sources/TorusUtils/Models/RetrieveSharesResponseModel.swift
create mode 100644 Sources/TorusUtils/VerifierParams.swift
create mode 100644 Tests/TorusUtilsTests/BaseTests/Combinations.swift
rename Tests/TorusUtilsTests/{Helpers => BaseTests}/EtherAddress.swift (61%)
rename Tests/TorusUtilsTests/{Helpers => BaseTests}/Lagrange.swift (75%)
create mode 100644 Tests/TorusUtilsTests/Celeste.swift
rename Tests/TorusUtilsTests/{Utils => Helpers}/JWTUtils.swift (76%)
delete mode 100644 Tests/TorusUtilsTests/IntegrationTest.swift
create mode 100644 Tests/TorusUtilsTests/SapphireDevnetTest.swift
create mode 100644 Tests/TorusUtilsTests/SapphireMainnetTests.swift
delete mode 100644 Tests/TorusUtilsTests/SapphireTest.swift
delete mode 100644 Tests/TorusUtilsTests/StubURLProtocolTest.swift
delete mode 100644 Tests/TorusUtilsTests/Utils/MockTorusUtils.swift
delete mode 100644 Tests/TorusUtilsTests/Utils/StubURLProtocol.swift
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..f3fdd83d 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" : "22bfadf7491d77a0bc1953af002cadbd61383e7d",
+ "version" : "6.0.2"
}
},
{
diff --git a/Package.swift b/Package.swift
index 57771d76..623cbc56 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.2"),
+ // 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 614fbe31..3cbecc7f 100644
--- a/README.md
+++ b/README.md
@@ -8,16 +8,16 @@ 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.1")
+ .package(url: "https://github.com/torusresearch/torus-utils-swift", from: "9.0.0")
],
targets: [
- .target( name: "",
+ .target( name: "",
dependencies: [
.product(name: "TorusUtils", package: "torus-utils-swift")
]
@@ -26,15 +26,19 @@ targets: [
...
```
+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))
```
@@ -46,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.
@@ -69,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
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 33c2f082..10044662 100755
--- a/Sources/TorusUtils/Extensions/String+Extension.swift
+++ b/Sources/TorusUtils/Extensions/String+Extension.swift
@@ -1,15 +1,8 @@
import Foundation
extension String {
- func hasHexPrefix() -> Bool {
- return hasPrefix("0x")
- }
-
func addHexPrefix() -> String {
- if !hasPrefix("0x") {
- return "0x" + self
- }
- return self
+ return "0x" + self
}
func stripHexPrefix() -> String {
@@ -20,17 +13,6 @@ extension String {
return self
}
- func has04Prefix() -> Bool {
- return hasPrefix("04")
- }
-
- func add04Prefix() -> String {
- if !hasPrefix("04") {
- return "04" + self
- }
- return self
- }
-
func strip04Prefix() -> String {
if hasPrefix("04") {
let indexStart = index(startIndex, offsetBy: 2)
@@ -39,7 +21,7 @@ extension String {
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 +30,17 @@ extension String {
}
}
- func customBytes() -> Array {
- data(using: String.Encoding.utf8, allowLossyConversion: true)?.bytes ?? Array(utf8)
- }
-
- func toChecksumAddress() -> String {
- let lowerCaseAddress = stripHexPrefix().lowercased()
- let arr = Array(lowerCaseAddress)
- let hash = 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 func hexEncodedToString() -> String {
+ var finalString = ""
+ let chars = Array(self)
-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)
+ 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
+ finalString.append(Character(decimalString))
}
+ return finalString
}
}
diff --git a/Sources/TorusUtils/Extensions/TorusUtils+extension.swift b/Sources/TorusUtils/Extensions/TorusUtils+extension.swift
deleted file mode 100644
index 9474a971..00000000
--- a/Sources/TorusUtils/Extensions/TorusUtils+extension.swift
+++ /dev/null
@@ -1,1326 +0,0 @@
-import AnyCodable
-import BigInt
-import CryptoKit
-import curveSecp256k1
-import FetchNodeDetails
-import Foundation
-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]
-
- let encoder = JSONEncoder()
- encoder.outputFormatting = .sortedKeys
- rpcdata = try encoder.encode(dataForRequest)
-
- // 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], xCoordinate: String, yCoordinate: 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 == xCoordinate && pubKeyY == yCoordinate {
- 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..e6623622 100644
--- a/Sources/TorusUtils/Helpers/Error.swift
+++ b/Sources/TorusUtils/Helpers/Error.swift
@@ -2,27 +2,20 @@ 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 gatingError(_ msg: String = "")
+ case invalidInput
}
extension TorusUtilError: CustomDebugStringConvertible {
@@ -30,48 +23,34 @@ 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
}
}
@@ -88,38 +67,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..6fe968e3
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/KeyUtils.swift
@@ -0,0 +1,190 @@
+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) {
+ let publicKeyUnprefixed = pubKey.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 ? "04" + X + Y : 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 3e4337d9..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..eb668140
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/MetadataUtils.swift
@@ -0,0 +1,111 @@
+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)
+ 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
+ }
+
+ 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) throws -> MetadataParams {
+ let privKey = try SecretKey(hex: privateKey)
+ let publicKey = try privKey.toPublic().serialize(compressed: false)
+
+ 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)
+ let (X, Y) = try KeyUtils.getPublicKeyCoords(pubKey: publicKey)
+ return .init(pub_key_X: X, pub_key_Y: Y, setData: setData, signature: Data(hex: sigData).base64EncodedString())
+ }
+
+ public static func getMetadata(legacyMetadataHost: String, 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 urlSession = URLSession(configuration: .default)
+ 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
+ }
+
+ public static func getOrSetNonce(legacyMetadataHost: String, serverTimeOffset: Int, 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 generateMetadataParams(serverTimeOffset: serverTimeOffset, 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 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(legacyMetadataHost: String, network: TorusNetwork, X: String, Y: String, serverTimeOffset: Int, privateKey: String? = nil, getOnly: Bool = false) async throws -> GetOrSetNonceResult {
+ if case .sapphire = network {
+ return try await getOrSetNonce(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffset, X: X, Y: Y, privateKey: privateKey, getOnly: getOnly)
+ } else {
+ throw TorusUtilError.metadataNonceMissing
+ }
+ }
+}
diff --git a/Sources/TorusUtils/Helpers/NodeUtils.swift b/Sources/TorusUtils/Helpers/NodeUtils.swift
new file mode 100644
index 00000000..5897a4cf
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/NodeUtils.swift
@@ -0,0 +1,592 @@
+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 minRequired = Int(trunc(Double(endpoints.count * 3 / 4) + 1))
+
+ let lookupResults: [JRPCResponse?] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [JRPCResponse?].self) { group -> [JRPCResponse?] in
+ 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 = [JRPCResponse?]()
+ for try await value in group {
+ collected.append(value)
+ if value != nil && value?.error == nil {
+ received += 1
+ if received >= minRequired {
+ group.cancelAll()
+ }
+ }
+ }
+ return collected
+ }
+
+ let lookupPubKeys = lookupResults.filter({ $0 != nil && $0?.error == nil })
+
+ let errorResult = try thresholdSame(arr: lookupResults.filter({ $0?.error != nil }).map { $0?.error }, threshold: threshold)
+
+ let normalizedKeyResults = lookupPubKeys.map({ normalizeKeysResult(result: ($0!.result)!) })
+
+ let keyResult = try thresholdSame(arr: normalizedKeyResults, threshold: threshold)
+
+ 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
+ }
+ }
+ }
+ }
+
+ 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
+
+ if case .sapphire = network {
+ let X: BigInt = BigInt(nonceResult?.pubNonce?.x ?? "0", radix: 16) ?? BigInt(0)
+ let Y: BigInt = BigInt(nonceResult?.pubNonce?.x ?? "0", radix: 16) ?? BigInt(0)
+ if nonceResult == nil || (X == BigInt(0) && Y == BigInt(0)) {
+ let metadataNonce = try await MetadataUtils.getOrSetSapphireMetadataNonce(legacyMetadataHost: legacyMetadataHost, network: network, X: keyResult!.keys[0].pub_key_X, Y: keyResult!.keys[0].pub_key_Y, serverTimeOffset: serverTimeOffset, getOnly: false)
+ nonceResult = metadataNonce
+ }
+ }
+
+ return KeyLookupResult(
+ keyResult: keyResult,
+ nodeIndexes: nodeIndexes,
+ serverTimeOffset: serverTimeOffset,
+ nonceResult: nonceResult,
+ errorResult: errorResult == nil ? nil : errorResult as? ErrorMessage)
+ }
+
+ 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: [String: Codable] = [:]
+ ) 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 minRequired = Int(trunc(Double(endpoints.count * 3 / 4) + 1))
+
+ let commitmentRequestResults: [JRPCResponse?] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [JRPCResponse?].self) { group -> [JRPCResponse?] in
+ 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 = [JRPCResponse?]()
+ for try await value in group {
+ collected.append(value)
+ if !isImportShareReq && value != nil && value?.error == nil {
+ received += 1
+ if received >= minRequired {
+ group.cancelAll()
+ }
+ } else if isImportShareReq {
+ if value == nil || value?.error != nil {
+ // cannot continue, all must pass for import
+ group.cancelAll()
+ }
+ }
+ }
+ return collected
+ }
+
+ let completedCommitmentRequests = commitmentRequestResults.filter({ $0 != nil && $0?.error == nil })
+
+ if importedShareCount > 0 && !(commitmentRequestResults.count == endpoints.count) {
+ throw TorusUtilError.commitmentRequestFailed
+ }
+
+ let nodeSigs = completedCommitmentRequests.filter({ $0?.error == nil }).map({ $0!.result })
+
+ var thresholdNonceData: GetOrSetNonceResult?
+
+ let sessionExpiry: Int? = extraParams["session_token_exp_second"] as? Int
+
+ var shareImportSuccess = false
+
+ var shareRequestResults: [ShareRequestResult?] = []
+
+ 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,
+ // extra_params: extraData
+ sub_verifier_ids: verifierParams.sub_verifier_ids,
+ session_token_exp_second: sessionExpiry,
+ verify_params: verifierParams.verify_params,
+ sss_endpoint: endpoints[j]
+ )
+
+ 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
+ }
+
+ shareRequestResults = decoded.result!
+
+ } else {
+ let shareResults: [JRPCResponse?] = try await withThrowingTaskGroup(of: JRPCResponse?.self, returning: [JRPCResponse?].self) {
+ group -> [JRPCResponse?] in
+ var received = 0
+
+ for i in 0 ..< endpoints.count {
+ if !nodeSigs.indices.contains(i) {
+ if isImportShareReq {
+ throw TorusUtilError.importShareFailed
+ }
+ continue
+ }
+
+ 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,
+ // extra_params: extraData
+ sub_verifier_ids: verifierParams.sub_verifier_ids,
+ session_token_exp_second: sessionExpiry,
+ verify_params: verifierParams.verify_params
+ )
+
+ 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?]()
+ for try await value in group {
+ collected.append(value)
+ if !isImportShareReq {
+ if value != nil && value?.error == nil {
+ received += 1
+ if received >= minRequired {
+ group.cancelAll()
+ }
+ }
+ }
+ }
+
+ return collected
+ }
+ shareRequestResults = shareResults.map({ $0?.result })
+ }
+
+ let shareResponses: [ShareRequestResult] = shareRequestResults.filter({ $0 != nil }).map({ $0! })
+
+ let pubkeys = shareResponses.filter({ $0.keys.count > 0 }).map { $0.keys[0].publicKey }
+
+ let thresholdPublicKey = try thresholdSame(arr: pubkeys, threshold: threshold)
+
+ 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)
+
+ let nX: BigInt = BigInt(thresholdNonceData?.pubNonce?.x ?? "0", radix: 16) ?? BigInt(0)
+ let nY: BigInt = BigInt(thresholdNonceData?.pubNonce?.x ?? "0", radix: 16) ?? BigInt(0)
+
+ if (thresholdNonceData == nil || (nX == BigInt(0) && nY == BigInt(0))) && verifierParams.extended_verifier_id == nil && !TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ if case .sapphire = network {
+ let metadataNonce = try await MetadataUtils.getOrSetSapphireMetadataNonce(legacyMetadataHost: legacyMetadataHost, network: network, X: thresholdPublicKey!.X, Y: thresholdPublicKey!.Y, serverTimeOffset: serverTimeOffsetResponse, getOnly: false)
+ thresholdNonceData = metadataNonce
+ } else {
+ throw TorusUtilError.runtime("invalid metadata result from nodes, nonce metadata is empty")
+ }
+ }
+
+ 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 = try thresholdSame(arr: isNewKeys, threshold: threshold)
+
+ let oAuthKey = privateKey!.addLeading0sForLength64()
+ 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 nonce = try await MetadataUtils.getOrSetNonce(legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffsetResponse, X: oAuthPublicKeyX, Y: oAuthPublicKeyY, getOnly: !(Bool(thresholdIsNewKey ?? "true")!))
+ 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, dictionary: ["pub_key_X": oAuthPublicKeyX, "pub_key_Y": oAuthPublicKeyY]))
+ let privateKeyWithNonce = (BigInt(oAuthKey, 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, dictionary: ["pub_key_X": oAuthPublicKeyX, "pub_key_Y": oAuthPublicKeyY]))
+ let privateKeyWithNonce = (BigInt(oAuthKey, radix: 16)! + BigInt(metadataNonce)).modulus(KeyUtils.getOrderOfCurve())
+ finalPubKey = try SecretKey(hex: privateKeyWithNonce.magnitude.serialize().hexString.addLeading0sForLength64()).toPublic().serialize(compressed: false)
+ }
+ } else {
+ typeOfUser = .v2
+ let publicNonce = KeyUtils.getPublicKeyFromCoords(pubKeyX: thresholdNonceData!.pubNonce!.x, pubKeyY: thresholdNonceData!.pubNonce!.y)
+ let oAuthPubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: oAuthPublicKeyX, pubKeyY: oAuthPublicKeyY)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [oAuthPubKey, publicNonce])
+ pubNonce = PubNonce(x: thresholdNonceData!.pubNonce!.x, y: thresholdNonceData!.pubNonce!.y)
+ }
+
+ 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, 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/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..2b7efbd4
--- /dev/null
+++ b/Sources/TorusUtils/Helpers/jsonRPC/Requests/ShareRequestParams.swift
@@ -0,0 +1,33 @@
+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?
+ // [key: string]; This should be strongly typed
+ public var sub_verifier_ids: [String]?
+ public var session_token_exp_second: Int?
+ public var verify_params: [VerifyParams?]?
+ public var sss_endpoint: String?
+ }
+
+ 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/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..7d50c571
--- /dev/null
+++ b/Sources/TorusUtils/Interfaces/MetaData/MetadataParams.swift
@@ -0,0 +1,29 @@
+import Foundation
+
+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 = .secp256k1) {
+ 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..70176c1a
--- /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 e36a4402..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,17 +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
+ 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
@@ -52,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..b9377c71 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 = (x * 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 594a7624..20c640ba 100644
--- a/Sources/TorusUtils/TorusUtils.swift
+++ b/Sources/TorusUtils/TorusUtils.swift
@@ -1,4 +1,3 @@
-import AnyCodable
import BigInt
import FetchNodeDetails
import Foundation
@@ -9,481 +8,359 @@ import OSLog
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
- allowHost = network.signerMap + "/api/allow"
- 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"
}
- // MARK: - getPublicAddress
+ internal static func isLegacyNetworkRouteMap(network: TorusNetwork) -> Bool {
+ if case .legacy = network {
+ return true
+ }
+ return false
+ }
- 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 apiKey
+ ///
+ /// - Parameters:
+ /// - apiKey: The api key to be assigned
+ public func setApiKey(apiKey: String) {
+ self.apiKey = apiKey
+ }
+
+ /// Reverts the apiKey for `TorusUtils` to the default value
+ public func removeApiKey() {
+ apiKey = "torus-default"
+ }
+
+ /// 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 {
+ if let privKey: String = torusKey.finalKeyData.privKey {
+ return 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
+ ) async throws -> TorusKey {
+ // This has to be done here as retrieveOrImport share does not have a reference to self
+ var params: [String: Codable] = [:]
+ params.updateValue(sessionTime, forKey: "session_token_exp_second")
+
+ 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: params)
+ }
+
+ /// 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)
+ }
+
+ /// 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,
- extraParams: [String: Codable] = [:]
+ newPrivateKey: String
) 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
+ let nodePubs = TorusNodePubModelToINodePub(nodes: nodePubKeys)
+ if endpoints.count != nodeIndexes.count {
+ throw TorusUtilError.runtime("Length of endpoints must be the same as length of nodeIndexes")
}
- 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
- }
+ let sharesData = try KeyUtils.generateShares(serverTimeOffset: serverTimeOffset ?? 0, nodeIndexes: nodeIndexes, nodePubKeys: nodePubs, privateKey: newPrivateKey)
+
+ 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)
}
- 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
+ ///
+ /// - 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)
}
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)
-
- let nonceResult = result.nonceResult
+ let keyAssignResult = try await NodeUtils.getPubKeyOrKeyAssign(endpoints: endpoints, network: network, verifier: verifier, verifierId: verifierId, legacyMetadataHost: legacyMetadataHost, serverTimeOffset: serverTimeOffset, extendedVerifierId: extendedVerifierId)
- if nonceResult?.pubNonce?.x == nil && extendedVerifierId == nil && !isLegacyNetwork() { throw TorusUtilError.runtime("metadata nonce is missing in share response")
+ 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 {
+ throw TorusUtilError.runtime(error)
}
+ }
- var modifiedPubKey: String
- var oAuthPubKeyString: String
- var pubNonce: PubNonce?
+ if keyAssignResult.keyResult == nil || keyAssignResult.keyResult?.keys.count == 0 {
+ throw TorusUtilError.runtime("node results do not match at final lookup")
+ }
- 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)
- } 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
- }
+ if keyAssignResult.nonceResult == nil && extendedVerifierId != nil && TorusUtils.isLegacyNetworkRouteMap(network: network) {
+ throw TorusUtilError.runtime("metadata nonce is missing in share response")
+ }
- 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)
- )
+ let pubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: keyAssignResult.keyResult!.keys[0].pub_key_X, pubKeyY: keyAssignResult.keyResult!.keys[0].pub_key_Y)
- } catch {
- throw error
+ 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 pubNonceResult = keyAssignResult.nonceResult!.pubNonce!
+ oAuthPubKey = pubKey
+ let pubNonceKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: pubNonceResult.x, pubKeyY: pubNonceResult.y)
+ finalPubKey = try KeyUtils.combinePublicKeys(keys: [oAuthPubKey!, pubNonceKey])
+ pubNonce = pubNonceResult
}
- }
- // 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 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
+ if oAuthPubKey == nil || finalPubKey == nil {
+ throw TorusUtilError.privateKeyDeriveFailed
}
+
+ 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 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
- }
+ 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
- do {
- for try await val in group {
- try Task.checkCancellation()
- group.cancelAll()
- return val
- }
- } catch {
- group.cancelAll()
- throw error
- }
- throw TorusUtilError.timeout
- })
- }
+ var nonceResult: GetOrSetNonceResult?
+ var finalPubKey: String?
+ var nonce: BigUInt?
+ var typeOfUser: UserType
+ var pubNonce: PubNonce?
- 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()
- do {
- 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, xCoordinate: pubKeyX, yCoordinate: pubKeyY, 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)
- }
+ let oAuthPubKey = KeyUtils.getPublicKeyFromCoords(pubKeyX: X, pubKeyY: Y)
- let oAuthKeyAddress = generateAddressFromPubKey(publicKeyX: oAuthKeyX, publicKeyY: oAuthKeyY)
- let (finalPubX, finalPubY) = try getPublicKeyPointFromPubkeyString(pubKey: finalPubKey)
- let finalEvmAddress = generateAddressFromPubKey(publicKeyX: finalPubX, publicKeyY: finalPubY)
+ let finalServertimeOffset = self.serverTimeOffset ?? serverTimeOffset
- 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()
- }
+ 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, dictionary: ["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, dictionary: ["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, xCoordinate: String, yCoordinate: 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 = xCoordinate.addLeading0sForLength64()
- var Y = yCoordinate.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.addLeading0sForLength64()
- Y = pointHex.y.addLeading0sForLength64()
- 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, xCoordinate: X.addLeading0sForLength64(), yCoordinate: 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/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/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..49384b3f
--- /dev/null
+++ b/Tests/TorusUtilsTests/SapphireDevnetTest.swift
@@ -0,0 +1,310 @@
+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)
+ }
+
+ /*
+ TODO: Re-enable this test once regression has been found, currently this is broken in dev accross the board
+ 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..0aee3f3c 100644
--- a/Tests/TorusUtilsTests/oneKeyTest.swift
+++ b/Tests/TorusUtilsTests/oneKeyTest.swift
@@ -1,88 +1,162 @@
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")
+ // v2 user, this should be empty.
+ // 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")
+ // v2 user, This should be zero.
+ // XCTAssertEqual(data.metadata.nonce, BigUInt("22d160abe5320fe2be52a57c7aca8fe5d7e5eff104ff4d2b32767e3344e040bf", radix: 16))
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ // v2 user, this should be true.
+ // 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")
+ // v2 user, this should be empty.
+ // 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")
+ // v2 user, This should be zero.
+ // XCTAssertEqual(data.metadata.nonce, BigUInt("d3d455dcab49dc700319244e9e187f443596f2acbce238cff1c215d8809fa1f9", radix: 16))
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ // v2 user, this should be true.
+ // 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)
+
+ // This swaps between v1 and v2
+ // XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ XCTAssertEqual(data.metadata.nonce, BigUInt(0))
+ // v2 user, this should be true
+ // 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")
+ // v2 user, this should be empty.
+ // 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")
+ // v2 user, This should be zero.
+ // XCTAssertEqual(data.metadata.nonce, BigUInt("aa0dcf552fb5be7a5c52b783c1b61c1aca7113872e172a5818994715c8a5497c", radix: 16))
+ XCTAssertEqual(data.metadata.typeOfUser, .v2)
+ // v2 user, this should be true.
+ // XCTAssertEqual(data.metadata.upgraded, false)
+ XCTAssertNotNil(data.nodesData)
}
- */
}
diff --git a/Torus-utils.podspec b/Torus-utils.podspec
index bfb37321..7a7ac1b8 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.1"
+ 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.2'
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..e9ee5f41 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.2):
- 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.2)
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: 48996680351bc41bd84690e6689fe85c0d458ba3
+ Torus-utils: ca3ee1cf3433b413c57613f6e65dba0789fbf4e3
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;