Skip to content

Commit

Permalink
Merge pull request #7 from LtbLightning/Updates-v13
Browse files Browse the repository at this point in the history
Updates for v13
  • Loading branch information
BitcoinZavior authored May 17, 2024
2 parents 76fbd36 + acbdfe4 commit 99015b0
Show file tree
Hide file tree
Showing 51 changed files with 4,947 additions and 4,940 deletions.
23 changes: 18 additions & 5 deletions .github/workflows/precompile_binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ jobs:
- windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Configure Cargo.toml optimizations
run: |
mkdir -p .cargo
echo "[profile.release]" >> .cargo/config.toml
echo "opt-level = 'z'" >> .cargo/config.toml
echo "lto = true" >> .cargo/config.toml
echo "codegen-units = 1" >> .cargo/config.toml
echo "panic = 'abort'" >> .cargo/config.toml
- uses: dart-lang/setup-dart@v1
- uses: subosito/flutter-action@v2
with:
Expand All @@ -25,7 +38,7 @@ jobs:
git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
- name: Install GTK
if: (matrix.os == 'ubuntu-20.04')
run: sudo apt-get update && sudo apt-get install libgtk-3-dev
Expand All @@ -34,12 +47,12 @@ jobs:
run: dart run build_tool precompile-binaries -v --manifest-dir=../../rust --repository=LtbLightning/payjoin-flutter
working-directory: cargokit/build_tool
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
PRIVATE_KEY: ${{ secrets.RELEASE_PRIVATE_KEY }}
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
PRIVATE_KEY: ${{ secrets.CARGOKIT_PRIVATE_KEY }}
- name: Precompile (with Android)
if: (matrix.os == 'ubuntu-20.04')
run: dart run build_tool precompile-binaries -v --manifest-dir=../../rust --repository=LtbLightning/payjoin-flutter --android-sdk-location=/usr/local/lib/android/sdk --android-ndk-version=24.0.8215888 --android-min-sdk-version=23
working-directory: cargokit/build_tool
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
PRIVATE_KEY: ${{ secrets.RELEASE_PRIVATE_KEY }}
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
PRIVATE_KEY: ${{ secrets.CARGOKIT_PRIVATE_KEY }}
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,46 @@
# payjoin
# Payjoin Flutter

A Flutter library for the [Payjoin Dev Kit](https://payjoindevkit.org/).

### How to Use

To use the `payjoin_flutter` package in your project, add it as a dependency in your project's pubspec.yaml:

```dart
dependencies:
payjoin_flutter: 0.13.0
```
### Requirements

- Flutter : 3.0 or higher
- Android minSdkVersion. : API 23 or higher.
- Deployment target : iOS 12.0 or greater.

### Build and run code

Before building the code, we need to set up the Bitcoin core properly in the regtest network. If you "don't"
have Bitcoin Core locally, please refer to this [page](https://learn.saylor.org/mod/page/view.php?id=36347). Or you can
install `Nigiri Bitcoin`, which is a tool designed to simplify the process of running local instances of Bitcoin and
Liquid networks for development and testing purposes. You can refer to
this [link](https://github.com/vulpemventures/nigiri), to install it on your local machine.

NB: The default credentials would be the following
```
rpc_user = "admin1"
rpc_password = "123"
rpc_host = "localhost"
rpc_port = "18443"
```
## Running the integration tests
Once we have set up the Bitcoin core properly in the `Regtest` network,

```shell
git clone https://github.com/LtbLightning/payjoin-flutter.git
cd payjoin-flutter
git checkout v0.13

cd example
#Run integration tests with bitcoin_core and bdk_flutter
flutter test integration_test
```

2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ android {
}

defaultConfig {
minSdkVersion 19
minSdkVersion 23
}
}

Expand Down
5 changes: 4 additions & 1 deletion cargokit/build_tool/lib/src/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,10 @@ class CargokitUserOptions {
}
userProjectDir = userProjectDir.parent;
}
return CargokitUserOptions._();
return CargokitUserOptions(
usePrecompiledBinaries: true,
verboseLogging: false,
);
}

final bool usePrecompiledBinaries;
Expand Down
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ android {
applicationId "io.f.payjoin.payjoin_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
minSdkVersion 23
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
99 changes: 99 additions & 0 deletions example/integration_test/bdk_full_cycle_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import 'dart:convert';

import 'package:bdk_flutter/bdk_flutter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:payjoin_flutter/common.dart' as common;
import 'package:payjoin_flutter/uri.dart' as pay_join_uri;
import 'package:payjoin_flutter_example/bdk_client.dart';
import 'package:payjoin_flutter_example/btc_client.dart';
import 'package:payjoin_flutter_example/payjoin_library.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('v1_to_v1', () {
setUp(() async {});
testWidgets('full_cycle', (WidgetTester tester) async {
final payJoinLib = PayJoinLibrary();
final btcClient = BtcClient("sender");
await btcClient.loadWallet();
final sender = BdkClient(
"puppy interest whip tonight dad never sudden response push zone pig patch");
final receiver = BdkClient(
"cart super leaf clinic pistol plug replace close super tooth wealth usage");
await sender.restoreWallet();
await receiver.restoreWallet();
// Receiver creates the payjoin URI
final pjReceiverAddress = (await receiver.getNewAddress()).address;
final pjSenderAddress = (await sender.getNewAddress()).address;
await btcClient.sendToAddress(await pjSenderAddress.asString(), 10);
await btcClient.sendToAddress(await pjReceiverAddress.asString(), 2);
await btcClient.generate(11, await pjSenderAddress.asString());
await receiver.syncWallet();
await sender.syncWallet();
final pjUri = await payJoinLib.buildPjUri(
0.0083285, await pjReceiverAddress.asString());
// Sender create a funded PSBT (not broadcast) to address with amount given in the pjUri
debugPrint("Sender Balance: ${(await sender.getBalance()).toString()}");
final uri = await pay_join_uri.Uri.fromString(pjUri);
final address = await uri.address();
int amount = (((await uri.amount()) ?? 0) * 100000000).toInt();
final senderPsbt = (await sender.createPsbt(address, amount, 2000));
final senderPsbtBase64 = await senderPsbt.serialize();
debugPrint(
"\nOriginal sender psbt: $senderPsbtBase64",
);
// Receiver part
final (provisionalProposal, ctx) =
await payJoinLib.handlePjRequest(senderPsbtBase64, pjUri, (e) async {
final script = ScriptBuf(bytes: e);
return (await receiver.getAddressInfo(script));
});
final availableInputs = await receiver.listUnspent();
// Select receiver payjoin inputs.
Map<int, common.OutPoint> candidateInputs = {
for (var input in availableInputs)
input.txout.value: common.OutPoint(
txid: input.outpoint.txid.toString(), vout: input.outpoint.vout)
};
final selectedOutpoint = await provisionalProposal.tryPreservingPrivacy(
candidateInputs: candidateInputs);
var selectedUtxo = availableInputs.firstWhere(
(i) =>
i.outpoint.txid.toString() == selectedOutpoint.txid &&
i.outpoint.vout == selectedOutpoint.vout,
orElse: () => throw Exception('UTXO not found'));
var txoToContribute = common.TxOut(
value: selectedUtxo.txout.value,
scriptPubkey: selectedUtxo.txout.scriptPubkey.bytes,
);

var outpointToContribute = common.OutPoint(
txid: selectedUtxo.outpoint.txid.toString(),
vout: selectedUtxo.outpoint.vout,
);
await provisionalProposal.contributeWitnessInput(
txo: txoToContribute, outpoint: outpointToContribute);
final receiverAddress = (await receiver.getNewAddress()).address;
await provisionalProposal.substituteOutputAddress(
address: await receiverAddress.asString());
final payJoinProposal =
await provisionalProposal.finalizeProposal(processPsbt: (e) async {
return await (await receiver
.signPsbt(await PartiallySignedTransaction.fromString(e)))
.serialize();
});
final receiverPsbt = await payJoinProposal.psbt();
debugPrint("\n Original receiver psbt: $receiverPsbt");
final receiverProcessedPsbt =
await ctx.processResponse(response: utf8.encode(receiverPsbt));
final senderProcessedPsbt = (await sender.signPsbt(
await PartiallySignedTransaction.fromString(receiverProcessedPsbt)));

final txid = await sender.broadcastPsbt(senderProcessedPsbt);
debugPrint("Broadcast success: $txid");
});
});
}
93 changes: 93 additions & 0 deletions example/integration_test/bitcoin_core_full_cycle_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import 'dart:convert';

import 'package:bdk_flutter/bdk_flutter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:payjoin_flutter/common.dart' as common;
import 'package:payjoin_flutter/uri.dart' as pay_join_uri;
import 'package:payjoin_flutter_example/btc_client.dart';
import 'package:payjoin_flutter_example/payjoin_library.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('v1_to_v1', () {
setUp(() async {});
testWidgets('full_cycle', (WidgetTester tester) async {
final payJoinLib = PayJoinLibrary();
final sender = BtcClient("receiver");
final client = BtcClient("");
final receiver = BtcClient("sender");
// Receiver creates the payjoin URI
final pjReceiverAddress = await receiver.getNewAddress();
final pjSenderAddress = await sender.getNewAddress();
//Generate blocks to receiver and sender
await client.sendToAddress(pjSenderAddress, 10);
await client.sendToAddress(pjReceiverAddress, 1);
await sender.generate(11, pjSenderAddress);
await receiver.generate(1, pjReceiverAddress);
final pjUri = await payJoinLib.buildPjUri(0.0083285, pjReceiverAddress);
// Sender create a funded PSBT (not broadcast) to address with amount given in the pjUri
debugPrint("Sender Balance: ${(await sender.getBalance()).toString()}");
final uri = await pay_join_uri.Uri.fromString(pjUri);
final address = await uri.address();
final amount = await uri.amount();
final senderPsbt =
(await sender.walletCreateFundedPsbt(amount, address, 2000))["psbt"];
debugPrint(
"\nOriginal sender psbt: $senderPsbt",
);
final (provisionalProposal, ctx) =
await payJoinLib.handlePjRequest(senderPsbt, pjUri, (e) async {
final script = ScriptBuf(bytes: e);
final address = await (await Address.fromScript(
script: script, network: Network.regtest))
.asString();
return (await receiver.getAddressInfo(address))["ismine"];
});
final availableInputs = await receiver.listUnspent([]);
// Select receiver payjoin inputs.
Map<int, common.OutPoint> candidateInputs = {};
for (var e in availableInputs) {
int amount = (e["amount"] * 100000000).toInt();
candidateInputs[amount] =
common.OutPoint(txid: e["txid"], vout: e["vout"]);
}
final selectedOutpoint = await provisionalProposal.tryPreservingPrivacy(
candidateInputs: candidateInputs);

final selectedUtxo = availableInputs.firstWhere((e) =>
(e["txid"] == selectedOutpoint.txid) &&
(e["vout"] == selectedOutpoint.vout));
final selectedUtxoScriptPubKey =
await ScriptBuf.fromHex(selectedUtxo["scriptPubKey"]);
int selectedUtxoAmount = (selectedUtxo["amount"] * 100000000).toInt();
final txoutToContribute = common.TxOut(
scriptPubkey: selectedUtxoScriptPubKey.bytes,
value: selectedUtxoAmount,
);
final outputToContribute = common.OutPoint(
txid: selectedUtxo["txid"], vout: selectedUtxo["vout"]);
await provisionalProposal.contributeWitnessInput(
txo: txoutToContribute, outpoint: outputToContribute);
final newReceiverAddress = await receiver.getNewAddress();
await provisionalProposal.substituteOutputAddress(
address: newReceiverAddress);
final payJoinProposal =
await provisionalProposal.finalizeProposal(processPsbt: (e) async {
return (await receiver.walletProcessPsbt(e))["psbt"];
});
final receiverPsbt = await payJoinProposal.psbt();
debugPrint("\n Original receiver psbt: $receiverPsbt");
final receiverProcessedPsbt =
await ctx.processResponse(response: utf8.encode(receiverPsbt));
final senderProcessedPsbt =
(await sender.walletProcessPsbt(receiverProcessedPsbt))["psbt"];
final senderFinalizedPsbt =
(await sender.finalizePsbt(senderProcessedPsbt));
final res = await sender.sendRawTransaction(senderFinalizedPsbt["hex"]);
debugPrint("Broadcast success: $res");
});
});
}
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
<string>12.0</string>
</dict>
</plist>
21 changes: 20 additions & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
PODS:
- bdk_flutter (0.31.2-dev.1):
- Flutter
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- payjoin_flutter (0.0.1)

DEPENDENCIES:
- bdk_flutter (from `.symlinks/plugins/bdk_flutter/ios`)
- Flutter (from `Flutter`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- payjoin_flutter (from `.symlinks/plugins/payjoin_flutter/ios`)

EXTERNAL SOURCES:
bdk_flutter:
:path: ".symlinks/plugins/bdk_flutter/ios"
Flutter:
:path: Flutter
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
payjoin_flutter:
:path: ".symlinks/plugins/payjoin_flutter/ios"

SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
bdk_flutter: 1d889a00393def5bcd2be9cad91fa0c2a34fff7f
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
payjoin_flutter: 9011d8ef87f28bd66bcf80a21fdef14951b8a2aa

PODFILE CHECKSUM: a57f30d18f102dd3ce366b1d62a55ecbef2158e5
Expand Down
Loading

0 comments on commit 99015b0

Please sign in to comment.