From cfb518e20e020c7b593fe32b43cbe8cef13b3587 Mon Sep 17 00:00:00 2001 From: Rakeally <40327144+Rakeally@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:26:07 +0100 Subject: [PATCH 1/4] btc multi sign --- .../kotlin/africa/ejara/trustdart/Coin.kt | 16 +++++ .../africa/ejara/trustdart/TrustdartPlugin.kt | 30 ++++++++++ .../africa/ejara/trustdart/coins/BTC.kt | 59 ++++++++++++++++++- .../africa/ejara/trustdart/coins/XTZ.kt | 1 - .../trustdart/interfaces/CoinInterface.kt | 7 +++ example/lib/operations.dart | 18 +++++- ios/Classes/Coin.swift | 17 ++++++ ios/Classes/SwiftTrustdartPlugin.swift | 22 +++++++ ios/Classes/coins/BTC.swift | 39 ++++++++++++ ios/Classes/protocols/CoinProtocol.swift | 2 + lib/trustdart.dart | 17 ++++++ 11 files changed, 225 insertions(+), 3 deletions(-) diff --git a/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt b/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt index 7490432..3b631e7 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt @@ -4,6 +4,7 @@ import africa.ejara.trustdart.interfaces.CoinInterface import africa.ejara.trustdart.utils.base64String import africa.ejara.trustdart.utils.toHex import africa.ejara.trustdart.utils.toHexByteArray +import com.google.protobuf.ByteString import org.json.JSONObject import wallet.core.java.AnySigner import wallet.core.jni.CoinType @@ -82,4 +83,19 @@ open class Coin(nameOfCoin: String, typeOfCoin: CoinType) : CoinInterface { return AnySigner.signJSON(opJson, privateKey.data(), coinType!!.value()) } + override fun multiSignTransaction( + path: String, + txData: Map, + privateKeys: ArrayList + ): String? { + val opJson = JSONObject(txData).toString() + val signatures = mutableListOf() + + for (privateKey in privateKeys) { + val signature = AnySigner.signJSON(opJson, privateKey.toByteArray(), coinType!!.value()) + signatures.add(signature) + } + return signatures.joinToString(",") + } + } diff --git a/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt b/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt index 36b3795..a230af7 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt @@ -164,6 +164,36 @@ class TrustdartPlugin : FlutterPlugin, MethodCallHandler { validator.details.errorDetails ) } + "multiSignTransaction" -> { + val coin: String? = call.argument("coin") + val path: String? = call.argument("path") + val txData: Map? = call.argument("txData") + val privateKeys: ArrayList? = call.argument("privateKeys") + var validator = WalletHandler().validate( + WalletError( + WalletHandlerErrorCodes.ArgumentsNull, + "[path], [coin], [privateKeys] and [txData] are required.", + null + ), arrayOf(path, coin, txData, privateKeys) + ) + if (validator.isValid) { + val txHash = WalletHandler().getCoin(coin) + .multiSignTransaction(path!!, txData!!, privateKeys!!) + validator = WalletHandler().validate( + WalletError( + WalletHandlerErrorCodes.TxHashNull, + "Could not sign transaction.", + null + ), arrayOf(txHash) + ) + if (validator.isValid) return result.success(txHash) + } + return result.error( + validator.details.errorCode, + validator.details.errorMessage, + validator.details.errorDetails + ) + } "signDataWithPrivateKey" -> { val coin: String? = call.argument("coin") val path: String? = call.argument("path") diff --git a/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt b/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt index 3825345..9f6dc9b 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt @@ -1,5 +1,6 @@ import africa.ejara.trustdart.Coin import africa.ejara.trustdart.Numeric +import africa.ejara.trustdart.utils.toHex import africa.ejara.trustdart.utils.toLong import com.google.protobuf.ByteString import wallet.core.java.AnySigner @@ -8,6 +9,9 @@ import wallet.core.jni.BitcoinScript import wallet.core.jni.CoinType import wallet.core.jni.HDWallet import wallet.core.jni.proto.Bitcoin +import java.util.* + + class BTC : Coin("BTC", CoinType.BITCOIN) { @@ -77,4 +81,57 @@ class BTC : Coin("BTC", CoinType.BITCOIN) { return Numeric.toHexString(output.encoded.toByteArray()) } -} \ No newline at end of file + + override fun multiSignTransaction( + path: String, + txData: Map, + privateKeys: ArrayList + ): String? { + val utxos: List> = txData["utxos"] as List> + + val input = Bitcoin.SigningInput.newBuilder() + .setAmount(txData["amount"]!!.toLong()) + .setHashType(BitcoinScript.hashTypeForCoin(coinType)) + .setToAddress(txData["toAddress"] as String) + .setChangeAddress(txData["changeAddress"] as String) + .setByteFee(1) + + val byteStrings: MutableList = privateKeys.map { ByteString.copyFrom(Numeric.hexStringToByteArray(it)) }.toMutableList() + + input.addAllPrivateKey(byteStrings); + + for (utx in utxos) { + val txHash = Numeric.hexStringToByteArray(utx["txid"] as String) + txHash.reverse() + val outPoint = Bitcoin.OutPoint.newBuilder() + .setHash(ByteString.copyFrom(txHash)) + .setIndex(utx["vout"] as Int) + .setSequence(Long.MAX_VALUE.toInt()) + .build() + val txScript = Numeric.hexStringToByteArray(utx["script"] as String) + val utxo = Bitcoin.UnspentTransaction.newBuilder() + .setAmount(utx["value"]!!.toLong()) + .setOutPoint(outPoint) + .setScript(ByteString.copyFrom(txScript)) + .build() + input.addUtxo(utxo) + } + + var output = AnySigner.sign(input.build(), coinType, Bitcoin.SigningOutput.parser()) + + // since we want to set our own fee + // but such functionality is not obvious in the trustwalletcore library + // a hack is used for now to calculate the byteFee + val size = output.encoded.toByteArray().size + val fees = txData["fees"]!!.toLong() + if (size > 0) { // prevent division by zero + val byteFee = fees.div(size) // this gives the fee per byte truncated to Long + // now we set new byte size + if (byteFee > 1) input.byteFee = byteFee + } + output = AnySigner.sign(input.build(), coinType, Bitcoin.SigningOutput.parser()) + return Numeric.toHexString(output.encoded.toByteArray()) + } + +}; + \ No newline at end of file diff --git a/android/src/main/kotlin/africa/ejara/trustdart/coins/XTZ.kt b/android/src/main/kotlin/africa/ejara/trustdart/coins/XTZ.kt index 07de6bd..669ef35 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/coins/XTZ.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/coins/XTZ.kt @@ -4,7 +4,6 @@ import africa.ejara.trustdart.utils.base64String import africa.ejara.trustdart.utils.toHex import africa.ejara.trustdart.utils.toHexBytes import africa.ejara.trustdart.utils.toLong -import android.util.Log import com.google.protobuf.ByteString import org.json.JSONObject import wallet.core.java.AnySigner diff --git a/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt b/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt index 752a20c..74b7b5d 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt @@ -1,5 +1,7 @@ package africa.ejara.trustdart.interfaces +import com.google.protobuf.ByteString + interface CoinInterface { fun generateAddress(path: String, mnemonic: String, passphrase: String): Map? fun getSeed(path: String, mnemonic: String, passphrase: String): ByteArray? @@ -10,4 +12,9 @@ interface CoinInterface { fun validateAddress(address: String): Boolean fun signDataWithPrivateKey(path: String, mnemonic: String, passphrase: String, txData: String): String? fun signTransaction(path: String, txData: Map, mnemonic: String, passphrase: String): String? + fun multiSignTransaction( + path: String, + txData: Map, + privateKeys: ArrayList + ): String? } \ No newline at end of file diff --git a/example/lib/operations.dart b/example/lib/operations.dart index b27fd15..a179493 100644 --- a/example/lib/operations.dart +++ b/example/lib/operations.dart @@ -102,7 +102,13 @@ Map operations = { "amount": 3000, "fees": 1000, "changeAddress": "15o5bzVX58t1NRvLchBUGuHscCs1sumr2R", - "change": 500 + "change": 500, + "privateKeys": [ + "a321c4996143e0add05864bbb694ceb399fbe5d0884d721b1a04755f9f7497a9", + "bbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866", + "619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9", + "eae04f225475e7630e58efdbefe50a003efd7e2ade3e67e171e023e9278b6ea4" + ] }, 'TRX': { "cmd": "TRC20", // can be TRC20 | TRX | TRC10 | CONTRACT | FREEZE @@ -320,6 +326,16 @@ runOperations() async { print('Transaction Check ...'); print([tx]); + print(operations[coin.code]["privateKeys"]); + String multiTxSign = await Trustdart.multiSignTransaction( + dondo, + coin.code, + coin.path, + operations[coin.code], + operations[coin.code]["privateKeys"]); + print('MultiSig Transaction Check ...'); + print([multiTxSign]); + String signedData = (await Trustdart.signDataWithPrivateKey( dondo, coin.code, diff --git a/ios/Classes/Coin.swift b/ios/Classes/Coin.swift index bfe1874..0a9e5c0 100644 --- a/ios/Classes/Coin.swift +++ b/ios/Classes/Coin.swift @@ -79,4 +79,21 @@ class Coin: CoinProtocol { } return nil } + + + + func multiSignTransaction(path: String, txData: [String: Any], privateKeys: [String]) -> String? { + let opJson = Utils.objToJson(from: txData) + var signatures = [String]() + + for privateKey in privateKeys { + let signature = AnySigner.signJSON(opJson!, key: privateKey.data(using: .utf8)!, coin: self.coinType) + signatures.append(signature) + } + if signatures.isEmpty { + return nil + } else { + return signatures.joined(separator: ",") + } +} } diff --git a/ios/Classes/SwiftTrustdartPlugin.swift b/ios/Classes/SwiftTrustdartPlugin.swift index e803fa4..2151b46 100644 --- a/ios/Classes/SwiftTrustdartPlugin.swift +++ b/ios/Classes/SwiftTrustdartPlugin.swift @@ -81,6 +81,28 @@ public class SwiftTrustdartPlugin: NSObject, FlutterPlugin { }else { result(err.details) } + + case "multiSignTransaction": + let args = call.arguments as! [String: Any] + let coin: String? = args["coin"] as? String + let path: String? = args["path"] as? String + let txData: [String: Any]? = args["txData"] as? [String: Any] + let privateKeys: [String]? = args["privateKeys"] as? [String] + let (isValid, err) = WalletHandler.validate(walletError: WalletError(code: .argumentsNull, message: "[coin] and [path] are required.", details: nil), coin, path) + + if isValid { + let txHash = WalletHandler().getCoin(coin!).multiSignTransaction(path: path!, txData: txData!, privateKeys: privateKeys ?? [] ) + + let (isValid, err) = WalletHandler.validate(walletError: WalletError(code: .txHashNull, message: "Failed to sign transaction.", details: nil), txHash) + if isValid { + result(txHash) + }else { + result(err.details) + } + }else { + result(err.details) + } + case "signDataWithPrivateKey": let args = call.arguments as! [String: Any] let coin: String? = args["coin"] as? String diff --git a/ios/Classes/coins/BTC.swift b/ios/Classes/coins/BTC.swift index 6479c0a..916e78c 100644 --- a/ios/Classes/coins/BTC.swift +++ b/ios/Classes/coins/BTC.swift @@ -61,4 +61,43 @@ class BTC: Coin { } } + + + + override func multiSignTransaction(path: String, txData: [String : Any], privateKeys: [String]) -> String? { + let utxos: [[String: Any]] = txData["utxos"] as! [[String: Any]] + var unspent: [BitcoinUnspentTransaction] = [] + + for utx in utxos { + unspent.append(BitcoinUnspentTransaction.with { + $0.outPoint.hash = Data.reverse(hexString: utx["txid"] as! String) + $0.outPoint.index = utx["vout"] as! UInt32 + $0.outPoint.sequence = UINT32_MAX + $0.amount = utx["value"] as! Int64 + $0.script = Data(hexString: utx["script"] as! String)! + }) + } + let privateKeyDataArray = privateKeys.compactMap { privateKey in + return Data(hexString: privateKey) + } + + let input: BitcoinSigningInput = BitcoinSigningInput.with { + $0.hashType = BitcoinScript.hashTypeForCoin(coinType: .bitcoin) + $0.amount = txData["amount"] as! Int64 + $0.toAddress = txData["toAddress"] as! String + $0.changeAddress = txData["changeAddress"] as! String // can be same sender address + $0.privateKey = privateKeyDataArray + $0.plan = BitcoinTransactionPlan.with { + $0.amount = txData["amount"] as! Int64 + $0.fee = txData["fees"] as! Int64 + $0.change = txData["change"] as! Int64 + $0.utxos = unspent + } + } + + let output: BitcoinSigningOutput = AnySigner.sign(input: input, coin: .bitcoin) + return output.encoded.hexString + + } + } diff --git a/ios/Classes/protocols/CoinProtocol.swift b/ios/Classes/protocols/CoinProtocol.swift index fb73e4e..0367028 100644 --- a/ios/Classes/protocols/CoinProtocol.swift +++ b/ios/Classes/protocols/CoinProtocol.swift @@ -18,4 +18,6 @@ protocol CoinProtocol { func validateAddress(address: String) -> Bool func signDataWithPrivateKey(path: String, mnemonic: String, passphrase: String, txData: String) -> String? func signTransaction(path: String, txData: [String: Any], mnemonic: String, passphrase: String) -> String? + func multiSignTransaction(path: String, txData: [String: Any], privateKeys: [String]) -> String? + } diff --git a/lib/trustdart.dart b/lib/trustdart.dart index 0d224cd..b366471 100644 --- a/lib/trustdart.dart +++ b/lib/trustdart.dart @@ -171,6 +171,23 @@ class Trustdart { } } + static Future multiSignTransaction(String mnemonic, String coin, + String path, Map txData, List? privateKeys, + [String passphrase = ""]) async { + try { + final String txHash = await _channel.invokeMethod( + 'multiSignTransaction', { + 'coin': coin, + 'txData': txData, + 'path': path, + 'privateKeys': privateKeys + }); + return txHash; + } catch (e) { + return ''; + } + } + static Future signDataWithPrivateKey( String mnemonic, String coin, String path, String txData, [String passphrase = ""]) async { From 50a0f3487406b476eb7ca3808bdb3dcb4a90a43d Mon Sep 17 00:00:00 2001 From: Rakeally <40327144+Rakeally@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:28:35 +0100 Subject: [PATCH 2/4] btc multi sign --- android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt b/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt index 9f6dc9b..8ddee25 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt @@ -9,7 +9,6 @@ import wallet.core.jni.BitcoinScript import wallet.core.jni.CoinType import wallet.core.jni.HDWallet import wallet.core.jni.proto.Bitcoin -import java.util.* From e9d7bfcc242ea48820ffe7343fb9e9130e71cbea Mon Sep 17 00:00:00 2001 From: rakeally Date: Wed, 13 Sep 2023 20:44:18 +0100 Subject: [PATCH 3/4] resolved review --- android/src/main/kotlin/africa/ejara/trustdart/Coin.kt | 5 ++--- .../kotlin/africa/ejara/trustdart/TrustdartPlugin.kt | 9 ++++----- .../src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt | 3 +-- .../africa/ejara/trustdart/interfaces/CoinInterface.kt | 3 +-- example/lib/operations.dart | 3 +-- ios/Classes/Coin.swift | 4 ++-- ios/Classes/SwiftTrustdartPlugin.swift | 9 ++++----- ios/Classes/coins/BTC.swift | 4 ++-- ios/Classes/protocols/CoinProtocol.swift | 2 +- lib/trustdart.dart | 6 ++---- 10 files changed, 20 insertions(+), 28 deletions(-) diff --git a/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt b/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt index 3b631e7..f8f5b17 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/Coin.kt @@ -44,13 +44,13 @@ open class Coin(nameOfCoin: String, typeOfCoin: CoinType) : CoinInterface { override fun getRawPrivateKey(path: String, mnemonic: String, passphrase: String): ByteArray? { val wallet = HDWallet(mnemonic, passphrase) return wallet.getKey(coinType, path).data() - } + } override fun getPublicKey(path: String, mnemonic: String, passphrase: String): String? { val wallet = HDWallet(mnemonic, passphrase) return wallet.getKey(coinType, path).getPublicKeySecp256k1(true).data().base64String() } - + override fun getRawPublicKey(path: String, mnemonic: String, passphrase: String): ByteArray? { val wallet = HDWallet(mnemonic, passphrase) return wallet.getKey(coinType, path).getPublicKeySecp256k1(true).data() @@ -84,7 +84,6 @@ open class Coin(nameOfCoin: String, typeOfCoin: CoinType) : CoinInterface { } override fun multiSignTransaction( - path: String, txData: Map, privateKeys: ArrayList ): String? { diff --git a/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt b/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt index a230af7..f9984c6 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/TrustdartPlugin.kt @@ -56,7 +56,7 @@ class TrustdartPlugin : FlutterPlugin, MethodCallHandler { validator.details.errorMessage, validator.details.errorDetails ) - } + } "checkMnemonic" -> { val mnemonic: String? = call.argument("mnemonic") val passphrase: String? = call.argument("passphrase") @@ -166,19 +166,18 @@ class TrustdartPlugin : FlutterPlugin, MethodCallHandler { } "multiSignTransaction" -> { val coin: String? = call.argument("coin") - val path: String? = call.argument("path") val txData: Map? = call.argument("txData") val privateKeys: ArrayList? = call.argument("privateKeys") var validator = WalletHandler().validate( WalletError( WalletHandlerErrorCodes.ArgumentsNull, - "[path], [coin], [privateKeys] and [txData] are required.", + "[coin], [privateKeys] and [txData] are required.", null - ), arrayOf(path, coin, txData, privateKeys) + ), arrayOf(coin, txData, privateKeys) ) if (validator.isValid) { val txHash = WalletHandler().getCoin(coin) - .multiSignTransaction(path!!, txData!!, privateKeys!!) + .multiSignTransaction(txData!!, privateKeys!!) validator = WalletHandler().validate( WalletError( WalletHandlerErrorCodes.TxHashNull, diff --git a/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt b/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt index 8ddee25..3c35715 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/coins/BTC.kt @@ -10,7 +10,7 @@ import wallet.core.jni.CoinType import wallet.core.jni.HDWallet import wallet.core.jni.proto.Bitcoin - + class BTC : Coin("BTC", CoinType.BITCOIN) { @@ -82,7 +82,6 @@ class BTC : Coin("BTC", CoinType.BITCOIN) { override fun multiSignTransaction( - path: String, txData: Map, privateKeys: ArrayList ): String? { diff --git a/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt b/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt index 74b7b5d..a7e556b 100644 --- a/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt +++ b/android/src/main/kotlin/africa/ejara/trustdart/interfaces/CoinInterface.kt @@ -1,5 +1,5 @@ package africa.ejara.trustdart.interfaces - + import com.google.protobuf.ByteString interface CoinInterface { @@ -13,7 +13,6 @@ interface CoinInterface { fun signDataWithPrivateKey(path: String, mnemonic: String, passphrase: String, txData: String): String? fun signTransaction(path: String, txData: Map, mnemonic: String, passphrase: String): String? fun multiSignTransaction( - path: String, txData: Map, privateKeys: ArrayList ): String? diff --git a/example/lib/operations.dart b/example/lib/operations.dart index a179493..bae9268 100644 --- a/example/lib/operations.dart +++ b/example/lib/operations.dart @@ -306,7 +306,7 @@ runOperations() async { bool valid = await Trustdart.validateAddress( coin.code, address['legacy']!, - ); + ); print([valid]); bool invalid = await Trustdart.validateAddress( @@ -330,7 +330,6 @@ runOperations() async { String multiTxSign = await Trustdart.multiSignTransaction( dondo, coin.code, - coin.path, operations[coin.code], operations[coin.code]["privateKeys"]); print('MultiSig Transaction Check ...'); diff --git a/ios/Classes/Coin.swift b/ios/Classes/Coin.swift index 0a9e5c0..5ed68c5 100644 --- a/ios/Classes/Coin.swift +++ b/ios/Classes/Coin.swift @@ -15,7 +15,7 @@ class Coin: CoinProtocol { init(name: String, coinType: CoinType){ self.name = name self.coinType = coinType - } + } func getName() -> String { return self.name @@ -82,7 +82,7 @@ class Coin: CoinProtocol { - func multiSignTransaction(path: String, txData: [String: Any], privateKeys: [String]) -> String? { + func multiSignTransaction(txData: [String: Any], privateKeys: [String]) -> String? { let opJson = Utils.objToJson(from: txData) var signatures = [String]() diff --git a/ios/Classes/SwiftTrustdartPlugin.swift b/ios/Classes/SwiftTrustdartPlugin.swift index 2151b46..b6d71d8 100644 --- a/ios/Classes/SwiftTrustdartPlugin.swift +++ b/ios/Classes/SwiftTrustdartPlugin.swift @@ -15,7 +15,7 @@ public class SwiftTrustdartPlugin: NSObject, FlutterPlugin { let wallet = WalletHandler().generateMnemonic(strength: 128, passphrase: call.arguments as! String) let (isValid, err) = WalletHandler.validate(walletError: WalletError(code: .noWallet, message: "Could not generate wallet", details: nil), wallet) if isValid { - result(wallet) + result(wallet) }else { result(err.details) } @@ -77,7 +77,7 @@ public class SwiftTrustdartPlugin: NSObject, FlutterPlugin { result(txHash) }else { result(err.details) - } + } }else { result(err.details) } @@ -85,13 +85,12 @@ public class SwiftTrustdartPlugin: NSObject, FlutterPlugin { case "multiSignTransaction": let args = call.arguments as! [String: Any] let coin: String? = args["coin"] as? String - let path: String? = args["path"] as? String let txData: [String: Any]? = args["txData"] as? [String: Any] let privateKeys: [String]? = args["privateKeys"] as? [String] - let (isValid, err) = WalletHandler.validate(walletError: WalletError(code: .argumentsNull, message: "[coin] and [path] are required.", details: nil), coin, path) + let (isValid, err) = WalletHandler.validate(walletError: WalletError(code: .argumentsNull, message: "[coin] are required.", details: nil), coin) if isValid { - let txHash = WalletHandler().getCoin(coin!).multiSignTransaction(path: path!, txData: txData!, privateKeys: privateKeys ?? [] ) + let txHash = WalletHandler().getCoin(coin!).multiSignTransaction(txData: txData!, privateKeys: privateKeys ?? [] ) let (isValid, err) = WalletHandler.validate(walletError: WalletError(code: .txHashNull, message: "Failed to sign transaction.", details: nil), txHash) if isValid { diff --git a/ios/Classes/coins/BTC.swift b/ios/Classes/coins/BTC.swift index 916e78c..86a0aa1 100644 --- a/ios/Classes/coins/BTC.swift +++ b/ios/Classes/coins/BTC.swift @@ -48,7 +48,7 @@ class BTC: Coin { $0.privateKey = [privateKey!.data] $0.plan = BitcoinTransactionPlan.with { $0.amount = txData["amount"] as! Int64 - $0.fee = txData["fees"] as! Int64 + $0.fee = txData["fees"] as! Int64 $0.change = txData["change"] as! Int64 $0.utxos = unspent } @@ -64,7 +64,7 @@ class BTC: Coin { - override func multiSignTransaction(path: String, txData: [String : Any], privateKeys: [String]) -> String? { + override func multiSignTransaction(txData: [String : Any], privateKeys: [String]) -> String? { let utxos: [[String: Any]] = txData["utxos"] as! [[String: Any]] var unspent: [BitcoinUnspentTransaction] = [] diff --git a/ios/Classes/protocols/CoinProtocol.swift b/ios/Classes/protocols/CoinProtocol.swift index 0367028..9f08df2 100644 --- a/ios/Classes/protocols/CoinProtocol.swift +++ b/ios/Classes/protocols/CoinProtocol.swift @@ -18,6 +18,6 @@ protocol CoinProtocol { func validateAddress(address: String) -> Bool func signDataWithPrivateKey(path: String, mnemonic: String, passphrase: String, txData: String) -> String? func signTransaction(path: String, txData: [String: Any], mnemonic: String, passphrase: String) -> String? - func multiSignTransaction(path: String, txData: [String: Any], privateKeys: [String]) -> String? + func multiSignTransaction(txData: [String: Any], privateKeys: [String]) -> String? } diff --git a/lib/trustdart.dart b/lib/trustdart.dart index b366471..020bc6d 100644 --- a/lib/trustdart.dart +++ b/lib/trustdart.dart @@ -171,15 +171,13 @@ class Trustdart { } } - static Future multiSignTransaction(String mnemonic, String coin, - String path, Map txData, List? privateKeys, - [String passphrase = ""]) async { + static Future multiSignTransaction(String coin, + String path, Map txData, List? privateKeys) async { try { final String txHash = await _channel.invokeMethod( 'multiSignTransaction', { 'coin': coin, 'txData': txData, - 'path': path, 'privateKeys': privateKeys }); return txHash; From 3e0e8d71a49924bac713196ca058a8262c30befc Mon Sep 17 00:00:00 2001 From: Rakeally <40327144+Rakeally@users.noreply.github.com> Date: Thu, 14 Sep 2023 10:11:49 +0100 Subject: [PATCH 4/4] resolved reviews --- example/lib/operations.dart | 9 +++------ lib/trustdart.dart | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/example/lib/operations.dart b/example/lib/operations.dart index bae9268..08fb7df 100644 --- a/example/lib/operations.dart +++ b/example/lib/operations.dart @@ -306,7 +306,7 @@ runOperations() async { bool valid = await Trustdart.validateAddress( coin.code, address['legacy']!, - ); + ); print([valid]); bool invalid = await Trustdart.validateAddress( @@ -327,11 +327,8 @@ runOperations() async { print([tx]); print(operations[coin.code]["privateKeys"]); - String multiTxSign = await Trustdart.multiSignTransaction( - dondo, - coin.code, - operations[coin.code], - operations[coin.code]["privateKeys"]); + String multiTxSign = await Trustdart.multiSignTransaction(coin.code, + operations[coin.code], operations[coin.code]["privateKeys"]); print('MultiSig Transaction Check ...'); print([multiTxSign]); diff --git a/lib/trustdart.dart b/lib/trustdart.dart index 020bc6d..5561c07 100644 --- a/lib/trustdart.dart +++ b/lib/trustdart.dart @@ -171,8 +171,8 @@ class Trustdart { } } - static Future multiSignTransaction(String coin, - String path, Map txData, List? privateKeys) async { + static Future multiSignTransaction( + String coin, Map txData, List? privateKeys) async { try { final String txHash = await _channel.invokeMethod( 'multiSignTransaction', {