Skip to content

Commit

Permalink
Merge pull request #2598 from get10101/feat/fund-with-mutinyfaucet
Browse files Browse the repository at this point in the history
feat: use mutinynet faucet
  • Loading branch information
bonomat authored Jun 4, 2024
2 parents 1b9e50b + 56e576a commit dd8b524
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
2 changes: 1 addition & 1 deletion mobile/lib/common/init_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ List<SingleChildWidget> createProviders() {
Provider(create: (context) => pollService),
Provider(create: (context) => memeService)
];
if (config.network == "regtest") {
if (config.network == "regtest" || config.network == "signet") {
providers.add(Provider(create: (context) => FaucetService()));
}

Expand Down
69 changes: 47 additions & 22 deletions mobile/lib/features/wallet/application/faucet_service.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
import 'dart:convert';
import 'dart:math';

import 'package:get_10101/common/domain/model.dart';
import 'package:get_10101/logger/logger.dart';
import 'package:http/http.dart' as http;

class FaucetService {
/// Pay the provided invoice with our faucet
Future<void> payInvoiceWithFaucet(String bip21Uri, Amount? invoiceAmount) async {
Future<void> payInvoiceWithFaucet(String bip21Uri, Amount? invoiceAmount, String network) async {
final split = bip21Uri.split(":");
final addressAndMaybeAmount = split[1].split("?");
logger.i("Funding $addressAndMaybeAmount");
final address = addressAndMaybeAmount[0];
final amount = invoiceAmount?.btc ?? 1.0;

logger.i("Funding $address with $amount");
// Default to the faucet on the 10101 server, but allow to override it
// locally if needed for dev testing
// It's not populated in Config struct, as it's not used in production

switch (network) {
case "regtest":
await payWith10101Faucet(address, amount);
break;
case "signet":
await payWithMutinyFaucet(address, amount);
break;
default:
throw Exception("Invalid network provided $network. Only regtest or signet supported");
}
}

Future<void> payWith10101Faucet(String address, double amountBtc) async {
// Faucet env variable needs to be set for local testing, otherwise we will fail here
if (!const bool.hasEnvironment("REGTEST_FAUCET")) {
throw Exception("Could not fund address. REGTEST_FAUCET not set");
}

String faucet =
const String.fromEnvironment("REGTEST_FAUCET", defaultValue: "http://34.32.62.120:8080");
const String.fromEnvironment("REGTEST_FAUCET", defaultValue: "http://localhost:8080");

final data = {
'jsonrpc': '1.0',
'method': 'sendtoaddress',
'params': [address, "$amount"],
'params': [address, "$amountBtc"],
};
final encodedData = json.encode(data);

Expand Down Expand Up @@ -63,24 +80,32 @@ class FaucetService {
}
}

// Pay the generated invoice with maker faucet
Future<void> payInvoiceWithMakerFaucet(String invoice) async {
// Default to the faucet on the 10101 server, but allow to override it
// locally if needed for dev testing
// It's not populated in Config struct, as it's not used in production
String faucet = const String.fromEnvironment("REGTEST_MAKER_FAUCET",
defaultValue: "http://34.32.62.120:80/maker/faucet");

final response = await http.post(
Uri.parse('$faucet/$invoice'),
);
Future<void> payWithMutinyFaucet(String address, double amountBtc) async {
final url = Uri.parse('https://faucet.mutinynet.com/api/onchain');
final headers = {
'Content-Type': 'application/json',
'Origin': 'https://faucet.mutinynet.com',
};
final body = jsonEncode({
'sats': min(amountBtc * 100000000, 10000000).toInt(),
'address': address,
});

logger.i("Response ${response.body}${response.statusCode}");
try {
final response = await http.post(
url,
headers: headers,
body: body,
);

if (response.statusCode != 200) {
throw Exception("Payment failed: Received ${response.statusCode}. ${response.body}");
} else {
logger.i("Paying invoice succeeded: ${response.body}");
if (response.statusCode == 200) {
logger.i('Funding successful ${response.body}');
} else {
logger.e('Request failed with status: ${response.statusCode} ${response.body}');
throw Exception("Failed funding address ${response.statusCode} ${response.body}");
}
} catch (e) {
throw Exception("Failed funding address ${e.toString()}");
}
}
}
11 changes: 7 additions & 4 deletions mobile/lib/features/wallet/receive_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ class _ReceiveScreenState extends State<ReceiveScreen> {
Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: GestureDetector(
onDoubleTap:
config.network == "regtest" ? () => setState(() => _faucet = !_faucet) : null,
onDoubleTap: config.network == "regtest" || config.network == "signet"
? () => setState(() => _faucet = !_faucet)
: null,
child: Center(
child: _faucet
? Column(
Expand All @@ -98,7 +99,7 @@ class _ReceiveScreenState extends State<ReceiveScreen> {
setState(() => _isPayInvoiceButtonDisabled = true);
final faucetService = context.read<FaucetService>();
faucetService
.payInvoiceWithFaucet(rawInvoice(), amount)
.payInvoiceWithFaucet(rawInvoice(), amount, config.network)
.catchError((error) {
setState(() => _isPayInvoiceButtonDisabled = false);
showSnackBar(ScaffoldMessenger.of(context), error.toString());
Expand All @@ -108,7 +109,9 @@ class _ReceiveScreenState extends State<ReceiveScreen> {
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0))),
),
child: const Text("Pay with 10101 faucet"),
child: config.network == "regtest"
? const Text("Pay with 10101 faucet")
: const Text("Pay with Mutinynet faucet"),
),
const SizedBox(height: 125),
],
Expand Down

0 comments on commit dd8b524

Please sign in to comment.