Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: multiple providers #7

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ let package = Package(
.library(
name: "Web3SwiftMpcProvider",
targets: ["Web3SwiftMpcProvider"]),
.library(
name: "MPCEthereumProvider",
targets: ["MPCEthereumProvider"]),
.library(
name: "MPCBitcoinProvider",
targets: ["MPCBitcoinProvider"]),


],
dependencies: [
Expand All @@ -19,12 +26,22 @@ let package = Package(
targets: [
.target(
name: "Web3SwiftMpcProvider",
dependencies: ["web3.swift", "tss-client-swift"],
dependencies: ["tss-client-swift"],
path: "Sources/Web3SwiftMpcProvider"
),
.target(
name: "MPCEthereumProvider",
dependencies: ["web3.swift", "Web3SwiftMpcProvider"],
path: "Sources/EthereumProvider"
),
.target(
name: "MPCBitcoinProvider",
dependencies: ["Web3SwiftMpcProvider"],
path: "Sources/BitcoinProvider"
),
.testTarget(
name: "Web3SwiftMpcProviderTests",
dependencies: ["Web3SwiftMpcProvider"],
dependencies: ["MPCEthereumProvider"],
path: "Tests"),
],
swiftLanguageVersions: [.v5]
Expand Down
31 changes: 31 additions & 0 deletions Sources/BitcoinProvider/BitcoinKitSigner.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// File.swift
//
//
// Created by CW Lee on 25/01/2024.
//

import Foundation
import Web3SwiftMpcProvider

public protocol ISigner {
func sign( message: Data ) -> Data
func schnorrSign(message: Data, publicKey: Data) -> Data
var publicKey : Data { get }
}

extension TssAccount : ISigner {
public func sign(message: Data) -> Data {
let data = try? self.tssSign(message: message)
return data ?? Data()
}

public func schnorrSign(message: Data, publicKey: Data) -> Data {
return Data()
}

public var publicKey: Data {
return Data(hex: self.ethAccountParams.publicKey)
}

}
172 changes: 172 additions & 0 deletions Sources/EthereumProvider/EthereumProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import BigInt
import Web3SwiftMpcProvider
import Foundation
import curveSecp256k1
import tss_client_swift
import web3

enum CustomSigningError: Error {
case generalError(error: String = "")

public var errorDescription: String {
switch self {
case let .generalError(err):
return err
}
}
}

enum EthereumSignerError: Error {
case emptyRawTransaction
case unknownError
}

extension TssAccount: EthereumAccountProtocol {
public var address: web3.EthereumAddress {
return EthereumAddress(KeyUtil.generateAddress(from: Data(hex: ethAccountParams.publicKey).suffix(64)).toChecksumAddress())
}


public func sign(message: Data) throws -> Data {
return try self.tssSign(message: message)
}

/// Signs using provided Data
///
/// - Parameters:
/// - data : Data to be signed
///
/// - Returns: `Data`
///
/// - Throws: On signing failure
public func sign(data: Data) throws -> Data {
let hash = data.sha3(.keccak256)
let signature = try sign(message: hash)
return signature
}

/// Signs using provided Hex String
///
/// - Parameters:
/// - hex : Hex string to be signed
///
/// - Returns: `Data`
///
/// - Throws: On signing failure
public func sign(hex: String) throws -> Data {
if let data = Data(hex: hex) {
return try sign(data: data)
} else {
throw EthereumAccountError.signError
}
}

/// Signs using provided hash
///
/// - Parameters:
/// - hash : Hash to be used for signing
///
/// - Returns: `Data`
///
/// - Throws: On signing failure
public func sign(hash: String) throws -> Data {
if let data = hash.web3.hexData {
return try sign(message: data)
} else {
throw EthereumAccountError.signError
}
}

/// Signs using provided message string
///
/// - Parameters:
/// - message : message to be used for signing
///
/// - Returns: `Data`
///
/// - Throws: On signing failure
public func sign(message: String) throws -> Data {
if let data = message.data(using: .utf8) {
return try sign(data: data)
} else {
throw EthereumAccountError.signError
}
}

/// Signs using provided message data, prefixing the data first
///
/// - Parameters:
/// - message : message to be used for signing
///
/// - Returns: `String`
///
/// - Throws: On signing failure
public func signMessage(message: Data) throws -> String {
let prefix = "\u{19}Ethereum Signed Message:\n\(String(message.count))"
guard var data = prefix.data(using: .ascii) else {
throw EthereumAccountError.signError
}
data.append(message)
let hash = data.web3.keccak256

var signed = try sign(message: hash)

// Check last char (v)
guard var last = signed.popLast() else {
throw EthereumAccountError.signError
}

if last < 27 {
last += 27
}

signed.append(last)
return signed.web3.hexString
}

/// Signs using provided structured typed message (EIP712)
///
/// - Parameters:
/// - message : message to be used for signing
///
/// - Returns: `String`
///
/// - Throws: On signing failure
public func signMessage(message: TypedData) throws -> String {
let hash = try message.signableHash()

var signed = try sign(message: hash)

// Check last char (v)
guard var last = signed.popLast() else {
throw EthereumAccountError.signError
}

if last < 27 {
last += 27
}

signed.append(last)
return signed.web3.hexString
}

/// Signs an ethereum transaction
///
/// - Parameters:
/// - transaction : Transaction to be signed
///
/// - Returns: `SignedTransaction`
///
/// - Throws: On signing failure
public func sign(transaction: EthereumTransaction) throws -> SignedTransaction {
guard let raw = transaction.raw else {
throw EthereumSignerError.emptyRawTransaction
}

// hash and sign data
let signed = try sign(data: raw)

return SignedTransaction(transaction: transaction, signature: signed)
}

}
4 changes: 3 additions & 1 deletion Sources/Web3SwiftMpcProvider/EthTssAccountParams.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation

public final class EthTssAccountParams {
private(set) var publicKey: String
public private(set) var publicKey: String
private(set) var factorKey: String
private(set) var tssNonce: Int32
private(set) var tssShare: String
Expand Down
Loading
Loading