Skip to content

Repository files navigation

BCSwiftFoundation

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.

Dependencies

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).

Building

Add to your project like any other Swift Package.

Usage

Derive address from a seed:

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")

Derive address from an xpub:

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]")

Parse an address:

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]")

Create and sign a transaction:

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)

About

A collection of useful primitives for cryptocurrency wallets.

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages