From da966a5a5af095c1682ca19c6f92f2adb1209c87 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 19 Oct 2021 16:26:12 +0200 Subject: [PATCH] Add bech32m support --- LibWally/Address.swift | 13 ++++++++++--- LibWally/Script.swift | 8 ++++++-- LibWallyTests/AddressTests.swift | 22 +++++++++++++++++++--- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/LibWally/Address.swift b/LibWally/Address.swift index 39de30d7..3385fda2 100644 --- a/LibWally/Address.swift +++ b/LibWally/Address.swift @@ -3,8 +3,12 @@ // Address // // Created by Sjors on 14/06/2019. -// Copyright © 2019 Blockchain. Distributed under the MIT software -// license, see the accompanying file LICENSE.md +// Copyright © 2019 Blockchain. +// Copyright © 2021 Sjors Provoost. +// Distributed under the MIT software license, see the accompanying file LICENSE.md + +// Temporarily define this until libwally-core adds it (potentially with a different version) +let WALLY_ADDRESS_TYPE_P2TR: Int32 = 0x08 // P2TR taproot address ("bc1p..)" import Foundation import CLibWally @@ -13,6 +17,7 @@ public enum AddressType { case payToPubKeyHash // P2PKH (legacy) case payToScriptHashPayToWitnessPubKeyHash // P2SH-P2WPKH (wrapped SegWit) case payToWitnessPubKeyHash // P2WPKH (native SegWit) + case payToTaproot // P2TR (Taproot) } public protocol AddressProtocol : LosslessStringConvertible { @@ -75,6 +80,8 @@ public struct Address : AddressProtocol { return WALLY_ADDRESS_TYPE_P2SH_P2WPKH case .payToWitnessPubKeyHash: return WALLY_ADDRESS_TYPE_P2WPKH + case .payToTaproot: + return WALLY_ADDRESS_TYPE_P2TR } }() @@ -130,7 +137,7 @@ public struct Address : AddressProtocol { precondition(wally_scriptpubkey_to_address(bytes, bytes_len, UInt32(network == .mainnet ? WALLY_NETWORK_BITCOIN_MAINNET : WALLY_NETWORK_BITCOIN_TESTNET), &output) == WALLY_OK) precondition(output != nil) self.address = String(cString: output!) - case .payToWitnessPubKeyHash, .payToWitnessScriptHash: + case .payToWitnessPubKeyHash, .payToWitnessScriptHash, .payToTaproot: var family: String switch network { case .mainnet: diff --git a/LibWally/Script.swift b/LibWally/Script.swift index 88d7c56f..32620149 100644 --- a/LibWally/Script.swift +++ b/LibWally/Script.swift @@ -3,8 +3,9 @@ // Script // // Created by Sjors on 14/06/2019. -// Copyright © 2019 Blockchain. Distributed under the MIT software -// license, see the accompanying file LICENSE.md +// Copyright © 2019 Blockchain. +// Copyright © 2021 Sjors Provoost. +// Distributed under the MIT software license, see the accompanying file LICENSE.md import Foundation import CLibWally @@ -17,6 +18,7 @@ public enum ScriptType { case payToScriptHash // P2SH (could be wrapped SegWit) case payToWitnessPubKeyHash // P2WPKH (native SegWit) case payToWitnessScriptHash // P2WS (native SegWit script) + case payToTaproot // P2TR (taproot script) case multiSig } @@ -60,6 +62,8 @@ public struct ScriptPubKey : LosslessStringConvertible, Equatable { return .payToWitnessPubKeyHash case WALLY_SCRIPT_TYPE_P2WSH: return .payToWitnessScriptHash + case WALLY_SCRIPT_TYPE_P2TR: + return .payToTaproot case WALLY_SCRIPT_TYPE_MULTISIG: return .multiSig default: diff --git a/LibWallyTests/AddressTests.swift b/LibWallyTests/AddressTests.swift index e605cd70..b3962de8 100644 --- a/LibWallyTests/AddressTests.swift +++ b/LibWallyTests/AddressTests.swift @@ -2,9 +2,10 @@ // AddressTests.swift // AddressTests // -// Created by Bitcoin Dev on 14/06/2019. -// Copyright © 2019 Blockchain. Distributed under the MIT software -// license, see the accompanying file LICENSE.md +// Created by Sjors Provoost on 14/06/2019. +// Copyright © 2019 Blockchain. +// Copyright © 2021 Sjors Provoost. +// Distributed under the MIT software license, see the accompanying file LICENSE.md import XCTest @testable import LibWally @@ -69,7 +70,22 @@ class AddressTests: XCTestCase { XCTAssertNotNil(address) XCTAssertEqual(address!.scriptPubKey, ScriptPubKey("0014bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe")) } + + func testParseTaprootAddress() { + let address = Address("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0") + XCTAssertNotNil(address) + XCTAssertEqual(address!.scriptPubKey.type, .payToTaproot) + XCTAssertEqual(address!.scriptPubKey, ScriptPubKey("512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")) + } + func testRenderTaprootAddress() { + let scriptPubKey = ScriptPubKey("512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798") + XCTAssertEqual(scriptPubKey!.type, .payToTaproot) + let address = Address(scriptPubKey!, .mainnet) + XCTAssertNotNil(address) + XCTAssertEqual(address!.description, "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0") + } + func testECDHDerivation() { let privKey = Key(Data("9cd3b16e10bd574fed3743d8e0de0b7b4e6c69f3245ab5a168ef010d22bfefa0")!, .mainnet) XCTAssertNotNil(privKey)