Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cashaccounts, Block and Rawtransactions #1

Open
wants to merge 113 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
6a8cbb3
Fix last name typo.
Aug 1, 2019
dc7e943
Merge pull request #1 from Bitcoin-com/fix-typos
tomas-forgac Aug 3, 2019
dad85bb
- taken some code analysis hints into account
tomas-forgac Oct 6, 2019
7f05f37
Merge remote-tracking branch 'origin/master'
tomas-forgac Oct 6, 2019
d54525d
implemented bip21
RomitRadical Nov 28, 2019
79a7a42
custom post keys
RomitRadical Jan 6, 2020
b09d891
get block details by block height or block hash
RomitRadical Jan 6, 2020
9617c9e
register and lookup cashaccounts
RomitRadical Jan 6, 2020
c62576a
get or decode raw transactions and scripts
RomitRadical Jan 6, 2020
5f60cca
export block and cashaccount files
RomitRadical Jan 6, 2020
916d243
added support p2sh scripts
RomitRadical Jan 10, 2020
9997a81
added p2sh support
RomitRadical Jan 10, 2020
c92f38d
transaction output supports p2sh address
RomitRadical Jan 10, 2020
1700cb0
p2sh support for toLegacyAddress() & toCashAddress()
RomitRadical Jan 10, 2020
eb81c18
typo
RomitRadical Jan 11, 2020
e381552
converted Crypto to a public class
RomitRadical Jan 12, 2020
98da872
export Crypto class
RomitRadical Jan 12, 2020
18fea5a
removed pubspec.lock
RomitRadical Jan 12, 2020
77b9a0c
replaced crypto funcs with crypto class
RomitRadical Jan 12, 2020
e6b4853
support for testnet address
RomitRadical Feb 5, 2020
78a396d
typo
RomitRadical Feb 5, 2020
fa58047
removed extra import
RomitRadical Mar 23, 2020
e15c268
added toSLPAddress and fixed include prefix
RomitRadical Mar 23, 2020
efa7d79
added toSLPAddress
RomitRadical Mar 23, 2020
c072d9c
advanced bch address methods
RomitRadical Apr 15, 2020
0f9eaff
update dependencies
RomitRadical Apr 15, 2020
943eab6
import more files
RomitRadical Apr 15, 2020
33c2414
add new files
RomitRadical Apr 15, 2020
868ecc1
updated dependency
RomitRadical Apr 15, 2020
20d8524
export opcodes
RomitRadical Apr 18, 2020
abaa673
export script
RomitRadical Apr 18, 2020
c07126e
added slp parser & slp mdm dep
RomitRadical Apr 22, 2020
2a7cc3b
added send slp feature
RomitRadical Apr 22, 2020
519c7a5
export slp class
RomitRadical Apr 22, 2020
1b4c687
changed token receiver address to string
RomitRadical Apr 23, 2020
5e01a6c
changed bch change addr format
RomitRadical Apr 23, 2020
8f1d956
change bch change receiver format
RomitRadical Apr 23, 2020
db146d0
convert slp to bch addr for output change
RomitRadical Apr 23, 2020
4c7aeaf
changed default extra fee rate to 1
RomitRadical Apr 23, 2020
7c52cb7
updated comments
RomitRadical Apr 23, 2020
fc723bf
removed default extra fee value
RomitRadical Apr 23, 2020
f867c84
if token change is lesser than 0 then add just 1 output amount
RomitRadical Apr 23, 2020
5f3282b
add inputs from a different bch only address to pay token tx fees
RomitRadical Apr 24, 2020
1a60a48
fixed token decimal precision to send amount
RomitRadical Apr 24, 2020
0f64e1a
token info bug
RomitRadical Apr 24, 2020
98fcd0a
removed Response for getRawTransaction
RomitRadical Apr 24, 2020
432044a
changed slp amounts to num
RomitRadical Jun 11, 2020
b978d56
send slp to multiple addresses
RomitRadical Jun 16, 2020
90371fb
set default value of total slpamount to 0
RomitRadical Jun 16, 2020
e410e0f
return fee data
RomitRadical Jun 16, 2020
7d4db7f
return hex and fee for token send
RomitRadical Jun 16, 2020
7d3b1f0
sign tx with wif
RomitRadical Jun 25, 2020
1fbee50
added named params to slp utxo map
RomitRadical Jun 25, 2020
b28fe24
deleted files
RomitRadical Aug 4, 2020
8c07caf
fix bch only outputs for slp send
RomitRadical Aug 30, 2020
fa0de4c
improved address format detection
RomitRadical Sep 17, 2020
c4b53fc
fixed address conversion bugs
RomitRadical Sep 17, 2020
369ed51
simplified slp judgements
RomitRadical Oct 21, 2020
cf78c43
added blockchain end points
RomitRadical Oct 27, 2020
0f560ee
fixed bigint decimal bug
RomitRadical Oct 28, 2020
b24b0f4
updated rest api call
RomitRadical Nov 6, 2020
b52d66e
added NFT Child Send
RomitRadical Jan 16, 2021
bc905f6
fix utxo isvalid bug
RomitRadical Jan 29, 2021
152c1e7
add nft group send
RomitRadical Jan 31, 2021
4ce85e7
add slp parser
RomitRadical Feb 16, 2021
b666a10
remove extra tx fee
RomitRadical Feb 22, 2021
76b6f75
upgraded dependencies
Mar 26, 2021
77d0ceb
upgraded packages
Mar 26, 2021
4610b90
upgraded bs58check_dart package
Mar 26, 2021
aa03e58
upgraded to bs58check_dart version
Mar 26, 2021
c5dbf48
Upgraded bip32
Mar 26, 2021
08df2d7
resolved errors
Mar 26, 2021
31ff6b6
Merge pull request #1 from DevanshiGarg08/staging
RomitRadical Apr 1, 2021
3fb94f6
add build incomplete to slp
RomitRadical Jun 3, 2021
e657b50
Merge branch 'master' of https://github.com/RomitRadical/bitbox-flutter
RomitRadical Jun 3, 2021
04a15f9
merge
RomitRadical Jun 3, 2021
7c752de
add anyone can pay flag for slp tx
RomitRadical Jun 24, 2021
06303d6
add default hashtype
RomitRadical Jul 6, 2021
dba8263
add extra BCH param
RomitRadical Jul 6, 2021
61f2819
add default value to script
RomitRadical Jul 8, 2021
669427c
update dep
RomitRadical Jan 11, 2022
388cc68
add magichash
RomitRadical Jan 11, 2022
c02119c
add sign bitcoin message function
RomitRadical Jan 11, 2022
ffe7a22
update packages
RomitRadical Jan 11, 2022
604056f
return uint8list sig
RomitRadical Jan 11, 2022
81c68b9
change type
RomitRadical Jan 11, 2022
e5e994a
update file
RomitRadical Jan 11, 2022
96fa716
update dep
RomitRadical Jan 19, 2022
d45ce5b
Update packages
RomitRadical Jan 19, 2022
89c4710
Update packages
RomitRadical Jan 19, 2022
7beeae7
fix bug
RomitRadical Jan 19, 2022
dc3362b
add sha256
RomitRadical Mar 19, 2022
7300588
update urls
RomitRadical May 16, 2022
3fee678
fix encoding/decoding issue with pointy castle
RomitRadical May 18, 2022
3f66069
update bip39 dep
RomitRadical May 19, 2022
6c233e9
update pointycastle version
RomitRadical May 19, 2022
87ca88b
removed pointycastle
RomitRadical May 19, 2022
09f35f4
add pointycastle
RomitRadical May 19, 2022
fb8ac5a
update lock
RomitRadical May 19, 2022
c71cf7e
fix apis
RomitRadical May 21, 2022
255b6b9
add op return script
RomitRadical Jun 19, 2022
7d4b2c1
add publicKey and privateKey files
RomitRadical Jul 22, 2022
4b4c35e
add ecies encryption/decryption
RomitRadical Jul 22, 2022
dd8ecac
export ecies
RomitRadical Jul 22, 2022
1cf59e1
change plugin
RomitRadical Aug 25, 2022
1e27805
upgrade packages
sathish76 Nov 29, 2022
63a6a86
ran dart migrate
sathish76 Nov 29, 2022
117b166
manual null safe type fixes
sathish76 Nov 29, 2022
4395127
fix type issue
sathish76 Jan 5, 2023
32f9aea
Merge pull request #1 from sathish76/fix_nullsafe
sathish76 Jun 28, 2023
d7dee48
add cash token address
sathish76 Jun 28, 2023
3855261
Merge pull request #2 from sathish76/feat/add_cash_token_address
sathish76 Jun 28, 2023
701605d
Merge pull request #4 from sathish76/master
RomitRadical Jul 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
.vscode/

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
Expand Down
34 changes: 18 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,32 @@ Works with mainnet and testnet.
## Getting Started

### 1) Depend on it
After you download the repository, add a local dependency into the pubspec.yaml of your testing or development projet:

```
dependencies:
bitbox_plugin:
path: <path to the directory>/
bitbox:
git:
url: https://github.com/RomitRadical/bitbox-flutter
ref: master
```

### 2) Import it

```
// There's a good chance your own project will use similar names as some of the
// classes in this library. A simple way to create some order is to import the
// There's a good chance your own project will use similar names as some of the
// classes in this library. A simple way to create some order is to import the
// library with Bitbox prefix:
import 'package:bitbox/bitbox.dart' as Bitbox;
import 'package:bitbox/bitbox.dart' as bitbox;
```

### 2) Use it

```
// set this to true to use testnet
final testnet = true;

// After running the code for the first time, depositing an amount to the address
// displayed in the console, and waiting for confirmation, paste the generated
// After running the code for the first time, depositing an amount to the address
// displayed in the console, and waiting for confirmation, paste the generated
// mnemonic here, so the code continues below with address withdrawal
String mnemonic = "";

Expand Down Expand Up @@ -86,7 +88,7 @@ if (addressDetails["balance"] > 0) {
// placeholder for total input balance
int totalBalance = 0;

// iterate through the list of address utxos and use them as inputs for the
// iterate through the list of address utxos and use them as inputs for the
// withdrawal transaction
utxos.forEach((Bitbox.Utxo utxo) {
// add the utxo as an input for the transaction
Expand Down Expand Up @@ -118,7 +120,7 @@ if (addressDetails["balance"] > 0) {

// sign all inputs
signatures.forEach((signature) {
builder.sign(signature["vin"], signature["key_pair"],
builder.sign(signature["vin"], signature["key_pair"],
signature["original_amount"]);
});

Expand All @@ -140,8 +142,9 @@ For further documentation, refer to apidoc of this repository

## Testing

There are some unit tests in test/bitbox_test.dart. They use data generated from the original [Bitbox for JS](https://developer.bitcoin.com/bitbox/) and compare them with the output of this library.
There are some unit tests in test/bitbox_test.dart. They use data generated from the original [Bitbox for JS](https://developer.bitcoin.com/bitbox/) and compare them with the output of this library.
The following is tested for both testnet and mainnet:

- Generating the master node from mnemonic and comparing both its XPub and XPriv
- Generating an account node and comparing XPub and XPriv
- Generating 10 test childs and comparing their private keys and addresses
Expand All @@ -156,12 +159,11 @@ To run the test:
1. Copy create_test_data.js to a separate directory and download the original Bitbox JS into the directory
2. Generate the testing data by runing create_test_data.js with your local nodeJS engine
3. Update bitbox_test.dart with the path to the generated test_data.json file
4. Run bitbox_test.dart
Optionally between step 1) and 2), send some balance to either testnet or mainnet addresses (or both), wait for confirmations and run create_test_data.js again to update the data and generate testing transactions

4. Run bitbox_test.dart
Optionally between step 1) and 2), send some balance to either testnet or mainnet addresses (or both), wait for confirmations and run create_test_data.js again to update the data and generate testing transactions

## Acknowledgments

This is a port of the original JS-based Bitbox library by Gabriel Cordana and Bitcoin.com, so first of all huge thanks to Gabriel and the whole Bitcoin.com team for doing so much for the BCH ecosystem.
This is a port of the original JS-based Bitbox library by Gabriel Cardona and Bitcoin.com, so first of all huge thanks to Gabriel and the whole Bitcoin.com team for doing so much for the BCH ecosystem.

Also I either re-used a lot of code originally wrote for Bitcoin or called some libraries (bip39 and bip32) by [anicdh](https://github.com/anicdh), so Thanks big time to him. Without that it would take me many more weeks!
2 changes: 1 addition & 1 deletion create_test_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function createTestData(mnemonic, testnet) {
"master_xpriv": bitbox.HDNode.toXPriv(masterNode),
"master_xpub": bitbox.HDNode.toXPub(masterNode),
"account_xpriv": bitbox.HDNode.toXPriv(accountNode),
"account_xpub": bitbox.HDNode.toXPub(accountNode),
"account_xpub": bitbox.HDNode.tdoXPub(accountNode),
"child_nodes" : []
};

Expand Down
114 changes: 114 additions & 0 deletions example/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import 'package:bitbox/bitbox.dart' as Bitbox;

void main() async {
// set this to false to use mainnet
final testnet = false;

// After running the code for the first time, depositing an amount to the address displayed in the console,
// and waiting for confirmation, paste the generated mnemonic here,
// so the code continues below with address withdrawal
String mnemonic =
"leaf tackle snap liar core motion material live camp quote mercy void";

if (mnemonic == "") {
// generate 12-word (128bit) mnemonic
mnemonic = Bitbox.Mnemonic.generate();

print(mnemonic);
}

// generate a seed from mnemonic
final seed = Bitbox.Mnemonic.toSeed(mnemonic);

// create an instance of Bitbox.HDNode for mainnet
final masterNode = Bitbox.HDNode.fromSeed(seed, testnet);

// This format is compatible with Bitcoin.com wallet.
// Other wallets use Change to m/44'/145'/0'/0
final accountDerivationPath = "m/44'/0'/0'/0";

// create an account node using the provided derivation path
final accountNode = masterNode.derivePath(accountDerivationPath);

// get account's extended private key
final accountXPriv = accountNode.toXPriv();

// create a Bitbox.HDNode instance of the first child in this account
final childNode = accountNode.derive(0);

// get an address of the child
final address = childNode.toCashAddress();

// if you are using testnet, set the appropriate rest api url before making
// any API calls (like getting address or transaction details or broadcasting a transaction
if (testnet) {
Bitbox.Bitbox.setRestUrl(restUrl: Bitbox.Bitbox.trestUrl);
}

// get address details
final addressDetails = await Bitbox.Address.details(address);

print(addressDetails);

// If there is a confirmed balance, attempt to withdraw it to the address defined below
if (addressDetails["balance"] > 0) {
final builder = Bitbox.Bitbox.transactionBuilder(testnet: testnet);

// retrieve address' utxos from the rest api
final utxos = await Bitbox.Address.utxo(address) as List<Bitbox.Utxo>;

// placeholder for input signatures
final signatures = <Map>[];

// placeholder for total input balance
int totalBalance = 0;

// iterate through the list of address utxos and use them as inputs for the withdrawal transaction
utxos.forEach((Bitbox.Utxo utxo) {
// add the utxo as an input for the transaction
builder.addInput(utxo.txid, utxo.vout);

// add a signature to the list to be used later
signatures.add({
"vin": signatures.length,
"key_pair": childNode.keyPair,
"original_amount": utxo.satoshis
});

totalBalance += utxo.satoshis!;
});

// set an address to send the remaining balance to
final outputAddress =
"bitcoincash:qq4vzza5uhgr42ntkl28x67qzda4af5hpgap6z0ntx";

// if there is an unspent balance, create a spending transaction
if (totalBalance > 0 && outputAddress != "") {
// calculate the fee based on number of inputs and one expected output
final fee = Bitbox.BitcoinCash.getByteCount(signatures.length, 1);

// calculate how much balance will be left over to spend after the fee
final sendAmount = totalBalance - fee;

// add the output based on the address provided in the testing data
builder.addOutput(outputAddress, sendAmount);

// sign all inputs
signatures.forEach((signature) {
builder.sign(signature["vin"], signature["key_pair"],
signature["original_amount"]);
});

// build the transaction
final tx = builder.build();

// broadcast the transaction
final txid = await Bitbox.RawTransactions.sendRawTransaction(tx.toHex());

// Yatta!
print("Transaction broadcasted: $txid");
} else if (totalBalance > 0) {
print("Enter an output address to test withdrawal transaction");
}
}
}
11 changes: 10 additions & 1 deletion lib/bitbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ export 'src/account.dart';
export 'src/address.dart';
export 'src/bitbox.dart';
export 'src/bitcoincash.dart';
export 'src/block.dart';
export 'src/blockchain.dart';
export 'src/cashaccounts.dart';
export 'src/crypto/crypto.dart';
export 'src/crypto/ecies.dart';
export 'src/ecpair.dart';
export 'src/hdnode.dart';
export 'src/mnemonic.dart';
export 'src/networks.dart';
export 'src/slp.dart';
export 'src/rawtransactions.dart';
export 'src/transaction.dart';
export 'src/transactionbuilder.dart';
export 'src/varuint.dart';
export 'src/varuint.dart';
export 'src/utils/opcodes.dart';
export 'src/utils/script.dart';
22 changes: 14 additions & 8 deletions lib/src/account.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,31 @@ import 'hdnode.dart';
class Account {
final HDNode accountNode;

int currentChild = 0;
int? currentChild = 0;

Account(this.accountNode, [this.currentChild]);

/// Returns address at the current position
String getCurrentAddress([legacyFormat = true]) {
String? getCurrentAddress([legacyFormat = true]) {
if (legacyFormat) {
return accountNode.derive(currentChild).toLegacyAddress();
return accountNode.derive(currentChild!).toLegacyAddress();
} else {
return accountNode.derive(currentChild).toCashAddress();
return accountNode.derive(currentChild!).toCashAddress();
}
}

/// moves the position forward and returns an address from the new position
String getNextAddress([legacyFormat = true]) {
String? getNextAddress([legacyFormat = true]) {
if (legacyFormat) {
return accountNode.derive(++currentChild).toLegacyAddress();
if (currentChild != null) {
currentChild = currentChild! + 1;
return accountNode.derive(currentChild!).toLegacyAddress();
}
} else {
return accountNode.derive(++currentChild).toCashAddress();
if (currentChild != null) {
currentChild = currentChild! + 1;
return accountNode.derive(currentChild!).toCashAddress();
}
}
}
}
}
Loading