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

feat: use mutinynet faucet #2598

Merged
merged 1 commit into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading