mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
Fix 1.8.0 of website (#3770)
This commit is contained in:
parent
01a7c7c838
commit
c0f2aa73db
@ -161,6 +161,9 @@
|
||||
"wallet/wallet-get-address": {
|
||||
"title": "Wallet Get Address APIs"
|
||||
},
|
||||
"wallet/wallet-price-example": {
|
||||
"title": "Wallet Price Example"
|
||||
},
|
||||
"wallet/wallet-rescan": {
|
||||
"title": "Wallet Rescans"
|
||||
},
|
||||
@ -775,6 +778,108 @@
|
||||
},
|
||||
"version-1.7.0/wallet/version-1.7.0-wallet-rpc": {
|
||||
"title": "Wallet RPC Examples"
|
||||
},
|
||||
"version-1.8.0/applications/version-1.8.0-server": {
|
||||
"title": "Application Server"
|
||||
},
|
||||
"version-1.8.0/chain/version-1.8.0-chain-query-api": {
|
||||
"title": "Chain Query API"
|
||||
},
|
||||
"version-1.8.0/chain/version-1.8.0-chain": {
|
||||
"title": "Blockchain Verification"
|
||||
},
|
||||
"version-1.8.0/chain/version-1.8.0-filter-sync": {
|
||||
"title": "Syncing Blockfilters"
|
||||
},
|
||||
"version-1.8.0/config/version-1.8.0-configuration": {
|
||||
"title": "Application Configuration"
|
||||
},
|
||||
"version-1.8.0/core/version-1.8.0-addresses": {
|
||||
"title": "Generating Addresses"
|
||||
},
|
||||
"version-1.8.0/core/version-1.8.0-dlc": {
|
||||
"title": "Discreet Log Contract Data Structures"
|
||||
},
|
||||
"version-1.8.0/core/version-1.8.0-hd-keys": {
|
||||
"title": "HD Key Generation"
|
||||
},
|
||||
"version-1.8.0/core/version-1.8.0-txbuilder": {
|
||||
"title": "TxBuilder Example"
|
||||
},
|
||||
"version-1.8.0/crypto/version-1.8.0-sign": {
|
||||
"title": "Sign API"
|
||||
},
|
||||
"version-1.8.0/version-1.8.0-getting-setup": {
|
||||
"title": "Getting Bitcoin-S installed on your machine"
|
||||
},
|
||||
"version-1.8.0/version-1.8.0-getting-started": {
|
||||
"title": "Intro and Getting Started"
|
||||
},
|
||||
"version-1.8.0/key-manager/version-1.8.0-key-manager": {
|
||||
"title": "Key Manager"
|
||||
},
|
||||
"version-1.8.0/node/version-1.8.0-node-api title: Node API": {
|
||||
"title": "node-api title: Node API"
|
||||
},
|
||||
"version-1.8.0/node/version-1.8.0-node": {
|
||||
"title": "Light Client"
|
||||
},
|
||||
"version-1.8.0/node/version-1.8.0-tor": {
|
||||
"title": "Setting up Tor with Light Client"
|
||||
},
|
||||
"version-1.8.0/oracle-explorer-client/version-1.8.0-oracle-explorer-client": {
|
||||
"title": "Oracle Explorer Client"
|
||||
},
|
||||
"version-1.8.0/oracle/version-1.8.0-oracle-election-example": {
|
||||
"title": "Election Example"
|
||||
},
|
||||
"version-1.8.0/oracle/version-1.8.0-oracle-price-example": {
|
||||
"title": "Price Example"
|
||||
},
|
||||
"version-1.8.0/oracle/version-1.8.0-oracle-server": {
|
||||
"title": "Oracle Server"
|
||||
},
|
||||
"version-1.8.0/rpc/version-1.8.0-rpc-bitcoind": {
|
||||
"title": "bitcoind/Bitcoin Core"
|
||||
},
|
||||
"version-1.8.0/rpc/version-1.8.0-rpc-eclair": {
|
||||
"title": "Eclair"
|
||||
},
|
||||
"version-1.8.0/rpc/version-1.8.0-lnd-rpc": {
|
||||
"title": "LND"
|
||||
},
|
||||
"version-1.8.0/secp256k1/version-1.8.0-jni-modify": {
|
||||
"title": "Adding to Secp256k1 JNI"
|
||||
},
|
||||
"version-1.8.0/secp256k1/version-1.8.0-secp256k1": {
|
||||
"title": "Secp256k1"
|
||||
},
|
||||
"version-1.8.0/testkit/version-1.8.0-testkit": {
|
||||
"title": "Testkit"
|
||||
},
|
||||
"version-1.8.0/tor/version-1.8.0-tor": {
|
||||
"title": "Tor Setup"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-dlc": {
|
||||
"title": "Executing A DLC with Bitcoin-S"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-wallet-callbacks": {
|
||||
"title": "Wallet Callbacks"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-wallet-election-example": {
|
||||
"title": "Wallet Election Example"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-wallet-price-example": {
|
||||
"title": "Wallet Price Example"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-wallet-rescan": {
|
||||
"title": "Wallet Rescans"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-wallet-sync": {
|
||||
"title": "Wallet Sync"
|
||||
},
|
||||
"version-1.8.0/wallet/version-1.8.0-wallet": {
|
||||
"title": "Wallet"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
|
@ -139,8 +139,10 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
|
||||
|
||||
## Server Endpoints
|
||||
|
||||
### Blockchain
|
||||
### Common
|
||||
- `getversion` - The version of our application you are using
|
||||
|
||||
### Blockchain
|
||||
- `getblockcount` - Get the current block height
|
||||
- `getfiltercount` - Get the number of filters
|
||||
- `getfilterheadercount` - Get the number of filter headers
|
||||
@ -189,8 +191,8 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
|
||||
- `amount` - Amount to send in BTC
|
||||
- `--feerate <value>` - Fee rate in sats per virtual byte
|
||||
- `sweepwallet` `address` `[options]` - Sends the entire wallet balance to the given address
|
||||
- `address` - Address to send to
|
||||
- `--feerate <value>` - Fee rate in sats per virtual byte
|
||||
- `address` - Address to send to
|
||||
- `--feerate <value>` - Fee rate in sats per virtual byte
|
||||
- `sendwithalgo` `address` `amount` `algo` `[options]` - Send money to the given address using a specific coin selection algo
|
||||
- `address` - Address to send to
|
||||
- `amount` - Amount to send in BTC
|
||||
@ -214,18 +216,80 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
|
||||
- `unlock` - Whether to unlock (true) or lock (false) the specified transactions
|
||||
- `transactions` - The transaction outpoints to unlock/lock, empty to apply to all utxos
|
||||
- `importseed` `walletname` `words` `passphrase` - Imports a mnemonic seed as a new seed file
|
||||
- `walletname` - Name to associate with this seed
|
||||
- `words` - Mnemonic seed words, space separated
|
||||
- `passphrase` - Passphrase to encrypt this seed with
|
||||
- `walletname` - Name to associate with this seed
|
||||
- `words` - Mnemonic seed words, space separated
|
||||
- `passphrase` - Passphrase to encrypt this seed with
|
||||
- `importxprv` `walletname` `xprv` `passphrase` - Imports a mnemonic seed as a new seed file
|
||||
- `walletname` - Name to associate with this seed
|
||||
- `xprv` - base58 encoded extended private key
|
||||
- `passphrase` - Passphrase to encrypt this seed with
|
||||
- `walletname` - Name to associate with this seed
|
||||
- `xprv` - base58 encoded extended private key
|
||||
- `passphrase` - Passphrase to encrypt this seed with
|
||||
- `keymanagerpassphrasechange` `oldpassphrase` `newpassphrase` - Changes the wallet passphrase
|
||||
- `oldpassphrase` - The current passphrase
|
||||
- `newpassphrase` - The new passphrase
|
||||
- `keymanagerpassphraseset` `passphrase` - Encrypts the wallet with the given passphrase
|
||||
- `passphrase` - The passphrase to encrypt the wallet with
|
||||
- `backupwallet` `location` - Backs up the wallet database in a safe and consistent manner.
|
||||
- `location` - The locations of the backup file
|
||||
|
||||
### DLC
|
||||
- `createcontractinfo` `announcement` `totalCollateral` `payouts`
|
||||
- the announcement to build the contract info for
|
||||
- the total amount of collateral in the DLC
|
||||
- The payouts can be in two formats
|
||||
1. `{ "outcomes" : { "outcome0" : 0, "outcome1": 1, ... }}`. The number is the amount of sats paid to YOU for that outcome.
|
||||
2. `[{"outcome":0,"payout":0,"extraPrecision":0,"isEndpoint":true}, {"outcome":1,"payout":1,"extraPrecision":0,"isEndpoint":true}, ...]`
|
||||
- `decodecontractinfo` `contractinfo` - Decodes a contract info into json
|
||||
- `contractinfo` - Hex encoded contract info
|
||||
- `decodeoffer` `offer` - Decodes an offer message into json
|
||||
- `offer` - Hex encoded dlc offer message
|
||||
- `decodeannouncement` `announcement` - Decodes an oracle announcement message into json
|
||||
- `announcement` - Hex encoded oracle announcement message
|
||||
- `decodeattestments` `attestments` - Decodes an oracle attestments message into json
|
||||
- `attestments` - Hex encoded oracle attestments message
|
||||
- `getdlchostaddress` - Returns the public listening address of the DLC Node
|
||||
- `createdlcoffer` `contractInfo` `collateral` `[feerate]` `locktime` `refundlocktime` - Creates a DLC offer that another party can accept
|
||||
- `contractInfo` - Hex encoded contractInfo message
|
||||
- `collateral` - Satoshis to fund your side of the DLC
|
||||
- `feerate` - Fee rate for both funding and closing transactions, in sats/vbytes
|
||||
- `locktime` - Locktime of the contract execution transactions
|
||||
- `refundlocktime` - Locktime of the refund transaction
|
||||
- `acceptdlc` `offer` `peer` - Accepts a DLC offer given from another party
|
||||
- `offer` - Hex encoded dlc offer message
|
||||
- `peer` - Peer's network address
|
||||
- `acceptdlcoffer` `offer` - Accepts a DLC offer given from another party
|
||||
- `offer` - Hex encoded offer message
|
||||
- `acceptdlcofferfromfile` `path` `[destination]` - Accepts a DLC offer given from another party
|
||||
- `path` - Path to dlc offer file
|
||||
- `destination` - Path to write dlc accept message
|
||||
- `signdlc` `accept` - Signs a DLC
|
||||
- `accept` - Hex encoded dlc accept message
|
||||
- `signdlcfromfile` `path` `[destination]` - Signs a DLC
|
||||
- `path` - Path to dlc accept file
|
||||
- `destination` - Path to write dlc sign message
|
||||
- `adddlcsigs` `sigs` - Adds DLC Signatures into the database
|
||||
- `sigs` - Hex encoded dlc sign message
|
||||
- `adddlcsigsfromfile` `path` - Adds DLC Signatures into the database
|
||||
- `path` - Path to dlc sign file
|
||||
- `adddlcsigsandbroadcast` `sigs` - Adds DLC Signatures into the database and broadcasts the funding transaction
|
||||
- `sigs` - Hex encoded dlc sign message
|
||||
- `adddlcsigsandbroadcastfromfile` `path` - Adds DLC Signatures into the database and broadcasts the funding transaction
|
||||
- `path` - Path to dlc sign file
|
||||
- `getdlcfundingtx` `contractId` - Returns the Funding Tx corresponding to the DLC with the given contractId
|
||||
- `contractId` - ContractId of the DLC
|
||||
- `broadcastdlcfundingtx` `contractId` - Broadcasts the funding Tx corresponding to the DLC with the given contractId
|
||||
- `contractId` - ContractId of the DLC
|
||||
- `executedlc` `contractId` `oraclesigs` `[options]` - Executes the DLC with the given contractId
|
||||
- `contractId` - ContractId of the DLC
|
||||
- `oraclesigs` - Array of oracle attestations
|
||||
- `--noBroadcast` - Gives full serialized transaction instead of broadcasting
|
||||
- `executedlcrefund` `contractId` `[options]` - Executes the Refund transaction for the given DLC
|
||||
- `contractId` - ContractId of the DLC
|
||||
- `--noBroadcast` - Gives full serialized transaction instead of broadcasting
|
||||
- `canceldlc` `dlcId` - Cancels a DLC and unreserves used utxos
|
||||
- `dlcId` - Internal id of the DLC
|
||||
- `getdlcs` - Returns all dlcs in the wallet
|
||||
- `getdlc` `dlcId` - Gets a specific dlc in the wallet
|
||||
- `dlcId` - Internal id of the DLC
|
||||
|
||||
### Network
|
||||
- `getpeers` - List the connected peers
|
||||
|
@ -245,6 +245,10 @@ bitcoin-s {
|
||||
|
||||
requiredConfirmations = 6
|
||||
|
||||
# Expected average fee rate over the long term
|
||||
# in satoshis per virtual byte
|
||||
longTermFeeRate = 10
|
||||
|
||||
# How big the address queue size is before we throw an exception
|
||||
# because of an overflow
|
||||
addressQueueSize = 10
|
||||
@ -266,6 +270,11 @@ bitcoin-s {
|
||||
|
||||
# Password that your seed is encrypted with
|
||||
aesPassword = changeMe
|
||||
|
||||
# At least 16 bytes of entropy encoded in hex
|
||||
# This will be used as the seed for any
|
||||
# project that is dependent on the keymanager
|
||||
entropy = ""
|
||||
}
|
||||
|
||||
# Bitcoin-S provides manny different fee providers
|
||||
|
@ -27,7 +27,7 @@ reason to keep using legacy transaction formats.
|
||||
val privkey = ECPrivateKey()
|
||||
// privkey: ECPrivateKey = Masked(ECPrivateKey)
|
||||
val pubkey = privkey.publicKey
|
||||
// pubkey: org.bitcoins.crypto.ECPublicKey = ECPublicKey(020da93f0234a254ea1a03c6b06e63c8f80ccc2b479822e60d0edfce39415332e5)
|
||||
// pubkey: org.bitcoins.crypto.ECPublicKey = ECPublicKey(0215f72a0df6644d33ecc352c731eec98ac4eee6243c6be0035ba92ad60c8000a4)
|
||||
|
||||
val segwitAddress = {
|
||||
// see https://bitcoin.org/en/glossary/pubkey-script
|
||||
@ -36,10 +36,10 @@ val segwitAddress = {
|
||||
val scriptPubKey = P2WPKHWitnessSPKV0(pubkey)
|
||||
Bech32Address(scriptPubKey, TestNet3)
|
||||
}
|
||||
// segwitAddress: Bech32Address = tb1q5zftsyt25tfjhz3ydv5upas4jl7v2pyrt7ja4t
|
||||
// segwitAddress: Bech32Address = tb1qctl5hvwm6rt8zg9waumnxa4vd5vr5lhmass4sm
|
||||
|
||||
println(segwitAddress.toString)
|
||||
// tb1q5zftsyt25tfjhz3ydv5upas4jl7v2pyrt7ja4t
|
||||
// tb1qctl5hvwm6rt8zg9waumnxa4vd5vr5lhmass4sm
|
||||
```
|
||||
|
||||
## Generating legacy (base58) addresses
|
||||
@ -52,8 +52,8 @@ Take a look:
|
||||
// we're reusing the same private/public key pair
|
||||
// from before. don't do this in an actual application!
|
||||
val legacyAddress = P2PKHAddress(pubkey, TestNet3)
|
||||
// legacyAddress: P2PKHAddress = mv9zAxoBHvG1Loa79XnwvNEmBxVkb4E1Cr
|
||||
// legacyAddress: P2PKHAddress = myJ1DXMQvzcUxMs8qwgjjjpGdM9S1JSTDG
|
||||
|
||||
println(legacyAddress.toString)
|
||||
// mv9zAxoBHvG1Loa79XnwvNEmBxVkb4E1Cr
|
||||
// myJ1DXMQvzcUxMs8qwgjjjpGdM9S1JSTDG
|
||||
```
|
||||
|
File diff suppressed because one or more lines are too long
@ -30,13 +30,13 @@ import org.bitcoins.core.hd._
|
||||
// how long our phrase ends up being
|
||||
// 256 bits of entropy results in 24 words
|
||||
val entropy: BitVector = MnemonicCode.getEntropy256Bits
|
||||
// entropy: BitVector = BitVector(256 bits, 0x102a49220ec3afbe50424890fa160dd1bf84514e458d1007f2ec82dd46e2d91d)
|
||||
// entropy: BitVector = BitVector(256 bits, 0xf7dc41290eed76fdf1fd3dfacc963cc88cf1ac1130efc14bbbc9726dee401521)
|
||||
|
||||
val mnemonicCode = MnemonicCode.fromEntropy(entropy)
|
||||
// mnemonicCode: MnemonicCode = Masked(MnemonicCodeImpl)
|
||||
|
||||
mnemonicCode.words // the phrase the user should write down
|
||||
// res0: Vector[String] = Vector(awake, false, embrace, budget, depend, tennis, donate, empower, movie, spawn, lock, pet, weapon, chunk, decorate, random, avoid, display, robot, aisle, stamp, imitate, good, prevent) // the phrase the user should write down
|
||||
// res0: Vector[String] = Vector(water, tilt, engage, build, student, leave, side, police, width, gorilla, monkey, much, someone, stock, dynamic, bulb, scout, fruit, venture, tooth, ten, cactus, fee, crew) // the phrase the user should write down
|
||||
|
||||
// the password argument is an optional, extra security
|
||||
// measure. all MnemonicCode instances will give you a
|
||||
@ -52,7 +52,7 @@ val xpriv = ExtPrivateKey.fromBIP39Seed(ExtKeyVersion.SegWitMainNetPriv,
|
||||
bip39Seed)
|
||||
// xpriv: ExtPrivateKey = Masked(ExtPrivateKeyImpl)
|
||||
val xpub = xpriv.extPublicKey
|
||||
// xpub: ExtPublicKey = zpub6jftahH18ngZwXWgKnZuhTPDTZmpnirTf8Egk51uGom33iFtJy8xkXjEeFvD1TdR4kWewyBqLMugDZyzerDn4Ukis2oY5UHLGanskzw7dma
|
||||
// xpub: ExtPublicKey = zpub6jftahH18ngZy6MsuwdYevKYzrWPBLqk7HXUJspgzCjYki1Y9dkfEmJcszAR1SxjDzP7H3P2V9mFUDcxwLhi8XyRMcZmj1MvXQkYGRQvioK
|
||||
|
||||
// you can now use the generated xpriv to derive further
|
||||
// private or public keys
|
||||
@ -103,7 +103,7 @@ val accountXpub = {
|
||||
// can generate addresses with it!
|
||||
accountXpriv.extPublicKey
|
||||
}
|
||||
// accountXpub: ExtPublicKey = zpub6qR7NyHhy8WjZ6a4iDoNfnGPMvs5qYNsSCEKYmM1x7SVwqp2wG46W9VzWnjkfiioHcdh74CUP9aF6wqhqguALVxGY3hXGnYUtyEFWSZTps9
|
||||
// accountXpub: ExtPublicKey = zpub6s4RZ4v5EdMGVimLDhx5gQhtb9NQi8XpJon97XsAEdGLaVguMYhr4QUocQpHydTmKqFW5RMm4XVeAWpuLZ42Ka3ouNKxzcwyjgWRdfhc6zR
|
||||
|
||||
// address no. 0 ---------------┐
|
||||
// external address ----------┐ |
|
||||
@ -126,12 +126,12 @@ val firstAccountAddress = {
|
||||
val scriptPubKey = P2WPKHWitnessSPKV0(pubkey)
|
||||
Bech32Address(scriptPubKey, TestNet3)
|
||||
}
|
||||
// firstAccountAddress: Bech32Address = tb1qlwuqstg4xxndk7d200e95x8hu5cg70ncmfqa60
|
||||
// firstAccountAddress: Bech32Address = tb1qzx29dfn3m94fmujuscz6h3xeuv7t552ev67zeh
|
||||
|
||||
// tada! We just generated an address you can send money to,
|
||||
// without having access to the private key!
|
||||
firstAccountAddress.value
|
||||
// res2: String = tb1qlwuqstg4xxndk7d200e95x8hu5cg70ncmfqa60
|
||||
// res2: String = tb1qzx29dfn3m94fmujuscz6h3xeuv7t552ev67zeh
|
||||
|
||||
// you can now continue deriving addresses from the same public
|
||||
// key, by imitating what we did above. To get the next
|
||||
|
@ -9,7 +9,7 @@ Bitcoin-S features a transaction building API that allows you to construct and s
|
||||
|
||||
```scala
|
||||
implicit val ec: ExecutionContext = ExecutionContext.Implicits.global
|
||||
// ec: ExecutionContext = scala.concurrent.impl.ExecutionContextImpl$$anon$3@381c8be6[Running, parallelism = 8, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
|
||||
// ec: ExecutionContext = scala.concurrent.impl.ExecutionContextImpl$$anon$3@4b78417f[Running, parallelism = 16, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
|
||||
|
||||
// Initialize a transaction builder
|
||||
val builder = RawTxBuilder()
|
||||
@ -19,19 +19,19 @@ val builder = RawTxBuilder()
|
||||
val privKey = ECPrivateKey.freshPrivateKey
|
||||
// privKey: ECPrivateKey = Masked(ECPrivateKey)
|
||||
val pubKey = privKey.publicKey
|
||||
// pubKey: ECPublicKey = ECPublicKey(02261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831)
|
||||
// pubKey: ECPublicKey = ECPublicKey(036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e)
|
||||
|
||||
// this is the script that the TxBuilder is going to create a
|
||||
// script signature that validly spends this scriptPubKey
|
||||
val creditingSpk = P2PKHScriptPubKey(pubKey = privKey.publicKey)
|
||||
// creditingSpk: P2PKHScriptPubKey = pkh(2c880c352e5b10e387055c19309f1534f2fc77af)
|
||||
// creditingSpk: P2PKHScriptPubKey = pkh(db55b744b69cf3434f84a9c2b95a1d31dfacbf40)
|
||||
val amount = 10000.satoshis
|
||||
// amount: Satoshis = 10000 sats
|
||||
|
||||
// this is the UTXO we are going to be spending
|
||||
val utxo =
|
||||
TransactionOutput(value = amount, scriptPubKey = creditingSpk)
|
||||
// utxo: TransactionOutput = TransactionOutput(10000 sats,pkh(2c880c352e5b10e387055c19309f1534f2fc77af))
|
||||
// utxo: TransactionOutput = TransactionOutput(10000 sats,pkh(db55b744b69cf3434f84a9c2b95a1d31dfacbf40))
|
||||
|
||||
// the private key that locks the funds for the script we are spending too
|
||||
val destinationPrivKey = ECPrivateKey.freshPrivateKey
|
||||
@ -44,7 +44,7 @@ val destinationAmount = 5000.satoshis
|
||||
// the script that corresponds to destination private key, this is what is receiving the money
|
||||
val destinationSPK =
|
||||
P2PKHScriptPubKey(pubKey = destinationPrivKey.publicKey)
|
||||
// destinationSPK: P2PKHScriptPubKey = pkh(7455d9f20af11d6ee888f9509a0d52c647e16f84)
|
||||
// destinationSPK: P2PKHScriptPubKey = pkh(8af1a6bbac7250d13f6cb0aa6c9ee792654531a1)
|
||||
|
||||
// this is where we are sending money too
|
||||
// we could add more destinations here if we
|
||||
@ -55,7 +55,7 @@ val destinations = {
|
||||
|
||||
Vector(destination0)
|
||||
}
|
||||
// destinations: Vector[TransactionOutput] = Vector(TransactionOutput(5000 sats,pkh(7455d9f20af11d6ee888f9509a0d52c647e16f84)))
|
||||
// destinations: Vector[TransactionOutput] = Vector(TransactionOutput(5000 sats,pkh(8af1a6bbac7250d13f6cb0aa6c9ee792654531a1)))
|
||||
|
||||
// Add the destinations to the tx builder
|
||||
builder ++= destinations
|
||||
@ -68,17 +68,17 @@ val creditingTx = BaseTransaction(version = Int32.one,
|
||||
inputs = Vector.empty,
|
||||
outputs = Vector(utxo),
|
||||
lockTime = UInt32.zero)
|
||||
// creditingTx: BaseTransaction = BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(2c880c352e5b10e387055c19309f1534f2fc77af))),UInt32Impl(0))
|
||||
// creditingTx: BaseTransaction = BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(db55b744b69cf3434f84a9c2b95a1d31dfacbf40))),UInt32Impl(0))
|
||||
|
||||
// this is the information we need from the crediting TX
|
||||
// to properly "link" it in the transaction we are creating
|
||||
val outPoint = TransactionOutPoint(creditingTx.txId, UInt32.zero)
|
||||
// outPoint: TransactionOutPoint = TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0)
|
||||
// outPoint: TransactionOutPoint = TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0)
|
||||
val input = TransactionInput(
|
||||
outPoint,
|
||||
EmptyScriptSignature,
|
||||
sequenceNumber = UInt32.zero)
|
||||
// input: TransactionInput = TransactionInputImpl(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),EmptyScriptSignature,UInt32Impl(0))
|
||||
// input: TransactionInput = TransactionInputImpl(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),EmptyScriptSignature,UInt32Impl(0))
|
||||
|
||||
// Add a new input to our builder
|
||||
builder += input
|
||||
@ -86,11 +86,11 @@ builder += input
|
||||
|
||||
// We can now generate a RawTxBuilderResult ready to be finalized
|
||||
val builderResult = builder.result()
|
||||
// builderResult: RawTxBuilderResult = RawTxBuilderResult(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(7455d9f20af11d6ee888f9509a0d52c647e16f84))),UInt32Impl(0))
|
||||
// builderResult: RawTxBuilderResult = RawTxBuilderResult(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(8af1a6bbac7250d13f6cb0aa6c9ee792654531a1))),UInt32Impl(0))
|
||||
|
||||
// this contains the information needed to analyze our input during finalization
|
||||
val inputInfo = P2PKHInputInfo(outPoint, amount, privKey.publicKey)
|
||||
// inputInfo: P2PKHInputInfo = P2PKHInputInfo(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),10000 sats,ECPublicKey(02261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831))
|
||||
// inputInfo: P2PKHInputInfo = P2PKHInputInfo(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),10000 sats,ECPublicKey(036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e))
|
||||
|
||||
// this is how much we are going to pay as a fee to the network
|
||||
// for this example, we are going to pay 1 satoshi per byte
|
||||
@ -100,18 +100,18 @@ val feeRate = SatoshisPerByte(1.satoshi)
|
||||
val changePrivKey = ECPrivateKey.freshPrivateKey
|
||||
// changePrivKey: ECPrivateKey = Masked(ECPrivateKey)
|
||||
val changeSPK = P2PKHScriptPubKey(pubKey = changePrivKey.publicKey)
|
||||
// changeSPK: P2PKHScriptPubKey = pkh(f05a1269fb55b9da304f8e9a6a3c02eee359620b)
|
||||
// changeSPK: P2PKHScriptPubKey = pkh(15dd7b93b6a03b8160d5cdded8be7af814b2c10d)
|
||||
|
||||
// We chose a finalizer that adds a change output to our tx based on a fee rate
|
||||
val finalizer = StandardNonInteractiveFinalizer(
|
||||
Vector(inputInfo),
|
||||
feeRate,
|
||||
changeSPK)
|
||||
// finalizer: StandardNonInteractiveFinalizer = StandardNonInteractiveFinalizer(Vector(P2PKHInputInfo(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),10000 sats,ECPublicKey(02261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831))),1 sats/byte,pkh(f05a1269fb55b9da304f8e9a6a3c02eee359620b))
|
||||
// finalizer: StandardNonInteractiveFinalizer = StandardNonInteractiveFinalizer(Vector(P2PKHInputInfo(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),10000 sats,ECPublicKey(036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e))),1 sats/byte,pkh(15dd7b93b6a03b8160d5cdded8be7af814b2c10d))
|
||||
|
||||
// We can now finalize the tx builder result from earlier with this finalizer
|
||||
val unsignedTx: Transaction = finalizer.buildTx(builderResult)
|
||||
// unsignedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(7455d9f20af11d6ee888f9509a0d52c647e16f84)), TransactionOutput(4775 sats,pkh(f05a1269fb55b9da304f8e9a6a3c02eee359620b))),UInt32Impl(0))
|
||||
// unsignedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(8af1a6bbac7250d13f6cb0aa6c9ee792654531a1)), TransactionOutput(4775 sats,pkh(15dd7b93b6a03b8160d5cdded8be7af814b2c10d))),UInt32Impl(0))
|
||||
|
||||
// We now turn to signing the unsigned transaction
|
||||
// this contains all the information we need to
|
||||
@ -121,12 +121,12 @@ val utxoInfo = ScriptSignatureParams(inputInfo = inputInfo,
|
||||
signers = Vector(privKey),
|
||||
hashType =
|
||||
HashType.sigHashAll)
|
||||
// utxoInfo: ScriptSignatureParams[P2PKHInputInfo] = ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),10000 sats,ECPublicKey(02261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(2c880c352e5b10e387055c19309f1534f2fc77af))),UInt32Impl(0)),Vector(Masked(ECPrivateKey)),SIGHASH_ALL(Int32Impl(1)))
|
||||
// utxoInfo: ScriptSignatureParams[P2PKHInputInfo] = ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),10000 sats,ECPublicKey(036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(db55b744b69cf3434f84a9c2b95a1d31dfacbf40))),UInt32Impl(0)),Vector(Masked(ECPrivateKey)),SIGHASH_ALL(Int32Impl(1)))
|
||||
|
||||
// all of the UTXO spending information, since we only have
|
||||
// one input, this is just one element
|
||||
val utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(utxoInfo)
|
||||
// utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),10000 sats,ECPublicKey(02261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(2c880c352e5b10e387055c19309f1534f2fc77af))),UInt32Impl(0)),Vector(Masked(ECPrivateKey)),SIGHASH_ALL(Int32Impl(1))))
|
||||
// utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),10000 sats,ECPublicKey(036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(db55b744b69cf3434f84a9c2b95a1d31dfacbf40))),UInt32Impl(0)),Vector(Masked(ECPrivateKey)),SIGHASH_ALL(Int32Impl(1))))
|
||||
|
||||
// Yay! Now we use the RawTxSigner object to sign the tx.
|
||||
// The 'sign' method is going produce a validly signed transaction
|
||||
@ -142,7 +142,7 @@ val signedTx: Transaction =
|
||||
utxoInfos = utxoInfos,
|
||||
expectedFeeRate = feeRate
|
||||
)
|
||||
// signedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(e44cf772914f525b7163e3a523dd3efa7d52a5d757aeb6adacd838d410f1ad93:0),P2PKHScriptSignature(ECPublicKeyBytes(ByteVector(33 bytes, 0x02261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831)), ECDigitalSignature(3044022014c360bbba112743031a01cbb4980f03c8e6e0c630cfb55d6ea933385b47b9660220412a91001d6b29c03042f9006e8f473b671b75883bb4061346e5ce6730fd6bbf01)),UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(7455d9f20af11d6ee888f9509a0d52c647e16f84)), TransactionOutput(4775 sats,pkh(f05a1269fb55b9da304f8e9a6a3c02eee359620b))),UInt32Impl(0))
|
||||
// signedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(f3b6fbb10c50ba74ad25ea1efd14609293a00cf2eab7ef1e8bb4c7fbf486470f:0),P2PKHScriptSignature(ECPublicKeyBytes(ByteVector(33 bytes, 0x036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e)), ECDigitalSignature(30440220754d4fbaef71c326445ff3677fa43bf9d5f9dbfddd7ef2081dbf7b36796c9cae02203a31fafc66d7941c8549810873c65dfc8ee7e7d1c030146b6294ef2b7d42750b01)),UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(8af1a6bbac7250d13f6cb0aa6c9ee792654531a1)), TransactionOutput(4775 sats,pkh(15dd7b93b6a03b8160d5cdded8be7af814b2c10d))),UInt32Impl(0))
|
||||
```
|
||||
|
||||
```scala
|
||||
@ -154,5 +154,5 @@ signedTx.outputs.length
|
||||
|
||||
//remember, you can call .hex on any bitcoin-s data structure to get the hex representation!
|
||||
signedTx.hex
|
||||
// res4: String = 020000000193adf110d438d8acadb6ae57d7a5527dfa3edd23a5e363715b524f9172f74ce4000000006a473044022014c360bbba112743031a01cbb4980f03c8e6e0c630cfb55d6ea933385b47b9660220412a91001d6b29c03042f9006e8f473b671b75883bb4061346e5ce6730fd6bbf012102261c1ff1989748d9d27f26094e7a2aff6940013be8e470b096f6c57cd8236831000000000288130000000000001976a9147455d9f20af11d6ee888f9509a0d52c647e16f8488aca7120000000000001976a914f05a1269fb55b9da304f8e9a6a3c02eee359620b88ac00000000
|
||||
// res4: String = 02000000010f4786f4fbc7b48b1eefb7eaf20ca093926014fd1eea25ad74ba500cb1fbb6f3000000006a4730440220754d4fbaef71c326445ff3677fa43bf9d5f9dbfddd7ef2081dbf7b36796c9cae02203a31fafc66d7941c8549810873c65dfc8ee7e7d1c030146b6294ef2b7d42750b0121036c002799e13526c534cd8c6dfb126a181b9d35488c61469308584038217bdd8e000000000288130000000000001976a9148af1a6bbac7250d13f6cb0aa6c9ee792654531a188aca7120000000000001976a91415dd7b93b6a03b8160d5cdded8be7af814b2c10d88ac00000000
|
||||
```
|
||||
|
@ -51,13 +51,13 @@ val extPrivKey = ExtPrivateKey(ExtKeyVersion.SegWitMainNetPriv)
|
||||
// extPrivKey: ExtPrivateKey = Masked(ExtPrivateKeyImpl)
|
||||
|
||||
extPrivKey.sign(DoubleSha256Digest.empty.bytes)
|
||||
// res0: ECDigitalSignature = ECDigitalSignature(304402200d093e8d339ebd7e340d4509b4fd7e53da75928644d40e681f0ec9e1b3fe5a3b0220208f9c8e6e403a95c26cca66823f2739cfbe1d9b5ab15ce39d23fd8635f0fd1b)
|
||||
// res0: ECDigitalSignature = ECDigitalSignature(304402205eaa4c2939acd1d0f1714a4c70f0dd91c40abbdb0d606de7f9ae9c96777b8e210220177c2ebb5102c0c248434153d51cc6b040ff4291a7a38ed0393f67dc1453b296)
|
||||
|
||||
val path = BIP32Path(Vector(BIP32Node(0,false)))
|
||||
// path: BIP32Path = m/0
|
||||
|
||||
extPrivKey.sign(DoubleSha256Digest.empty.bytes,path)
|
||||
// res1: ECDigitalSignature = ECDigitalSignature(3044022050641ec9e6ac14017cb8c812e83e48ee6bb1862215f06ac9a88399be490dcdcc02203202049ce78e8965964d315024d97f6df41a066930cf024379fd5bfc7cc5c0ed)
|
||||
// res1: ECDigitalSignature = ECDigitalSignature(3045022100830556edd484703cfce53586f48ad01186ad1923f4cd5585923545eec7717b70022024858630a306c3bbf37e60fc2ba52c7f3a9e27ec49ad1d72cacdb46ac8b2b38e)
|
||||
```
|
||||
|
||||
With `ExtSign`, you can use `ExtPrivateKey` to sign transactions inside of `TxBuilder` since `UTXOSpendingInfo` takes in `Sign` as a parameter.
|
||||
|
@ -192,16 +192,18 @@ bitcoin-s {
|
||||
## Step 6 (Optional): Moving To Testnet
|
||||
|
||||
To run your Bitcoin-S Server on testnet, simply change `network = testnet3` and change
|
||||
your `peers = ["neutrino.testnet3.suredbits.com:18333"] ` in your `.bitcoin-s/bitcoin-s.conf` file.
|
||||
your `bitcoin-s.node.peers = ["neutrino.testnet3.suredbits.com:18333"] ` in your `$HOME/.bitcoin-s/bitcoin-s.conf` file.
|
||||
This will allow you to connect to Suredbits' neutrino-enabled `bitcoind` node.
|
||||
Keep in mind then when you restart your server, it will begin initial sync which will take
|
||||
many hours as all block filters for all testnet blocks will be downloaded.
|
||||
If you wish to speed this process up,
|
||||
download [this snapshot](https://s3-us-west-2.amazonaws.com/www.suredbits.com/chaindb-testnet-2021-02-03.zip), unzip it and put the file in your `$HOME/.bitcoin-s/testnet3` directory and then from there, run
|
||||
|
||||
This will start syncing your testnet node from block header ~1,900,000 rather than starting from zero.
|
||||
|
||||
```bashrc
|
||||
$ unzip chaindb-testnet-2021-02-03.zip
|
||||
$ mv chaindb.sqlite ~/.bitcoin-s/testnet/
|
||||
$ mv chaindb.sqlite ~/.bitcoin-s/testnet3/
|
||||
```
|
||||
|
||||
This should take a couple minutes to execute, but once it is done, you will only have a short while left to sync once you start your server.
|
||||
This should take a couple minutes to execute, but once it is done, you will only have a short while left to sync once you start your server.
|
@ -60,35 +60,35 @@ Add this to your `build.sbt`:
|
||||
```scala
|
||||
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-bitcoind-rpc" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-bitcoind-rpc" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-core" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-core" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-chain" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-chain" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-dlc-oracle" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-dlc-oracle" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-eclair-rpc" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-eclair-rpc" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-fee-provider" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-fee-provider" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-key-manager" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-key-manager" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-lnd-rpc" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-lnd-rpc" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-node" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-node" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-oracle-explorer-client" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-oracle-explorer-client" % "1.8.0"
|
||||
|
||||
libraryDependencies +="org.bitcoin-s" % "bitcoin-s-secp256k1jni" % "1.7.0"
|
||||
libraryDependencies +="org.bitcoin-s" % "bitcoin-s-secp256k1jni" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-testkit-core" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-testkit-core" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-testkit" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-testkit" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-wallet" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-wallet" % "1.8.0"
|
||||
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-zmq" % "1.7.0"
|
||||
libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-zmq" % "1.8.0"
|
||||
|
||||
```
|
||||
|
||||
@ -97,7 +97,7 @@ libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-zmq" % "1.7.0"
|
||||
|
||||
You can also run on the bleeding edge of Bitcoin-S, by
|
||||
adding a snapshot build to your `build.sbt`. The most
|
||||
recent snapshot published is `1.7.0-156-4d6c4c7b-20210905-1056-SNAPSHOT`.
|
||||
recent snapshot published is `1.8.0-5-01a7c7c8-SNAPSHOT`.
|
||||
|
||||
|
||||
|
||||
|
@ -32,14 +32,14 @@ import org.bitcoins.core.crypto._
|
||||
|
||||
//get 256 bits of random entropy
|
||||
val entropy = MnemonicCode.getEntropy256Bits
|
||||
// entropy: scodec.bits.BitVector = BitVector(256 bits, 0xcb635b5bc8413aa3e1bfdb2767d3642c915b5c39af0cb5cfd69b9cb1d92cb009)
|
||||
// entropy: scodec.bits.BitVector = BitVector(256 bits, 0x4e2b2183caf2d1e2e4f17852b174165381a9424ec84cd9160ed1b07de5450832)
|
||||
|
||||
val mnemonic = MnemonicCode.fromEntropy(entropy)
|
||||
// mnemonic: MnemonicCode = Masked(MnemonicCodeImpl)
|
||||
|
||||
//you can print that mnemonic seed with this
|
||||
println(mnemonic.words)
|
||||
// Vector(slice, bracket, street, mountain, beauty, faint, manage, window, cherry, direct, suit, float, between, puppy, trade, thunder, remind, leaf, plunge, defense, budget, north, scan, color)
|
||||
// Vector(evolve, flip, genius, nominee, code, vapor, need, congress, famous, merry, airport, poem, box, patrol, depth, another, suit, race, refuse, genius, tattoo, penalty, camp, estate)
|
||||
```
|
||||
|
||||
Now that we have a `MnemonicCode` that was securely generated, we need to now create `KeyManagerParams` which tells us how to generate
|
||||
@ -60,7 +60,7 @@ Now we can construct a native segwit key manager for the regtest network!
|
||||
//this will create a temp directory with the prefix 'key-manager-example` that will
|
||||
//have a file in it called "encrypted-bitcoin-s-seed.json"
|
||||
val seedPath = Files.createTempDirectory("key-manager-example").resolve(WalletStorage.ENCRYPTED_SEED_FILE_NAME)
|
||||
// seedPath: Path = /var/folders/fg/scntn26d4h55x96zc456l0r40000gn/T/key-manager-example1673183639044643511/encrypted-bitcoin-s-seed.json
|
||||
// seedPath: Path = /tmp/key-manager-example9635890526842539338/encrypted-bitcoin-s-seed.json
|
||||
|
||||
//let's create a native segwit key manager
|
||||
val purpose = HDPurposes.SegWit
|
||||
@ -71,19 +71,19 @@ val network = RegTest
|
||||
// network: RegTest.type = RegTest
|
||||
|
||||
val kmParams = KeyManagerParams(seedPath, purpose, network)
|
||||
// kmParams: KeyManagerParams = KeyManagerParams(/var/folders/fg/scntn26d4h55x96zc456l0r40000gn/T/key-manager-example1673183639044643511/encrypted-bitcoin-s-seed.json,m/84',RegTest)
|
||||
// kmParams: KeyManagerParams = KeyManagerParams(/tmp/key-manager-example9635890526842539338/encrypted-bitcoin-s-seed.json,m/84',RegTest)
|
||||
|
||||
val aesPasswordOpt = Some(AesPassword.fromString("password"))
|
||||
// aesPasswordOpt: Some[AesPassword] = Some(Masked(AesPassword))
|
||||
|
||||
val km = BIP39KeyManager.initializeWithMnemonic(aesPasswordOpt, mnemonic, None, kmParams)
|
||||
// km: Either[KeyManagerInitializeError, BIP39KeyManager] = Right(org.bitcoins.keymanager.bip39.BIP39KeyManager@1633c6a6)
|
||||
// km: Either[KeyManagerInitializeError, BIP39KeyManager] = Right(org.bitcoins.keymanager.bip39.BIP39KeyManager@2e0b2b2f)
|
||||
|
||||
val rootXPub = km.right.get.getRootXPub
|
||||
// rootXPub: ExtPublicKey = vpub5SLqN2bLY4WeZYoPHeAUPnfNRvwcHsUv2TJZvaC2WMh8ejD6DXcngh8W2MutwRcJNNUXToVZ7ivpMb4723bTh3n2JWX3DdXRdCa4b5UiYZz
|
||||
// rootXPub: ExtPublicKey = vpub5SLqN2bLY4WeXzMWKjW38b3MSZ5ygXdLojJugCjMGpAmsEgVDmBMebNGad9fNX4HUxMeqbfn33Tdeo7DWcY1U66B1pkj3CuEz4pVDuCbckh
|
||||
|
||||
println(rootXPub)
|
||||
// vpub5SLqN2bLY4WeZYoPHeAUPnfNRvwcHsUv2TJZvaC2WMh8ejD6DXcngh8W2MutwRcJNNUXToVZ7ivpMb4723bTh3n2JWX3DdXRdCa4b5UiYZz
|
||||
// vpub5SLqN2bLY4WeXzMWKjW38b3MSZ5ygXdLojJugCjMGpAmsEgVDmBMebNGad9fNX4HUxMeqbfn33Tdeo7DWcY1U66B1pkj3CuEz4pVDuCbckh
|
||||
```
|
||||
|
||||
Which should print something that looks like this
|
||||
@ -98,17 +98,17 @@ again after initializing it once. You can use the same `mnemonic` for different
|
||||
```scala
|
||||
//let's create a nested segwit key manager for mainnet
|
||||
val mainnetKmParams = KeyManagerParams(seedPath, HDPurposes.SegWit, MainNet)
|
||||
// mainnetKmParams: KeyManagerParams = KeyManagerParams(/var/folders/fg/scntn26d4h55x96zc456l0r40000gn/T/key-manager-example1673183639044643511/encrypted-bitcoin-s-seed.json,m/84',MainNet)
|
||||
// mainnetKmParams: KeyManagerParams = KeyManagerParams(/tmp/key-manager-example9635890526842539338/encrypted-bitcoin-s-seed.json,m/84',MainNet)
|
||||
|
||||
//we do not need to all `initializeWithMnemonic()` again as we have saved the seed to dis
|
||||
val mainnetKeyManager = BIP39KeyManager.fromMnemonic(mnemonic, mainnetKmParams, None, Instant.now)
|
||||
// mainnetKeyManager: BIP39KeyManager = org.bitcoins.keymanager.bip39.BIP39KeyManager@13413c18
|
||||
// mainnetKeyManager: BIP39KeyManager = org.bitcoins.keymanager.bip39.BIP39KeyManager@36fd850f
|
||||
|
||||
val mainnetXpub = mainnetKeyManager.getRootXPub
|
||||
// mainnetXpub: ExtPublicKey = zpub6jftahH18ngZxjZrd5JyE93P7oXQ4MSuguPT49ma2PCes8U1EAH3Awm47BkEw4DyzvwkThsnxNM1tjWMtqFWszWRmsJjZGoNi6pe9Kym5i1
|
||||
// mainnetXpub: ExtPublicKey = zpub6jftahH18ngZwB7yfAeXxwRN8RfmT1bLUBPnonJtnqgJ5dwQEPqc8qzpfSz1N9fy7WpsqW41sgsqBwZUPQC4f2paVBYRNrBC4y54nGrrecr
|
||||
|
||||
println(mainnetXpub)
|
||||
// zpub6jftahH18ngZxjZrd5JyE93P7oXQ4MSuguPT49ma2PCes8U1EAH3Awm47BkEw4DyzvwkThsnxNM1tjWMtqFWszWRmsJjZGoNi6pe9Kym5i1
|
||||
// zpub6jftahH18ngZwB7yfAeXxwRN8RfmT1bLUBPnonJtnqgJ5dwQEPqc8qzpfSz1N9fy7WpsqW41sgsqBwZUPQC4f2paVBYRNrBC4y54nGrrecr
|
||||
```
|
||||
|
||||
Which gives us something that looks like this
|
||||
|
@ -50,7 +50,7 @@ implicit val ec = system.dispatcher
|
||||
//so let's start one (make sure you ran 'sbt downloadBitcoind')
|
||||
val instance = BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.Experimental))
|
||||
val p2pPort = instance.p2pPort
|
||||
val bitcoindF = BitcoindRpcTestUtil.startedBitcoindRpcClient(instance, Vector.newBuilder)
|
||||
val bitcoindF = BitcoindRpcTestUtil.startedBitcoindRpcClient(Some(instance), Vector.newBuilder)
|
||||
|
||||
//contains information on how to connect to bitcoin's p2p info
|
||||
val peerF = bitcoindF.flatMap(b => NodeUnitTest.createPeer(b))
|
||||
@ -77,7 +77,7 @@ val config = ConfigFactory.parseString {
|
||||
|""".stripMargin
|
||||
}
|
||||
|
||||
implicit val appConfig = BitcoinSAppConfig(datadir, Vector(config))
|
||||
implicit val appConfig = BitcoinSAppConfig(datadir, config)
|
||||
implicit val chainConfig = appConfig.chainConf
|
||||
implicit val nodeConfig = appConfig.nodeConf
|
||||
|
||||
|
@ -41,7 +41,7 @@ implicit val ec = system.dispatcher
|
||||
|
||||
val datadirPath = Paths.get("path", "to", "datadir")
|
||||
val binaryPath = Paths.get("path", "to", "eclair-node-0.5.0-ac08560", "bin", "eclair-node.sh")
|
||||
val instance = EclairInstance.fromDatadir(datadirPath.toFile, logbackXml = None, proxyParams = None)
|
||||
val instance = EclairInstanceLocal.fromDatadir(datadirPath.toFile, logbackXml = None, proxyParams = None)
|
||||
val client = new EclairRpcClient(instance, Some(binaryPath.toFile))
|
||||
|
||||
val startedF = client.start()
|
||||
|
@ -6,22 +6,22 @@ original_id: lnd-rpc
|
||||
|
||||
This is an RPC client for [LND](https://github.com/LightningNetwork/lnd). It assumes that a bitcoind instance is running.
|
||||
|
||||
Currently, this RPC client is written for [v0.13.1](https://github.com/lightningnetwork/lnd/releases/tag/v0.13.1-beta) version of LND.
|
||||
Currently, this RPC client is written for [v0.13.3](https://github.com/lightningnetwork/lnd/releases/tag/v0.13.3-beta) version of LND.
|
||||
|
||||
## Configuration of LND
|
||||
|
||||
Please see the [sample configuration for LND](https://github.com/lightningnetwork/lnd/blob/v0.13.1-beta/sample-lnd.conf).
|
||||
Please see the [sample configuration for LND](https://github.com/lightningnetwork/lnd/blob/v0.13.3-beta/sample-lnd.conf).
|
||||
|
||||
You can find the configuration we use for our testing infrastructure for lnd [here](https://github.com/bitcoin-s/bitcoin-s/blob/656e0928bf1bf4f511f60dec625699b454f29a1f/testkit/src/main/scala/org/bitcoins/testkit/lnd/LndRpcTestUtil.scala#L90).
|
||||
|
||||
## Starting LND
|
||||
|
||||
You need to download the binaries from the [LND's github](https://github.com/lightningnetwork/lnd/releases/tag/v0.13.1-beta).
|
||||
You need to download the binaries from the [LND's github](https://github.com/lightningnetwork/lnd/releases/tag/v0.13.3-beta).
|
||||
|
||||
To run lnd by unzipping the `lnd-linux-amd64-v0.13.1-beta.tar.gz` (or whichever platform you are on) and then running
|
||||
To run lnd by unzipping the `lnd-linux-amd64-v0.13.3-beta.tar.gz` (or whichever platform you are on) and then running
|
||||
|
||||
```bash
|
||||
$ ./lnd-linux-amd64-v0.13.1-beta/lnd
|
||||
$ ./lnd-linux-amd64-v0.13.3-beta/lnd
|
||||
```
|
||||
|
||||
If you wish to start lnd from the RPC client, you can construct a [`LndRpcClient.binary`](https://github.com/bitcoin-s/bitcoin-s/blob/656e0928bf1bf4f511f60dec625699b454f29a1f/lnd-rpc/src/main/scala/org/bitcoins/lnd/rpc/LndRpcClient.scala#L35) field set
|
||||
@ -36,8 +36,8 @@ implicit val system = ActorSystem(s"lnd-rpc-${System.currentTimeMillis}")
|
||||
implicit val ec = system.dispatcher
|
||||
|
||||
val datadirPath = Paths.get("path", "to", "datadir")
|
||||
val binaryPath = Paths.get("path", "to", "lnd-linux-amd64-v0.13.1-beta", "lnd")
|
||||
val instance = LndInstance.fromDataDir(datadirPath.toFile)
|
||||
val binaryPath = Paths.get("path", "to", "lnd-linux-amd64-v0.13.3-beta", "lnd")
|
||||
val instance = LndInstanceLocal.fromDataDir(datadirPath.toFile)
|
||||
val client = new LndRpcClient(instance, Some(binaryPath.toFile))
|
||||
|
||||
val startedF = client.start()
|
||||
|
@ -71,13 +71,13 @@ val privKey = ECPrivateKey.freshPrivateKey
|
||||
// privKey: ECPrivateKey = Masked(ECPrivateKey)
|
||||
// calls bouncy castle indirectly via CryptoContext
|
||||
val publicKey = privKey.publicKey
|
||||
// publicKey: ECPublicKey = ECPublicKey(03f1ed491e36174a5b4386414627bf647cefefbac9bef5ee656683ef37b4d46574)
|
||||
// publicKey: ECPublicKey = ECPublicKey(02143b4062f1b2c4f4452fc1198c391c8eca72ae75d53f81131474316598ee8f55)
|
||||
val dataToSign = DoubleSha256Digest.empty
|
||||
// dataToSign: DoubleSha256Digest = DoubleSha256Digest(0000000000000000000000000000000000000000000000000000000000000000)
|
||||
|
||||
// calls bouncy castle indirectly via CryptoContext
|
||||
val signature = privKey.sign(dataToSign.bytes)
|
||||
// signature: ECDigitalSignature = ECDigitalSignature(3045022100b945f4cc13bfb778c18431f9404e7979790edf15bd7d8c24ff1b2225f3f9f4f002200bbe5dd069dd80ebbb642c051be8c3859a2dd6926aed338c3e9ab6fe4986428e)
|
||||
// signature: ECDigitalSignature = ECDigitalSignature(3044022054ec419010e5053ff500932e1e9d412662c9bc0ad682946f75ce5945623c7fd50220474e26b0c72e1dd155558577b9669128207e244f7d4c5890910ef08b5d62b26e)
|
||||
|
||||
// calls bouncy castle indirectly via CryptoContext
|
||||
val verified = publicKey.verify(dataToSign.bytes, signature)
|
||||
|
@ -27,24 +27,14 @@ Here is an example of constructing a wallet and registering a callback, so you c
|
||||
implicit val system: ActorSystem = ActorSystem("example")
|
||||
implicit val ec: ExecutionContextExecutor = system.dispatcher
|
||||
implicit val walletConf: WalletAppConfig =
|
||||
BitcoinSTestAppConfig.getNeutrinoTestConfig(Vector.empty).walletConf
|
||||
BitcoinSTestAppConfig.getNeutrinoTestConfig().walletConf
|
||||
|
||||
// let's use a helper method to get a v19 bitcoind
|
||||
// and a ChainApi
|
||||
val bitcoind = BitcoindV19RpcClient(BitcoindInstance.fromConfigFile())
|
||||
|
||||
val bitcoind = BitcoindV19RpcClient(BitcoindInstanceLocal.fromConfFile())
|
||||
val aesPasswordOpt = Some(AesPassword.fromString("password"))
|
||||
|
||||
// Create our key manager
|
||||
val keyManagerE = BIP39KeyManager.initialize(aesPasswordOpt = aesPasswordOpt,
|
||||
kmParams = walletConf.kmParams,
|
||||
bip39PasswordOpt = None)
|
||||
|
||||
val keyManager = keyManagerE match {
|
||||
case Right(keyManager) => keyManager
|
||||
case Left(err) =>
|
||||
throw new RuntimeException(s"Cannot initialize key manager err=$err")
|
||||
}
|
||||
|
||||
// Here is a super simple example of a callback, this could be replaced with anything, from
|
||||
// relaying the transaction on the network, finding relevant wallet outputs, verifying the transaction,
|
||||
// or writing it to disk
|
||||
@ -57,11 +47,10 @@ val exampleCallbacks = WalletCallbacks(
|
||||
|
||||
// Now we can create a wallet
|
||||
val wallet =
|
||||
Wallet(keyManager = keyManager,
|
||||
Wallet(
|
||||
nodeApi = bitcoind,
|
||||
chainQueryApi = bitcoind,
|
||||
feeRateApi = ConstantFeeRateProvider(SatoshisPerVirtualByte.one),
|
||||
creationTime = Instant.now)
|
||||
feeRateApi = ConstantFeeRateProvider(SatoshisPerVirtualByte.one))
|
||||
|
||||
// Finally, we can add the callbacks to our wallet config
|
||||
walletConf.addCallbacks(exampleCallbacks)
|
||||
|
@ -91,12 +91,9 @@ val getBlockFunc = {hash: DoubleSha256DigestBE => bitcoind.getBlockRaw(hash) }
|
||||
//yay! We are now all setup. Using our 3 functions above and a wallet, we can now sync
|
||||
//a fresh wallet
|
||||
implicit val walletAppConfig = WalletAppConfig.fromDefaultDatadir()
|
||||
implicit val kmAppConfig = KeyManagerAppConfig.fromDefaultDatadir()
|
||||
val keyManager: BIP39KeyManager = {
|
||||
BIP39KeyManager.fromParams(walletAppConfig.kmParams,None,None).right.get
|
||||
}
|
||||
|
||||
val feeRateProvider: FeeRateApi = MempoolSpaceProvider.fromBlockTarget(6, proxyParams = None)
|
||||
val wallet = Wallet(keyManager, bitcoind, bitcoind, feeRateProvider, keyManager.creationTime)
|
||||
val wallet = Wallet(bitcoind, bitcoind, feeRateProvider)
|
||||
|
||||
//yay! we have a synced wallet
|
||||
val syncedWalletF = WalletSync.syncFullBlocks(wallet,
|
||||
|
Loading…
Reference in New Issue
Block a user