A collection of useful primitives for cryptocurrency wallets.
Opinionated Swift wrapper around LibWally.
Supports particular enhancements used by Blockchain Commons from our fork of libwally-core: bc-libwally-core, in the bc-maintenance branch.
Depends on BCSwiftWally, which is a thin wrapper around LibWally that has a new build system for building a universal XCFramework for use with MacOSX, Mac Catalyst, iOS devices, and the iOS simulator across Intel and Apple Silicon (ARM).
Add to your project like any other Swift Package.
import BCFoundation
letmnemonic=BIP39(mnemonic:"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about")!
letseed=BIP39.Seed(bip39: mnemonic, passphrase:"bip39 passphrase")letmasterKey=try!HDKey(bip39Seed: seed)assert(masterKey.keyFingerprint.hex =="7b343b65")letpath=DerivationPath(string:"m/44'/0'/0'")!
letaccountKey=try!HDKey(parent: masterKey, childDerivationPath: path)assert(accountKey.base58PrivateKey =="xprv9z3bixmawU269r5jUAbWbVFDY3qN6LZdHH7r28C7gmZMXPfbN8o39622JvuyvQxBYPBMEtJNetWBCyy6hZXcAEubReyb95MnJQR5bAMiR2d")assert(accountKey.base58PublicKey =="xpub6D2x8UJUmqaPNLACaC8WxdBx65frVoHUeW3SpWbjF76LQBzjug7HgtLWACEbNoRubqXqM9y7t822g9RpEPPxmALG8tiZYVw5Ec66swihmUy")assert(Bitcoin.Address(hdKey: accountKey, type:.payToWitnessPubKeyHash).description =="bc1qtqq3hzwgswm56tt3h04ss8qmmttt6py9yj8h6c")import BCFoundation
letaccountKey=try!HDKey(base58:"xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ")letreceivePath=DerivationPath(string:"0/0")!
letreceiveKey=try!HDKey(parent: accountKey, childDerivationPath: receivePath)letaddress=Bitcoin.Address(hdKey: receiveKey, type:.payToPubKeyHash)assert(address.description =="1BiCdXSDHyeXSzmx2paVPFVTrmyx7BeCGD")assert(address.scriptPubKey.description =="pkh:[OP_DUP OP_HASH160 757c05317fcb85e910c5f3e6cd9dc4d06b5d8321 OP_EQUALVERIFY OP_CHECKSIG]")import BCFoundation
letaddress=Bitcoin.Address(string:"bc1q6zwjfmhdl4pvhvfpv8pchvtanlar8hrhqdyv0t")!
assert(address.scriptPubKey.hex =="0014d09d24eeedfd42cbb12161c38bb17d9ffa33dc77")assert(address.scriptPubKey.type! ==.wpkh)assert(address.scriptPubKey.description =="wpkh:[OP_0 d09d24eeedfd42cbb12161c38bb17d9ffa33dc77]")import BCFoundation
letpubKey=ECCompressedPublicKey(hex:"03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c")!
letprevTx=TxHash(hex:"0000000000000000000000000000000000000000000000000000000000000000")!
letvout:UInt32=0letlegacyInputBytes:Int=192letamount1:Satoshi=1000+ Satoshi(legacyInputBytes)letscriptSig=ScriptSig(type:.payToPubKeyHash(pubKey))letscriptPubKey1=ScriptPubKey(hex:"76a914bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe88ac")!
lettxInput1=TxInput(prevTx: prevTx, vout: vout, amount: amount1, sig:.scriptSig(scriptSig), scriptPubKey: scriptPubKey1)lethdKey=try!HDKey(base58:"xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs")lettxOutput=TxOutput(scriptPubKey: scriptPubKey1, amount:1000)lettx1=Transaction(inputs:[txInput1], outputs:[txOutput])letsignedTx= tx1.signed(with:[hdKey])!
assert(signedTx.inputs![0].isSigned)assert(signedTx.description =="01000000010000000000000000000000000000000000000000000000000000000000000000000000006a47304402203d274300310c06582d0186fc197106120c4838fa5d686fe3aa0478033c35b97802205379758b11b869ede2f5ab13a738493a93571268d66b2a875ae148625bd20578012103501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711cffffffff01e8030000000000001976a914bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe88ac00000000")assert(signedTx.vbytes == legacyInputBytes -1)