From 6eb52e15b8dbcfc2c3ba3264a8288144fab8ca02 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Mon, 14 Sep 2026 15:11:16 -0500 Subject: [PATCH 01/17] feat: cache federation expiration and successor --- lib/frb_generated.dart | 718 +++++++++++++-------- lib/multimint.dart | 28 +- lib/nostr.dart | 2 +- lib/screens/federation_expiry_screen.dart | 318 +++++++++ lib/widgets/federation_expiry_banner.dart | 104 +++ rust/ecashapp/src/frb_generated.rs | 746 ++++++++++++++-------- rust/ecashapp/src/multimint.rs | 116 +++- 7 files changed, 1494 insertions(+), 538 deletions(-) create mode 100644 lib/screens/federation_expiry_screen.dart create mode 100644 lib/widgets/federation_expiry_banner.dart diff --git a/lib/frb_generated.dart b/lib/frb_generated.dart index ef36ae65..6dde6e5c 100644 --- a/lib/frb_generated.dart +++ b/lib/frb_generated.dart @@ -69,7 +69,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.9.0'; @override - int get rustContentHash => 1098215331; + int get rustContentHash => -165126491; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -116,6 +116,10 @@ abstract class RustLibApi extends BaseApi { String? network, }); + BigInt? crateMultimintFederationMetaAutoAccessorGetExpiryTimestamp({ + required FederationMeta that, + }); + List crateMultimintFederationMetaAutoAccessorGetGuardians({ required FederationMeta that, }); @@ -140,10 +144,19 @@ abstract class RustLibApi extends BaseApi { required FederationMeta that, }); + String? crateMultimintFederationMetaAutoAccessorGetSuccessorInvite({ + required FederationMeta that, + }); + String? crateMultimintFederationMetaAutoAccessorGetWelcome({ required FederationMeta that, }); + void crateMultimintFederationMetaAutoAccessorSetExpiryTimestamp({ + required FederationMeta that, + BigInt? expiryTimestamp, + }); + void crateMultimintFederationMetaAutoAccessorSetGuardians({ required FederationMeta that, required List guardians, @@ -174,6 +187,11 @@ abstract class RustLibApi extends BaseApi { required FederationSelector selector, }); + void crateMultimintFederationMetaAutoAccessorSetSuccessorInvite({ + required FederationMeta that, + String? successorInvite, + }); + void crateMultimintFederationMetaAutoAccessorSetWelcome({ required FederationMeta that, String? welcome, @@ -1926,7 +1944,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - List crateMultimintFederationMetaAutoAccessorGetGuardians({ + BigInt? crateMultimintFederationMetaAutoAccessorGetExpiryTimestamp({ required FederationMeta that, }) { return handler.executeSync( @@ -1939,6 +1957,39 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 9)!; }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_box_autoadd_u_64, + decodeErrorData: null, + ), + constMeta: + kCrateMultimintFederationMetaAutoAccessorGetExpiryTimestampConstMeta, + argValues: [that], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintFederationMetaAutoAccessorGetExpiryTimestampConstMeta => + const TaskConstMeta( + debugName: "FederationMeta_auto_accessor_get_expiry_timestamp", + argNames: ["that"], + ); + + @override + List crateMultimintFederationMetaAutoAccessorGetGuardians({ + required FederationMeta that, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationMeta( + that, + serializer, + ); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 10)!; + }, codec: SseCodec( decodeSuccessData: sse_decode_list_guardian, decodeErrorData: null, @@ -1970,7 +2021,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 10)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 11)!; }, codec: SseCodec( decodeSuccessData: sse_decode_u_64, @@ -2003,7 +2054,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 11)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 12)!; }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -2036,7 +2087,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 12)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 13)!; }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -2068,7 +2119,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 13)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 14)!; }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -2101,7 +2152,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 14)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 15)!; }, codec: SseCodec( decodeSuccessData: @@ -2123,6 +2174,39 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["that"], ); + @override + String? crateMultimintFederationMetaAutoAccessorGetSuccessorInvite({ + required FederationMeta that, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationMeta( + that, + serializer, + ); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 16)!; + }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_String, + decodeErrorData: null, + ), + constMeta: + kCrateMultimintFederationMetaAutoAccessorGetSuccessorInviteConstMeta, + argValues: [that], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintFederationMetaAutoAccessorGetSuccessorInviteConstMeta => + const TaskConstMeta( + debugName: "FederationMeta_auto_accessor_get_successor_invite", + argNames: ["that"], + ); + @override String? crateMultimintFederationMetaAutoAccessorGetWelcome({ required FederationMeta that, @@ -2135,7 +2219,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 15)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 17)!; }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -2155,6 +2239,41 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["that"], ); + @override + void crateMultimintFederationMetaAutoAccessorSetExpiryTimestamp({ + required FederationMeta that, + BigInt? expiryTimestamp, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationMeta( + that, + serializer, + ); + sse_encode_opt_box_autoadd_u_64(expiryTimestamp, serializer); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 18)!; + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: + kCrateMultimintFederationMetaAutoAccessorSetExpiryTimestampConstMeta, + argValues: [that, expiryTimestamp], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintFederationMetaAutoAccessorSetExpiryTimestampConstMeta => + const TaskConstMeta( + debugName: "FederationMeta_auto_accessor_set_expiry_timestamp", + argNames: ["that", "expiryTimestamp"], + ); + @override void crateMultimintFederationMetaAutoAccessorSetGuardians({ required FederationMeta that, @@ -2169,7 +2288,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_list_guardian(guardians, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 16)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 19)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2204,7 +2323,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_u_64(lastUpdated, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 17)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 20)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2239,7 +2358,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_opt_String(lnaddressApi, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 18)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 21)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2274,7 +2393,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_opt_String(picture, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 19)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 22)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2308,7 +2427,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_opt_String(recurringdApi, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 20)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 23)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2346,7 +2465,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { selector, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 21)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 24)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2367,6 +2486,41 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["that", "selector"], ); + @override + void crateMultimintFederationMetaAutoAccessorSetSuccessorInvite({ + required FederationMeta that, + String? successorInvite, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationMeta( + that, + serializer, + ); + sse_encode_opt_String(successorInvite, serializer); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 25)!; + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: + kCrateMultimintFederationMetaAutoAccessorSetSuccessorInviteConstMeta, + argValues: [that, successorInvite], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintFederationMetaAutoAccessorSetSuccessorInviteConstMeta => + const TaskConstMeta( + debugName: "FederationMeta_auto_accessor_set_successor_invite", + argNames: ["that", "successorInvite"], + ); + @override void crateMultimintFederationMetaAutoAccessorSetWelcome({ required FederationMeta that, @@ -2381,7 +2535,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_opt_String(welcome, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 22)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 26)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2413,7 +2567,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 23)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 27)!; }, codec: SseCodec( decodeSuccessData: @@ -2447,7 +2601,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 24)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 28)!; }, codec: SseCodec( decodeSuccessData: sse_decode_String, @@ -2480,7 +2634,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 25)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 29)!; }, codec: SseCodec( decodeSuccessData: sse_decode_opt_String, @@ -2518,7 +2672,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { federationId, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 26)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 30)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2553,7 +2707,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_String(federationName, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 27)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 31)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2588,7 +2742,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_opt_String(network, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 28)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 32)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2621,7 +2775,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 29)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 33)!; }, codec: SseCodec( decodeSuccessData: sse_decode_String, @@ -2655,7 +2809,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 30)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 34)!; }, codec: SseCodec( decodeSuccessData: sse_decode_String, @@ -2687,7 +2841,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 31)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 35)!; }, codec: SseCodec( decodeSuccessData: @@ -2721,7 +2875,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 32)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 36)!; }, codec: SseCodec( decodeSuccessData: sse_decode_String, @@ -2753,7 +2907,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 33)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 37)!; }, codec: SseCodec( decodeSuccessData: @@ -2787,7 +2941,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 34)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 38)!; }, codec: SseCodec( decodeSuccessData: sse_decode_String, @@ -2822,7 +2976,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_String(authenticationToken, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 35)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 39)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2858,7 +3012,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_String(domain, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 36)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 40)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2895,7 +3049,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { lnAddressApi, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 37)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 41)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2930,7 +3084,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_String(lnurl, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 38)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 42)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -2967,7 +3121,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { recurringdApi, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 39)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 43)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -3002,7 +3156,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { serializer, ); sse_encode_String(username, serializer); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 40)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 44)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -3035,7 +3189,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { that, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 41)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 45)!; }, codec: SseCodec( decodeSuccessData: @@ -3074,7 +3228,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { federationId, serializer, ); - return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 42)!; + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 46)!; }, codec: SseCodec( decodeSuccessData: sse_decode_unit, @@ -3108,7 +3262,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 43, + funcId: 47, port: port_, ); }, @@ -3149,7 +3303,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 44, + funcId: 48, port: port_, ); }, @@ -3196,7 +3350,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 45, + funcId: 49, port: port_, ); }, @@ -3243,7 +3397,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 46, + funcId: 50, port: port_, ); }, @@ -3291,7 +3445,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 47, + funcId: 51, port: port_, ); }, @@ -3338,7 +3492,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 48, + funcId: 52, port: port_, ); }, @@ -3384,7 +3538,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 49, + funcId: 53, port: port_, ); }, @@ -3426,7 +3580,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 50, + funcId: 54, port: port_, ); }, @@ -3469,7 +3623,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 51, + funcId: 55, port: port_, ); }, @@ -3513,7 +3667,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 52, + funcId: 56, port: port_, ); }, @@ -3559,7 +3713,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 53, + funcId: 57, port: port_, ); }, @@ -3603,7 +3757,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 54, + funcId: 58, port: port_, ); }, @@ -3652,7 +3806,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 55, + funcId: 59, port: port_, ); }, @@ -3719,7 +3873,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 56, + funcId: 60, port: port_, ); }, @@ -3775,7 +3929,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 57, + funcId: 61, port: port_, ); }, @@ -3832,7 +3986,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 58, + funcId: 62, port: port_, ); }, @@ -3868,7 +4022,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 59, + funcId: 63, port: port_, ); }, @@ -3910,7 +4064,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 60, + funcId: 64, port: port_, ); }, @@ -3947,7 +4101,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 61, + funcId: 65, port: port_, ); }, @@ -3983,7 +4137,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 62, + funcId: 66, port: port_, ); }, @@ -4019,7 +4173,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 63, + funcId: 67, port: port_, ); }, @@ -4055,7 +4209,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 64, + funcId: 68, port: port_, ); }, @@ -4098,7 +4252,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 65, + funcId: 69, port: port_, ); }, @@ -4135,7 +4289,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 66, + funcId: 70, port: port_, ); }, @@ -4172,7 +4326,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 67, + funcId: 71, port: port_, ); }, @@ -4215,7 +4369,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 68, + funcId: 72, port: port_, ); }, @@ -4256,7 +4410,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 69, + funcId: 73, port: port_, ); }, @@ -4300,7 +4454,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 70, + funcId: 74, port: port_, ); }, @@ -4337,7 +4491,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 71, + funcId: 75, port: port_, ); }, @@ -4378,7 +4532,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 72, + funcId: 76, port: port_, ); }, @@ -4419,7 +4573,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 73, + funcId: 77, port: port_, ); }, @@ -4462,7 +4616,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 74, + funcId: 78, port: port_, ); }, @@ -4497,7 +4651,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 75, + funcId: 79, port: port_, ); }, @@ -4544,7 +4698,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 76, + funcId: 80, port: port_, ); }, @@ -4589,7 +4743,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 77, + funcId: 81, port: port_, ); }, @@ -4635,7 +4789,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 78, + funcId: 82, port: port_, ); }, @@ -4678,7 +4832,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 79, + funcId: 83, port: port_, ); }, @@ -4723,7 +4877,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 80, + funcId: 84, port: port_, ); }, @@ -4770,7 +4924,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 81, + funcId: 85, port: port_, ); }, @@ -4819,7 +4973,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 82, + funcId: 86, port: port_, ); }, @@ -4871,7 +5025,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 83, + funcId: 87, port: port_, ); }, @@ -4916,7 +5070,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 84, + funcId: 88, port: port_, ); }, @@ -4963,7 +5117,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 85, + funcId: 89, port: port_, ); }, @@ -5008,7 +5162,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 86, + funcId: 90, port: port_, ); }, @@ -5044,7 +5198,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 87, + funcId: 91, port: port_, ); }, @@ -5084,7 +5238,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 88, + funcId: 92, port: port_, ); }, @@ -5126,7 +5280,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 89, + funcId: 93, port: port_, ); }, @@ -5176,7 +5330,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 90, + funcId: 94, port: port_, ); }, @@ -5214,7 +5368,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 91, + funcId: 95, port: port_, ); }, @@ -5260,7 +5414,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 92, + funcId: 96, port: port_, ); }, @@ -5313,7 +5467,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 93, + funcId: 97, port: port_, ); }, @@ -5369,7 +5523,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 94, + funcId: 98, port: port_, ); }, @@ -5431,7 +5585,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 95, + funcId: 99, port: port_, ); }, @@ -5476,7 +5630,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 96, + funcId: 100, port: port_, ); }, @@ -5512,7 +5666,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 97, + funcId: 101, port: port_, ); }, @@ -5553,7 +5707,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 98, + funcId: 102, port: port_, ); }, @@ -5603,7 +5757,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 99, + funcId: 103, port: port_, ); }, @@ -5662,7 +5816,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 100, + funcId: 104, port: port_, ); }, @@ -5701,7 +5855,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 101, + funcId: 105, port: port_, ); }, @@ -5759,7 +5913,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 102, + funcId: 106, port: port_, ); }, @@ -5825,7 +5979,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 103, + funcId: 107, port: port_, ); }, @@ -5864,7 +6018,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 104, + funcId: 108, port: port_, ); }, @@ -5905,7 +6059,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 105, + funcId: 109, port: port_, ); }, @@ -5943,7 +6097,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 106, + funcId: 110, port: port_, ); }, @@ -5981,7 +6135,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 107, + funcId: 111, port: port_, ); }, @@ -6028,7 +6182,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 108, + funcId: 112, port: port_, ); }, @@ -6077,7 +6231,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 109, + funcId: 113, port: port_, ); }, @@ -6129,7 +6283,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 110, + funcId: 114, port: port_, ); }, @@ -6182,7 +6336,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 111, + funcId: 115, port: port_, ); }, @@ -6218,7 +6372,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 112, + funcId: 116, port: port_, ); }, @@ -6256,7 +6410,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 113, + funcId: 117, port: port_, ); }, @@ -6292,7 +6446,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 114, + funcId: 118, port: port_, ); }, @@ -6328,7 +6482,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 115, + funcId: 119, port: port_, ); }, @@ -6366,7 +6520,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 116, + funcId: 120, port: port_, ); }, @@ -6402,7 +6556,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 117, + funcId: 121, port: port_, ); }, @@ -6440,7 +6594,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 118, + funcId: 122, port: port_, ); }, @@ -6475,7 +6629,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 119, + funcId: 123, port: port_, ); }, @@ -6514,7 +6668,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 120, + funcId: 124, port: port_, ); }, @@ -6551,7 +6705,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 121, + funcId: 125, port: port_, ); }, @@ -6587,7 +6741,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 122, + funcId: 126, port: port_, ); }, @@ -6625,7 +6779,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 123, + funcId: 127, port: port_, ); }, @@ -6665,7 +6819,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 124, + funcId: 128, port: port_, ); }, @@ -6705,7 +6859,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 125, + funcId: 129, port: port_, ); }, @@ -6747,7 +6901,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 126, + funcId: 130, port: port_, ); }, @@ -6788,7 +6942,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 127, + funcId: 131, port: port_, ); }, @@ -6826,7 +6980,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 128, + funcId: 132, port: port_, ); }, @@ -6866,7 +7020,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 129, + funcId: 133, port: port_, ); }, @@ -6911,7 +7065,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 130, + funcId: 134, port: port_, ); }, @@ -6945,7 +7099,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 131, + funcId: 135, port: port_, ); }, @@ -6983,7 +7137,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 132, + funcId: 136, port: port_, ); }, @@ -7021,7 +7175,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 133, + funcId: 137, )!; }, codec: SseCodec( @@ -7051,7 +7205,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 134, + funcId: 138, )!; }, codec: SseCodec( @@ -7084,7 +7238,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 135, + funcId: 139, )!; }, codec: SseCodec( @@ -7120,7 +7274,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 136, + funcId: 140, port: port_, ); }, @@ -7156,7 +7310,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 137, + funcId: 141, )!; }, codec: SseCodec( @@ -7191,7 +7345,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 138, + funcId: 142, )!; }, codec: SseCodec( @@ -7226,7 +7380,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 139, + funcId: 143, )!; }, codec: SseCodec( @@ -7261,7 +7415,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 140, + funcId: 144, )!; }, codec: SseCodec( @@ -7299,7 +7453,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 141, + funcId: 145, )!; }, codec: SseCodec( @@ -7336,7 +7490,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 142, + funcId: 146, )!; }, codec: SseCodec( @@ -7373,7 +7527,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 143, + funcId: 147, )!; }, codec: SseCodec( @@ -7409,7 +7563,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 144, + funcId: 148, )!; }, codec: SseCodec( @@ -7445,7 +7599,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 145, + funcId: 149, )!; }, codec: SseCodec( @@ -7483,7 +7637,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 146, + funcId: 150, )!; }, codec: SseCodec( @@ -7523,7 +7677,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 147, + funcId: 151, )!; }, codec: SseCodec( @@ -7562,7 +7716,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 148, + funcId: 152, )!; }, codec: SseCodec( @@ -7601,7 +7755,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 149, + funcId: 153, )!; }, codec: SseCodec( @@ -7640,7 +7794,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 150, + funcId: 154, )!; }, codec: SseCodec( @@ -7678,7 +7832,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 151, + funcId: 155, )!; }, codec: SseCodec( @@ -7716,7 +7870,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 152, + funcId: 156, )!; }, codec: SseCodec( @@ -7752,7 +7906,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 153, + funcId: 157, )!; }, codec: SseCodec( @@ -7790,7 +7944,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 154, + funcId: 158, )!; }, codec: SseCodec( @@ -7827,7 +7981,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 155, + funcId: 159, )!; }, codec: SseCodec( @@ -7865,7 +8019,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 156, + funcId: 160, )!; }, codec: SseCodec( @@ -7903,7 +8057,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 157, + funcId: 161, )!; }, codec: SseCodec( @@ -7942,7 +8096,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 158, + funcId: 162, )!; }, codec: SseCodec( @@ -7982,7 +8136,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 159, + funcId: 163, )!; }, codec: SseCodec( @@ -8021,7 +8175,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 160, + funcId: 164, )!; }, codec: SseCodec( @@ -8064,7 +8218,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 161, + funcId: 165, )!; }, codec: SseCodec( @@ -8103,7 +8257,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 162, + funcId: 166, )!; }, codec: SseCodec( @@ -8134,7 +8288,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 163, + funcId: 167, port: port_, ); }, @@ -8162,7 +8316,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 164, + funcId: 168, port: port_, ); }, @@ -8195,7 +8349,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 165, + funcId: 169, port: port_, ); }, @@ -8236,7 +8390,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 166, + funcId: 170, port: port_, ); }, @@ -8276,7 +8430,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 167, + funcId: 171, port: port_, ); }, @@ -8317,7 +8471,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 168, + funcId: 172, port: port_, ); }, @@ -8357,7 +8511,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 169, + funcId: 173, port: port_, ); }, @@ -8386,7 +8540,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 170, + funcId: 174, port: port_, ); }, @@ -8417,7 +8571,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 171, + funcId: 175, port: port_, ); }, @@ -8452,7 +8606,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 172, + funcId: 176, port: port_, ); }, @@ -8490,7 +8644,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 173, + funcId: 177, port: port_, ); }, @@ -8530,7 +8684,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 174, + funcId: 178, port: port_, ); }, @@ -8565,7 +8719,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 175, + funcId: 179, port: port_, ); }, @@ -8602,7 +8756,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 176, + funcId: 180, port: port_, ); }, @@ -8645,7 +8799,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 177, + funcId: 181, port: port_, ); }, @@ -8697,7 +8851,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 178, + funcId: 182, port: port_, ); }, @@ -8726,7 +8880,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 179, + funcId: 183, port: port_, ); }, @@ -8757,7 +8911,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 180, + funcId: 184, port: port_, ); }, @@ -8798,7 +8952,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 181, + funcId: 185, port: port_, ); }, @@ -8834,7 +8988,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 182, + funcId: 186, port: port_, ); }, @@ -8868,7 +9022,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 183, + funcId: 187, port: port_, ); }, @@ -8903,7 +9057,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 184, + funcId: 188, port: port_, ); }, @@ -8954,7 +9108,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 185, + funcId: 189, port: port_, ); }, @@ -9010,7 +9164,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 186, + funcId: 190, port: port_, ); }, @@ -9039,7 +9193,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 187, + funcId: 191, port: port_, ); }, @@ -9068,7 +9222,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 188, + funcId: 192, port: port_, ); }, @@ -9101,7 +9255,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 189, + funcId: 193, port: port_, ); }, @@ -9131,7 +9285,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 190, + funcId: 194, port: port_, ); }, @@ -9158,7 +9312,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 191, + funcId: 195, port: port_, ); }, @@ -9185,7 +9339,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 192, + funcId: 196, port: port_, ); }, @@ -9212,7 +9366,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 193, + funcId: 197, port: port_, ); }, @@ -9239,7 +9393,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 194, + funcId: 198, port: port_, ); }, @@ -9275,7 +9429,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 195, + funcId: 199, port: port_, ); }, @@ -9305,7 +9459,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 196, + funcId: 200, port: port_, ); }, @@ -9333,7 +9487,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 197, + funcId: 201, port: port_, ); }, @@ -9368,7 +9522,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 198, + funcId: 202, port: port_, ); }, @@ -9407,7 +9561,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 199, + funcId: 203, port: port_, ); }, @@ -9443,7 +9597,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 200, + funcId: 204, port: port_, ); }, @@ -9481,7 +9635,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 201, + funcId: 205, port: port_, ); }, @@ -9511,7 +9665,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 202, + funcId: 206, port: port_, ); }, @@ -9546,7 +9700,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 203, + funcId: 207, port: port_, ); }, @@ -9582,7 +9736,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 204, + funcId: 208, port: port_, ); }, @@ -9612,7 +9766,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 205, + funcId: 209, port: port_, ); }, @@ -9640,7 +9794,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 206, + funcId: 210, port: port_, ); }, @@ -9667,7 +9821,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 207, + funcId: 211, port: port_, ); }, @@ -9700,7 +9854,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 208, + funcId: 212, port: port_, ); }, @@ -9729,7 +9883,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 209, + funcId: 213, port: port_, ); }, @@ -9756,7 +9910,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 210, + funcId: 214, port: port_, ); }, @@ -9786,7 +9940,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 211, + funcId: 215, port: port_, ); }, @@ -9825,7 +9979,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 212, + funcId: 216, port: port_, ); }, @@ -9864,7 +10018,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 213, + funcId: 217, port: port_, ); }, @@ -9903,7 +10057,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 214, + funcId: 218, port: port_, ); }, @@ -9941,7 +10095,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 215, + funcId: 219, port: port_, ); }, @@ -9980,7 +10134,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 216, + funcId: 220, port: port_, ); }, @@ -10021,7 +10175,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 217, + funcId: 221, port: port_, ); }, @@ -10064,7 +10218,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 218, + funcId: 222, port: port_, ); }, @@ -10104,7 +10258,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 219, + funcId: 223, port: port_, ); }, @@ -10143,7 +10297,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 220, + funcId: 224, port: port_, ); }, @@ -10184,7 +10338,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 221, + funcId: 225, port: port_, ); }, @@ -10223,7 +10377,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 222, + funcId: 226, port: port_, ); }, @@ -10252,7 +10406,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 223, + funcId: 227, port: port_, ); }, @@ -10279,7 +10433,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 224, + funcId: 228, port: port_, ); }, @@ -10306,7 +10460,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 225, + funcId: 229, port: port_, ); }, @@ -10334,7 +10488,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 226, + funcId: 230, port: port_, ); }, @@ -10362,7 +10516,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 227, + funcId: 231, )!; }, codec: SseCodec( @@ -10393,7 +10547,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 228, + funcId: 232, port: port_, ); }, @@ -10427,7 +10581,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 229, + funcId: 233, port: port_, ); }, @@ -10459,7 +10613,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 230, + funcId: 234, port: port_, ); }, @@ -10498,7 +10652,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 231, + funcId: 235, port: port_, ); }, @@ -10530,7 +10684,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 232, + funcId: 236, port: port_, ); }, @@ -10560,7 +10714,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 233, + funcId: 237, port: port_, ); }, @@ -10594,7 +10748,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 234, + funcId: 238, port: port_, ); }, @@ -10635,7 +10789,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 235, + funcId: 239, port: port_, ); }, @@ -10673,7 +10827,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 236, + funcId: 240, port: port_, ); }, @@ -10713,7 +10867,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 237, + funcId: 241, port: port_, ); }, @@ -10756,7 +10910,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 238, + funcId: 242, )!; }, codec: SseCodec( @@ -10791,7 +10945,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 239, + funcId: 243, port: port_, ); }, @@ -10825,7 +10979,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 240, + funcId: 244, port: port_, ); }, @@ -10861,7 +11015,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 241, + funcId: 245, port: port_, ); }, @@ -10891,7 +11045,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 242, + funcId: 246, port: port_, ); }, @@ -10936,7 +11090,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 243, + funcId: 247, port: port_, ); }, @@ -10990,7 +11144,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 244, + funcId: 248, port: port_, ); }, @@ -11019,7 +11173,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 245, + funcId: 249, port: port_, ); }, @@ -11052,7 +11206,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 246, + funcId: 250, port: port_, ); }, @@ -11096,7 +11250,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 247, + funcId: 251, port: port_, ); }, @@ -11147,7 +11301,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 248, + funcId: 252, port: port_, ); }, @@ -11177,7 +11331,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 249, + funcId: 253, port: port_, ); }, @@ -11213,7 +11367,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 250, + funcId: 254, port: port_, ); }, @@ -11244,7 +11398,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 251, + funcId: 255, port: port_, ); }, @@ -11291,7 +11445,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 252, + funcId: 256, port: port_, ); }, @@ -11349,7 +11503,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 253, + funcId: 257, port: port_, ); }, @@ -11382,7 +11536,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 254, + funcId: 258, port: port_, ); }, @@ -11415,7 +11569,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 255, + funcId: 259, port: port_, ); }, @@ -11445,7 +11599,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 256, + funcId: 260, port: port_, ); }, @@ -11484,7 +11638,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 257, + funcId: 261, port: port_, ); }, @@ -11514,7 +11668,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 258, + funcId: 262, port: port_, ); }, @@ -11544,7 +11698,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 259, + funcId: 263, port: port_, ); }, @@ -11574,7 +11728,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 260, + funcId: 264, port: port_, ); }, @@ -11606,7 +11760,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 261, + funcId: 265, port: port_, ); }, @@ -11637,7 +11791,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 262, + funcId: 266, port: port_, ); }, @@ -11673,7 +11827,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 263, + funcId: 267, port: port_, ); }, @@ -11707,7 +11861,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 264, + funcId: 268, port: port_, ); }, @@ -11750,7 +11904,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 265, + funcId: 269, port: port_, ); }, @@ -11792,7 +11946,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 266, + funcId: 270, port: port_, ); }, @@ -11825,7 +11979,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 267, + funcId: 271, port: port_, ); }, @@ -11864,7 +12018,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 268, + funcId: 272, port: port_, ); }, @@ -11894,7 +12048,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 269, + funcId: 273, port: port_, ); }, @@ -11922,7 +12076,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 270, + funcId: 274, port: port_, ); }, @@ -11957,7 +12111,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 271, + funcId: 275, port: port_, ); }, @@ -12003,7 +12157,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 272, + funcId: 276, port: port_, ); }, @@ -12045,7 +12199,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 273, + funcId: 277, port: port_, ); }, @@ -21363,6 +21517,9 @@ class FederationMetaImpl extends RustOpaque implements FederationMeta { RustLib.instance.api.rust_arc_decrement_strong_count_FederationMetaPtr, ); + BigInt? get expiryTimestamp => RustLib.instance.api + .crateMultimintFederationMetaAutoAccessorGetExpiryTimestamp(that: this); + List get guardians => RustLib.instance.api .crateMultimintFederationMetaAutoAccessorGetGuardians(that: this); @@ -21381,9 +21538,18 @@ class FederationMetaImpl extends RustOpaque implements FederationMeta { FederationSelector get selector => RustLib.instance.api .crateMultimintFederationMetaAutoAccessorGetSelector(that: this); + String? get successorInvite => RustLib.instance.api + .crateMultimintFederationMetaAutoAccessorGetSuccessorInvite(that: this); + String? get welcome => RustLib.instance.api .crateMultimintFederationMetaAutoAccessorGetWelcome(that: this); + set expiryTimestamp(BigInt? expiryTimestamp) => RustLib.instance.api + .crateMultimintFederationMetaAutoAccessorSetExpiryTimestamp( + that: this, + expiryTimestamp: expiryTimestamp, + ); + set guardians(List guardians) => RustLib.instance.api.crateMultimintFederationMetaAutoAccessorSetGuardians( that: this, @@ -21420,6 +21586,12 @@ class FederationMetaImpl extends RustOpaque implements FederationMeta { selector: selector, ); + set successorInvite(String? successorInvite) => RustLib.instance.api + .crateMultimintFederationMetaAutoAccessorSetSuccessorInvite( + that: this, + successorInvite: successorInvite, + ); + set welcome(String? welcome) => RustLib.instance.api.crateMultimintFederationMetaAutoAccessorSetWelcome( that: this, @@ -22085,6 +22257,20 @@ class MultimintImpl extends RustOpaque implements Multimint { recover: recover, ); + /// Leaves a federation. + /// + /// Returns as soon as the federation is gone from the app's point of view: + /// its config row is deleted, its client is out of the map, and its task + /// group has been detached, so nothing can route to it or spawn onto it any + /// more. The teardown that actually takes time — cancelling the + /// federation's background tasks, waiting for them to release their client + /// references, and shutting the client down so its own executor stops — + /// runs on a detached task afterwards. Leaving should never make the user + /// watch a spinner. + /// + /// Every other persisted row is deliberately kept. The client database, the + /// Lightning Address registration, the NWC pairing and the cached metadata + /// are all reused if the user joins this federation again. Future leaveFederation({required FederationId federationId}) => RustLib.instance.api.crateMultimintMultimintLeaveFederation( that: this, diff --git a/lib/multimint.dart b/lib/multimint.dart index 824f1a20..61fe8d8e 100644 --- a/lib/multimint.dart +++ b/lib/multimint.dart @@ -11,9 +11,9 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; import 'package:freezed_annotation/freezed_annotation.dart' hide protected; part 'multimint.freezed.dart'; -// These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `release_ln_address`, `remove_recovery_progress_cache`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` -// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ClientType`, `LNAddressRegisterRequest`, `LNAddressRemoveRequest`, `OnChainWithdrawalMeta`, `WrappedEcash` -// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` +// These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_expiry_timestamp`, `get_federation`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_successor_invite`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `join_federation_inner`, `join_federation_on`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `register_federation`, `release_ln_address`, `remove_recovery_progress_cache`, `retire_recovery_client`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `shutdown_client`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_federation_teardown`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` +// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ClientType`, `JoinedFederation`, `LNAddressRegisterRequest`, `LNAddressRemoveRequest`, `OnChainWithdrawalMeta`, `WrappedEcash` +// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` // These functions are ignored (category: IgnoreBecauseExplicitAttribute): `federation_network` // These functions have error during generation (see debug logs or enable `stop_on_error: true` for more details): `subscribe_peer_status` @@ -53,6 +53,8 @@ abstract class EcashAppResultU64 implements RustOpaqueInterface {} // Rust type: RustOpaqueMoi> abstract class FederationMeta implements RustOpaqueInterface { + BigInt? get expiryTimestamp; + List get guardians; BigInt get lastUpdated; @@ -65,8 +67,12 @@ abstract class FederationMeta implements RustOpaqueInterface { FederationSelector get selector; + String? get successorInvite; + String? get welcome; + set expiryTimestamp(BigInt? expiryTimestamp); + set guardians(List guardians); set lastUpdated(BigInt lastUpdated); @@ -79,6 +85,8 @@ abstract class FederationMeta implements RustOpaqueInterface { set selector(FederationSelector selector); + set successorInvite(String? successorInvite); + set welcome(String? welcome); } @@ -355,6 +363,20 @@ abstract class Multimint implements RustOpaqueInterface { required bool recover, }); + /// Leaves a federation. + /// + /// Returns as soon as the federation is gone from the app's point of view: + /// its config row is deleted, its client is out of the map, and its task + /// group has been detached, so nothing can route to it or spawn onto it any + /// more. The teardown that actually takes time — cancelling the + /// federation's background tasks, waiting for them to release their client + /// references, and shutting the client down so its own executor stops — + /// runs on a detached task afterwards. Leaving should never make the user + /// watch a spinner. + /// + /// Every other persisted row is deliberately kept. The client database, the + /// Lightning Address registration, the NWC pairing and the cached metadata + /// are all reused if the user joins this federation again. Future leaveFederation({required FederationId federationId}); /// Computes the largest amount (in msats) the user can pay over Lightning diff --git a/lib/nostr.dart b/lib/nostr.dart index f1add854..e0449bc2 100644 --- a/lib/nostr.dart +++ b/lib/nostr.dart @@ -9,7 +9,7 @@ import 'lib.dart'; import 'multimint.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; -// These functions are ignored because they are not marked as `pub`: `add_relays_from_db`, `broadcast_nwc_info`, `broadcast_response`, `check_nwc_budget`, `check_nwc_payment_limit`, `connection_info`, `fetch_observer_federations`, `get_or_insert_default_relays`, `handle_request`, `method_name`, `now_millis`, `nwc_limits`, `parse_content`, `parse_federation_id`, `parse_federation_name`, `parse_invite_codes`, `parse_modules`, `parse_network`, `parse_picture`, `purge_legacy_nwc_configs`, `record_nwc_spend`, `spawn_listen_for_nwc`, `update_federations_from_nostr`, `window_state` +// These functions are ignored because they are not marked as `pub`: `add_relays_from_db`, `broadcast_nwc_info`, `broadcast_response`, `check_nwc_budget`, `check_nwc_payment_limit`, `connection_info`, `fetch_observer_federations`, `get_or_insert_default_relays`, `handle_request`, `method_name`, `now_millis`, `nwc_limits`, `parse_content`, `parse_federation_id`, `parse_federation_name`, `parse_invite_codes`, `parse_modules`, `parse_network`, `parse_picture`, `purge_legacy_nwc_configs`, `record_nwc_spend`, `restart_nwc_listener`, `spawn_listen_for_nwc`, `stop_nwc_listener`, `update_federations_from_nostr`, `window_state` // These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `WalletConnectRequest`, `WalletConnectResponse` // These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `try_from`, `try_from` // These functions are ignored (category: IgnoreBecauseExplicitAttribute): `get_nwc_config`, `listen_for_nwc` diff --git a/lib/screens/federation_expiry_screen.dart b/lib/screens/federation_expiry_screen.dart new file mode 100644 index 00000000..6899e9b5 --- /dev/null +++ b/lib/screens/federation_expiry_screen.dart @@ -0,0 +1,318 @@ +import 'package:ecashapp/db.dart'; +import 'package:ecashapp/discover.dart'; +import 'package:ecashapp/extensions/build_context_l10n.dart'; +import 'package:ecashapp/multimint.dart'; +import 'package:ecashapp/providers/preferences_provider.dart'; +import 'package:ecashapp/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; + +/// Converts the raw `federation_expiry_timestamp` (Unix *seconds*, as the +/// guardians publish it) into a local [DateTime]. +DateTime expiryDateTime(BigInt expiryTimestamp) => + DateTime.fromMillisecondsSinceEpoch(expiryTimestamp.toInt() * 1000); + +/// Coarse "how long is left" text, in the largest unit that still reads as a +/// number the user can act on. Deliberately not a precise countdown: this is a +/// deadline to plan around, not a timer. +String formatTimeUntilExpiry(BuildContext context, DateTime expiry) { + final remaining = expiry.difference(DateTime.now()); + if (remaining.isNegative) return context.l10n.federationExpiryPassed; + if (remaining.inDays > 0) { + return context.l10n.federationExpiryInDays(remaining.inDays); + } + if (remaining.inHours > 0) { + return context.l10n.federationExpiryInHours(remaining.inHours); + } + return context.l10n.federationExpiryInMinutes(remaining.inMinutes); +} + +/// Explains a guardian-announced shutdown and what the user has to do about it. +/// +/// Reached from the dashboard's expiry banner. Everything here is read from the +/// federation meta the caller already has, so the screen never blocks on a +/// network call — a user opening it because their money is at stake should not +/// meet a spinner. +class FederationExpiryScreen extends StatelessWidget { + final FederationSelector fed; + + /// Unix seconds the guardians published as the shutdown time. + final BigInt expiryTimestamp; + + /// Current balance, so the user can see what still has to be moved without + /// navigating back. Null while the dashboard is still loading it. + final BigInt? balanceMsats; + + /// Opens the join flow. Threaded down from the app root because joining + /// changes which federation is selected, which only the root can do. + final void Function(FederationSelector fed, bool recovering) onJoin; + + /// Pops back to the dashboard and starts a send. Null when there is nothing + /// to move. + final VoidCallback? onMoveFunds; + + /// The Lightning Address registered against this federation, if any, as + /// `user@domain`. It keeps resolving to this federation after the shutdown is + /// announced — the registration lives on the recurringd server, not here — so + /// the screen has to say so rather than claim all receiving has stopped. + final String? lightningAddress; + + const FederationExpiryScreen({ + super.key, + required this.fed, + required this.expiryTimestamp, + required this.balanceMsats, + required this.onJoin, + this.onMoveFunds, + this.lightningAddress, + }); + + void _onFindFederation(BuildContext context) { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => Discover(onJoin: onJoin, showAppBar: true), + ), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final expiry = expiryDateTime(expiryTimestamp); + final hasExpired = expiry.isBefore(DateTime.now()); + final warning = theme.colorScheme.error; + + return Scaffold( + appBar: AppBar(title: Text(context.l10n.federationExpiryTitle)), + body: SafeArea( + child: ListView( + padding: const EdgeInsets.fromLTRB(24, 8, 24, 32), + children: [ + Center( + child: Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: warning.withValues(alpha: 0.12), + ), + child: Icon( + Icons.warning_amber_rounded, + size: 48, + color: warning, + ), + ), + ), + const SizedBox(height: 20), + Text( + hasExpired + ? context.l10n.federationExpiryHeadlinePast( + fed.federationName, + ) + : context.l10n.federationExpiryHeadline(fed.federationName), + style: theme.textTheme.headlineSmall?.copyWith( + color: warning, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 24), + _FactsCard( + rows: [ + ( + hasExpired + ? context.l10n.federationExpiryClosedOn + : context.l10n.federationExpiryClosesOn, + DateFormat.yMMMMd().add_jm().format(expiry), + ), + ( + context.l10n.federationExpiryTimeRemaining, + formatTimeUntilExpiry(context, expiry), + ), + ( + context.l10n.federationExpiryYourBalance, + formatBalance( + balanceMsats, + false, + context.select( + (prefs) => prefs.bitcoinDisplay, + ), + ), + ), + ], + ), + const SizedBox(height: 24), + Text( + context.l10n.federationExpiryExplanation, + style: theme.textTheme.bodyMedium?.copyWith(height: 1.5), + ), + const SizedBox(height: 28), + Text( + context.l10n.federationExpiryWhatToDo, + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 12), + _Step( + number: 1, + text: context.l10n.federationExpiryStepReceivesOff, + note: + lightningAddress != null + ? context.l10n.federationExpiryLightningAddressNote( + lightningAddress!, + ) + : null, + ), + _Step(number: 2, text: context.l10n.federationExpiryStepMoveFunds), + _Step( + number: 3, + text: context.l10n.federationExpiryStepJoinAnother, + ), + const SizedBox(height: 28), + if (onMoveFunds != null) ...[ + OutlinedButton.icon( + onPressed: () { + Navigator.of(context).pop(); + onMoveFunds!(); + }, + icon: const Icon(Icons.upload), + label: Text(context.l10n.federationExpiryMoveFunds), + style: OutlinedButton.styleFrom( + minimumSize: const Size.fromHeight(48), + ), + ), + const SizedBox(height: 12), + ], + FilledButton.icon( + onPressed: () => _onFindFederation(context), + icon: const Icon(Icons.search), + label: Text(context.l10n.federationExpiryFindFederation), + style: FilledButton.styleFrom( + minimumSize: const Size.fromHeight(48), + ), + ), + ], + ), + ), + ); + } +} + +/// The three headline facts, as label/value rows on one surface. +class _FactsCard extends StatelessWidget { + final List<(String, String)> rows; + + const _FactsCard({required this.rows}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + decoration: BoxDecoration( + color: theme.colorScheme.surface, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + children: [ + for (final (index, row) in rows.indexed) ...[ + Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + row.$1, + style: theme.textTheme.bodyMedium?.copyWith( + color: Colors.grey, + ), + ), + const Spacer(), + Flexible( + child: Text( + row.$2, + style: theme.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.end, + ), + ), + ], + ), + ), + if (index != rows.length - 1) + Divider(height: 1, color: Colors.grey.withValues(alpha: 0.2)), + ], + ], + ), + ); + } +} + +class _Step extends StatelessWidget { + final int number; + final String text; + + /// Caveat shown under the step, set apart from it. Used where the general + /// statement has an exception the user needs to act on. + final String? note; + + const _Step({required this.number, required this.text, this.note}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + return Padding( + padding: const EdgeInsets.only(bottom: 14), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 24, + height: 24, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: theme.colorScheme.primary.withValues(alpha: 0.15), + ), + child: Text( + '$number', // i18n-ignore - list numbering, not prose + style: theme.textTheme.bodySmall?.copyWith( + color: theme.colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + text, + style: theme.textTheme.bodyMedium?.copyWith(height: 1.4), + ), + if (note != null) ...[ + const SizedBox(height: 8), + Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: theme.colorScheme.error.withValues(alpha: 0.10), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + note!, + style: theme.textTheme.bodySmall?.copyWith(height: 1.4), + ), + ), + ], + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/federation_expiry_banner.dart b/lib/widgets/federation_expiry_banner.dart new file mode 100644 index 00000000..e6411e19 --- /dev/null +++ b/lib/widgets/federation_expiry_banner.dart @@ -0,0 +1,104 @@ +import 'package:ecashapp/extensions/build_context_l10n.dart'; +import 'package:ecashapp/screens/federation_expiry_screen.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +/// Height [FederationExpiryBanner] lays out at, for the pinned sliver header +/// that has to declare its extent before the banner is measured. +/// +/// Declaring less than the banner measures clips it; declaring more trips the +/// sliver's layoutExtent-vs-paintExtent assertion unless the header forces its +/// child to fill the box. Both texts are capped at one line, so only they grow +/// with the user's font setting and the padding around them stays fixed — +/// which is why the scale applies to just one of the two terms. +/// +/// `federation_expiry_banner_test.dart` pins this to what the widget actually +/// measures, so a padding or text-style change there fails a test rather than +/// an assertion on someone's dashboard. +double federationExpiryBannerExtent(BuildContext context) { + const chrome = 32.0; // 8 outer top padding + 12/12 card vertical padding + const textLines = 40.0; // title + gap + subtitle, at scale 1.0 + return chrome + MediaQuery.textScalerOf(context).scale(textLines); +} + +/// Loud, tappable warning that the guardians have scheduled this federation's +/// shutdown. +/// +/// Sits directly under the balance on the dashboard, in the error colour, and +/// stays put while the transaction list scrolls — the point is that it cannot +/// be missed by someone who only ever glances at their balance. +class FederationExpiryBanner extends StatelessWidget { + /// Unix seconds the guardians published as the shutdown time. + final BigInt expiryTimestamp; + final VoidCallback onTap; + + const FederationExpiryBanner({ + super.key, + required this.expiryTimestamp, + required this.onTap, + }); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final warning = theme.colorScheme.error; + final expiry = expiryDateTime(expiryTimestamp); + final date = DateFormat.yMMMd().format(expiry); + final subtitle = + expiry.isBefore(DateTime.now()) + ? context.l10n.federationExpiryBannerSubtitlePast(date) + : context.l10n.federationExpiryBannerSubtitle(date); + + return Padding( + padding: const EdgeInsets.only(top: 8), + child: Material( + color: warning.withValues(alpha: 0.12), + borderRadius: BorderRadius.circular(12), + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all(color: warning.withValues(alpha: 0.5)), + ), + child: Row( + children: [ + Icon(Icons.warning_amber_rounded, color: warning, size: 24), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.l10n.federationExpiryBannerTitle, + style: theme.textTheme.bodyMedium?.copyWith( + color: warning, + fontWeight: FontWeight.bold, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 2), + Text( + subtitle, + style: theme.textTheme.bodySmall?.copyWith( + color: Colors.white70, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + Icon(Icons.chevron_right, color: warning, size: 20), + ], + ), + ), + ), + ), + ); + } +} diff --git a/rust/ecashapp/src/frb_generated.rs b/rust/ecashapp/src/frb_generated.rs index 64e54d6a..e494bd01 100644 --- a/rust/ecashapp/src/frb_generated.rs +++ b/rust/ecashapp/src/frb_generated.rs @@ -43,7 +43,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.9.0"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1098215331; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -165126491; // Section: executor @@ -439,6 +439,52 @@ fn wire__crate__db__FederationConfig_auto_accessor_set_network_impl( }, ) } +fn wire__crate__multimint__FederationMeta_auto_accessor_get_expiry_timestamp_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "FederationMeta_auto_accessor_get_expiry_timestamp", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()), + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok(api_that_guard.expiry_timestamp.clone())?; + Ok(output_ok) + })()) + }, + ) +} fn wire__crate__multimint__FederationMeta_auto_accessor_get_guardians_impl( ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -715,6 +761,52 @@ fn wire__crate__multimint__FederationMeta_auto_accessor_get_selector_impl( }, ) } +fn wire__crate__multimint__FederationMeta_auto_accessor_get_successor_invite_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "FederationMeta_auto_accessor_get_successor_invite", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()), + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok(api_that_guard.successor_invite.clone())?; + Ok(output_ok) + })()) + }, + ) +} fn wire__crate__multimint__FederationMeta_auto_accessor_get_welcome_impl( ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -761,6 +853,57 @@ fn wire__crate__multimint__FederationMeta_auto_accessor_get_welcome_impl( }, ) } +fn wire__crate__multimint__FederationMeta_auto_accessor_set_expiry_timestamp_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "FederationMeta_auto_accessor_set_expiry_timestamp", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_expiry_timestamp = >::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref_mut()), + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok({ + { + api_that_guard.expiry_timestamp = api_expiry_timestamp; + }; + })?; + Ok(output_ok) + })()) + }, + ) +} fn wire__crate__multimint__FederationMeta_auto_accessor_set_guardians_impl( ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -1067,6 +1210,57 @@ fn wire__crate__multimint__FederationMeta_auto_accessor_set_selector_impl( }, ) } +fn wire__crate__multimint__FederationMeta_auto_accessor_set_successor_invite_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "FederationMeta_auto_accessor_set_successor_invite", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_successor_invite = >::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref_mut()), + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok({ + { + api_that_guard.successor_invite = api_successor_invite; + }; + })?; + Ok(output_ok) + })()) + }, + ) +} fn wire__crate__multimint__FederationMeta_auto_accessor_set_welcome_impl( ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, rust_vec_len_: i32, @@ -17670,555 +17864,555 @@ fn pde_ffi_dispatcher_primary_impl( ) { // Codec=Pde (Serialization + dispatch), see doc to use other codecs match func_id { - 43 => wire__crate__multimint__Multimint_ack_seed_phrase_impl( + 47 => wire__crate__multimint__Multimint_ack_seed_phrase_impl( port, ptr, rust_vec_len, data_len, ), - 44 => wire__crate__multimint__Multimint_allocate_deposit_address_impl( + 48 => wire__crate__multimint__Multimint_allocate_deposit_address_impl( port, ptr, rust_vec_len, data_len, ), - 45 => wire__crate__multimint__Multimint_await_ecash_reissue_impl( + 49 => wire__crate__multimint__Multimint_await_ecash_reissue_impl( port, ptr, rust_vec_len, data_len, ), - 46 => wire__crate__multimint__Multimint_await_ecash_send_impl( + 50 => wire__crate__multimint__Multimint_await_ecash_send_impl( port, ptr, rust_vec_len, data_len, ), - 47 => { + 51 => { wire__crate__multimint__Multimint_await_receive_impl(port, ptr, rust_vec_len, data_len) } - 48 => wire__crate__multimint__Multimint_await_send_impl(port, ptr, rust_vec_len, data_len), - 49 => { + 52 => wire__crate__multimint__Multimint_await_send_impl(port, ptr, rust_vec_len, data_len), + 53 => { wire__crate__multimint__Multimint_await_withdraw_impl(port, ptr, rust_vec_len, data_len) } - 50 => wire__crate__multimint__Multimint_balance_impl(port, ptr, rust_vec_len, data_len), - 51 => wire__crate__multimint__Multimint_calculate_ecash_reissue_fees_impl( + 54 => wire__crate__multimint__Multimint_balance_impl(port, ptr, rust_vec_len, data_len), + 55 => wire__crate__multimint__Multimint_calculate_ecash_reissue_fees_impl( port, ptr, rust_vec_len, data_len, ), - 52 => wire__crate__multimint__Multimint_calculate_ecash_send_fees_impl( + 56 => wire__crate__multimint__Multimint_calculate_ecash_send_fees_impl( port, ptr, rust_vec_len, data_len, ), - 53 => wire__crate__multimint__Multimint_calculate_withdraw_fees_impl( + 57 => wire__crate__multimint__Multimint_calculate_withdraw_fees_impl( port, ptr, rust_vec_len, data_len, ), - 54 => wire__crate__multimint__Multimint_check_ecash_spent_impl( + 58 => wire__crate__multimint__Multimint_check_ecash_spent_impl( port, ptr, rust_vec_len, data_len, ), - 55 => wire__crate__multimint__Multimint_check_ln_address_availability_impl( + 59 => wire__crate__multimint__Multimint_check_ln_address_availability_impl( port, ptr, rust_vec_len, data_len, ), - 56 => wire__crate__multimint__Multimint_compute_all_gateway_previews_impl( + 60 => wire__crate__multimint__Multimint_compute_all_gateway_previews_impl( port, ptr, rust_vec_len, data_len, ), - 57 => wire__crate__multimint__Multimint_compute_receive_amount_with_fees_impl( + 61 => wire__crate__multimint__Multimint_compute_receive_amount_with_fees_impl( port, ptr, rust_vec_len, data_len, ), - 58 => wire__crate__multimint__Multimint_contains_client_impl( + 62 => wire__crate__multimint__Multimint_contains_client_impl( port, ptr, rust_vec_len, data_len, ), - 59 => wire__crate__multimint__Multimint_federations_impl(port, ptr, rust_vec_len, data_len), - 60 => { + 63 => wire__crate__multimint__Multimint_federations_impl(port, ptr, rust_vec_len, data_len), + 64 => { wire__crate__multimint__Multimint_get_addresses_impl(port, ptr, rust_vec_len, data_len) } - 61 => wire__crate__multimint__Multimint_get_all_btc_prices_impl( + 65 => wire__crate__multimint__Multimint_get_all_btc_prices_impl( port, ptr, rust_vec_len, data_len, ), - 62 => wire__crate__multimint__Multimint_get_all_invite_codes_impl( + 66 => wire__crate__multimint__Multimint_get_all_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 63 => wire__crate__multimint__Multimint_get_bitcoin_display_impl( + 67 => wire__crate__multimint__Multimint_get_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 64 => { + 68 => { wire__crate__multimint__Multimint_get_btc_price_impl(port, ptr, rust_vec_len, data_len) } - 65 => wire__crate__multimint__Multimint_get_cached_federation_meta_impl( + 69 => wire__crate__multimint__Multimint_get_cached_federation_meta_impl( port, ptr, rust_vec_len, data_len, ), - 66 => wire__crate__multimint__Multimint_get_federation_order_impl( + 70 => wire__crate__multimint__Multimint_get_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 67 => wire__crate__multimint__Multimint_get_fiat_currency_impl( + 71 => wire__crate__multimint__Multimint_get_fiat_currency_impl( port, ptr, rust_vec_len, data_len, ), - 68 => wire__crate__multimint__Multimint_get_invite_code_impl( + 72 => wire__crate__multimint__Multimint_get_invite_code_impl( port, ptr, rust_vec_len, data_len, ), - 69 => wire__crate__multimint__Multimint_get_ln_address_config_impl( + 73 => wire__crate__multimint__Multimint_get_ln_address_config_impl( port, ptr, rust_vec_len, data_len, ), - 70 => wire__crate__multimint__Multimint_get_max_withdrawable_amount_impl( + 74 => wire__crate__multimint__Multimint_get_max_withdrawable_amount_impl( port, ptr, rust_vec_len, data_len, ), - 71 => { + 75 => { wire__crate__multimint__Multimint_get_mnemonic_impl(port, ptr, rust_vec_len, data_len) } - 72 => wire__crate__multimint__Multimint_get_note_summary_impl( + 76 => wire__crate__multimint__Multimint_get_note_summary_impl( port, ptr, rust_vec_len, data_len, ), - 73 => wire__crate__multimint__Multimint_get_pegin_fee_quote_impl( + 77 => wire__crate__multimint__Multimint_get_pegin_fee_quote_impl( port, ptr, rust_vec_len, data_len, ), - 74 => wire__crate__multimint__Multimint_get_recovery_progress_impl( + 78 => wire__crate__multimint__Multimint_get_recovery_progress_impl( port, ptr, rust_vec_len, data_len, ), - 75 => { + 79 => { wire__crate__multimint__Multimint_get_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 76 => wire__crate__multimint__Multimint_guardian_add_gateway_impl( + 80 => wire__crate__multimint__Multimint_guardian_add_gateway_impl( port, ptr, rust_vec_len, data_len, ), - 77 => { + 81 => { wire__crate__multimint__Multimint_guardian_audit_impl(port, ptr, rust_vec_len, data_len) } - 78 => wire__crate__multimint__Multimint_guardian_backup_statistics_impl( + 82 => wire__crate__multimint__Multimint_guardian_backup_statistics_impl( port, ptr, rust_vec_len, data_len, ), - 79 => wire__crate__multimint__Multimint_guardian_list_gateways_impl( + 83 => wire__crate__multimint__Multimint_guardian_list_gateways_impl( port, ptr, rust_vec_len, data_len, ), - 80 => { + 84 => { wire__crate__multimint__Multimint_guardian_login_impl(port, ptr, rust_vec_len, data_len) } - 81 => wire__crate__multimint__Multimint_guardian_meta_accept_impl( + 85 => wire__crate__multimint__Multimint_guardian_meta_accept_impl( port, ptr, rust_vec_len, data_len, ), - 82 => wire__crate__multimint__Multimint_guardian_meta_propose_field_impl( + 86 => wire__crate__multimint__Multimint_guardian_meta_propose_field_impl( port, ptr, rust_vec_len, data_len, ), - 83 => wire__crate__multimint__Multimint_guardian_meta_state_impl( + 87 => wire__crate__multimint__Multimint_guardian_meta_state_impl( port, ptr, rust_vec_len, data_len, ), - 84 => wire__crate__multimint__Multimint_guardian_meta_withdraw_impl( + 88 => wire__crate__multimint__Multimint_guardian_meta_withdraw_impl( port, ptr, rust_vec_len, data_len, ), - 85 => wire__crate__multimint__Multimint_guardian_remove_gateway_impl( + 89 => wire__crate__multimint__Multimint_guardian_remove_gateway_impl( port, ptr, rust_vec_len, data_len, ), - 86 => wire__crate__multimint__Multimint_guardian_status_impl( + 90 => wire__crate__multimint__Multimint_guardian_status_impl( port, ptr, rust_vec_len, data_len, ), - 87 => wire__crate__multimint__Multimint_has_seed_phrase_ack_impl( + 91 => wire__crate__multimint__Multimint_has_seed_phrase_ack_impl( port, ptr, rust_vec_len, data_len, ), - 88 => wire__crate__multimint__Multimint_join_federation_impl( + 92 => wire__crate__multimint__Multimint_join_federation_impl( port, ptr, rust_vec_len, data_len, ), - 89 => wire__crate__multimint__Multimint_leave_federation_impl( + 93 => wire__crate__multimint__Multimint_leave_federation_impl( port, ptr, rust_vec_len, data_len, ), - 90 => wire__crate__multimint__Multimint_max_lightning_send_impl( + 94 => wire__crate__multimint__Multimint_max_lightning_send_impl( port, ptr, rust_vec_len, data_len, ), - 91 => wire__crate__multimint__Multimint_new_impl(port, ptr, rust_vec_len, data_len), - 92 => wire__crate__multimint__Multimint_parse_ecash_impl(port, ptr, rust_vec_len, data_len), - 93 => wire__crate__multimint__Multimint_probe_invoice_is_loopback_impl( + 95 => wire__crate__multimint__Multimint_new_impl(port, ptr, rust_vec_len, data_len), + 96 => wire__crate__multimint__Multimint_parse_ecash_impl(port, ptr, rust_vec_len, data_len), + 97 => wire__crate__multimint__Multimint_probe_invoice_is_loopback_impl( port, ptr, rust_vec_len, data_len, ), - 94 => wire__crate__multimint__Multimint_receive_impl(port, ptr, rust_vec_len, data_len), - 95 => wire__crate__multimint__Multimint_recheck_address_impl( + 98 => wire__crate__multimint__Multimint_receive_impl(port, ptr, rust_vec_len, data_len), + 99 => wire__crate__multimint__Multimint_recheck_address_impl( port, ptr, rust_vec_len, data_len, ), - 96 => wire__crate__multimint__Multimint_recover_ln_address_impl( + 100 => wire__crate__multimint__Multimint_recover_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 97 => wire__crate__multimint__Multimint_refresh_connections_impl( + 101 => wire__crate__multimint__Multimint_refresh_connections_impl( port, ptr, rust_vec_len, data_len, ), - 98 => wire__crate__multimint__Multimint_refresh_federation_meta_impl( + 102 => wire__crate__multimint__Multimint_refresh_federation_meta_impl( port, ptr, rust_vec_len, data_len, ), - 99 => wire__crate__multimint__Multimint_register_ln_address_impl( + 103 => wire__crate__multimint__Multimint_register_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 100 => { + 104 => { wire__crate__multimint__Multimint_reissue_ecash_impl(port, ptr, rust_vec_len, data_len) } - 101 => wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( + 105 => wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( port, ptr, rust_vec_len, data_len, ), - 102 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), - 103 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), - 104 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( + 106 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), + 107 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), + 108 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 105 => wire__crate__multimint__Multimint_set_federation_order_impl( + 109 => wire__crate__multimint__Multimint_set_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 106 => wire__crate__multimint__Multimint_set_fiat_currency_impl( + 110 => wire__crate__multimint__Multimint_set_fiat_currency_impl( port, ptr, rust_vec_len, data_len, ), - 107 => { + 111 => { wire__crate__multimint__Multimint_set_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 108 => { + 112 => { wire__crate__multimint__Multimint_transactions_impl(port, ptr, rust_vec_len, data_len) } - 109 => { + 113 => { wire__crate__multimint__Multimint_wallet_summary_impl(port, ptr, rust_vec_len, data_len) } - 110 => wire__crate__multimint__Multimint_withdraw_to_address_impl( + 114 => wire__crate__multimint__Multimint_withdraw_to_address_impl( port, ptr, rust_vec_len, data_len, ), - 111 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( + 115 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 112 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( + 116 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( port, ptr, rust_vec_len, data_len, ), - 113 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( + 117 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( port, ptr, rust_vec_len, data_len, ), - 114 => { + 118 => { wire__crate__nostr__NostrClient_get_all_contacts_impl(port, ptr, rust_vec_len, data_len) } - 115 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( + 119 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 116 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), - 117 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( + 120 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), + 121 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 118 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( + 122 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( port, ptr, rust_vec_len, data_len, ), - 119 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( + 123 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 120 => wire__crate__nostr__NostrClient_get_public_federations_impl( + 124 => wire__crate__nostr__NostrClient_get_public_federations_impl( port, ptr, rust_vec_len, data_len, ), - 121 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), - 122 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( + 125 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), + 126 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 123 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), - 124 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), - 125 => wire__crate__nostr__NostrClient_paginate_contacts_impl( + 127 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), + 128 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), + 129 => wire__crate__nostr__NostrClient_paginate_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 126 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( + 130 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 127 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( + 131 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 128 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), - 129 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( + 132 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), + 133 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 130 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( + 134 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 131 => { + 135 => { wire__crate__nostr__NostrClient_sync_contacts_impl(port, ptr, rust_vec_len, data_len) } - 132 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 136 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( + 136 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 140 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( port, ptr, rust_vec_len, data_len, ), - 163 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), - 164 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), - 165 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), - 166 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), - 167 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), - 168 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), - 169 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), - 170 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), - 171 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), - 172 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), - 173 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), - 174 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), - 175 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), - 176 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), - 177 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), - 178 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), - 179 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), - 180 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), - 181 => { + 167 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), + 168 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), + 169 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), + 170 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), + 171 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), + 172 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), + 173 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), + 174 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), + 175 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), + 176 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), + 177 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), + 178 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), + 179 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), + 180 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), + 181 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), + 182 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), + 183 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), + 184 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), + 185 => { wire__crate__compute_receive_amount_with_fees_impl(port, ptr, rust_vec_len, data_len) } - 182 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), - 183 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), - 184 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), - 185 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 186 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), - 187 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), - 188 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 189 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), - 190 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), - 191 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), - 192 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 193 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), - 194 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), - 195 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 196 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), - 197 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 198 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), - 199 => { + 186 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), + 187 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), + 188 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), + 189 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 190 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), + 191 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), + 192 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 193 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), + 194 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), + 195 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), + 196 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 197 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), + 198 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), + 199 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 200 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), + 201 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 202 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), + 203 => { wire__crate__get_invoice_from_lnaddress_or_lnurl_impl(port, ptr, rust_vec_len, data_len) } - 200 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), - 201 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), - 202 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), - 203 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 204 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), - 205 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 206 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 207 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 208 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), - 209 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), - 210 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 211 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), - 212 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), - 213 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), - 214 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), - 215 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), - 216 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), - 217 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), - 218 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), - 219 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), - 220 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), - 221 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), - 222 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), - 223 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), - 224 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), - 225 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), - 226 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), - 228 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), - 229 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), - 230 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), - 231 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), - 232 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), - 233 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), - 234 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), - 235 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), - 236 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), - 237 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), - 239 => { + 204 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), + 205 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), + 206 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), + 207 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 208 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), + 209 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 210 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 211 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 212 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), + 213 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), + 214 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 215 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), + 216 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), + 217 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), + 218 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), + 219 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), + 220 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), + 221 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), + 222 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), + 223 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), + 224 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), + 225 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), + 226 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), + 227 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), + 228 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), + 229 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), + 230 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), + 232 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), + 233 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), + 234 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), + 235 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), + 236 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), + 237 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), + 238 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), + 239 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), + 240 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), + 241 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), + 243 => { wire__crate__parse_scanned_text_for_federation_impl(port, ptr, rust_vec_len, data_len) } - 240 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), - 241 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), - 242 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), - 243 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), - 244 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), - 245 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), - 246 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 247 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), - 248 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), - 249 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), - 250 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 251 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), - 252 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), - 253 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), - 254 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 255 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), - 256 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 257 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 258 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 259 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 260 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), - 261 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 262 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), - 263 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), - 264 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), - 265 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), - 266 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 267 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), - 268 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), - 269 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 270 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), - 271 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), - 272 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), - 273 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), + 244 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), + 245 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), + 246 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), + 247 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), + 248 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), + 249 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), + 250 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 251 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), + 252 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), + 253 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), + 254 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 255 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), + 256 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), + 257 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), + 258 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 259 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), + 260 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 261 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 262 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 263 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 264 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), + 265 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 266 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), + 267 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), + 268 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), + 269 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), + 270 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 271 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), + 272 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), + 273 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 274 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), + 275 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), + 276 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), + 277 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -18271,315 +18465,335 @@ fn pde_ffi_dispatcher_sync_impl( rust_vec_len, data_len, ), - 9 => wire__crate__multimint__FederationMeta_auto_accessor_get_guardians_impl( + 9 => wire__crate__multimint__FederationMeta_auto_accessor_get_expiry_timestamp_impl( ptr, rust_vec_len, data_len, ), - 10 => wire__crate__multimint__FederationMeta_auto_accessor_get_last_updated_impl( + 10 => wire__crate__multimint__FederationMeta_auto_accessor_get_guardians_impl( ptr, rust_vec_len, data_len, ), - 11 => wire__crate__multimint__FederationMeta_auto_accessor_get_lnaddress_api_impl( + 11 => wire__crate__multimint__FederationMeta_auto_accessor_get_last_updated_impl( ptr, rust_vec_len, data_len, ), - 12 => wire__crate__multimint__FederationMeta_auto_accessor_get_picture_impl( + 12 => wire__crate__multimint__FederationMeta_auto_accessor_get_lnaddress_api_impl( ptr, rust_vec_len, data_len, ), - 13 => wire__crate__multimint__FederationMeta_auto_accessor_get_recurringd_api_impl( + 13 => wire__crate__multimint__FederationMeta_auto_accessor_get_picture_impl( ptr, rust_vec_len, data_len, ), - 14 => wire__crate__multimint__FederationMeta_auto_accessor_get_selector_impl( + 14 => wire__crate__multimint__FederationMeta_auto_accessor_get_recurringd_api_impl( ptr, rust_vec_len, data_len, ), - 15 => wire__crate__multimint__FederationMeta_auto_accessor_get_welcome_impl( + 15 => wire__crate__multimint__FederationMeta_auto_accessor_get_selector_impl( ptr, rust_vec_len, data_len, ), - 16 => wire__crate__multimint__FederationMeta_auto_accessor_set_guardians_impl( + 16 => wire__crate__multimint__FederationMeta_auto_accessor_get_successor_invite_impl( ptr, rust_vec_len, data_len, ), - 17 => wire__crate__multimint__FederationMeta_auto_accessor_set_last_updated_impl( + 17 => wire__crate__multimint__FederationMeta_auto_accessor_get_welcome_impl( ptr, rust_vec_len, data_len, ), - 18 => wire__crate__multimint__FederationMeta_auto_accessor_set_lnaddress_api_impl( + 18 => wire__crate__multimint__FederationMeta_auto_accessor_set_expiry_timestamp_impl( ptr, rust_vec_len, data_len, ), - 19 => wire__crate__multimint__FederationMeta_auto_accessor_set_picture_impl( + 19 => wire__crate__multimint__FederationMeta_auto_accessor_set_guardians_impl( ptr, rust_vec_len, data_len, ), - 20 => wire__crate__multimint__FederationMeta_auto_accessor_set_recurringd_api_impl( + 20 => wire__crate__multimint__FederationMeta_auto_accessor_set_last_updated_impl( ptr, rust_vec_len, data_len, ), - 21 => wire__crate__multimint__FederationMeta_auto_accessor_set_selector_impl( + 21 => wire__crate__multimint__FederationMeta_auto_accessor_set_lnaddress_api_impl( ptr, rust_vec_len, data_len, ), - 22 => wire__crate__multimint__FederationMeta_auto_accessor_set_welcome_impl( + 22 => wire__crate__multimint__FederationMeta_auto_accessor_set_picture_impl( ptr, rust_vec_len, data_len, ), - 23 => wire__crate__multimint__FederationSelector_auto_accessor_get_federation_id_impl( + 23 => wire__crate__multimint__FederationMeta_auto_accessor_set_recurringd_api_impl( ptr, rust_vec_len, data_len, ), - 24 => wire__crate__multimint__FederationSelector_auto_accessor_get_federation_name_impl( + 24 => wire__crate__multimint__FederationMeta_auto_accessor_set_selector_impl( ptr, rust_vec_len, data_len, ), - 25 => wire__crate__multimint__FederationSelector_auto_accessor_get_network_impl( + 25 => wire__crate__multimint__FederationMeta_auto_accessor_set_successor_invite_impl( ptr, rust_vec_len, data_len, ), - 26 => wire__crate__multimint__FederationSelector_auto_accessor_set_federation_id_impl( + 26 => wire__crate__multimint__FederationMeta_auto_accessor_set_welcome_impl( ptr, rust_vec_len, data_len, ), - 27 => wire__crate__multimint__FederationSelector_auto_accessor_set_federation_name_impl( + 27 => wire__crate__multimint__FederationSelector_auto_accessor_get_federation_id_impl( ptr, rust_vec_len, data_len, ), - 28 => wire__crate__multimint__FederationSelector_auto_accessor_set_network_impl( + 28 => wire__crate__multimint__FederationSelector_auto_accessor_get_federation_name_impl( ptr, rust_vec_len, data_len, ), - 29 => wire__crate__db__LightningAddressConfig_auto_accessor_get_authentication_token_impl( + 29 => wire__crate__multimint__FederationSelector_auto_accessor_get_network_impl( ptr, rust_vec_len, data_len, ), - 30 => wire__crate__db__LightningAddressConfig_auto_accessor_get_domain_impl( + 30 => wire__crate__multimint__FederationSelector_auto_accessor_set_federation_id_impl( ptr, rust_vec_len, data_len, ), - 31 => wire__crate__db__LightningAddressConfig_auto_accessor_get_ln_address_api_impl( + 31 => wire__crate__multimint__FederationSelector_auto_accessor_set_federation_name_impl( ptr, rust_vec_len, data_len, ), - 32 => wire__crate__db__LightningAddressConfig_auto_accessor_get_lnurl_impl( + 32 => wire__crate__multimint__FederationSelector_auto_accessor_set_network_impl( ptr, rust_vec_len, data_len, ), - 33 => wire__crate__db__LightningAddressConfig_auto_accessor_get_recurringd_api_impl( + 33 => wire__crate__db__LightningAddressConfig_auto_accessor_get_authentication_token_impl( ptr, rust_vec_len, data_len, ), - 34 => wire__crate__db__LightningAddressConfig_auto_accessor_get_username_impl( + 34 => wire__crate__db__LightningAddressConfig_auto_accessor_get_domain_impl( ptr, rust_vec_len, data_len, ), - 35 => wire__crate__db__LightningAddressConfig_auto_accessor_set_authentication_token_impl( + 35 => wire__crate__db__LightningAddressConfig_auto_accessor_get_ln_address_api_impl( ptr, rust_vec_len, data_len, ), - 36 => wire__crate__db__LightningAddressConfig_auto_accessor_set_domain_impl( + 36 => wire__crate__db__LightningAddressConfig_auto_accessor_get_lnurl_impl( ptr, rust_vec_len, data_len, ), - 37 => wire__crate__db__LightningAddressConfig_auto_accessor_set_ln_address_api_impl( + 37 => wire__crate__db__LightningAddressConfig_auto_accessor_get_recurringd_api_impl( ptr, rust_vec_len, data_len, ), - 38 => wire__crate__db__LightningAddressConfig_auto_accessor_set_lnurl_impl( + 38 => wire__crate__db__LightningAddressConfig_auto_accessor_get_username_impl( ptr, rust_vec_len, data_len, ), - 39 => wire__crate__db__LightningAddressConfig_auto_accessor_set_recurringd_api_impl( + 39 => wire__crate__db__LightningAddressConfig_auto_accessor_set_authentication_token_impl( ptr, rust_vec_len, data_len, ), - 40 => wire__crate__db__LightningAddressConfig_auto_accessor_set_username_impl( + 40 => wire__crate__db__LightningAddressConfig_auto_accessor_set_domain_impl( ptr, rust_vec_len, data_len, ), - 41 => wire__crate__db__LightningAddressKey_auto_accessor_get_federation_id_impl( + 41 => wire__crate__db__LightningAddressConfig_auto_accessor_set_ln_address_api_impl( ptr, rust_vec_len, data_len, ), - 42 => wire__crate__db__LightningAddressKey_auto_accessor_set_federation_id_impl( + 42 => wire__crate__db__LightningAddressConfig_auto_accessor_set_lnurl_impl( ptr, rust_vec_len, data_len, ), - 133 => { + 43 => wire__crate__db__LightningAddressConfig_auto_accessor_set_recurringd_api_impl( + ptr, + rust_vec_len, + data_len, + ), + 44 => wire__crate__db__LightningAddressConfig_auto_accessor_set_username_impl( + ptr, + rust_vec_len, + data_len, + ), + 45 => wire__crate__db__LightningAddressKey_auto_accessor_get_federation_id_impl( + ptr, + rust_vec_len, + data_len, + ), + 46 => wire__crate__db__LightningAddressKey_auto_accessor_set_federation_id_impl( + ptr, + rust_vec_len, + data_len, + ), + 137 => { wire__crate__fountain__OobNotesDecoder_add_fragment_impl(ptr, rust_vec_len, data_len) } - 134 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), - 135 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), - 137 => { + 138 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), + 139 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), + 141 => { wire__crate__multimint__OobNotesWrapper_amount_msats_impl(ptr, rust_vec_len, data_len) } - 138 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), - 139 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( + 142 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), + 143 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( ptr, rust_vec_len, data_len, ), - 140 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( + 144 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( ptr, rust_vec_len, data_len, ), - 141 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( + 145 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( ptr, rust_vec_len, data_len, ), - 142 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( + 146 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 143 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( + 147 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( ptr, rust_vec_len, data_len, ), - 144 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( + 148 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( ptr, rust_vec_len, data_len, ), - 145 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( + 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( ptr, rust_vec_len, data_len, ), - 146 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( + 150 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( ptr, rust_vec_len, data_len, ), - 147 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( + 151 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( ptr, rust_vec_len, data_len, ), - 148 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( + 152 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( ptr, rust_vec_len, data_len, ), - 149 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( + 153 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 150 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( + 154 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( ptr, rust_vec_len, data_len, ), - 151 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( + 155 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( ptr, rust_vec_len, data_len, ), - 152 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( + 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( ptr, rust_vec_len, data_len, ), - 153 => { + 157 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 154 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( + 158 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 155 => { + 159 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 156 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( + 160 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( ptr, rust_vec_len, data_len, ), - 157 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( + 161 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 158 => { + 162 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 159 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( + 163 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 160 => { + 164 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 161 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( + 165 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( ptr, rust_vec_len, data_len, ), - 162 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( + 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 227 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), - 238 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), + 231 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), + 242 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), _ => unreachable!(), } } diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index e901f752..9f702d54 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -120,6 +120,13 @@ use crate::{ /// `MAX_INVOICE_EXPIRY_SECS` (`60 * 60 * 24`). Raising this breaks LNv2 /// receives. const DEFAULT_EXPIRY_TIME_SECS: u32 = 86400; +/// Well-known meta field: unix timestamp (seconds) after which the guardians +/// will shut the federation down. See fedimint +/// `docs/meta_fields/federation_expiry_timestamp.md`. +const META_FEDERATION_EXPIRY_TIMESTAMP_KEY: &str = "federation_expiry_timestamp"; +/// Well-known meta field: invite code of the federation users should migrate +/// to before the shutdown. See fedimint `docs/meta_fields/federation_successor.md`. +const META_FEDERATION_SUCCESSOR_KEY: &str = "federation_successor"; const CACHE_UPDATE_INTERVAL_SECS: u64 = 30; const PRICE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 5; const FEDERATION_BACKUP_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 60 * 24; @@ -367,6 +374,14 @@ pub struct FederationMeta { pub last_updated: u64, pub recurringd_api: Option, pub lnaddress_api: Option, + /// Unix timestamp in seconds after which the guardians will shut the + /// federation down (`federation_expiry_timestamp` meta field). `None` when + /// no shutdown has been announced. + pub expiry_timestamp: Option, + /// Invite code of the federation users should migrate to before the + /// shutdown (`federation_successor` meta field). Already validated to parse + /// as an [`InviteCode`]; `None` when the guardians have not set one. + pub successor_invite: Option, } #[derive(Debug, Serialize, Clone, Eq, PartialEq, Encodable, Decodable)] @@ -1001,7 +1016,16 @@ impl Multimint { info_to_flutter("Purged FederationMeta cache for schema migration v1").await; } - let target_version: u64 = 1; + if current_version < 2 { + // Migration v2: FederationMeta gained expiry_timestamp and + // successor_invite. Entries persisted in the old layout fail to + // decode (which panics on read), so purge them; the cache task + // rebuilds each one on its next pass. + dbtx.remove_by_prefix(&FederationMetaKeyPrefix).await; + info_to_flutter("Purged FederationMeta cache for schema migration v2").await; + } + + let target_version: u64 = 2; if current_version < target_version { dbtx.insert_entry(&SchemaVersionKey, &target_version).await; dbtx.commit_tx().await; @@ -1758,6 +1782,30 @@ impl Multimint { Some(SafeUrl::parse(url_str).ok()?.to_string()) } + /// Reads `federation_expiry_timestamp` from the meta JSON. + /// + /// The fedimint docs specify a base-10 integer of unix seconds, but the + /// guardian dashboard writes it as a JSON *string* (`"1767225600"`) while + /// `Client::get_meta_expiration_timestamp` reads a JSON *number*, so both + /// spellings are accepted. Anything else (negative, fractional, + /// non-numeric) is treated as unset rather than surfacing a bogus date. + fn get_expiry_timestamp(meta: &serde_json::Value) -> Option { + match meta.get(META_FEDERATION_EXPIRY_TIMESTAMP_KEY)? { + serde_json::Value::Number(n) => n.as_u64(), + serde_json::Value::String(s) => s.trim().parse::().ok(), + _ => None, + } + } + + /// Reads `federation_successor` from the meta JSON, keeping it only when it + /// parses as an invite code so the UI never offers a join it cannot + /// complete. + fn get_successor_invite(meta: &serde_json::Value) -> Option { + let invite = meta.get(META_FEDERATION_SUCCESSOR_KEY)?.as_str()?.trim(); + InviteCode::from_str(invite).ok()?; + Some(invite.to_string()) + } + /// Resolves the Bitcoin network for a federation from whichever wallet /// module it has. walletv1 and walletv2 both expose `get_network()`, but a /// federation only has one of them, so we try both. Returns `None` for a @@ -1867,6 +1915,8 @@ impl Multimint { let picture = Self::get_url("fedi:federation_icon_url", &meta); let recurringd_api = Self::get_url("recurringd_api", &meta); let lnaddress_api = Self::get_url("lnaddress_api", &meta); + let expiry_timestamp = Self::get_expiry_timestamp(&meta); + let successor_invite = Self::get_successor_invite(&meta); FederationMeta { picture, @@ -1876,6 +1926,8 @@ impl Multimint { last_updated, recurringd_api, lnaddress_api, + expiry_timestamp, + successor_invite, } } None => FederationMeta { @@ -1886,6 +1938,8 @@ impl Multimint { last_updated, recurringd_api: None, lnaddress_api: None, + expiry_timestamp: None, + successor_invite: None, }, }; @@ -1920,6 +1974,8 @@ impl Multimint { || old.welcome != federation_meta.welcome || old.selector.federation_name != federation_meta.selector.federation_name || old.guardians != federation_meta.guardians + || old.expiry_timestamp != federation_meta.expiry_timestamp + || old.successor_invite != federation_meta.successor_invite } None => true, }; @@ -7076,14 +7132,70 @@ mod tests { use std::collections::BTreeMap; use fedimint_client::module::module::recovery::RecoveryProgress; + use fedimint_core::config::FederationId; use fedimint_core::core::ModuleKind; + use fedimint_core::invite_code::InviteCode; + use fedimint_core::PeerId; use fedimint_lnv2_common::gateway_api::PaymentFee; + use serde_json::json; use crate::multimint::{ aggregate_recovery_progress, gross_invoice_for_contract, recovery_module_for_kind, - RecoveryModule, MAX_GATEWAY_PPM, + Multimint, RecoveryModule, MAX_GATEWAY_PPM, }; + #[test] + fn expiry_timestamp_accepts_number_and_string() { + // The guardian dashboard writes the timestamp as a string while the + // fedimint client helper reads a number; both spellings must parse. + let as_string = json!({ "federation_expiry_timestamp": "1767225600" }); + assert_eq!( + Multimint::get_expiry_timestamp(&as_string), + Some(1_767_225_600) + ); + let as_number = json!({ "federation_expiry_timestamp": 1767225600 }); + assert_eq!( + Multimint::get_expiry_timestamp(&as_number), + Some(1_767_225_600) + ); + } + + #[test] + fn expiry_timestamp_rejects_garbage() { + for value in [ + json!("soon"), + json!(-1), + json!(1.5), + json!(true), + json!(null), + ] { + let meta = json!({ "federation_expiry_timestamp": value }); + assert_eq!(Multimint::get_expiry_timestamp(&meta), None, "{meta}"); + } + assert_eq!(Multimint::get_expiry_timestamp(&json!({})), None); + } + + #[test] + fn successor_invite_requires_valid_invite_code() { + let invite = InviteCode::new( + "wss://foo.bar".parse().unwrap(), + PeerId::from(0), + FederationId::dummy(), + None, + ) + .to_string(); + let meta = json!({ "federation_successor": invite }); + assert_eq!(Multimint::get_successor_invite(&meta), Some(invite)); + + let bogus = json!({ "federation_successor": "fed11notaninvite" }); + assert_eq!(Multimint::get_successor_invite(&bogus), None); + assert_eq!( + Multimint::get_successor_invite(&json!({ "federation_successor": 42 })), + None + ); + assert_eq!(Multimint::get_successor_invite(&json!({})), None); + } + fn payment_fee(base_msats: u64, ppm: u64) -> PaymentFee { PaymentFee { base: fedimint_core::Amount::from_msats(base_msats), From d69fa4e070b107f8058adacf666479bf1296c497 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Mon, 14 Sep 2026 17:00:23 -0500 Subject: [PATCH 02/17] feat: add remove Lightning Address --- lib/app.dart | 1 + lib/db.dart | 4 +- lib/frb_generated.dart | 448 ++++++++++++-------- lib/l10n/app_en.arb | 155 ++++++- lib/l10n/app_es.arb | 58 ++- lib/lib.dart | 8 + lib/ln_address.dart | 85 +++- lib/multimint.dart | 9 +- lib/screens/dashboard.dart | 146 ++++++- lib/screens/federation_expiry_screen.dart | 254 ++++++----- lib/setttings.dart | 2 +- lib/widgets/federation_expiry_banner.dart | 159 ++++--- rust/ecashapp/src/db.rs | 16 +- rust/ecashapp/src/frb_generated.rs | 490 ++++++++++++++-------- rust/ecashapp/src/lib.rs | 11 + rust/ecashapp/src/multimint.rs | 171 +++++++- 16 files changed, 1462 insertions(+), 555 deletions(-) diff --git a/lib/app.dart b/lib/app.dart index c4ff5309..0e416439 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -653,6 +653,7 @@ class _MyAppState extends State { fed: _selectedFederation!, recovering: _isRecovering!, onLeaveFederation: _leaveFederation, + onJoin: _onJoinPressed, ); } else { if (recoverFederations) { diff --git a/lib/db.dart b/lib/db.dart index 0dade80a..4a4bcaaf 100644 --- a/lib/db.dart +++ b/lib/db.dart @@ -7,8 +7,8 @@ import 'frb_generated.dart'; import 'lib.dart'; import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; -// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `BitcoinDisplayKey`, `BtcPriceKey`, `BtcPrice`, `BtcPricesKey`, `BtcPrices`, `ContactKeyPrefix`, `ContactKey`, `ContactSyncConfigKey`, `DbKeyPrefix`, `FederationBackupKey`, `FederationConfigKeyPrefix`, `FederationConfigKey`, `FederationMetaKeyPrefix`, `FederationMetaKey`, `FederationOrderKey`, `FederationOrder`, `FiatCurrencyKey`, `LightningAddressKeyPrefix`, `NostrRelaysKeyPrefix`, `NostrRelaysKey`, `NostrWalletConnectConfig`, `NostrWalletConnectKeyPrefix`, `NostrWalletConnectKey`, `NostrWalletConnectV2Config`, `NostrWalletConnectV2KeyPrefix`, `NostrWalletConnectV2Key`, `NwcLimitsKey`, `NwcLimits`, `NwcSpendWindowKey`, `NwcSpendWindow`, `PinAttemptsKey`, `PinAttempts`, `PinCodeHashKey`, `PinCredentialKey`, `RequirePinForSpendingKey`, `SchemaVersionKey`, `SeedPhraseAckKey`, `ShowMsatsKey`, `Timestamp`, `WalletV2PendingDepositFederationPrefix`, `WalletV2PendingDepositKey` -// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `cmp`, `cmp`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `hash`, `hash`, `hash`, `partial_cmp`, `partial_cmp`, `partial_cmp`, `partial_cmp` +// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `BitcoinDisplayKey`, `BtcPriceKey`, `BtcPrice`, `BtcPricesKey`, `BtcPrices`, `ContactKeyPrefix`, `ContactKey`, `ContactSyncConfigKey`, `DbKeyPrefix`, `FederationBackupKey`, `FederationConfigKeyPrefix`, `FederationConfigKey`, `FederationMetaKeyPrefix`, `FederationMetaKey`, `FederationMetaV1`, `FederationOrderKey`, `FederationOrder`, `FiatCurrencyKey`, `LightningAddressKeyPrefix`, `NostrRelaysKeyPrefix`, `NostrRelaysKey`, `NostrWalletConnectConfig`, `NostrWalletConnectKeyPrefix`, `NostrWalletConnectKey`, `NostrWalletConnectV2Config`, `NostrWalletConnectV2KeyPrefix`, `NostrWalletConnectV2Key`, `NwcLimitsKey`, `NwcLimits`, `NwcSpendWindowKey`, `NwcSpendWindow`, `PinAttemptsKey`, `PinAttempts`, `PinCodeHashKey`, `PinCredentialKey`, `RequirePinForSpendingKey`, `SchemaVersionKey`, `SeedPhraseAckKey`, `ShowMsatsKey`, `Timestamp`, `WalletV2PendingDepositFederationPrefix`, `WalletV2PendingDepositKey` +// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `cmp`, `cmp`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `hash`, `hash`, `hash`, `partial_cmp`, `partial_cmp`, `partial_cmp`, `partial_cmp` // Rust type: RustOpaqueMoi> abstract class FederationConfig implements RustOpaqueInterface { diff --git a/lib/frb_generated.dart b/lib/frb_generated.dart index 6dde6e5c..f3c0ace4 100644 --- a/lib/frb_generated.dart +++ b/lib/frb_generated.dart @@ -69,7 +69,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.9.0'; @override - int get rustContentHash => -165126491; + int get rustContentHash => 1834095429; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -642,6 +642,12 @@ abstract class RustLibApi extends BaseApi { required List backupInviteCodes, }); + Future crateMultimintMultimintRemoveLnAddress({ + required Multimint that, + required FederationId federationId, + required String lnAddressApi, + }); + Future crateMultimintMultimintSend({ required Multimint that, required FederationId federationId, @@ -1311,6 +1317,11 @@ abstract class RustLibApi extends BaseApi { Future crateRejoinFromBackupInvites(); + Future crateRemoveLnAddress({ + required FederationId federationId, + required String lnAddressApi, + }); + Future crateRemoveNwcConnectionInfo({ required FederationId federationId, }); @@ -5876,6 +5887,49 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["that", "backupInviteCodes"], ); + @override + Future crateMultimintMultimintRemoveLnAddress({ + required Multimint that, + required FederationId federationId, + required String lnAddressApi, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( + that, + serializer, + ); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationId( + federationId, + serializer, + ); + sse_encode_String(lnAddressApi, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 106, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kCrateMultimintMultimintRemoveLnAddressConstMeta, + argValues: [that, federationId, lnAddressApi], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateMultimintMultimintRemoveLnAddressConstMeta => + const TaskConstMeta( + debugName: "Multimint_remove_ln_address", + argNames: ["that", "federationId", "lnAddressApi"], + ); + @override Future crateMultimintMultimintSend({ required Multimint that, @@ -5913,7 +5967,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 106, + funcId: 107, port: port_, ); }, @@ -5979,7 +6033,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 107, + funcId: 108, port: port_, ); }, @@ -6018,7 +6072,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 108, + funcId: 109, port: port_, ); }, @@ -6059,7 +6113,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 109, + funcId: 110, port: port_, ); }, @@ -6097,7 +6151,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 110, + funcId: 111, port: port_, ); }, @@ -6135,7 +6189,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 111, + funcId: 112, port: port_, ); }, @@ -6182,7 +6236,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 112, + funcId: 113, port: port_, ); }, @@ -6231,7 +6285,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 113, + funcId: 114, port: port_, ); }, @@ -6283,7 +6337,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 114, + funcId: 115, port: port_, ); }, @@ -6336,7 +6390,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 115, + funcId: 116, port: port_, ); }, @@ -6372,7 +6426,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 116, + funcId: 117, port: port_, ); }, @@ -6410,7 +6464,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 117, + funcId: 118, port: port_, ); }, @@ -6446,7 +6500,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 118, + funcId: 119, port: port_, ); }, @@ -6482,7 +6536,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 119, + funcId: 120, port: port_, ); }, @@ -6520,7 +6574,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 120, + funcId: 121, port: port_, ); }, @@ -6556,7 +6610,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 121, + funcId: 122, port: port_, ); }, @@ -6594,7 +6648,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 122, + funcId: 123, port: port_, ); }, @@ -6629,7 +6683,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 123, + funcId: 124, port: port_, ); }, @@ -6668,7 +6722,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 124, + funcId: 125, port: port_, ); }, @@ -6705,7 +6759,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 125, + funcId: 126, port: port_, ); }, @@ -6741,7 +6795,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 126, + funcId: 127, port: port_, ); }, @@ -6779,7 +6833,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 127, + funcId: 128, port: port_, ); }, @@ -6819,7 +6873,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 128, + funcId: 129, port: port_, ); }, @@ -6859,7 +6913,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 129, + funcId: 130, port: port_, ); }, @@ -6901,7 +6955,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 130, + funcId: 131, port: port_, ); }, @@ -6942,7 +6996,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 131, + funcId: 132, port: port_, ); }, @@ -6980,7 +7034,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 132, + funcId: 133, port: port_, ); }, @@ -7020,7 +7074,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 133, + funcId: 134, port: port_, ); }, @@ -7065,7 +7119,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 134, + funcId: 135, port: port_, ); }, @@ -7099,7 +7153,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 135, + funcId: 136, port: port_, ); }, @@ -7137,7 +7191,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 136, + funcId: 137, port: port_, ); }, @@ -7175,7 +7229,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 137, + funcId: 138, )!; }, codec: SseCodec( @@ -7205,7 +7259,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 138, + funcId: 139, )!; }, codec: SseCodec( @@ -7238,7 +7292,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 139, + funcId: 140, )!; }, codec: SseCodec( @@ -7274,7 +7328,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 140, + funcId: 141, port: port_, ); }, @@ -7310,7 +7364,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 141, + funcId: 142, )!; }, codec: SseCodec( @@ -7345,7 +7399,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 142, + funcId: 143, )!; }, codec: SseCodec( @@ -7380,7 +7434,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 143, + funcId: 144, )!; }, codec: SseCodec( @@ -7415,7 +7469,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 144, + funcId: 145, )!; }, codec: SseCodec( @@ -7453,7 +7507,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 145, + funcId: 146, )!; }, codec: SseCodec( @@ -7490,7 +7544,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 146, + funcId: 147, )!; }, codec: SseCodec( @@ -7527,7 +7581,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 147, + funcId: 148, )!; }, codec: SseCodec( @@ -7563,7 +7617,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 148, + funcId: 149, )!; }, codec: SseCodec( @@ -7599,7 +7653,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 149, + funcId: 150, )!; }, codec: SseCodec( @@ -7637,7 +7691,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 150, + funcId: 151, )!; }, codec: SseCodec( @@ -7677,7 +7731,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 151, + funcId: 152, )!; }, codec: SseCodec( @@ -7716,7 +7770,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 152, + funcId: 153, )!; }, codec: SseCodec( @@ -7755,7 +7809,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 153, + funcId: 154, )!; }, codec: SseCodec( @@ -7794,7 +7848,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 154, + funcId: 155, )!; }, codec: SseCodec( @@ -7832,7 +7886,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 155, + funcId: 156, )!; }, codec: SseCodec( @@ -7870,7 +7924,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 156, + funcId: 157, )!; }, codec: SseCodec( @@ -7906,7 +7960,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 157, + funcId: 158, )!; }, codec: SseCodec( @@ -7944,7 +7998,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 158, + funcId: 159, )!; }, codec: SseCodec( @@ -7981,7 +8035,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 159, + funcId: 160, )!; }, codec: SseCodec( @@ -8019,7 +8073,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 160, + funcId: 161, )!; }, codec: SseCodec( @@ -8057,7 +8111,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 161, + funcId: 162, )!; }, codec: SseCodec( @@ -8096,7 +8150,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 162, + funcId: 163, )!; }, codec: SseCodec( @@ -8136,7 +8190,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 163, + funcId: 164, )!; }, codec: SseCodec( @@ -8175,7 +8229,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 164, + funcId: 165, )!; }, codec: SseCodec( @@ -8218,7 +8272,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 165, + funcId: 166, )!; }, codec: SseCodec( @@ -8257,7 +8311,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 166, + funcId: 167, )!; }, codec: SseCodec( @@ -8288,7 +8342,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 167, + funcId: 168, port: port_, ); }, @@ -8316,7 +8370,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 168, + funcId: 169, port: port_, ); }, @@ -8349,7 +8403,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 169, + funcId: 170, port: port_, ); }, @@ -8390,7 +8444,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 170, + funcId: 171, port: port_, ); }, @@ -8430,7 +8484,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 171, + funcId: 172, port: port_, ); }, @@ -8471,7 +8525,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 172, + funcId: 173, port: port_, ); }, @@ -8511,7 +8565,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 173, + funcId: 174, port: port_, ); }, @@ -8540,7 +8594,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 174, + funcId: 175, port: port_, ); }, @@ -8571,7 +8625,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 175, + funcId: 176, port: port_, ); }, @@ -8606,7 +8660,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 176, + funcId: 177, port: port_, ); }, @@ -8644,7 +8698,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 177, + funcId: 178, port: port_, ); }, @@ -8684,7 +8738,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 178, + funcId: 179, port: port_, ); }, @@ -8719,7 +8773,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 179, + funcId: 180, port: port_, ); }, @@ -8756,7 +8810,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 180, + funcId: 181, port: port_, ); }, @@ -8799,7 +8853,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 181, + funcId: 182, port: port_, ); }, @@ -8851,7 +8905,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 182, + funcId: 183, port: port_, ); }, @@ -8880,7 +8934,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 183, + funcId: 184, port: port_, ); }, @@ -8911,7 +8965,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 184, + funcId: 185, port: port_, ); }, @@ -8952,7 +9006,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 185, + funcId: 186, port: port_, ); }, @@ -8988,7 +9042,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 186, + funcId: 187, port: port_, ); }, @@ -9022,7 +9076,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 187, + funcId: 188, port: port_, ); }, @@ -9057,7 +9111,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 188, + funcId: 189, port: port_, ); }, @@ -9108,7 +9162,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 189, + funcId: 190, port: port_, ); }, @@ -9164,7 +9218,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 190, + funcId: 191, port: port_, ); }, @@ -9193,7 +9247,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 191, + funcId: 192, port: port_, ); }, @@ -9222,7 +9276,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 192, + funcId: 193, port: port_, ); }, @@ -9255,7 +9309,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 193, + funcId: 194, port: port_, ); }, @@ -9285,7 +9339,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 194, + funcId: 195, port: port_, ); }, @@ -9312,7 +9366,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 195, + funcId: 196, port: port_, ); }, @@ -9339,7 +9393,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 196, + funcId: 197, port: port_, ); }, @@ -9366,7 +9420,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 197, + funcId: 198, port: port_, ); }, @@ -9393,7 +9447,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 198, + funcId: 199, port: port_, ); }, @@ -9429,7 +9483,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 199, + funcId: 200, port: port_, ); }, @@ -9459,7 +9513,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 200, + funcId: 201, port: port_, ); }, @@ -9487,7 +9541,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 201, + funcId: 202, port: port_, ); }, @@ -9522,7 +9576,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 202, + funcId: 203, port: port_, ); }, @@ -9561,7 +9615,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 203, + funcId: 204, port: port_, ); }, @@ -9597,7 +9651,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 204, + funcId: 205, port: port_, ); }, @@ -9635,7 +9689,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 205, + funcId: 206, port: port_, ); }, @@ -9665,7 +9719,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 206, + funcId: 207, port: port_, ); }, @@ -9700,7 +9754,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 207, + funcId: 208, port: port_, ); }, @@ -9736,7 +9790,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 208, + funcId: 209, port: port_, ); }, @@ -9766,7 +9820,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 209, + funcId: 210, port: port_, ); }, @@ -9794,7 +9848,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 210, + funcId: 211, port: port_, ); }, @@ -9821,7 +9875,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 211, + funcId: 212, port: port_, ); }, @@ -9854,7 +9908,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 212, + funcId: 213, port: port_, ); }, @@ -9883,7 +9937,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 213, + funcId: 214, port: port_, ); }, @@ -9910,7 +9964,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 214, + funcId: 215, port: port_, ); }, @@ -9940,7 +9994,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 215, + funcId: 216, port: port_, ); }, @@ -9979,7 +10033,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 216, + funcId: 217, port: port_, ); }, @@ -10018,7 +10072,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 217, + funcId: 218, port: port_, ); }, @@ -10057,7 +10111,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 218, + funcId: 219, port: port_, ); }, @@ -10095,7 +10149,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 219, + funcId: 220, port: port_, ); }, @@ -10134,7 +10188,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 220, + funcId: 221, port: port_, ); }, @@ -10175,7 +10229,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 221, + funcId: 222, port: port_, ); }, @@ -10218,7 +10272,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 222, + funcId: 223, port: port_, ); }, @@ -10258,7 +10312,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 223, + funcId: 224, port: port_, ); }, @@ -10297,7 +10351,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 224, + funcId: 225, port: port_, ); }, @@ -10338,7 +10392,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 225, + funcId: 226, port: port_, ); }, @@ -10377,7 +10431,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 226, + funcId: 227, port: port_, ); }, @@ -10406,7 +10460,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 227, + funcId: 228, port: port_, ); }, @@ -10433,7 +10487,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 228, + funcId: 229, port: port_, ); }, @@ -10460,7 +10514,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 229, + funcId: 230, port: port_, ); }, @@ -10488,7 +10542,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 230, + funcId: 231, port: port_, ); }, @@ -10516,7 +10570,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 231, + funcId: 232, )!; }, codec: SseCodec( @@ -10547,7 +10601,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 232, + funcId: 233, port: port_, ); }, @@ -10581,7 +10635,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 233, + funcId: 234, port: port_, ); }, @@ -10613,7 +10667,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 234, + funcId: 235, port: port_, ); }, @@ -10652,7 +10706,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 235, + funcId: 236, port: port_, ); }, @@ -10684,7 +10738,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 236, + funcId: 237, port: port_, ); }, @@ -10714,7 +10768,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 237, + funcId: 238, port: port_, ); }, @@ -10748,7 +10802,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 238, + funcId: 239, port: port_, ); }, @@ -10789,7 +10843,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 239, + funcId: 240, port: port_, ); }, @@ -10827,7 +10881,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 240, + funcId: 241, port: port_, ); }, @@ -10867,7 +10921,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 241, + funcId: 242, port: port_, ); }, @@ -10910,7 +10964,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 242, + funcId: 243, )!; }, codec: SseCodec( @@ -10945,7 +10999,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 243, + funcId: 244, port: port_, ); }, @@ -10979,7 +11033,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 244, + funcId: 245, port: port_, ); }, @@ -11015,7 +11069,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 245, + funcId: 246, port: port_, ); }, @@ -11045,7 +11099,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 246, + funcId: 247, port: port_, ); }, @@ -11090,7 +11144,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 247, + funcId: 248, port: port_, ); }, @@ -11144,7 +11198,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 248, + funcId: 249, port: port_, ); }, @@ -11173,7 +11227,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 249, + funcId: 250, port: port_, ); }, @@ -11206,7 +11260,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 250, + funcId: 251, port: port_, ); }, @@ -11250,7 +11304,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 251, + funcId: 252, port: port_, ); }, @@ -11301,7 +11355,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 252, + funcId: 253, port: port_, ); }, @@ -11331,7 +11385,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 253, + funcId: 254, port: port_, ); }, @@ -11352,6 +11406,43 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: [], ); + @override + Future crateRemoveLnAddress({ + required FederationId federationId, + required String lnAddressApi, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationId( + federationId, + serializer, + ); + sse_encode_String(lnAddressApi, serializer); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 255, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kCrateRemoveLnAddressConstMeta, + argValues: [federationId, lnAddressApi], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateRemoveLnAddressConstMeta => const TaskConstMeta( + debugName: "remove_ln_address", + argNames: ["federationId", "lnAddressApi"], + ); + @override Future crateRemoveNwcConnectionInfo({ required FederationId federationId, @@ -11367,7 +11458,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 254, + funcId: 256, port: port_, ); }, @@ -11398,7 +11489,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 255, + funcId: 257, port: port_, ); }, @@ -11445,7 +11536,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 256, + funcId: 258, port: port_, ); }, @@ -11503,7 +11594,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 257, + funcId: 259, port: port_, ); }, @@ -11536,7 +11627,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 258, + funcId: 260, port: port_, ); }, @@ -11569,7 +11660,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 259, + funcId: 261, port: port_, ); }, @@ -11599,7 +11690,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 260, + funcId: 262, port: port_, ); }, @@ -11638,7 +11729,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 261, + funcId: 263, port: port_, ); }, @@ -11668,7 +11759,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 262, + funcId: 264, port: port_, ); }, @@ -11698,7 +11789,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 263, + funcId: 265, port: port_, ); }, @@ -11728,7 +11819,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 264, + funcId: 266, port: port_, ); }, @@ -11760,7 +11851,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 265, + funcId: 267, port: port_, ); }, @@ -11791,7 +11882,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 266, + funcId: 268, port: port_, ); }, @@ -11827,7 +11918,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 267, + funcId: 269, port: port_, ); }, @@ -11861,7 +11952,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 268, + funcId: 270, port: port_, ); }, @@ -11904,7 +11995,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 269, + funcId: 271, port: port_, ); }, @@ -11946,7 +12037,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 270, + funcId: 272, port: port_, ); }, @@ -11979,7 +12070,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 271, + funcId: 273, port: port_, ); }, @@ -12018,7 +12109,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 272, + funcId: 274, port: port_, ); }, @@ -12048,7 +12139,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 273, + funcId: 275, port: port_, ); }, @@ -12076,7 +12167,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 274, + funcId: 276, port: port_, ); }, @@ -12111,7 +12202,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 275, + funcId: 277, port: port_, ); }, @@ -12157,7 +12248,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 276, + funcId: 278, port: port_, ); }, @@ -12199,7 +12290,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 277, + funcId: 279, port: port_, ); }, @@ -22438,6 +22529,17 @@ class MultimintImpl extends RustOpaque implements Multimint { backupInviteCodes: backupInviteCodes, ); + /// Gives up the Lightning Address registered for a federation, on the + /// server and locally. Errors when none is registered. + Future removeLnAddress({ + required FederationId federationId, + required String lnAddressApi, + }) => RustLib.instance.api.crateMultimintMultimintRemoveLnAddress( + that: this, + federationId: federationId, + lnAddressApi: lnAddressApi, + ); + Future send({ required FederationId federationId, required String invoice, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a7883d30..d4c76f5d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -751,6 +751,36 @@ "couldNotRegisterLnAddress": "Could not register Lightning Address", "@couldNotRegisterLnAddress": {}, + "removeLnAddress": "Remove Lightning Address", + "@removeLnAddress": {}, + + "removeLnAddressConfirmTitle": "Remove Lightning Address?", + "@removeLnAddressConfirmTitle": {}, + + "removeLnAddressConfirmBody": "{address} will stop working right away. Payments sent to it will fail, and the name becomes free for anyone to claim.", + "@removeLnAddressConfirmBody": { + "placeholders": { + "address": { + "type": "String" + } + } + }, + + "remove": "Remove", + "@remove": {}, + + "removedAddress": "Removed {address}", + "@removedAddress": { + "placeholders": { + "address": { + "type": "String" + } + } + }, + + "couldNotRemoveLnAddress": "Could not remove Lightning Address", + "@couldNotRemoveLnAddress": {}, + "leaveFederation": "Leave Federation", "@leaveFederation": {}, @@ -2092,5 +2122,128 @@ } }, - "nwcDailyBudgetDialogBody": "The most a paired app may spend in total over 24 hours. The count starts with its first payment and resets 24 hours later." + "nwcDailyBudgetDialogBody": "The most a paired app may spend in total over 24 hours. The count starts with its first payment and resets 24 hours later.", + + "federationExpiryBannerTitle": "This federation is shutting down", + "@federationExpiryBannerTitle": {}, + + "federationExpiryBannerSubtitle": "Closes on {date}. Tap for details.", + "@federationExpiryBannerSubtitle": { + "placeholders": { + "date": { + "type": "String" + } + } + }, + + "federationExpiryBannerSubtitlePast": "Closed on {date}. Tap for details.", + "@federationExpiryBannerSubtitlePast": { + "placeholders": { + "date": { + "type": "String" + } + } + }, + + "federationExpiryBannerSubtitleSuccessor": "The guardians named a successor federation. Tap for details.", + "@federationExpiryBannerSubtitleSuccessor": {}, + + "federationExpiryTitle": "Federation shutdown", + "@federationExpiryTitle": {}, + + "federationExpiryHeadline": "{federationName} is shutting down", + "@federationExpiryHeadline": { + "placeholders": { + "federationName": { + "type": "String" + } + } + }, + + "federationExpiryHeadlinePast": "{federationName} has shut down", + "@federationExpiryHeadlinePast": { + "placeholders": { + "federationName": { + "type": "String" + } + } + }, + + "federationExpiryClosesOn": "Closes on", + "@federationExpiryClosesOn": {}, + + "federationExpiryClosedOn": "Closed on", + "@federationExpiryClosedOn": {}, + + "federationExpiryTimeRemaining": "Time remaining", + "@federationExpiryTimeRemaining": {}, + + "federationExpiryYourBalance": "Your balance", + "@federationExpiryYourBalance": {}, + + "federationExpiryPassed": "Deadline passed", + "@federationExpiryPassed": {}, + + "federationExpiryInDays": "{count, plural, =1{1 day} other{{count} days}}", + "@federationExpiryInDays": { + "placeholders": { + "count": { + "type": "int" + } + } + }, + + "federationExpiryInHours": "{count, plural, =1{1 hour} other{{count} hours}}", + "@federationExpiryInHours": { + "placeholders": { + "count": { + "type": "int" + } + } + }, + + "federationExpiryInMinutes": "{count, plural, =1{1 minute} other{{count} minutes}}", + "@federationExpiryInMinutes": { + "placeholders": { + "count": { + "type": "int" + } + } + }, + + "federationExpiryExplanation": "The guardians who run this federation have announced its shutdown. Once it closes, ecash issued by it can no longer be redeemed, and any balance still held here is lost.", + "@federationExpiryExplanation": {}, + + "federationExpiryWhatToDo": "What to do", + "@federationExpiryWhatToDo": {}, + + "federationExpiryStepReceivesOff": "Stop receiving into this federation. Share invoices and addresses from another federation instead.", + "@federationExpiryStepReceivesOff": {}, + + "federationExpiryStepRemoveLightningAddress": "Remove your Lightning Address {address}. It is registered with this federation alone, so it keeps paying in here until it is removed. Setting one up on another federation does not replace it.", + "@federationExpiryStepRemoveLightningAddress": { + "placeholders": { + "address": { + "type": "String" + } + } + }, + + "federationExpiryStepMoveFunds": "Move your balance out, for example with a Lightning payment to another wallet or federation.", + "@federationExpiryStepMoveFunds": {}, + + "federationExpiryStepJoinAnother": "Join another federation so you can keep using the app.", + "@federationExpiryStepJoinAnother": {}, + + "federationExpiryStepJoinSuccessor": "Join the successor federation the guardians recommend, then move your balance there.", + "@federationExpiryStepJoinSuccessor": {}, + + "federationExpiryMoveFunds": "Move funds", + "@federationExpiryMoveFunds": {}, + + "federationExpiryFindFederation": "Find a federation", + "@federationExpiryFindFederation": {}, + + "federationExpiryJoinSuccessor": "Join successor federation", + "@federationExpiryJoinSuccessor": {} } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 136bb1ad..ebdf2f2e 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -215,6 +215,12 @@ "unableToCheckAvailability": "No se pudo verificar la disponibilidad de Dirección Lightning", "claimedAddress": "Se reclamó {address}", "couldNotRegisterLnAddress": "No se pudo registrar la Dirección Lightning", + "removeLnAddress": "Eliminar Dirección Lightning", + "removeLnAddressConfirmTitle": "¿Eliminar Dirección Lightning?", + "removeLnAddressConfirmBody": "{address} dejará de funcionar de inmediato. Los pagos enviados a ella fallarán y el nombre quedará libre para que cualquiera lo reclame.", + "remove": "Eliminar", + "removedAddress": "Se eliminó {address}", + "couldNotRemoveLnAddress": "No se pudo eliminar la Dirección Lightning", "leaveFederation": "Abandonar Federación", "leaveFederationConfirm": "¿Estás seguro de que quieres abandonar esta federación? Necesitarás volver a unirte para acceder a los fondos restantes.", "currentBalance": "Saldo actual", @@ -605,5 +611,55 @@ "nwcDailyBudgetSubtitle": "{sats} sats por día", - "nwcDailyBudgetDialogBody": "Lo máximo que una app vinculada puede gastar en total durante 24 horas. El conteo empieza con su primer pago y se reinicia 24 horas después." + "nwcDailyBudgetDialogBody": "Lo máximo que una app vinculada puede gastar en total durante 24 horas. El conteo empieza con su primer pago y se reinicia 24 horas después.", + + "federationExpiryBannerTitle": "Esta federación va a cerrar", + + "federationExpiryBannerSubtitle": "Cierra el {date}. Toca para ver detalles.", + + "federationExpiryBannerSubtitlePast": "Cerró el {date}. Toca para ver detalles.", + + "federationExpiryBannerSubtitleSuccessor": "Los guardianes nombraron una federación sucesora. Toca para ver detalles.", + + "federationExpiryTitle": "Cierre de la federación", + + "federationExpiryHeadline": "{federationName} va a cerrar", + + "federationExpiryHeadlinePast": "{federationName} ha cerrado", + + "federationExpiryClosesOn": "Cierra el", + + "federationExpiryClosedOn": "Cerró el", + + "federationExpiryTimeRemaining": "Tiempo restante", + + "federationExpiryYourBalance": "Tu saldo", + + "federationExpiryPassed": "Plazo vencido", + + "federationExpiryInDays": "{count, plural, =1{1 día} other{{count} días}}", + + "federationExpiryInHours": "{count, plural, =1{1 hora} other{{count} horas}}", + + "federationExpiryInMinutes": "{count, plural, =1{1 minuto} other{{count} minutos}}", + + "federationExpiryExplanation": "Los guardianes que operan esta federación han anunciado su cierre. Una vez cerrada, el ecash que emitió ya no podrá canjearse y cualquier saldo que quede aquí se perderá.", + + "federationExpiryWhatToDo": "Qué hacer", + + "federationExpiryStepReceivesOff": "Deja de recibir en esta federación. Comparte facturas y direcciones de otra federación en su lugar.", + + "federationExpiryStepRemoveLightningAddress": "Elimina tu Lightning Address {address}. Está registrada solo en esta federación, así que seguirá pagando aquí hasta que la elimines. Configurar una en otra federación no la reemplaza.", + + "federationExpiryStepMoveFunds": "Saca tu saldo, por ejemplo con un pago Lightning a otra billetera o federación.", + + "federationExpiryStepJoinAnother": "Únete a otra federación para seguir usando la app.", + + "federationExpiryStepJoinSuccessor": "Únete a la federación sucesora que recomiendan los guardianes y luego mueve tu saldo allí.", + + "federationExpiryMoveFunds": "Mover fondos", + + "federationExpiryFindFederation": "Buscar una federación", + + "federationExpiryJoinSuccessor": "Unirse a la federación sucesora" } diff --git a/lib/lib.dart b/lib/lib.dart index 83e539be..23f4b0d9 100644 --- a/lib/lib.dart +++ b/lib/lib.dart @@ -511,6 +511,14 @@ Future registerLnAddress({ domain: domain, ); +Future removeLnAddress({ + required FederationId federationId, + required String lnAddressApi, +}) => RustLib.instance.api.crateRemoveLnAddress( + federationId: federationId, + lnAddressApi: lnAddressApi, +); + Future getInviteCode({ required FederationId federationId, required int peer, diff --git a/lib/ln_address.dart b/lib/ln_address.dart index 883063b1..bf4c0411 100644 --- a/lib/ln_address.dart +++ b/lib/ln_address.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:ecashapp/db.dart'; import 'package:ecashapp/extensions/build_context_l10n.dart'; import 'package:ecashapp/lib.dart'; import 'package:ecashapp/multimint.dart'; @@ -10,13 +11,16 @@ import 'package:flutter/material.dart'; class LightningAddressScreen extends StatefulWidget { final List<(FederationSelector, bool)> federations; + + /// Called once the address for [fed] has been registered or removed, so the + /// app refreshes what it shows for that federation. final void Function(FederationSelector fed, bool recovering) - onLnAddressRegistered; + onLnAddressChanged; const LightningAddressScreen({ super.key, required this.federations, - required this.onLnAddressRegistered, + required this.onLnAddressChanged, }); @override @@ -46,6 +50,11 @@ class _LightningAddressScreenState extends State { final _lnApiController = TextEditingController(); final _recurringdApiController = TextEditingController(); bool _registering = false; + bool _removing = false; + + /// The address currently registered for the selected federation, if any. + /// Only then is there something to remove. + LightningAddressConfig? _existingConfig; @override void initState() { @@ -156,7 +165,7 @@ class _LightningAddressScreenState extends State { domain: _selectedDomain!, ); - widget.onLnAddressRegistered(_selectedFederation!, false); + widget.onLnAddressChanged(_selectedFederation!, false); Navigator.of(context).pop(); ToastService().show( message: context.l10n.claimedAddress("$username@$_selectedDomain"), @@ -177,6 +186,51 @@ class _LightningAddressScreenState extends State { } } + /// Gives up the selected federation's address after an explicit + /// confirmation: the name stops working at once and anyone may claim it. + Future _onRemovePressed() async { + final fed = _selectedFederation; + final config = _existingConfig; + if (fed == null || config == null) return; + final address = '${config.username}@${config.domain}'; + + final confirmed = await confirmExternalRequest( + context, + title: context.l10n.removeLnAddressConfirmTitle, + body: context.l10n.removeLnAddressConfirmBody(address), + confirmLabel: context.l10n.remove, + ); + if (!confirmed || !mounted) return; + + setState(() => _removing = true); + try { + await removeLnAddress( + federationId: fed.federationId, + lnAddressApi: _lnAddressApi, + ); + if (!mounted) return; + widget.onLnAddressChanged(fed, false); + Navigator.of(context).pop(); + ToastService().show( + message: context.l10n.removedAddress(address), + duration: const Duration(seconds: 5), + onTap: () {}, + icon: const Icon(Icons.check), + ); + } catch (e) { + AppLogger.instance.error("Could not remove Lightning Address: $e"); + if (!mounted) return; + ToastService().show( + message: context.l10n.couldNotRemoveLnAddress, + duration: const Duration(seconds: 5), + onTap: () {}, + icon: const Icon(Icons.error), + ); + } finally { + if (mounted) setState(() => _removing = false); + } + } + Future _onFederationSet(FederationSelector? fed) async { if (fed == null) return false; @@ -185,12 +239,17 @@ class _LightningAddressScreenState extends State { setState(() { _selectedFederation = fed; + _existingConfig = null; }); try { final config = await getLnAddressConfig(federationId: fed.federationId); + // The user may have picked another federation while this one loaded; + // its result must not land on the one now selected. + if (!mounted || _selectedFederation != fed) return false; if (config != null) { setState(() { + _existingConfig = config; _selectedDomain = config.domain; _usernameController.text = config.username; }); @@ -364,6 +423,26 @@ class _LightningAddressScreenState extends State { : Text(context.l10n.register), ), ), + if (_existingConfig != null) ...[ + const SizedBox(height: 12), + Center( + child: TextButton.icon( + onPressed: _removing ? null : _onRemovePressed, + icon: const Icon(Icons.delete_outline), + label: + _removing + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : Text(context.l10n.removeLnAddress), + style: TextButton.styleFrom( + foregroundColor: Theme.of(context).colorScheme.error, + ), + ), + ), + ], const SizedBox(height: 16), ] else ...[ Padding( diff --git a/lib/multimint.dart b/lib/multimint.dart index 61fe8d8e..15c0309e 100644 --- a/lib/multimint.dart +++ b/lib/multimint.dart @@ -11,7 +11,7 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; import 'package:freezed_annotation/freezed_annotation.dart' hide protected; part 'multimint.freezed.dart'; -// These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_expiry_timestamp`, `get_federation`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_successor_invite`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `join_federation_inner`, `join_federation_on`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `register_federation`, `release_ln_address`, `remove_recovery_progress_cache`, `retire_recovery_client`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `shutdown_client`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_federation_teardown`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` +// These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_expiry_timestamp`, `get_federation`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_successor_invite`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `join_federation_inner`, `join_federation_on`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `migrate_federation_meta_v3`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `register_federation`, `release_ln_address`, `remove_recovery_progress_cache`, `retire_recovery_client`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `shutdown_client`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_federation_teardown`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` // These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ClientType`, `JoinedFederation`, `LNAddressRegisterRequest`, `LNAddressRemoveRequest`, `OnChainWithdrawalMeta`, `WrappedEcash` // These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` // These functions are ignored (category: IgnoreBecauseExplicitAttribute): `federation_network` @@ -496,6 +496,13 @@ abstract class Multimint implements RustOpaqueInterface { required List backupInviteCodes, }); + /// Gives up the Lightning Address registered for a federation, on the + /// server and locally. Errors when none is registered. + Future removeLnAddress({ + required FederationId federationId, + required String lnAddressApi, + }); + Future send({ required FederationId federationId, required String invoice, diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 111af790..41c07ae0 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -19,9 +19,11 @@ import 'package:ecashapp/scan.dart'; import 'package:ecashapp/theme.dart'; import 'package:ecashapp/models.dart'; +import 'package:ecashapp/screens/federation_expiry_screen.dart'; import 'package:ecashapp/screens/my_wallet_screen.dart'; import 'package:ecashapp/widgets/dashboard_balance.dart'; import 'package:ecashapp/widgets/empty_transactions.dart'; +import 'package:ecashapp/widgets/federation_expiry_banner.dart'; import 'package:ecashapp/widgets/pending_deposit_item.dart'; import 'package:ecashapp/widgets/transaction_item.dart'; @@ -30,11 +32,16 @@ class Dashboard extends StatefulWidget { final bool recovering; final VoidCallback onLeaveFederation; + /// Selects a freshly joined federation. Needed here because the shutdown + /// details screen lets the user join the announced successor. + final void Function(FederationSelector fed, bool recovering) onJoin; + const Dashboard({ super.key, required this.fed, required this.recovering, required this.onLeaveFederation, + required this.onJoin, }); @override @@ -57,6 +64,13 @@ class _DashboardState extends State { VoidCallback? _pendingAction; LightningAddressConfig? _lnAddressConfig; + /// Guardian-announced shutdown, read from the cached federation meta. Either + /// being set puts the warning banner under the balance. + BigInt? _expiryTimestamp; + String? _successorInvite; + bool get _isShuttingDown => + _expiryTimestamp != null || _successorInvite != null; + List _recentTransactions = []; bool _isLoadingTransactions = true; @@ -78,6 +92,7 @@ class _DashboardState extends State { _loadBalance(); _loadBtcPrices(); _loadLightningAddress(); + _loadFederationMeta(); _loadRecentTransactions(); final depositEvents = @@ -162,6 +177,13 @@ class _DashboardState extends State { _loadBalance(); _loadRecentTransactions(); } + } else if (event is MultimintEvent_MetaUpdated) { + final selectorIdString = await federationIdToString( + federationId: widget.fed.federationId, + ); + if (event.field0 == selectorIdString) { + _loadFederationMeta(); + } } }); } @@ -249,6 +271,48 @@ class _DashboardState extends State { }); } + /// Reads the shutdown announcement off the cached meta. The background cache + /// task keeps that fresh and publishes MetaUpdated when the guardians change + /// it, so this is a local read that never waits on a guardian. + Future _loadFederationMeta() async { + final FederationMeta meta; + try { + meta = await getFederationMeta(federationId: widget.fed.federationId); + } catch (e) { + // Expected when the federation was left while this screen is still up. + AppLogger.instance.warn('Could not load federation meta: $e'); + return; + } + if (!mounted) return; + setState(() { + _expiryTimestamp = meta.expiryTimestamp; + _successorInvite = meta.successorInvite; + }); + } + + void _openShutdownDetails() { + final lnAddress = _lnAddressConfig; + final hasBalance = balanceMsats != null && balanceMsats! > BigInt.zero; + Navigator.push( + context, + MaterialPageRoute( + builder: + (_) => FederationExpiryScreen( + federationName: widget.fed.federationName, + expiryTimestamp: _expiryTimestamp, + successorInvite: _successorInvite, + balanceMsats: balanceMsats, + onJoin: widget.onJoin, + onMoveFunds: hasBalance ? _onSendPressed : null, + lightningAddress: + lnAddress != null + ? '${lnAddress.username}@${lnAddress.domain}' + : null, + ), + ), + ); + } + List _getModulesForPaymentType() { switch (_selectedPaymentType) { case PaymentType.lightning: @@ -413,6 +477,9 @@ class _DashboardState extends State { @override Widget build(BuildContext context) { + // Zero when nothing is announced, so the header lays out exactly as before. + final bannerExtent = + _isShuttingDown ? federationExpiryBannerExtent(context) : 0.0; return Scaffold( floatingActionButton: recovering @@ -463,6 +530,11 @@ class _DashboardState extends State { isLoadingPrices: _isLoadingPrices, pricesFailed: _pricesFailed, ), + if (_isShuttingDown) + FederationExpiryBanner( + expiryTimestamp: _expiryTimestamp, + onTap: _openShutdownDetails, + ), const SizedBox(height: 24), RecoveryStatus( key: ValueKey(_selectedPaymentType), @@ -482,8 +554,12 @@ class _DashboardState extends State { SliverPersistentHeader( pinned: true, delegate: _DashboardBalanceHeader( - minExtent: _headerMinExtent, - maxExtent: _headerMaxExtent, + minExtent: _headerMinExtent + bannerExtent, + maxExtent: _headerMaxExtent + bannerExtent, + expiryTimestamp: _expiryTimestamp, + successorInvite: _successorInvite, + bannerExtent: bannerExtent, + onShutdownTap: _openShutdownDetails, balanceMsats: balanceMsats, isLoading: isLoadingBalance, recovering: recovering, @@ -674,9 +750,23 @@ class _DashboardBalanceHeader extends SliverPersistentHeaderDelegate { final VoidCallback? onWalletTap; final Color backgroundColor; + /// Guardian-announced shutdown. The banner shows when either is set. + final BigInt? expiryTimestamp; + final String? successorInvite; + + /// Vertical space reserved under the balance for the banner; both extents + /// already include it, so the collapse range is unchanged. Zero without an + /// announcement. + final double bannerExtent; + final VoidCallback onShutdownTap; + _DashboardBalanceHeader({ required this.minExtent, required this.maxExtent, + required this.expiryTimestamp, + required this.successorInvite, + required this.bannerExtent, + required this.onShutdownTap, required this.balanceMsats, required this.isLoading, required this.recovering, @@ -697,24 +787,45 @@ class _DashboardBalanceHeader extends SliverPersistentHeaderDelegate { ) { final range = maxExtent - minExtent; final t = (shrinkOffset / range).clamp(0.0, 1.0); + final showBanner = expiryTimestamp != null || successorInvite != null; return ClipRect( child: SizedBox.expand( child: ColoredBox( color: backgroundColor, - child: Padding( - padding: EdgeInsets.only(top: lerpDouble(48.0, 8.0, t)!), - child: DashboardBalance( - balanceMsats: balanceMsats, - isLoading: isLoading, - recovering: recovering, - btcPrices: btcPrices, - isLoadingPrices: isLoadingPrices, - pricesFailed: pricesFailed, - lnAddressConfig: lnAddressConfig, - onLnAddressTap: onLnAddressTap, - onWalletTap: onWalletTap, - collapseProgress: t, - ), + child: Stack( + children: [ + // The balance keeps the space it had before; the banner is + // anchored below it so it stays fully visible while the balance + // collapses. + Positioned.fill( + bottom: bannerExtent, + child: Padding( + padding: EdgeInsets.only(top: lerpDouble(48.0, 8.0, t)!), + child: DashboardBalance( + balanceMsats: balanceMsats, + isLoading: isLoading, + recovering: recovering, + btcPrices: btcPrices, + isLoadingPrices: isLoadingPrices, + pricesFailed: pricesFailed, + lnAddressConfig: lnAddressConfig, + onLnAddressTap: onLnAddressTap, + onWalletTap: onWalletTap, + collapseProgress: t, + ), + ), + ), + if (showBanner) + Positioned( + left: 0, + right: 0, + bottom: 0, + child: FederationExpiryBanner( + expiryTimestamp: expiryTimestamp, + onTap: onShutdownTap, + ), + ), + ], ), ), ), @@ -730,6 +841,9 @@ class _DashboardBalanceHeader extends SliverPersistentHeaderDelegate { isLoadingPrices != oldDelegate.isLoadingPrices || pricesFailed != oldDelegate.pricesFailed || lnAddressConfig != oldDelegate.lnAddressConfig || + expiryTimestamp != oldDelegate.expiryTimestamp || + successorInvite != oldDelegate.successorInvite || + bannerExtent != oldDelegate.bannerExtent || minExtent != oldDelegate.minExtent || maxExtent != oldDelegate.maxExtent; } diff --git a/lib/screens/federation_expiry_screen.dart b/lib/screens/federation_expiry_screen.dart index 6899e9b5..3ba14a42 100644 --- a/lib/screens/federation_expiry_screen.dart +++ b/lib/screens/federation_expiry_screen.dart @@ -1,8 +1,11 @@ import 'package:ecashapp/db.dart'; import 'package:ecashapp/discover.dart'; import 'package:ecashapp/extensions/build_context_l10n.dart'; +import 'package:ecashapp/generated/app_localizations.dart'; import 'package:ecashapp/multimint.dart'; import 'package:ecashapp/providers/preferences_provider.dart'; +import 'package:ecashapp/screens/federation_info_screen.dart'; +import 'package:ecashapp/toast.dart'; import 'package:ecashapp/utils.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -16,36 +19,45 @@ DateTime expiryDateTime(BigInt expiryTimestamp) => /// Coarse "how long is left" text, in the largest unit that still reads as a /// number the user can act on. Deliberately not a precise countdown: this is a /// deadline to plan around, not a timer. -String formatTimeUntilExpiry(BuildContext context, DateTime expiry) { - final remaining = expiry.difference(DateTime.now()); - if (remaining.isNegative) return context.l10n.federationExpiryPassed; +String formatTimeUntilExpiry( + AppLocalizations l10n, + DateTime expiry, { + DateTime? now, +}) { + final remaining = expiry.difference(now ?? DateTime.now()); + if (remaining.isNegative) return l10n.federationExpiryPassed; if (remaining.inDays > 0) { - return context.l10n.federationExpiryInDays(remaining.inDays); + return l10n.federationExpiryInDays(remaining.inDays); } if (remaining.inHours > 0) { - return context.l10n.federationExpiryInHours(remaining.inHours); + return l10n.federationExpiryInHours(remaining.inHours); } - return context.l10n.federationExpiryInMinutes(remaining.inMinutes); + return l10n.federationExpiryInMinutes(remaining.inMinutes); } /// Explains a guardian-announced shutdown and what the user has to do about it. /// /// Reached from the dashboard's expiry banner. Everything here is read from the /// federation meta the caller already has, so the screen never blocks on a -/// network call — a user opening it because their money is at stake should not +/// network call: a user opening it because their money is at stake should not /// meet a spinner. -class FederationExpiryScreen extends StatelessWidget { - final FederationSelector fed; +class FederationExpiryScreen extends StatefulWidget { + final String federationName; - /// Unix seconds the guardians published as the shutdown time. - final BigInt expiryTimestamp; + /// Unix seconds the guardians published as the shutdown time. Null when they + /// only named a successor. + final BigInt? expiryTimestamp; + + /// Invite code of the federation the guardians want users to move to. Null + /// when they only published a date. + final String? successorInvite; /// Current balance, so the user can see what still has to be moved without /// navigating back. Null while the dashboard is still loading it. final BigInt? balanceMsats; - /// Opens the join flow. Threaded down from the app root because joining - /// changes which federation is selected, which only the root can do. + /// Selects a freshly joined federation. Threaded down from the app root + /// because only the root can change which federation is selected. final void Function(FederationSelector fed, bool recovering) onJoin; /// Pops back to the dashboard and starts a send. Null when there is nothing @@ -53,39 +65,122 @@ class FederationExpiryScreen extends StatelessWidget { final VoidCallback? onMoveFunds; /// The Lightning Address registered against this federation, if any, as - /// `user@domain`. It keeps resolving to this federation after the shutdown is - /// announced — the registration lives on the recurringd server, not here — so - /// the screen has to say so rather than claim all receiving has stopped. + /// `user@domain`. Registrations are per federation and live on the address + /// server, so it keeps paying in here after the shutdown is announced and + /// setting one up elsewhere does not retire it. Removing it gets its own + /// step. final String? lightningAddress; const FederationExpiryScreen({ super.key, - required this.fed, + required this.federationName, required this.expiryTimestamp, + required this.successorInvite, required this.balanceMsats, required this.onJoin, this.onMoveFunds, this.lightningAddress, }); - void _onFindFederation(BuildContext context) { + @override + State createState() => _FederationExpiryScreenState(); +} + +class _FederationExpiryScreenState extends State { + // Guards against pushing the preview route twice while one is already opening. + bool _isOpeningPreview = false; + + void _onFindFederation() { Navigator.push( context, MaterialPageRoute( - builder: (_) => Discover(onJoin: onJoin, showAppBar: true), + builder: (_) => Discover(onJoin: widget.onJoin, showAppBar: true), + ), + ); + } + + /// Opens the successor's preview so the user sees its guardians before + /// committing, then hands the joined federation to the app root and returns + /// to the dashboard, which by then shows the successor. + Future _onJoinSuccessor() async { + if (_isOpeningPreview) return; + setState(() => _isOpeningPreview = true); + + final joined = await Navigator.push<(FederationSelector, bool)>( + context, + MaterialPageRoute( + builder: + (_) => FederationInfoScreen( + inviteCode: widget.successorInvite, + joinable: true, + onLeaveFederation: () {}, + ), ), ); + + if (!mounted) return; + setState(() => _isOpeningPreview = false); + if (joined == null) return; + + final (fed, recovering) = joined; + final message = context.l10n.joinedFederation(fed.federationName); + widget.onJoin(fed, recovering); + Navigator.popUntil(context, (route) => route.isFirst); + ToastService().show( + message: message, + duration: const Duration(seconds: 5), + onTap: () {}, + icon: const Icon(Icons.info), + ); } @override Widget build(BuildContext context) { final theme = Theme.of(context); - final expiry = expiryDateTime(expiryTimestamp); - final hasExpired = expiry.isBefore(DateTime.now()); + final l10n = context.l10n; final warning = theme.colorScheme.error; + final expiryTimestamp = widget.expiryTimestamp; + final expiry = + expiryTimestamp != null ? expiryDateTime(expiryTimestamp) : null; + final hasExpired = expiry != null && expiry.isBefore(DateTime.now()); + final hasSuccessor = widget.successorInvite != null; + final bitcoinDisplay = context.select( + (prefs) => prefs.bitcoinDisplay, + ); + + final steps = [ + l10n.federationExpiryStepReceivesOff, + if (widget.lightningAddress != null) + l10n.federationExpiryStepRemoveLightningAddress( + widget.lightningAddress!, + ), + l10n.federationExpiryStepMoveFunds, + hasSuccessor + ? l10n.federationExpiryStepJoinSuccessor + : l10n.federationExpiryStepJoinAnother, + ]; + + final facts = <(String, String)>[ + if (expiry != null) + ( + hasExpired + ? l10n.federationExpiryClosedOn + : l10n.federationExpiryClosesOn, + DateFormat.yMMMMd().add_jm().format(expiry), + ), + if (expiry != null && !hasExpired) + ( + l10n.federationExpiryTimeRemaining, + formatTimeUntilExpiry(l10n, expiry), + ), + ( + l10n.federationExpiryYourBalance, + formatBalance(widget.balanceMsats, false, bitcoinDisplay), + ), + ]; return Scaffold( - appBar: AppBar(title: Text(context.l10n.federationExpiryTitle)), + appBar: AppBar(title: Text(l10n.federationExpiryTitle)), body: SafeArea( child: ListView( padding: const EdgeInsets.fromLTRB(24, 8, 24, 32), @@ -107,10 +202,8 @@ class FederationExpiryScreen extends StatelessWidget { const SizedBox(height: 20), Text( hasExpired - ? context.l10n.federationExpiryHeadlinePast( - fed.federationName, - ) - : context.l10n.federationExpiryHeadline(fed.federationName), + ? l10n.federationExpiryHeadlinePast(widget.federationName) + : l10n.federationExpiryHeadline(widget.federationName), style: theme.textTheme.headlineSmall?.copyWith( color: warning, fontWeight: FontWeight.bold, @@ -118,81 +211,55 @@ class FederationExpiryScreen extends StatelessWidget { textAlign: TextAlign.center, ), const SizedBox(height: 24), - _FactsCard( - rows: [ - ( - hasExpired - ? context.l10n.federationExpiryClosedOn - : context.l10n.federationExpiryClosesOn, - DateFormat.yMMMMd().add_jm().format(expiry), - ), - ( - context.l10n.federationExpiryTimeRemaining, - formatTimeUntilExpiry(context, expiry), - ), - ( - context.l10n.federationExpiryYourBalance, - formatBalance( - balanceMsats, - false, - context.select( - (prefs) => prefs.bitcoinDisplay, - ), - ), - ), - ], - ), + _FactsCard(rows: facts), const SizedBox(height: 24), Text( - context.l10n.federationExpiryExplanation, + l10n.federationExpiryExplanation, style: theme.textTheme.bodyMedium?.copyWith(height: 1.5), ), const SizedBox(height: 28), Text( - context.l10n.federationExpiryWhatToDo, + l10n.federationExpiryWhatToDo, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), - _Step( - number: 1, - text: context.l10n.federationExpiryStepReceivesOff, - note: - lightningAddress != null - ? context.l10n.federationExpiryLightningAddressNote( - lightningAddress!, - ) - : null, - ), - _Step(number: 2, text: context.l10n.federationExpiryStepMoveFunds), - _Step( - number: 3, - text: context.l10n.federationExpiryStepJoinAnother, - ), + for (final (index, text) in steps.indexed) + _Step(number: index + 1, text: text), const SizedBox(height: 28), - if (onMoveFunds != null) ...[ + if (widget.onMoveFunds != null) ...[ OutlinedButton.icon( onPressed: () { Navigator.of(context).pop(); - onMoveFunds!(); + widget.onMoveFunds!(); }, icon: const Icon(Icons.upload), - label: Text(context.l10n.federationExpiryMoveFunds), + label: Text(l10n.federationExpiryMoveFunds), style: OutlinedButton.styleFrom( minimumSize: const Size.fromHeight(48), ), ), const SizedBox(height: 12), ], - FilledButton.icon( - onPressed: () => _onFindFederation(context), - icon: const Icon(Icons.search), - label: Text(context.l10n.federationExpiryFindFederation), - style: FilledButton.styleFrom( - minimumSize: const Size.fromHeight(48), + if (hasSuccessor) + FilledButton.icon( + onPressed: _isOpeningPreview ? null : _onJoinSuccessor, + icon: const Icon(Icons.login), + label: Text(l10n.federationExpiryJoinSuccessor), + style: FilledButton.styleFrom( + minimumSize: const Size.fromHeight(48), + ), + ) + else + FilledButton.icon( + onPressed: _onFindFederation, + icon: const Icon(Icons.search), + label: Text(l10n.federationExpiryFindFederation), + style: FilledButton.styleFrom( + minimumSize: const Size.fromHeight(48), + ), ), - ), ], ), ), @@ -200,7 +267,7 @@ class FederationExpiryScreen extends StatelessWidget { } } -/// The three headline facts, as label/value rows on one surface. +/// The headline facts, as label/value rows on one surface. class _FactsCard extends StatelessWidget { final List<(String, String)> rows; @@ -255,11 +322,7 @@ class _Step extends StatelessWidget { final int number; final String text; - /// Caveat shown under the step, set apart from it. Used where the general - /// statement has an exception the user needs to act on. - final String? note; - - const _Step({required this.number, required this.text, this.note}); + const _Step({required this.number, required this.text}); @override Widget build(BuildContext context) { @@ -287,28 +350,9 @@ class _Step extends StatelessWidget { ), const SizedBox(width: 12), Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - text, - style: theme.textTheme.bodyMedium?.copyWith(height: 1.4), - ), - if (note != null) ...[ - const SizedBox(height: 8), - Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: theme.colorScheme.error.withValues(alpha: 0.10), - borderRadius: BorderRadius.circular(8), - ), - child: Text( - note!, - style: theme.textTheme.bodySmall?.copyWith(height: 1.4), - ), - ), - ], - ], + child: Text( + text, + style: theme.textTheme.bodyMedium?.copyWith(height: 1.4), ), ), ], diff --git a/lib/setttings.dart b/lib/setttings.dart index c87d8da4..8aa646c1 100644 --- a/lib/setttings.dart +++ b/lib/setttings.dart @@ -103,7 +103,7 @@ class _SettingsScreenState extends State { builder: (context) => LightningAddressScreen( federations: feds, - onLnAddressRegistered: widget.onJoin, + onLnAddressChanged: widget.onJoin, ), ), ); diff --git a/lib/widgets/federation_expiry_banner.dart b/lib/widgets/federation_expiry_banner.dart index e6411e19..0d20a6fb 100644 --- a/lib/widgets/federation_expiry_banner.dart +++ b/lib/widgets/federation_expiry_banner.dart @@ -1,35 +1,60 @@ import 'package:ecashapp/extensions/build_context_l10n.dart'; import 'package:ecashapp/screens/federation_expiry_screen.dart'; import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; +import 'package:intl/intl.dart' hide TextDirection; /// Height [FederationExpiryBanner] lays out at, for the pinned sliver header /// that has to declare its extent before the banner is measured. /// -/// Declaring less than the banner measures clips it; declaring more trips the -/// sliver's layoutExtent-vs-paintExtent assertion unless the header forces its -/// child to fill the box. Both texts are capped at one line, so only they grow -/// with the user's font setting and the padding around them stays fixed — -/// which is why the scale applies to just one of the two terms. -/// -/// `federation_expiry_banner_test.dart` pins this to what the widget actually -/// measures, so a padding or text-style change there fails a test rather than -/// an assertion on someone's dashboard. +/// The banner sizes itself to exactly this value, so the header and the widget +/// can never disagree. The two text lines are measured with the styles and +/// font scale the banner renders with (the engine rounds line heights to whole +/// pixels, so a linear formula would drift), leaving only the fixed padding +/// around them as an assumption. `federation_expiry_banner_test.dart` renders +/// the banner at several font scales and fails if that assumption stops +/// holding, so a padding change here breaks a test rather than clipping on +/// someone's dashboard. double federationExpiryBannerExtent(BuildContext context) { - const chrome = 32.0; // 8 outer top padding + 12/12 card vertical padding - const textLines = 40.0; // title + gap + subtitle, at scale 1.0 - return chrome + MediaQuery.textScalerOf(context).scale(textLines); + // 8 outer top padding + 12/12 card padding + 1/1 border + 2 gap between lines. + const chrome = 36.0; + final textTheme = Theme.of(context).textTheme; + return chrome + + _lineHeight(context, _titleStyle(textTheme)) + + _lineHeight(context, _subtitleStyle(textTheme)); +} + +TextStyle? _titleStyle(TextTheme textTheme) => + textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.bold); + +TextStyle? _subtitleStyle(TextTheme textTheme) => + textTheme.bodySmall?.copyWith(color: Colors.white70); + +/// Height of one line of [style] at the user's font scale, laid out the way +/// the banner's `Text` widgets will be: inheriting from the surrounding +/// `Material`'s default text style, which is `bodyMedium`. +double _lineHeight(BuildContext context, TextStyle? style) { + final base = Theme.of(context).textTheme.bodyMedium; + final painter = TextPainter( + text: TextSpan(text: 'X', style: base?.merge(style) ?? style), + textDirection: Directionality.maybeOf(context) ?? TextDirection.ltr, + textScaler: MediaQuery.textScalerOf(context), + maxLines: 1, + )..layout(); + final height = painter.height; + painter.dispose(); + return height; } -/// Loud, tappable warning that the guardians have scheduled this federation's -/// shutdown. +/// Loud, tappable warning that the guardians have announced this federation's +/// shutdown, by publishing a date, naming a successor, or both. /// /// Sits directly under the balance on the dashboard, in the error colour, and -/// stays put while the transaction list scrolls — the point is that it cannot +/// stays put while the transaction list scrolls: the point is that it cannot /// be missed by someone who only ever glances at their balance. class FederationExpiryBanner extends StatelessWidget { - /// Unix seconds the guardians published as the shutdown time. - final BigInt expiryTimestamp; + /// Unix seconds the guardians published as the shutdown time. Null when they + /// only named a successor, which changes the wording but not the urgency. + final BigInt? expiryTimestamp; final VoidCallback onTap; const FederationExpiryBanner({ @@ -38,63 +63,69 @@ class FederationExpiryBanner extends StatelessWidget { required this.onTap, }); + String _subtitle(BuildContext context) { + final expiryTimestamp = this.expiryTimestamp; + if (expiryTimestamp == null) { + return context.l10n.federationExpiryBannerSubtitleSuccessor; + } + final expiry = expiryDateTime(expiryTimestamp); + final date = DateFormat.yMMMd().format(expiry); + return expiry.isBefore(DateTime.now()) + ? context.l10n.federationExpiryBannerSubtitlePast(date) + : context.l10n.federationExpiryBannerSubtitle(date); + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); final warning = theme.colorScheme.error; - final expiry = expiryDateTime(expiryTimestamp); - final date = DateFormat.yMMMd().format(expiry); - final subtitle = - expiry.isBefore(DateTime.now()) - ? context.l10n.federationExpiryBannerSubtitlePast(date) - : context.l10n.federationExpiryBannerSubtitle(date); return Padding( padding: const EdgeInsets.only(top: 8), - child: Material( - color: warning.withValues(alpha: 0.12), - borderRadius: BorderRadius.circular(12), - child: InkWell( - onTap: onTap, + child: SizedBox( + height: federationExpiryBannerExtent(context) - 8, + child: Material( + color: warning.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(12), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all(color: warning.withValues(alpha: 0.5)), - ), - child: Row( - children: [ - Icon(Icons.warning_amber_rounded, color: warning, size: 24), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - context.l10n.federationExpiryBannerTitle, - style: theme.textTheme.bodyMedium?.copyWith( - color: warning, - fontWeight: FontWeight.bold, + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all(color: warning.withValues(alpha: 0.5)), + ), + child: Row( + children: [ + Icon(Icons.warning_amber_rounded, color: warning, size: 24), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + context.l10n.federationExpiryBannerTitle, + style: _titleStyle( + theme.textTheme, + )?.copyWith(color: warning), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 2), - Text( - subtitle, - style: theme.textTheme.bodySmall?.copyWith( - color: Colors.white70, + const SizedBox(height: 2), + Text( + _subtitle(context), + style: _subtitleStyle(theme.textTheme), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], + ], + ), ), - ), - Icon(Icons.chevron_right, color: warning, size: 20), - ], + Icon(Icons.chevron_right, color: warning, size: 20), + ], + ), ), ), ), diff --git a/rust/ecashapp/src/db.rs b/rust/ecashapp/src/db.rs index cb0727ea..96c1a70d 100644 --- a/rust/ecashapp/src/db.rs +++ b/rust/ecashapp/src/db.rs @@ -13,7 +13,7 @@ use fedimint_core::{ }; use serde::{Deserialize, Serialize}; -use crate::multimint::FederationMeta; +use crate::multimint::{FederationMeta, FederationSelector, Guardian}; /// A `SystemTime` persisted in our database. /// @@ -223,6 +223,20 @@ impl_db_lookup!( query_prefix = FederationMetaKeyPrefix, ); +/// `FederationMeta` as persisted before schema v3, without `expiry_timestamp` +/// and `successor_invite`. Kept only so the v3 migration can decode entries +/// written by earlier builds and re-encode them in the current layout. +#[derive(Debug, Encodable, Decodable)] +pub(crate) struct FederationMetaV1 { + pub(crate) picture: Option, + pub(crate) welcome: Option, + pub(crate) guardians: Vec, + pub(crate) selector: FederationSelector, + pub(crate) last_updated: u64, + pub(crate) recurringd_api: Option, + pub(crate) lnaddress_api: Option, +} + #[derive(Debug, Encodable, Decodable)] pub(crate) struct BtcPriceKey; diff --git a/rust/ecashapp/src/frb_generated.rs b/rust/ecashapp/src/frb_generated.rs index e494bd01..947c4371 100644 --- a/rust/ecashapp/src/frb_generated.rs +++ b/rust/ecashapp/src/frb_generated.rs @@ -43,7 +43,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.9.0"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -165126491; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1834095429; // Section: executor @@ -6616,6 +6616,83 @@ fn wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( }, ) } +fn wire__crate__multimint__Multimint_remove_ln_address_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "Multimint_remove_ln_address", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_federation_id = , + >>::sse_decode(&mut deserializer); + let api_ln_address_api = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| async move { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || async move { + let mut api_that_guard = None; + let mut api_federation_id_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order( + vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_federation_id, + 1, + false, + ), + ], + ); + for i in decode_indices_ { + match i { + 0 => { + api_that_guard = + Some(api_that.lockable_decode_async_ref().await) + } + 1 => { + api_federation_id_guard = + Some(api_federation_id.lockable_decode_async_ref().await) + } + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let api_federation_id_guard = api_federation_id_guard.unwrap(); + let output_ok = crate::multimint::Multimint::remove_ln_address( + &*api_that_guard, + &*api_federation_id_guard, + api_ln_address_api, + ) + .await?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} fn wire__crate__multimint__Multimint_send_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -14245,6 +14322,66 @@ fn wire__crate__rejoin_from_backup_invites_impl( }, ) } +fn wire__crate__remove_ln_address_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "remove_ln_address", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_federation_id = , + >>::sse_decode(&mut deserializer); + let api_ln_address_api = ::sse_decode(&mut deserializer); + deserializer.end(); + move |context| async move { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || async move { + let mut api_federation_id_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order( + vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_federation_id, + 0, + false, + )], + ); + for i in decode_indices_ { + match i { + 0 => { + api_federation_id_guard = + Some(api_federation_id.lockable_decode_async_ref().await) + } + _ => unreachable!(), + } + } + let api_federation_id_guard = api_federation_id_guard.unwrap(); + let output_ok = + crate::remove_ln_address(&*api_federation_id_guard, api_ln_address_api) + .await?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} fn wire__crate__remove_nwc_connection_info_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -18161,258 +18298,265 @@ fn pde_ffi_dispatcher_primary_impl( rust_vec_len, data_len, ), - 106 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), - 107 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), - 108 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( + 106 => wire__crate__multimint__Multimint_remove_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 109 => wire__crate__multimint__Multimint_set_federation_order_impl( + 107 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), + 108 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), + 109 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 110 => wire__crate__multimint__Multimint_set_fiat_currency_impl( + 110 => wire__crate__multimint__Multimint_set_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 111 => { + 111 => wire__crate__multimint__Multimint_set_fiat_currency_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 112 => { wire__crate__multimint__Multimint_set_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 112 => { + 113 => { wire__crate__multimint__Multimint_transactions_impl(port, ptr, rust_vec_len, data_len) } - 113 => { + 114 => { wire__crate__multimint__Multimint_wallet_summary_impl(port, ptr, rust_vec_len, data_len) } - 114 => wire__crate__multimint__Multimint_withdraw_to_address_impl( + 115 => wire__crate__multimint__Multimint_withdraw_to_address_impl( port, ptr, rust_vec_len, data_len, ), - 115 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( + 116 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 116 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( + 117 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( port, ptr, rust_vec_len, data_len, ), - 117 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( + 118 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( port, ptr, rust_vec_len, data_len, ), - 118 => { + 119 => { wire__crate__nostr__NostrClient_get_all_contacts_impl(port, ptr, rust_vec_len, data_len) } - 119 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( + 120 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 120 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), - 121 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( + 121 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), + 122 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 122 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( + 123 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( port, ptr, rust_vec_len, data_len, ), - 123 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( + 124 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 124 => wire__crate__nostr__NostrClient_get_public_federations_impl( + 125 => wire__crate__nostr__NostrClient_get_public_federations_impl( port, ptr, rust_vec_len, data_len, ), - 125 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), - 126 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( + 126 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), + 127 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 127 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), - 128 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), - 129 => wire__crate__nostr__NostrClient_paginate_contacts_impl( + 128 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), + 129 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), + 130 => wire__crate__nostr__NostrClient_paginate_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 130 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( + 131 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 131 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( + 132 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 132 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), - 133 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( + 133 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), + 134 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 134 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( + 135 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 135 => { + 136 => { wire__crate__nostr__NostrClient_sync_contacts_impl(port, ptr, rust_vec_len, data_len) } - 136 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 140 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( + 137 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 141 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( port, ptr, rust_vec_len, data_len, ), - 167 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), - 168 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), - 169 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), - 170 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), - 171 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), - 172 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), - 173 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), - 174 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), - 175 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), - 176 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), - 177 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), - 178 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), - 179 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), - 180 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), - 181 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), - 182 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), - 183 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), - 184 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), - 185 => { + 168 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), + 169 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), + 170 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), + 171 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), + 172 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), + 173 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), + 174 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), + 175 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), + 176 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), + 177 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), + 178 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), + 179 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), + 180 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), + 181 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), + 182 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), + 183 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), + 184 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), + 185 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), + 186 => { wire__crate__compute_receive_amount_with_fees_impl(port, ptr, rust_vec_len, data_len) } - 186 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), - 187 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), - 188 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), - 189 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 190 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), - 191 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), - 192 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 193 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), - 194 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), - 195 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), - 196 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 197 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), - 198 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), - 199 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 200 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), - 201 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 202 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), - 203 => { + 187 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), + 188 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), + 189 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), + 190 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 191 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), + 192 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), + 193 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 194 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), + 195 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), + 196 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), + 197 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 198 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), + 199 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), + 200 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 201 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), + 202 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 203 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), + 204 => { wire__crate__get_invoice_from_lnaddress_or_lnurl_impl(port, ptr, rust_vec_len, data_len) } - 204 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), - 205 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), - 206 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), - 207 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 208 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), - 209 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 210 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 211 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 212 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), - 213 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), - 214 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 215 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), - 216 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), - 217 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), - 218 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), - 219 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), - 220 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), - 221 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), - 222 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), - 223 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), - 224 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), - 225 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), - 226 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), - 227 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), - 228 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), - 229 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), - 230 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), - 232 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), - 233 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), - 234 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), - 235 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), - 236 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), - 237 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), - 238 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), - 239 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), - 240 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), - 241 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), - 243 => { + 205 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), + 206 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), + 207 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), + 208 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 209 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), + 210 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 211 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 212 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 213 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), + 214 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), + 215 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 216 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), + 217 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), + 218 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), + 219 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), + 220 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), + 221 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), + 222 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), + 223 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), + 224 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), + 225 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), + 226 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), + 227 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), + 228 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), + 229 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), + 230 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), + 231 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), + 233 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), + 234 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), + 235 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), + 236 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), + 237 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), + 238 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), + 239 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), + 240 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), + 241 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), + 242 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), + 244 => { wire__crate__parse_scanned_text_for_federation_impl(port, ptr, rust_vec_len, data_len) } - 244 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), - 245 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), - 246 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), - 247 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), - 248 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), - 249 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), - 250 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 251 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), - 252 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), - 253 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), - 254 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 255 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), - 256 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), - 257 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), - 258 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 259 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), - 260 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 261 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 262 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 263 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 264 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), - 265 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 266 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), - 267 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), - 268 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), - 269 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), - 270 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 271 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), - 272 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), - 273 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 274 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), - 275 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), - 276 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), - 277 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), + 245 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), + 246 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), + 247 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), + 248 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), + 249 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), + 250 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), + 251 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 252 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), + 253 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), + 254 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), + 255 => wire__crate__remove_ln_address_impl(port, ptr, rust_vec_len, data_len), + 256 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 257 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), + 258 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), + 259 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), + 260 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 261 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), + 262 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 263 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 264 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 265 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 266 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), + 267 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 268 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), + 269 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), + 270 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), + 271 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), + 272 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 273 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), + 274 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), + 275 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 276 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), + 277 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), + 278 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), + 279 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -18655,145 +18799,145 @@ fn pde_ffi_dispatcher_sync_impl( rust_vec_len, data_len, ), - 137 => { + 138 => { wire__crate__fountain__OobNotesDecoder_add_fragment_impl(ptr, rust_vec_len, data_len) } - 138 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), - 139 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), - 141 => { + 139 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), + 140 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), + 142 => { wire__crate__multimint__OobNotesWrapper_amount_msats_impl(ptr, rust_vec_len, data_len) } - 142 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), - 143 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( + 143 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), + 144 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( ptr, rust_vec_len, data_len, ), - 144 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( + 145 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( ptr, rust_vec_len, data_len, ), - 145 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( + 146 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( ptr, rust_vec_len, data_len, ), - 146 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( + 147 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 147 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( + 148 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( ptr, rust_vec_len, data_len, ), - 148 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( + 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( ptr, rust_vec_len, data_len, ), - 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( + 150 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( ptr, rust_vec_len, data_len, ), - 150 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( + 151 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( ptr, rust_vec_len, data_len, ), - 151 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( + 152 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( ptr, rust_vec_len, data_len, ), - 152 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( + 153 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( ptr, rust_vec_len, data_len, ), - 153 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( + 154 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 154 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( + 155 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( ptr, rust_vec_len, data_len, ), - 155 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( + 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( ptr, rust_vec_len, data_len, ), - 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( + 157 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( ptr, rust_vec_len, data_len, ), - 157 => { + 158 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 158 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( + 159 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 159 => { + 160 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 160 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( + 161 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( ptr, rust_vec_len, data_len, ), - 161 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( + 162 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 162 => { + 163 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 163 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( + 164 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 164 => { + 165 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 165 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( + 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( ptr, rust_vec_len, data_len, ), - 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( + 167 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 231 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), - 242 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), + 232 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), + 243 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), _ => unreachable!(), } } diff --git a/rust/ecashapp/src/lib.rs b/rust/ecashapp/src/lib.rs index 9471c73e..7b347134 100644 --- a/rust/ecashapp/src/lib.rs +++ b/rust/ecashapp/src/lib.rs @@ -1045,6 +1045,17 @@ pub async fn register_ln_address( .await } +#[frb] +pub async fn remove_ln_address( + federation_id: &FederationId, + ln_address_api: String, +) -> anyhow::Result<()> { + let multimint = get_multimint(); + multimint + .remove_ln_address(federation_id, ln_address_api) + .await +} + #[frb] pub async fn get_invite_code(federation_id: &FederationId, peer: u16) -> anyhow::Result { let multimint = get_multimint(); diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index 9f702d54..f7916f80 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -31,12 +31,15 @@ use fedimint_core::{ base32::{decode_prefixed, encode_prefixed, FEDIMINT_PREFIX}, config::{FederationId, META_FEDERATION_NAME_KEY}, core::{ModuleInstanceId, ModuleKind}, - db::{mem_impl::MemDatabase, Database, IDatabaseTransactionOpsCoreTyped}, + db::{ + mem_impl::MemDatabase, Database, DatabaseKeyPrefix, DatabaseTransaction, + IDatabaseTransactionOpsCore, IDatabaseTransactionOpsCoreTyped, + }, encoding::{Decodable, Encodable}, endpoint_constants::CONSENSUS_ORD_LATENCY_ENDPOINT, envs::BitcoinRpcConfig, invite_code::InviteCode, - module::{ApiAuth, ApiRequestErased}, + module::{registry::ModuleDecoderRegistry, ApiAuth, ApiRequestErased}, task::TaskGroup, util::SafeUrl, Amount, NumPeers, @@ -107,8 +110,9 @@ use crate::{ db::{ BitcoinDisplay, BitcoinDisplayKey, BtcPrice, BtcPriceKey, BtcPrices, BtcPricesKey, Connector, ContactSyncConfigKey, FederationBackupKey, FederationMetaKey, - FederationMetaKeyPrefix, FiatCurrency, FiatCurrencyKey, LightningAddressConfig, - LightningAddressKey, LightningAddressKeyPrefix, SchemaVersionKey, Timestamp, + FederationMetaKeyPrefix, FederationMetaV1, FiatCurrency, FiatCurrencyKey, + LightningAddressConfig, LightningAddressKey, LightningAddressKeyPrefix, SchemaVersionKey, + Timestamp, }, error_to_flutter, get_nostr_client, info_to_flutter, payment_error_to_flutter, wallet::WalletHandler, @@ -933,6 +937,56 @@ impl OnChainWithdrawalMeta { } } +/// Schema v3: re-encodes every cached `FederationMeta` written in the layout +/// before `expiry_timestamp` and `successor_invite` existed, with both unset. +/// Entries already in the current layout are left alone; anything else is +/// dropped for the cache task to rebuild. Returns how many were re-encoded and +/// how many dropped. +async fn migrate_federation_meta_v3( + dbtx: &mut DatabaseTransaction<'_, Cap>, +) -> (usize, usize) { + let decoders = ModuleDecoderRegistry::default(); + let entries: Vec<(Vec, Vec)> = dbtx + .raw_find_by_prefix(&FederationMetaKeyPrefix.to_bytes()) + .await + .expect("Unrecoverable error reading the FederationMeta cache") + .collect() + .await; + + let (mut migrated, mut dropped) = (0, 0); + for (key, value) in entries { + if FederationMeta::consensus_decode_whole(&value, &decoders).is_ok() { + continue; + } + match FederationMetaV1::consensus_decode_whole(&value, &decoders) { + Ok(old) => { + let current = FederationMeta { + picture: old.picture, + welcome: old.welcome, + guardians: old.guardians, + selector: old.selector, + last_updated: old.last_updated, + recurringd_api: old.recurringd_api, + lnaddress_api: old.lnaddress_api, + expiry_timestamp: None, + successor_invite: None, + }; + dbtx.raw_insert_bytes(&key, ¤t.consensus_encode_to_vec()) + .await + .expect("Unrecoverable error writing the FederationMeta cache"); + migrated += 1; + } + Err(_) => { + dbtx.raw_remove_entry(&key) + .await + .expect("Unrecoverable error removing a FederationMeta cache entry"); + dropped += 1; + } + } + } + (migrated, dropped) +} + impl Multimint { pub async fn new(db: Database, creation_type: MultimintCreation) -> anyhow::Result { let start = Instant::now(); @@ -1016,16 +1070,21 @@ impl Multimint { info_to_flutter("Purged FederationMeta cache for schema migration v1").await; } - if current_version < 2 { - // Migration v2: FederationMeta gained expiry_timestamp and - // successor_invite. Entries persisted in the old layout fail to - // decode (which panics on read), so purge them; the cache task - // rebuilds each one on its next pass. - dbtx.remove_by_prefix(&FederationMetaKeyPrefix).await; - info_to_flutter("Purged FederationMeta cache for schema migration v2").await; + if current_version < 3 { + // Migration v3: FederationMeta gained expiry_timestamp and + // successor_invite. Re-encode each cached entry with both unset so + // it decodes again; the cache task fills in the real values on its + // next pass. (v2 purged the cache instead, but a database can be + // at v2 through a build that never shipped, so the step is redone + // as v3 in a form that copes with whatever it finds.) + let (migrated, dropped) = migrate_federation_meta_v3(&mut dbtx).await; + info_to_flutter(format!( + "Schema migration v3: re-encoded {migrated} cached FederationMeta entries, dropped {dropped}" + )) + .await; } - let target_version: u64 = 2; + let target_version: u64 = 3; if current_version < target_version { dbtx.insert_entry(&SchemaVersionKey, &target_version).await; dbtx.commit_tx().await; @@ -5605,6 +5664,21 @@ impl Multimint { Ok(()) } + /// Gives up the Lightning Address registered for a federation, on the + /// server and locally. Errors when none is registered. + pub async fn remove_ln_address( + &self, + federation_id: &FederationId, + ln_address_api: String, + ) -> anyhow::Result<()> { + let config = self + .get_ln_address_config(federation_id) + .await + .context("No Lightning Address is registered for this federation")?; + self.release_ln_address(federation_id, &config, &ln_address_api) + .await + } + /// Register LNURL/LN Address pub async fn register_ln_address( &self, @@ -7134,16 +7208,85 @@ mod tests { use fedimint_client::module::module::recovery::RecoveryProgress; use fedimint_core::config::FederationId; use fedimint_core::core::ModuleKind; + use fedimint_core::db::mem_impl::MemDatabase; + use fedimint_core::db::{ + Database, DatabaseKeyPrefix, IDatabaseTransactionOpsCore, IDatabaseTransactionOpsCoreTyped, + }; + use fedimint_core::encoding::Encodable; use fedimint_core::invite_code::InviteCode; + use fedimint_core::module::registry::ModuleDecoderRegistry; use fedimint_core::PeerId; use fedimint_lnv2_common::gateway_api::PaymentFee; use serde_json::json; + use crate::db::{FederationMetaKey, FederationMetaKeyPrefix, FederationMetaV1}; use crate::multimint::{ - aggregate_recovery_progress, gross_invoice_for_contract, recovery_module_for_kind, - Multimint, RecoveryModule, MAX_GATEWAY_PPM, + aggregate_recovery_progress, gross_invoice_for_contract, migrate_federation_meta_v3, + recovery_module_for_kind, FederationSelector, Guardian, Multimint, RecoveryModule, + MAX_GATEWAY_PPM, }; + #[tokio::test] + async fn migration_v3_re_encodes_old_entries_and_drops_the_rest() { + let db = Database::new(MemDatabase::new(), ModuleDecoderRegistry::default()); + let key = FederationMetaKey { + federation_id: FederationId::dummy(), + }; + let old = FederationMetaV1 { + picture: Some("https://example.com/icon.png".to_string()), + welcome: Some("welcome".to_string()), + guardians: vec![Guardian { + peer_id: 0, + name: "alpha".to_string(), + version: Some("0.12.0".to_string()), + }], + selector: FederationSelector { + federation_name: "Old Fed".to_string(), + federation_id: FederationId::dummy(), + network: Some("bitcoin".to_string()), + }, + last_updated: 42, + recurringd_api: Some("https://recurringd.example.com/".to_string()), + lnaddress_api: None, + }; + // An entry in no known layout, under the same prefix. + let mut junk_key = FederationMetaKeyPrefix.to_bytes(); + junk_key.push(0xff); + + let mut dbtx = db.begin_transaction().await; + dbtx.raw_insert_bytes(&key.to_bytes(), &old.consensus_encode_to_vec()) + .await + .expect("insert"); + dbtx.raw_insert_bytes(&junk_key, b"not a federation meta") + .await + .expect("insert"); + dbtx.commit_tx().await; + + let mut dbtx = db.begin_transaction().await; + assert_eq!(migrate_federation_meta_v3(&mut dbtx).await, (1, 1)); + dbtx.commit_tx().await; + + let mut dbtx = db.begin_transaction_nc().await; + let meta = dbtx + .get_value(&key) + .await + .expect("the re-encoded entry reads with the derived decoder"); + assert_eq!(meta.picture, old.picture); + assert_eq!(meta.welcome, old.welcome); + assert_eq!(meta.guardians, old.guardians); + assert_eq!(meta.selector, old.selector); + assert_eq!(meta.last_updated, old.last_updated); + assert_eq!(meta.recurringd_api, old.recurringd_api); + assert_eq!(meta.lnaddress_api, old.lnaddress_api); + assert_eq!(meta.expiry_timestamp, None); + assert_eq!(meta.successor_invite, None); + assert!(dbtx.raw_get_bytes(&junk_key).await.expect("read").is_none()); + + // Entries already in the current layout are left as they are. + let mut dbtx = db.begin_transaction().await; + assert_eq!(migrate_federation_meta_v3(&mut dbtx).await, (0, 0)); + } + #[test] fn expiry_timestamp_accepts_number_and_string() { // The guardian dashboard writes the timestamp as a string while the From d75d449836c155e97b9803e1429806bbb91869b4 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Tue, 15 Sep 2026 09:30:06 -0500 Subject: [PATCH 03/17] feat: federation expiration screen --- lib/l10n/app_en.arb | 19 +- lib/l10n/app_es.arb | 13 +- lib/ln_address.dart | 20 +- lib/screens/dashboard.dart | 66 +++++- lib/screens/federation_expiry_screen.dart | 271 ++++++++++++++------- lib/screens/federation_info_screen.dart | 178 +------------- lib/widgets/leave_federation_dialog.dart | 182 ++++++++++++++ test/federation_expiry_banner_test.dart | 154 ++++++++++++ test/federation_expiry_screen_test.dart | 275 ++++++++++++++++++++++ 9 files changed, 900 insertions(+), 278 deletions(-) create mode 100644 lib/widgets/leave_federation_dialog.dart create mode 100644 test/federation_expiry_banner_test.dart create mode 100644 test/federation_expiry_screen_test.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d4c76f5d..6898dabe 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2217,9 +2217,6 @@ "federationExpiryWhatToDo": "What to do", "@federationExpiryWhatToDo": {}, - "federationExpiryStepReceivesOff": "Stop receiving into this federation. Share invoices and addresses from another federation instead.", - "@federationExpiryStepReceivesOff": {}, - "federationExpiryStepRemoveLightningAddress": "Remove your Lightning Address {address}. It is registered with this federation alone, so it keeps paying in here until it is removed. Setting one up on another federation does not replace it.", "@federationExpiryStepRemoveLightningAddress": { "placeholders": { @@ -2229,17 +2226,23 @@ } }, - "federationExpiryStepMoveFunds": "Move your balance out, for example with a Lightning payment to another wallet or federation.", + "federationExpiryStepMoveFunds": "Move your balance out of this federation. Sending it on-chain to a wallet you control keeps it safe whatever happens here.", "@federationExpiryStepMoveFunds": {}, - "federationExpiryStepJoinAnother": "Join another federation so you can keep using the app.", + "federationExpiryStepJoinAnother": "Optionally, join another federation so you can keep using the app.", "@federationExpiryStepJoinAnother": {}, - "federationExpiryStepJoinSuccessor": "Join the successor federation the guardians recommend, then move your balance there.", + "federationExpiryStepJoinSuccessor": "Optionally, join the successor federation the guardians recommend and move your balance there.", "@federationExpiryStepJoinSuccessor": {}, - "federationExpiryMoveFunds": "Move funds", - "@federationExpiryMoveFunds": {}, + "federationExpiryStepLeave": "Leave this federation once your balance is out and your Lightning Address is removed.", + "@federationExpiryStepLeave": {}, + + "federationExpirySendOnchain": "Send on-chain", + "@federationExpirySendOnchain": {}, + + "federationExpiryManageLightningAddress": "Manage Lightning Address", + "@federationExpiryManageLightningAddress": {}, "federationExpiryFindFederation": "Find a federation", "@federationExpiryFindFederation": {}, diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index ebdf2f2e..28ad5f84 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -647,17 +647,18 @@ "federationExpiryWhatToDo": "Qué hacer", - "federationExpiryStepReceivesOff": "Deja de recibir en esta federación. Comparte facturas y direcciones de otra federación en su lugar.", - "federationExpiryStepRemoveLightningAddress": "Elimina tu Lightning Address {address}. Está registrada solo en esta federación, así que seguirá pagando aquí hasta que la elimines. Configurar una en otra federación no la reemplaza.", + "federationExpiryStepRemoveLightningAddress": "Elimina tu Dirección Lightning {address}. Está registrada solo en esta federación, así que seguirá pagando aquí hasta que la elimines. Configurar una en otra federación no la reemplaza.", - "federationExpiryStepMoveFunds": "Saca tu saldo, por ejemplo con un pago Lightning a otra billetera o federación.", + "federationExpiryStepMoveFunds": "Saca tu saldo de esta federación. Enviarlo on-chain a una billetera que controles lo mantiene a salvo pase lo que pase aquí.", - "federationExpiryStepJoinAnother": "Únete a otra federación para seguir usando la app.", + "federationExpiryStepJoinAnother": "Opcionalmente, únete a otra federación para seguir usando la app.", - "federationExpiryStepJoinSuccessor": "Únete a la federación sucesora que recomiendan los guardianes y luego mueve tu saldo allí.", + "federationExpiryStepJoinSuccessor": "Opcionalmente, únete a la federación sucesora que recomiendan los guardianes y mueve tu saldo allí.", - "federationExpiryMoveFunds": "Mover fondos", + "federationExpiryStepLeave": "Abandona esta federación cuando hayas sacado tu saldo y eliminado tu Dirección Lightning.", + "federationExpirySendOnchain": "Enviar on-chain", + "federationExpiryManageLightningAddress": "Gestionar Dirección Lightning", "federationExpiryFindFederation": "Buscar una federación", diff --git a/lib/ln_address.dart b/lib/ln_address.dart index bf4c0411..23032e5f 100644 --- a/lib/ln_address.dart +++ b/lib/ln_address.dart @@ -17,10 +17,15 @@ class LightningAddressScreen extends StatefulWidget { final void Function(FederationSelector fed, bool recovering) onLnAddressChanged; + /// Federation to open on, as its id string, when the caller has one in + /// mind. Otherwise the first federation with an address is selected. + final String? initialFederationId; + const LightningAddressScreen({ super.key, required this.federations, required this.onLnAddressChanged, + this.initialFederationId, }); @override @@ -98,7 +103,20 @@ class _LightningAddressScreenState extends State { _usernameController.addListener(_onUsernameChanged); await _updateDomains(); - // Set the selected federation to the first federation + // The caller's federation, if it named one the dropdown can show. + final wanted = widget.initialFederationId; + if (wanted != null) { + for (final (fed, recovering) in widget.federations) { + if (recovering) continue; + final id = await federationIdToString(federationId: fed.federationId); + if (id == wanted) { + await _onFederationSet(fed); + return; + } + } + } + + // Otherwise the first federation that already has an address. if (widget.federations.isNotEmpty) { for (final fed in widget.federations) { if (await _onFederationSet(fed.$1)) { diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 41c07ae0..8607f16f 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -10,6 +10,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:ecashapp/lib.dart'; +import 'package:ecashapp/ln_address.dart'; import 'package:ecashapp/multimint.dart'; import 'package:ecashapp/number_pad.dart'; import 'package:ecashapp/screens/lightning_send/recipient_entry.dart'; @@ -24,6 +25,7 @@ import 'package:ecashapp/screens/my_wallet_screen.dart'; import 'package:ecashapp/widgets/dashboard_balance.dart'; import 'package:ecashapp/widgets/empty_transactions.dart'; import 'package:ecashapp/widgets/federation_expiry_banner.dart'; +import 'package:ecashapp/widgets/leave_federation_dialog.dart'; import 'package:ecashapp/widgets/pending_deposit_item.dart'; import 'package:ecashapp/widgets/transaction_item.dart'; @@ -292,7 +294,6 @@ class _DashboardState extends State { void _openShutdownDetails() { final lnAddress = _lnAddressConfig; - final hasBalance = balanceMsats != null && balanceMsats! > BigInt.zero; Navigator.push( context, MaterialPageRoute( @@ -302,17 +303,76 @@ class _DashboardState extends State { expiryTimestamp: _expiryTimestamp, successorInvite: _successorInvite, balanceMsats: balanceMsats, - onJoin: widget.onJoin, - onMoveFunds: hasBalance ? _onSendPressed : null, lightningAddress: lnAddress != null ? '${lnAddress.username}@${lnAddress.domain}' : null, + loadBalance: () => balance(federationId: widget.fed.federationId), + loadLightningAddress: _lightningAddressString, + onSendOnchain: _openOnchainSend, + onOpenLightningAddress: _openLightningAddressScreen, + onJoin: widget.onJoin, + onLeaveFederation: _confirmLeaveFederation, + ), + ), + ).then((_) { + // The checklist may have moved the balance or dropped the address. + _loadBalance(); + _loadLightningAddress(); + _loadRecentTransactions(); + }); + } + + Future _lightningAddressString() async { + final config = await getLnAddressConfig( + federationId: widget.fed.federationId, + ); + return config == null ? null : '${config.username}@${config.domain}'; + } + + /// The on-chain send flow, pushed above whatever is showing so the user + /// returns to where they started once it is done. + Future _openOnchainSend() => Navigator.push( + context, + MaterialPageRoute( + builder: + (_) => NumberPad( + fed: widget.fed, + paymentType: PaymentType.onchain, + btcPrices: _btcPrices, + onWithdrawCompleted: null, + ), + ), + ); + + /// The Lightning Address screen with this federation already selected. The + /// screen pops itself after a change, and the caller re-reads the address + /// then, so no app-level refresh is needed here. + Future _openLightningAddressScreen() async { + final feds = await federations(); + final federationId = await federationIdToString( + federationId: widget.fed.federationId, + ); + if (!mounted) return; + await Navigator.push( + context, + MaterialPageRoute( + builder: + (_) => LightningAddressScreen( + federations: feds, + initialFederationId: federationId, + onLnAddressChanged: (_, _) {}, ), ), ); } + Future _confirmLeaveFederation() => showLeaveFederationDialog( + context, + fed: widget.fed, + onLeaveFederation: widget.onLeaveFederation, + ); + List _getModulesForPaymentType() { switch (_selectedPaymentType) { case PaymentType.lightning: diff --git a/lib/screens/federation_expiry_screen.dart b/lib/screens/federation_expiry_screen.dart index 3ba14a42..ade50eee 100644 --- a/lib/screens/federation_expiry_screen.dart +++ b/lib/screens/federation_expiry_screen.dart @@ -35,12 +35,14 @@ String formatTimeUntilExpiry( return l10n.federationExpiryInMinutes(remaining.inMinutes); } -/// Explains a guardian-announced shutdown and what the user has to do about it. +/// Explains a guardian-announced shutdown and walks the user out of the +/// federation: move the balance, drop the Lightning Address, optionally join +/// the successor, leave. Each step links to the flow that does it, and steps +/// that no longer apply fall off the list. /// -/// Reached from the dashboard's expiry banner. Everything here is read from the -/// federation meta the caller already has, so the screen never blocks on a -/// network call: a user opening it because their money is at stake should not -/// meet a spinner. +/// Reached from the dashboard's expiry banner. The facts shown come from the +/// caller, so the screen opens without a network call; once a step's flow +/// returns, the balance and address are re-read through the loaders. class FederationExpiryScreen extends StatefulWidget { final String federationName; @@ -52,24 +54,29 @@ class FederationExpiryScreen extends StatefulWidget { /// when they only published a date. final String? successorInvite; - /// Current balance, so the user can see what still has to be moved without - /// navigating back. Null while the dashboard is still loading it. + /// Balance and Lightning Address (`user@domain`) as the dashboard last saw + /// them. The screen starts from these and refreshes through [loadBalance] + /// and [loadLightningAddress] after each step. final BigInt? balanceMsats; + final String? lightningAddress; + final Future Function() loadBalance; + final Future Function() loadLightningAddress; - /// Selects a freshly joined federation. Threaded down from the app root - /// because only the root can change which federation is selected. - final void Function(FederationSelector fed, bool recovering) onJoin; + /// Opens the on-chain send flow for this federation, completing once the + /// user is back here. + final Future Function() onSendOnchain; - /// Pops back to the dashboard and starts a send. Null when there is nothing - /// to move. - final VoidCallback? onMoveFunds; + /// Opens the Lightning Address screen with this federation selected, + /// completing once the user is back here. + final Future Function() onOpenLightningAddress; - /// The Lightning Address registered against this federation, if any, as - /// `user@domain`. Registrations are per federation and live on the address - /// server, so it keeps paying in here after the shutdown is announced and - /// setting one up elsewhere does not retire it. Removing it gets its own - /// step. - final String? lightningAddress; + /// Selects a freshly joined federation. Threaded from the app root because + /// only the root can change which federation is selected. + final void Function(FederationSelector fed, bool recovering) onJoin; + + /// Confirms and leaves this federation. Supplied by the dashboard, which + /// has the federation id and the app root's callback this needs. + final Future Function() onLeaveFederation; const FederationExpiryScreen({ super.key, @@ -77,9 +84,13 @@ class FederationExpiryScreen extends StatefulWidget { required this.expiryTimestamp, required this.successorInvite, required this.balanceMsats, + required this.lightningAddress, + required this.loadBalance, + required this.loadLightningAddress, + required this.onSendOnchain, + required this.onOpenLightningAddress, required this.onJoin, - this.onMoveFunds, - this.lightningAddress, + required this.onLeaveFederation, }); @override @@ -87,25 +98,49 @@ class FederationExpiryScreen extends StatefulWidget { } class _FederationExpiryScreenState extends State { - // Guards against pushing the preview route twice while one is already opening. - bool _isOpeningPreview = false; + late BigInt? _balanceMsats = widget.balanceMsats; + late String? _lightningAddress = widget.lightningAddress; - void _onFindFederation() { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => Discover(onJoin: widget.onJoin, showAppBar: true), - ), - ); + /// One step's flow at a time; every link is disabled while one runs. + bool _busy = false; + + /// Runs a step's flow, then re-reads what it may have changed so the list + /// reflects the new state when the user lands back here. + Future _run(Future Function() flow) async { + if (_busy) return; + setState(() => _busy = true); + try { + await flow(); + } finally { + if (mounted) setState(() => _busy = false); + } + if (mounted) await _refresh(); } - /// Opens the successor's preview so the user sees its guardians before - /// committing, then hands the joined federation to the app root and returns - /// to the dashboard, which by then shows the successor. - Future _onJoinSuccessor() async { - if (_isOpeningPreview) return; - setState(() => _isOpeningPreview = true); + Future _refresh() async { + var balance = _balanceMsats; + var address = _lightningAddress; + try { + balance = await widget.loadBalance(); + } catch (e) { + AppLogger.instance.warn('Could not refresh balance: $e'); + } + try { + address = await widget.loadLightningAddress(); + } catch (e) { + AppLogger.instance.warn('Could not refresh Lightning Address: $e'); + } + if (!mounted) return; + setState(() { + _balanceMsats = balance; + _lightningAddress = address; + }); + } + /// Previews the successor so the user sees its guardians before committing, + /// then hands the joined federation to the app root and returns to the + /// dashboard, which by then shows the successor. + Future _joinSuccessor() async { final joined = await Navigator.push<(FederationSelector, bool)>( context, MaterialPageRoute( @@ -117,10 +152,7 @@ class _FederationExpiryScreenState extends State { ), ), ); - - if (!mounted) return; - setState(() => _isOpeningPreview = false); - if (joined == null) return; + if (!mounted || joined == null) return; final (fed, recovering) = joined; final message = context.l10n.joinedFederation(fed.federationName); @@ -134,6 +166,13 @@ class _FederationExpiryScreenState extends State { ); } + Future _findFederation() => Navigator.push( + context, + MaterialPageRoute( + builder: (_) => Discover(onJoin: widget.onJoin, showAppBar: true), + ), + ); + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -144,20 +183,50 @@ class _FederationExpiryScreenState extends State { expiryTimestamp != null ? expiryDateTime(expiryTimestamp) : null; final hasExpired = expiry != null && expiry.isBefore(DateTime.now()); final hasSuccessor = widget.successorInvite != null; + final hasBalance = _balanceMsats != null && _balanceMsats! > BigInt.zero; + final lightningAddress = _lightningAddress; final bitcoinDisplay = context.select( (prefs) => prefs.bitcoinDisplay, ); - final steps = [ - l10n.federationExpiryStepReceivesOff, - if (widget.lightningAddress != null) - l10n.federationExpiryStepRemoveLightningAddress( - widget.lightningAddress!, + final steps = <_StepSpec>[ + if (hasBalance) + _StepSpec( + text: l10n.federationExpiryStepMoveFunds, + action: l10n.federationExpirySendOnchain, + icon: Icons.upload, + onTap: () => _run(widget.onSendOnchain), ), - l10n.federationExpiryStepMoveFunds, - hasSuccessor - ? l10n.federationExpiryStepJoinSuccessor - : l10n.federationExpiryStepJoinAnother, + if (lightningAddress != null) + _StepSpec( + text: l10n.federationExpiryStepRemoveLightningAddress( + lightningAddress, + ), + action: l10n.federationExpiryManageLightningAddress, + icon: Icons.flash_on, + onTap: () => _run(widget.onOpenLightningAddress), + ), + if (hasSuccessor) + _StepSpec( + text: l10n.federationExpiryStepJoinSuccessor, + action: l10n.federationExpiryJoinSuccessor, + icon: Icons.login, + onTap: () => _run(_joinSuccessor), + ) + else + _StepSpec( + text: l10n.federationExpiryStepJoinAnother, + action: l10n.federationExpiryFindFederation, + icon: Icons.search, + onTap: () => _run(_findFederation), + ), + _StepSpec( + text: l10n.federationExpiryStepLeave, + action: l10n.leaveFederation, + icon: Icons.logout, + onTap: () => _run(widget.onLeaveFederation), + destructive: true, + ), ]; final facts = <(String, String)>[ @@ -175,7 +244,7 @@ class _FederationExpiryScreenState extends State { ), ( l10n.federationExpiryYourBalance, - formatBalance(widget.balanceMsats, false, bitcoinDisplay), + formatBalance(_balanceMsats, false, bitcoinDisplay), ), ]; @@ -225,40 +294,14 @@ class _FederationExpiryScreenState extends State { ), ), const SizedBox(height: 12), - for (final (index, text) in steps.indexed) - _Step(number: index + 1, text: text), - const SizedBox(height: 28), - if (widget.onMoveFunds != null) ...[ - OutlinedButton.icon( - onPressed: () { - Navigator.of(context).pop(); - widget.onMoveFunds!(); - }, - icon: const Icon(Icons.upload), - label: Text(l10n.federationExpiryMoveFunds), - style: OutlinedButton.styleFrom( - minimumSize: const Size.fromHeight(48), - ), - ), - const SizedBox(height: 12), - ], - if (hasSuccessor) - FilledButton.icon( - onPressed: _isOpeningPreview ? null : _onJoinSuccessor, - icon: const Icon(Icons.login), - label: Text(l10n.federationExpiryJoinSuccessor), - style: FilledButton.styleFrom( - minimumSize: const Size.fromHeight(48), - ), - ) - else - FilledButton.icon( - onPressed: _onFindFederation, - icon: const Icon(Icons.search), - label: Text(l10n.federationExpiryFindFederation), - style: FilledButton.styleFrom( - minimumSize: const Size.fromHeight(48), - ), + for (final (index, step) in steps.indexed) + _Step( + number: index + 1, + text: step.text, + actionLabel: step.action, + icon: step.icon, + destructive: step.destructive, + onPressed: _busy ? null : step.onTap, ), ], ), @@ -267,6 +310,25 @@ class _FederationExpiryScreenState extends State { } } +/// One checklist entry: what to do, and the link that does it. +class _StepSpec { + final String text; + final String action; + final IconData icon; + final Future Function() onTap; + + /// Rendered in the error colour, for the step that cannot be undone. + final bool destructive; + + const _StepSpec({ + required this.text, + required this.action, + required this.icon, + required this.onTap, + this.destructive = false, + }); +} + /// The headline facts, as label/value rows on one surface. class _FactsCard extends StatelessWidget { final List<(String, String)> rows; @@ -321,12 +383,26 @@ class _FactsCard extends StatelessWidget { class _Step extends StatelessWidget { final int number; final String text; + final String actionLabel; + final IconData icon; + final bool destructive; - const _Step({required this.number, required this.text}); + /// Null while another step's flow is running, which disables the link. + final VoidCallback? onPressed; + + const _Step({ + required this.number, + required this.text, + required this.actionLabel, + required this.icon, + required this.destructive, + required this.onPressed, + }); @override Widget build(BuildContext context) { final theme = Theme.of(context); + final accent = destructive ? theme.colorScheme.error : null; return Padding( padding: const EdgeInsets.only(bottom: 14), child: Row( @@ -350,9 +426,28 @@ class _Step extends StatelessWidget { ), const SizedBox(width: 12), Expanded( - child: Text( - text, - style: theme.textTheme.bodyMedium?.copyWith(height: 1.4), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + text, + style: theme.textTheme.bodyMedium?.copyWith(height: 1.4), + ), + const SizedBox(height: 4), + Align( + alignment: Alignment.centerLeft, + child: TextButton.icon( + onPressed: onPressed, + icon: Icon(icon, size: 18), + label: Text(actionLabel), + style: TextButton.styleFrom( + foregroundColor: accent, + padding: const EdgeInsets.symmetric(horizontal: 8), + visualDensity: VisualDensity.compact, + ), + ), + ), + ], ), ), ], diff --git a/lib/screens/federation_info_screen.dart b/lib/screens/federation_info_screen.dart index a6e6ed50..8930b2ee 100644 --- a/lib/screens/federation_info_screen.dart +++ b/lib/screens/federation_info_screen.dart @@ -6,13 +6,12 @@ import 'package:ecashapp/widgets/federation_utxo_list.dart'; import 'package:ecashapp/lib.dart'; import 'package:ecashapp/multimint.dart'; import 'package:ecashapp/nwc.dart'; -import 'package:ecashapp/providers/preferences_provider.dart'; import 'package:ecashapp/toast.dart'; import 'package:ecashapp/utils.dart'; import 'package:ecashapp/widgets/gateways.dart'; +import 'package:ecashapp/widgets/leave_federation_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:provider/provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; enum _InfoSection { guardians, utxos, gateways } @@ -165,176 +164,11 @@ class _FederationInfoScreenState extends State { // --- Leave federation logic --- - Future _onLeavePressed() async { - final screenNavigator = Navigator.of(context); - final bitcoinDisplay = context.read().bitcoinDisplay; - - // Fetch the balance up front so we can warn the user before they leave a - // federation that still holds funds. Failures here are non-fatal — we just - // fall back to the plain confirmation dialog. - BigInt? balanceMsats; - try { - balanceMsats = await balance(federationId: _fed!.federationId); - } catch (e) { - AppLogger.instance.warn( - "Could not fetch balance for leave confirmation: $e", - ); - } - if (!mounted) return; - - await showDialog( - context: context, - builder: (dialogContext) { - bool isLeaving = false; - - return StatefulBuilder( - builder: (sbContext, setState) { - final theme = Theme.of(sbContext); - final hasBalance = - balanceMsats != null && balanceMsats > BigInt.zero; - - return AlertDialog( - // Keep the dialog from stretching across wide screens (tablet, - // desktop, foldable) — a modal that spans the viewport reads as - // a full-screen takeover rather than a focused confirmation. - insetPadding: const EdgeInsets.symmetric( - horizontal: 40, - vertical: 24, - ), - title: Row( - children: [ - Icon( - Icons.warning_amber_rounded, - color: theme.colorScheme.error, - ), - const SizedBox(width: 12), - Expanded(child: Text(sbContext.l10n.leaveFederation)), - ], - ), - content: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 420), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(sbContext.l10n.leaveFederationConfirm), - if (hasBalance) ...[ - const SizedBox(height: 20), - // Compact "balance at risk" row — the amount is what - // matters, so lead with it. Kept intentionally quiet - // (no filled background) so it feels like a fact about - // the federation, not a second alarm. - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Icon( - Icons.account_balance_wallet_outlined, - color: theme.colorScheme.onSurfaceVariant, - size: 18, - ), - const SizedBox(width: 10), - Text( - sbContext.l10n.currentBalance, - style: theme.textTheme.bodyMedium?.copyWith( - color: theme.colorScheme.onSurfaceVariant, - ), - ), - const Spacer(), - Text( - formatBalance(balanceMsats, false, bitcoinDisplay), - style: theme.textTheme.bodyLarge?.copyWith( - color: theme.colorScheme.error, - fontWeight: FontWeight.w600, - fontFeatures: const [ - FontFeature.tabularFigures(), - ], - ), - ), - ], - ), - ], - ], - ), - ), - actions: [ - TextButton( - onPressed: - isLeaving - ? null - : () => Navigator.of(dialogContext).pop(), - child: Text(sbContext.l10n.cancel), - ), - TextButton( - style: TextButton.styleFrom( - foregroundColor: theme.colorScheme.error, - ), - onPressed: - isLeaving - ? null - : () async { - setState(() { - isLeaving = true; - }); - - try { - await leaveFederation( - federationId: _fed!.federationId, - ); - await stopNwcServiceForFederation( - _fed!.federationId, - ); - try { - backupInviteCodes(); - } catch (e) { - AppLogger.instance.error( - "Could not backup Nostr invite codes: $e", - ); - } - widget.onLeaveFederation(); - - if (dialogContext.mounted) { - Navigator.of(dialogContext).pop(); - } - screenNavigator.popUntil( - (route) => route.isFirst, - ); - } catch (e) { - AppLogger.instance.error( - "Error leaving federation: $e", - ); - ToastService().show( - message: sbContext.l10n.leaveFederationError, - duration: const Duration(seconds: 5), - onTap: () {}, - icon: const Icon(Icons.error), - ); - if (dialogContext.mounted) { - Navigator.of(dialogContext).pop(); - } - } finally { - if (mounted) { - setState(() { - isLeaving = false; - }); - } - } - }, - child: - isLeaving - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : Text(sbContext.l10n.leaveFederation), - ), - ], - ); - }, - ); - }, - ); - } + Future _onLeavePressed() => showLeaveFederationDialog( + context, + fed: _fed!, + onLeaveFederation: widget.onLeaveFederation, + ); // --- Guardian dashboard login logic --- diff --git a/lib/widgets/leave_federation_dialog.dart b/lib/widgets/leave_federation_dialog.dart new file mode 100644 index 00000000..2e5aee72 --- /dev/null +++ b/lib/widgets/leave_federation_dialog.dart @@ -0,0 +1,182 @@ +import 'package:ecashapp/extensions/build_context_l10n.dart'; +import 'package:ecashapp/lib.dart'; +import 'package:ecashapp/multimint.dart'; +import 'package:ecashapp/nwc.dart'; +import 'package:ecashapp/providers/preferences_provider.dart'; +import 'package:ecashapp/toast.dart'; +import 'package:ecashapp/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +/// Confirms leaving [fed], warning about any balance still held there, then +/// leaves: the client is torn down, the federation's NWC listener stopped, the +/// invite-code backup refreshed and [onLeaveFederation] told. Every route above +/// the first is popped afterwards, since the screens beneath belonged to a +/// federation that no longer exists. +/// +/// Shared by the federation info screen and the shutdown checklist. +Future showLeaveFederationDialog( + BuildContext context, { + required FederationSelector fed, + required VoidCallback onLeaveFederation, +}) async { + final screenNavigator = Navigator.of(context); + final bitcoinDisplay = context.read().bitcoinDisplay; + + // Fetch the balance up front so we can warn the user before they leave a + // federation that still holds funds. Failures here are non-fatal — we just + // fall back to the plain confirmation dialog. + BigInt? balanceMsats; + try { + balanceMsats = await balance(federationId: fed.federationId); + } catch (e) { + AppLogger.instance.warn( + "Could not fetch balance for leave confirmation: $e", + ); + } + if (!context.mounted) return; + + await showDialog( + context: context, + builder: (dialogContext) { + bool isLeaving = false; + + return StatefulBuilder( + builder: (sbContext, setState) { + final theme = Theme.of(sbContext); + final hasBalance = balanceMsats != null && balanceMsats > BigInt.zero; + + return AlertDialog( + // Keep the dialog from stretching across wide screens (tablet, + // desktop, foldable) — a modal that spans the viewport reads as + // a full-screen takeover rather than a focused confirmation. + insetPadding: const EdgeInsets.symmetric( + horizontal: 40, + vertical: 24, + ), + title: Row( + children: [ + Icon( + Icons.warning_amber_rounded, + color: theme.colorScheme.error, + ), + const SizedBox(width: 12), + Expanded(child: Text(sbContext.l10n.leaveFederation)), + ], + ), + content: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 420), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(sbContext.l10n.leaveFederationConfirm), + if (hasBalance) ...[ + const SizedBox(height: 20), + // Compact "balance at risk" row — the amount is what + // matters, so lead with it. Kept intentionally quiet + // (no filled background) so it feels like a fact about + // the federation, not a second alarm. + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.account_balance_wallet_outlined, + color: theme.colorScheme.onSurfaceVariant, + size: 18, + ), + const SizedBox(width: 10), + Text( + sbContext.l10n.currentBalance, + style: theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.onSurfaceVariant, + ), + ), + const Spacer(), + Text( + formatBalance(balanceMsats, false, bitcoinDisplay), + style: theme.textTheme.bodyLarge?.copyWith( + color: theme.colorScheme.error, + fontWeight: FontWeight.w600, + fontFeatures: const [FontFeature.tabularFigures()], + ), + ), + ], + ), + ], + ], + ), + ), + actions: [ + TextButton( + onPressed: + isLeaving ? null : () => Navigator.of(dialogContext).pop(), + child: Text(sbContext.l10n.cancel), + ), + TextButton( + style: TextButton.styleFrom( + foregroundColor: theme.colorScheme.error, + ), + onPressed: + isLeaving + ? null + : () async { + setState(() { + isLeaving = true; + }); + + try { + await leaveFederation( + federationId: fed.federationId, + ); + await stopNwcServiceForFederation(fed.federationId); + try { + backupInviteCodes(); + } catch (e) { + AppLogger.instance.error( + "Could not backup Nostr invite codes: $e", + ); + } + onLeaveFederation(); + + if (dialogContext.mounted) { + Navigator.of(dialogContext).pop(); + } + screenNavigator.popUntil((route) => route.isFirst); + } catch (e) { + AppLogger.instance.error( + "Error leaving federation: $e", + ); + ToastService().show( + message: sbContext.l10n.leaveFederationError, + duration: const Duration(seconds: 5), + onTap: () {}, + icon: const Icon(Icons.error), + ); + if (dialogContext.mounted) { + Navigator.of(dialogContext).pop(); + } + } finally { + if (sbContext.mounted) { + setState(() { + isLeaving = false; + }); + } + } + }, + child: + isLeaving + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : Text(sbContext.l10n.leaveFederation), + ), + ], + ); + }, + ); + }, + ); +} diff --git a/test/federation_expiry_banner_test.dart b/test/federation_expiry_banner_test.dart new file mode 100644 index 00000000..d62d406b --- /dev/null +++ b/test/federation_expiry_banner_test.dart @@ -0,0 +1,154 @@ +import 'package:ecashapp/generated/app_localizations.dart'; +import 'package:ecashapp/screens/federation_expiry_screen.dart'; +import 'package:ecashapp/theme.dart'; +import 'package:ecashapp/widgets/federation_expiry_banner.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:intl/intl.dart'; + +/// Hosts [child] under the real app theme and localizations at [textScale], +/// top-aligned so the measured height is the banner's own, not the screen's. +Widget harness(Widget child, {double textScale = 1.0}) { + return MaterialApp( + theme: cypherpunkNinjaTheme, + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: const [Locale('en'), Locale('es')], + home: Builder( + builder: + (context) => MediaQuery( + data: MediaQuery.of( + context, + ).copyWith(textScaler: TextScaler.linear(textScale)), + child: Scaffold( + body: Align(alignment: Alignment.topCenter, child: child), + ), + ), + ), + ); +} + +BigInt unixSeconds(DateTime t) => BigInt.from(t.millisecondsSinceEpoch ~/ 1000); + +/// The date exactly as the banner prints it, so the assertions do not depend +/// on the test's locale settings agreeing with a hand-written string. +String bannerDate(BigInt unixSeconds) => + DateFormat.yMMMd().format(expiryDateTime(unixSeconds)); + +void main() { + final inAMonth = unixSeconds(DateTime.now().add(const Duration(days: 30))); + final lastWeek = unixSeconds( + DateTime.now().subtract(const Duration(days: 7)), + ); + + group('FederationExpiryBanner', () { + // The dashboard's pinned header declares this height before the banner is + // measured, so the two must agree at every font scale a user can pick, and + // neither text line may be squeezed to make that true. + for (final scale in [0.85, 1.0, 1.3, 2.0]) { + testWidgets('fills exactly the extent it declares at text scale $scale', ( + tester, + ) async { + await tester.pumpWidget( + harness( + FederationExpiryBanner(expiryTimestamp: inAMonth, onTap: () {}), + textScale: scale, + ), + ); + expect(tester.takeException(), isNull); + + final banner = find.byType(FederationExpiryBanner); + final context = tester.element(banner); + expect( + tester.getSize(banner).height, + moreOrLessEquals( + federationExpiryBannerExtent(context), + epsilon: 0.01, + ), + ); + + final texts = find.descendant(of: banner, matching: find.byType(Text)); + expect(texts, findsNWidgets(2)); + for (final text in texts.evaluate()) { + final paragraph = tester.renderObject( + find.byWidget(text.widget), + ); + expect( + paragraph.size.height, + greaterThanOrEqualTo(paragraph.textSize.height - 0.01), + reason: 'a line was clipped to fit the declared extent', + ); + } + }); + } + + testWidgets('names the closing date while it is still ahead', ( + tester, + ) async { + await tester.pumpWidget( + harness( + FederationExpiryBanner(expiryTimestamp: inAMonth, onTap: () {}), + ), + ); + final l10n = AppLocalizations.of( + tester.element(find.byType(FederationExpiryBanner)), + ); + expect( + find.text(l10n.federationExpiryBannerSubtitle(bannerDate(inAMonth))), + findsOneWidget, + ); + }); + + testWidgets('switches to past tense once the date has gone by', ( + tester, + ) async { + await tester.pumpWidget( + harness( + FederationExpiryBanner(expiryTimestamp: lastWeek, onTap: () {}), + ), + ); + final l10n = AppLocalizations.of( + tester.element(find.byType(FederationExpiryBanner)), + ); + expect( + find.text( + l10n.federationExpiryBannerSubtitlePast(bannerDate(lastWeek)), + ), + findsOneWidget, + ); + }); + + testWidgets('explains a successor when there is no date', (tester) async { + await tester.pumpWidget( + harness(FederationExpiryBanner(expiryTimestamp: null, onTap: () {})), + ); + final l10n = AppLocalizations.of( + tester.element(find.byType(FederationExpiryBanner)), + ); + expect( + find.text(l10n.federationExpiryBannerSubtitleSuccessor), + findsOneWidget, + ); + }); + + testWidgets('is tappable across its whole surface', (tester) async { + var taps = 0; + await tester.pumpWidget( + harness( + FederationExpiryBanner( + expiryTimestamp: inAMonth, + onTap: () => taps++, + ), + ), + ); + await tester.tap(find.byType(FederationExpiryBanner)); + expect(taps, 1); + }); + }); +} diff --git a/test/federation_expiry_screen_test.dart b/test/federation_expiry_screen_test.dart new file mode 100644 index 00000000..a48f4e26 --- /dev/null +++ b/test/federation_expiry_screen_test.dart @@ -0,0 +1,275 @@ +import 'package:ecashapp/generated/app_localizations.dart'; +import 'package:ecashapp/providers/preferences_provider.dart'; +import 'package:ecashapp/screens/federation_expiry_screen.dart'; +import 'package:ecashapp/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:provider/provider.dart'; + +BigInt unixSeconds(DateTime t) => BigInt.from(t.millisecondsSinceEpoch ~/ 1000); + +/// Hosts the screen under the app theme, localizations and the preferences +/// provider its balance row reads. The provider's Rust-backed load fails under +/// `flutter test` and falls back to defaults, which is all the row needs. +Widget harness(Widget child) { + return ChangeNotifierProvider( + create: (_) => PreferencesProvider(), + child: MaterialApp( + theme: cypherpunkNinjaTheme, + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: const [Locale('en'), Locale('es')], + home: child, + ), + ); +} + +/// Records which of the screen's flows were invoked, and lets a test decide +/// what the loaders report once a flow has run. +class Flows { + int sendOnchain = 0; + int openLightningAddress = 0; + int leave = 0; + BigInt? balanceAfter; + String? addressAfter; +} + +void main() { + final en = lookupAppLocalizations(const Locale('en')); + final now = DateTime(2026, 9, 14, 12); + + group('formatTimeUntilExpiry', () { + test('uses the largest unit that still gives a whole number', () { + String at(Duration ahead) => + formatTimeUntilExpiry(en, now.add(ahead), now: now); + + expect(at(const Duration(days: 3, hours: 5)), '3 days'); + expect(at(const Duration(days: 1)), '1 day'); + expect(at(const Duration(hours: 23, minutes: 59)), '23 hours'); + expect(at(const Duration(hours: 1)), '1 hour'); + expect(at(const Duration(minutes: 45)), '45 minutes'); + expect(at(const Duration(minutes: 1)), '1 minute'); + }); + + test('reports a passed deadline rather than a negative count', () { + expect( + formatTimeUntilExpiry( + en, + now.subtract(const Duration(hours: 2)), + now: now, + ), + en.federationExpiryPassed, + ); + }); + }); + + group('FederationExpiryScreen', () { + final inAMonth = unixSeconds(DateTime.now().add(const Duration(days: 30))); + final lastWeek = unixSeconds( + DateTime.now().subtract(const Duration(days: 7)), + ); + const address = 'alice@example.com'; + + Future pumpScreen( + WidgetTester tester, { + BigInt? expiryTimestamp, + String? successorInvite, + BigInt? balanceMsats, + String? lightningAddress, + }) async { + // Tall enough that the whole list, links included, is laid out. + tester.view.physicalSize = const Size(800, 3000); + tester.view.devicePixelRatio = 1.0; + addTearDown(tester.view.resetPhysicalSize); + addTearDown(tester.view.resetDevicePixelRatio); + + final flows = + Flows() + ..balanceAfter = balanceMsats + ..addressAfter = lightningAddress; + await tester.pumpWidget( + harness( + FederationExpiryScreen( + // A fresh state per pump, as a fresh push gives it in the app; + // otherwise a second pump updates the first screen in place. + key: UniqueKey(), + federationName: 'Old Fed', + expiryTimestamp: expiryTimestamp, + successorInvite: successorInvite, + balanceMsats: balanceMsats, + lightningAddress: lightningAddress, + loadBalance: () async => flows.balanceAfter, + loadLightningAddress: () async => flows.addressAfter, + onSendOnchain: () async => flows.sendOnchain++, + onOpenLightningAddress: () async => flows.openLightningAddress++, + onJoin: (_, _) {}, + onLeaveFederation: () async => flows.leave++, + ), + ), + ); + await tester.pump(); + return flows; + } + + double top(WidgetTester tester, String text) => + tester.getTopLeft(find.text(text)).dy; + + testWidgets('lists only the steps that still apply', (tester) async { + await pumpScreen(tester, expiryTimestamp: inAMonth); + expect(find.text(en.federationExpirySendOnchain), findsNothing); + expect( + find.text(en.federationExpiryManageLightningAddress), + findsNothing, + ); + expect(find.text(en.federationExpiryFindFederation), findsOneWidget); + expect(find.text(en.leaveFederation), findsOneWidget); + }); + + testWidgets('puts moving the balance first while there is one', ( + tester, + ) async { + await pumpScreen( + tester, + expiryTimestamp: inAMonth, + balanceMsats: BigInt.from(21_000), + lightningAddress: address, + ); + expect(find.text(en.federationExpiryStepMoveFunds), findsOneWidget); + expect( + top(tester, en.federationExpirySendOnchain), + lessThan(top(tester, en.federationExpiryManageLightningAddress)), + ); + + await pumpScreen( + tester, + expiryTimestamp: inAMonth, + balanceMsats: BigInt.zero, + ); + expect(find.text(en.federationExpirySendOnchain), findsNothing); + }); + + testWidgets( + 'links the Lightning Address step only while one is registered', + (tester) async { + await pumpScreen( + tester, + expiryTimestamp: inAMonth, + lightningAddress: address, + successorInvite: 'fed11successor', + ); + expect( + find.text(en.federationExpiryStepRemoveLightningAddress(address)), + findsOneWidget, + ); + expect( + top(tester, en.federationExpiryManageLightningAddress), + lessThan(top(tester, en.federationExpiryJoinSuccessor)), + ); + + await pumpScreen(tester, expiryTimestamp: inAMonth); + expect(find.textContaining(address), findsNothing); + }, + ); + + testWidgets('offers the successor when named, discovery otherwise', ( + tester, + ) async { + await pumpScreen( + tester, + expiryTimestamp: inAMonth, + successorInvite: 'fed11successor', + ); + expect(find.text(en.federationExpiryStepJoinSuccessor), findsOneWidget); + expect(find.text(en.federationExpiryJoinSuccessor), findsOneWidget); + expect(find.text(en.federationExpiryFindFederation), findsNothing); + expect( + top(tester, en.federationExpiryJoinSuccessor), + lessThan(top(tester, en.leaveFederation)), + ); + + await pumpScreen(tester, expiryTimestamp: inAMonth); + expect(find.text(en.federationExpiryStepJoinAnother), findsOneWidget); + expect(find.text(en.federationExpiryFindFederation), findsOneWidget); + expect(find.text(en.federationExpiryJoinSuccessor), findsNothing); + }); + + testWidgets('sending on-chain runs the flow and re-reads the balance', ( + tester, + ) async { + final flows = await pumpScreen( + tester, + expiryTimestamp: inAMonth, + balanceMsats: BigInt.from(21_000), + ); + flows.balanceAfter = BigInt.zero; + + await tester.tap(find.text(en.federationExpirySendOnchain)); + await tester.pumpAndSettle(); + + expect(flows.sendOnchain, 1); + // Nothing left to move, so the step is gone and the balance row agrees. + expect(find.text(en.federationExpirySendOnchain), findsNothing); + expect(find.text(en.federationExpiryYourBalance), findsOneWidget); + }); + + testWidgets('managing the address runs the flow and re-reads it', ( + tester, + ) async { + final flows = await pumpScreen( + tester, + expiryTimestamp: inAMonth, + lightningAddress: address, + ); + flows.addressAfter = null; + + await tester.tap(find.text(en.federationExpiryManageLightningAddress)); + await tester.pumpAndSettle(); + + expect(flows.openLightningAddress, 1); + expect(find.textContaining(address), findsNothing); + }); + + testWidgets('leaving is handed to the caller', (tester) async { + final flows = await pumpScreen(tester, expiryTimestamp: inAMonth); + await tester.tap(find.text(en.leaveFederation)); + await tester.pumpAndSettle(); + expect(flows.leave, 1); + }); + + testWidgets('shows the date and time left for a future shutdown', ( + tester, + ) async { + await pumpScreen(tester, expiryTimestamp: inAMonth); + expect(find.text(en.federationExpiryHeadline('Old Fed')), findsOneWidget); + expect(find.text(en.federationExpiryClosesOn), findsOneWidget); + expect(find.text(en.federationExpiryTimeRemaining), findsOneWidget); + }); + + testWidgets('speaks in the past tense once the date has gone by', ( + tester, + ) async { + await pumpScreen(tester, expiryTimestamp: lastWeek); + expect( + find.text(en.federationExpiryHeadlinePast('Old Fed')), + findsOneWidget, + ); + expect(find.text(en.federationExpiryClosedOn), findsOneWidget); + expect(find.text(en.federationExpiryTimeRemaining), findsNothing); + }); + + testWidgets('omits the date rows when only a successor is set', ( + tester, + ) async { + await pumpScreen(tester, successorInvite: 'fed11successor'); + expect(find.text(en.federationExpiryHeadline('Old Fed')), findsOneWidget); + expect(find.text(en.federationExpiryClosesOn), findsNothing); + expect(find.text(en.federationExpiryTimeRemaining), findsNothing); + expect(find.text(en.federationExpiryYourBalance), findsOneWidget); + }); + }); +} From 559648290da62efd39e500bea5500ff460093592 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Tue, 15 Sep 2026 09:54:19 -0500 Subject: [PATCH 04/17] fix: walletv2 sweep --- lib/frb_generated.dart | 1074 ++++++++++++++------- lib/frb_generated.io.dart | 266 +++-- lib/frb_generated.web.dart | 242 +++-- lib/lib.dart | 2 +- lib/multimint.dart | 21 +- lib/onchain_send.dart | 13 +- lib/screens/federation_expiry_screen.dart | 5 +- rust/ecashapp/src/frb_generated.rs | 963 ++++++++++++------ rust/ecashapp/src/lib.rs | 4 +- rust/ecashapp/src/multimint.rs | 12 +- rust/ecashapp/src/wallet/mod.rs | 173 ++-- test/federation_expiry_screen_test.dart | 10 +- 12 files changed, 1889 insertions(+), 896 deletions(-) diff --git a/lib/frb_generated.dart b/lib/frb_generated.dart index f3c0ace4..3d57110c 100644 --- a/lib/frb_generated.dart +++ b/lib/frb_generated.dart @@ -69,7 +69,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.9.0'; @override - int get rustContentHash => 1834095429; + int get rustContentHash => 1847422546; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -287,6 +287,24 @@ abstract class RustLibApi extends BaseApi { required FederationId federationId, }); + BigInt crateMultimintMaxWithdrawQuoteAutoAccessorGetAmountSats({ + required MaxWithdrawQuote that, + }); + + WithdrawFeesResponse crateMultimintMaxWithdrawQuoteAutoAccessorGetFees({ + required MaxWithdrawQuote that, + }); + + void crateMultimintMaxWithdrawQuoteAutoAccessorSetAmountSats({ + required MaxWithdrawQuote that, + required BigInt amountSats, + }); + + void crateMultimintMaxWithdrawQuoteAutoAccessorSetFees({ + required MaxWithdrawQuote that, + required WithdrawFeesResponse fees, + }); + Future crateMultimintMultimintAckSeedPhrase({required Multimint that}); Future<(String, BigInt?)> crateMultimintMultimintAllocateDepositAddress({ @@ -436,7 +454,8 @@ abstract class RustLibApi extends BaseApi { required FederationId federationId, }); - Future crateMultimintMultimintGetMaxWithdrawableAmount({ + Future + crateMultimintMultimintGetMaxWithdrawableAmount({ required Multimint that, required FederationId federationId, required String address, @@ -1100,7 +1119,7 @@ abstract class RustLibApi extends BaseApi { required FederationId federationId, }); - Future crateGetMaxWithdrawableAmount({ + Future crateGetMaxWithdrawableAmount({ required FederationId federationId, required String address, }); @@ -1445,6 +1464,15 @@ abstract class RustLibApi extends BaseApi { CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_DatabasePtr; + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_EcashAppResultMaxWithdrawQuote; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuote; + + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuotePtr; + RustArcIncrementStrongCountFnType get rust_arc_increment_strong_count_EcashAppResultOobNotesWrapper; @@ -1490,15 +1518,6 @@ abstract class RustLibApi extends BaseApi { CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_EcashAppResultWithdrawFeesResponsePtr; - RustArcIncrementStrongCountFnType - get rust_arc_increment_strong_count_EcashAppResultU64; - - RustArcDecrementStrongCountFnType - get rust_arc_decrement_strong_count_EcashAppResultU64; - - CrossPlatformFinalizerArg - get rust_arc_decrement_strong_count_EcashAppResultU64Ptr; - RustArcIncrementStrongCountFnType get rust_arc_increment_strong_count_EventBusMultimintEvent; @@ -1570,6 +1589,15 @@ abstract class RustLibApi extends BaseApi { CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_LightningAddressKeyPtr; + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_MaxWithdrawQuote; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_MaxWithdrawQuote; + + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_MaxWithdrawQuotePtr; + RustArcIncrementStrongCountFnType get rust_arc_increment_strong_count_Multimint; @@ -3260,6 +3288,144 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { argNames: ["that", "federationId"], ); + @override + BigInt crateMultimintMaxWithdrawQuoteAutoAccessorGetAmountSats({ + required MaxWithdrawQuote that, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + that, + serializer, + ); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 47)!; + }, + codec: SseCodec( + decodeSuccessData: sse_decode_u_64, + decodeErrorData: null, + ), + constMeta: + kCrateMultimintMaxWithdrawQuoteAutoAccessorGetAmountSatsConstMeta, + argValues: [that], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintMaxWithdrawQuoteAutoAccessorGetAmountSatsConstMeta => + const TaskConstMeta( + debugName: "MaxWithdrawQuote_auto_accessor_get_amount_sats", + argNames: ["that"], + ); + + @override + WithdrawFeesResponse crateMultimintMaxWithdrawQuoteAutoAccessorGetFees({ + required MaxWithdrawQuote that, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + that, + serializer, + ); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 48)!; + }, + codec: SseCodec( + decodeSuccessData: + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerWithdrawFeesResponse, + decodeErrorData: null, + ), + constMeta: kCrateMultimintMaxWithdrawQuoteAutoAccessorGetFeesConstMeta, + argValues: [that], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintMaxWithdrawQuoteAutoAccessorGetFeesConstMeta => + const TaskConstMeta( + debugName: "MaxWithdrawQuote_auto_accessor_get_fees", + argNames: ["that"], + ); + + @override + void crateMultimintMaxWithdrawQuoteAutoAccessorSetAmountSats({ + required MaxWithdrawQuote that, + required BigInt amountSats, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + that, + serializer, + ); + sse_encode_u_64(amountSats, serializer); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 49)!; + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: + kCrateMultimintMaxWithdrawQuoteAutoAccessorSetAmountSatsConstMeta, + argValues: [that, amountSats], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintMaxWithdrawQuoteAutoAccessorSetAmountSatsConstMeta => + const TaskConstMeta( + debugName: "MaxWithdrawQuote_auto_accessor_set_amount_sats", + argNames: ["that", "amountSats"], + ); + + @override + void crateMultimintMaxWithdrawQuoteAutoAccessorSetFees({ + required MaxWithdrawQuote that, + required WithdrawFeesResponse fees, + }) { + return handler.executeSync( + SyncTask( + callFfi: () { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + that, + serializer, + ); + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerWithdrawFeesResponse( + fees, + serializer, + ); + return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 50)!; + }, + codec: SseCodec( + decodeSuccessData: sse_decode_unit, + decodeErrorData: null, + ), + constMeta: kCrateMultimintMaxWithdrawQuoteAutoAccessorSetFeesConstMeta, + argValues: [that, fees], + apiImpl: this, + ), + ); + } + + TaskConstMeta + get kCrateMultimintMaxWithdrawQuoteAutoAccessorSetFeesConstMeta => + const TaskConstMeta( + debugName: "MaxWithdrawQuote_auto_accessor_set_fees", + argNames: ["that", "fees"], + ); + @override Future crateMultimintMultimintAckSeedPhrase({required Multimint that}) { return handler.executeNormal( @@ -3273,7 +3439,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 47, + funcId: 51, port: port_, ); }, @@ -3314,7 +3480,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 48, + funcId: 52, port: port_, ); }, @@ -3361,7 +3527,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 49, + funcId: 53, port: port_, ); }, @@ -3408,7 +3574,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 50, + funcId: 54, port: port_, ); }, @@ -3456,7 +3622,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 51, + funcId: 55, port: port_, ); }, @@ -3503,7 +3669,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 52, + funcId: 56, port: port_, ); }, @@ -3549,7 +3715,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 53, + funcId: 57, port: port_, ); }, @@ -3591,7 +3757,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 54, + funcId: 58, port: port_, ); }, @@ -3634,7 +3800,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 55, + funcId: 59, port: port_, ); }, @@ -3678,7 +3844,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 56, + funcId: 60, port: port_, ); }, @@ -3724,7 +3890,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 57, + funcId: 61, port: port_, ); }, @@ -3768,7 +3934,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 58, + funcId: 62, port: port_, ); }, @@ -3817,7 +3983,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 59, + funcId: 63, port: port_, ); }, @@ -3884,7 +4050,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 60, + funcId: 64, port: port_, ); }, @@ -3940,7 +4106,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 61, + funcId: 65, port: port_, ); }, @@ -3997,7 +4163,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 62, + funcId: 66, port: port_, ); }, @@ -4033,7 +4199,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 63, + funcId: 67, port: port_, ); }, @@ -4075,7 +4241,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 64, + funcId: 68, port: port_, ); }, @@ -4112,7 +4278,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 65, + funcId: 69, port: port_, ); }, @@ -4148,7 +4314,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 66, + funcId: 70, port: port_, ); }, @@ -4184,7 +4350,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 67, + funcId: 71, port: port_, ); }, @@ -4220,7 +4386,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 68, + funcId: 72, port: port_, ); }, @@ -4263,7 +4429,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 69, + funcId: 73, port: port_, ); }, @@ -4300,7 +4466,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 70, + funcId: 74, port: port_, ); }, @@ -4337,7 +4503,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 71, + funcId: 75, port: port_, ); }, @@ -4380,7 +4546,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 72, + funcId: 76, port: port_, ); }, @@ -4421,7 +4587,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 73, + funcId: 77, port: port_, ); }, @@ -4444,7 +4610,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - Future crateMultimintMultimintGetMaxWithdrawableAmount({ + Future + crateMultimintMultimintGetMaxWithdrawableAmount({ required Multimint that, required FederationId federationId, required String address, @@ -4465,13 +4632,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 74, + funcId: 78, port: port_, ); }, codec: SseCodec( decodeSuccessData: - sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64, + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote, decodeErrorData: null, ), constMeta: kCrateMultimintMultimintGetMaxWithdrawableAmountConstMeta, @@ -4502,7 +4669,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 75, + funcId: 79, port: port_, ); }, @@ -4543,7 +4710,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 76, + funcId: 80, port: port_, ); }, @@ -4584,7 +4751,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 77, + funcId: 81, port: port_, ); }, @@ -4627,7 +4794,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 78, + funcId: 82, port: port_, ); }, @@ -4662,7 +4829,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 79, + funcId: 83, port: port_, ); }, @@ -4709,7 +4876,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 80, + funcId: 84, port: port_, ); }, @@ -4754,7 +4921,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 81, + funcId: 85, port: port_, ); }, @@ -4800,7 +4967,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 82, + funcId: 86, port: port_, ); }, @@ -4843,7 +5010,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 83, + funcId: 87, port: port_, ); }, @@ -4888,7 +5055,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 84, + funcId: 88, port: port_, ); }, @@ -4935,7 +5102,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 85, + funcId: 89, port: port_, ); }, @@ -4984,7 +5151,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 86, + funcId: 90, port: port_, ); }, @@ -5036,7 +5203,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 87, + funcId: 91, port: port_, ); }, @@ -5081,7 +5248,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 88, + funcId: 92, port: port_, ); }, @@ -5128,7 +5295,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 89, + funcId: 93, port: port_, ); }, @@ -5173,7 +5340,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 90, + funcId: 94, port: port_, ); }, @@ -5209,7 +5376,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 91, + funcId: 95, port: port_, ); }, @@ -5249,7 +5416,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 92, + funcId: 96, port: port_, ); }, @@ -5291,7 +5458,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 93, + funcId: 97, port: port_, ); }, @@ -5341,7 +5508,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 94, + funcId: 98, port: port_, ); }, @@ -5379,7 +5546,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 95, + funcId: 99, port: port_, ); }, @@ -5425,7 +5592,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 96, + funcId: 100, port: port_, ); }, @@ -5478,7 +5645,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 97, + funcId: 101, port: port_, ); }, @@ -5534,7 +5701,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 98, + funcId: 102, port: port_, ); }, @@ -5596,7 +5763,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 99, + funcId: 103, port: port_, ); }, @@ -5641,7 +5808,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 100, + funcId: 104, port: port_, ); }, @@ -5677,7 +5844,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 101, + funcId: 105, port: port_, ); }, @@ -5718,7 +5885,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 102, + funcId: 106, port: port_, ); }, @@ -5768,7 +5935,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 103, + funcId: 107, port: port_, ); }, @@ -5827,7 +5994,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 104, + funcId: 108, port: port_, ); }, @@ -5866,7 +6033,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 105, + funcId: 109, port: port_, ); }, @@ -5909,7 +6076,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 106, + funcId: 110, port: port_, ); }, @@ -5967,7 +6134,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 107, + funcId: 111, port: port_, ); }, @@ -6033,7 +6200,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 108, + funcId: 112, port: port_, ); }, @@ -6072,7 +6239,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 109, + funcId: 113, port: port_, ); }, @@ -6113,7 +6280,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 110, + funcId: 114, port: port_, ); }, @@ -6151,7 +6318,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 111, + funcId: 115, port: port_, ); }, @@ -6189,7 +6356,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 112, + funcId: 116, port: port_, ); }, @@ -6236,7 +6403,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 113, + funcId: 117, port: port_, ); }, @@ -6285,7 +6452,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 114, + funcId: 118, port: port_, ); }, @@ -6337,7 +6504,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 115, + funcId: 119, port: port_, ); }, @@ -6390,7 +6557,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 116, + funcId: 120, port: port_, ); }, @@ -6426,7 +6593,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 117, + funcId: 121, port: port_, ); }, @@ -6464,7 +6631,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 118, + funcId: 122, port: port_, ); }, @@ -6500,7 +6667,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 119, + funcId: 123, port: port_, ); }, @@ -6536,7 +6703,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 120, + funcId: 124, port: port_, ); }, @@ -6574,7 +6741,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 121, + funcId: 125, port: port_, ); }, @@ -6610,7 +6777,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 122, + funcId: 126, port: port_, ); }, @@ -6648,7 +6815,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 123, + funcId: 127, port: port_, ); }, @@ -6683,7 +6850,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 124, + funcId: 128, port: port_, ); }, @@ -6722,7 +6889,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 125, + funcId: 129, port: port_, ); }, @@ -6759,7 +6926,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 126, + funcId: 130, port: port_, ); }, @@ -6795,7 +6962,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 127, + funcId: 131, port: port_, ); }, @@ -6833,7 +7000,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 128, + funcId: 132, port: port_, ); }, @@ -6873,7 +7040,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 129, + funcId: 133, port: port_, ); }, @@ -6913,7 +7080,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 130, + funcId: 134, port: port_, ); }, @@ -6955,7 +7122,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 131, + funcId: 135, port: port_, ); }, @@ -6996,7 +7163,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 132, + funcId: 136, port: port_, ); }, @@ -7034,7 +7201,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 133, + funcId: 137, port: port_, ); }, @@ -7074,7 +7241,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 134, + funcId: 138, port: port_, ); }, @@ -7119,7 +7286,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 135, + funcId: 139, port: port_, ); }, @@ -7153,7 +7320,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 136, + funcId: 140, port: port_, ); }, @@ -7191,7 +7358,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 137, + funcId: 141, port: port_, ); }, @@ -7229,7 +7396,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 138, + funcId: 142, )!; }, codec: SseCodec( @@ -7259,7 +7426,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 139, + funcId: 143, )!; }, codec: SseCodec( @@ -7292,7 +7459,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 140, + funcId: 144, )!; }, codec: SseCodec( @@ -7328,7 +7495,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 141, + funcId: 145, port: port_, ); }, @@ -7364,7 +7531,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 142, + funcId: 146, )!; }, codec: SseCodec( @@ -7399,7 +7566,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 143, + funcId: 147, )!; }, codec: SseCodec( @@ -7434,7 +7601,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 144, + funcId: 148, )!; }, codec: SseCodec( @@ -7469,7 +7636,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 145, + funcId: 149, )!; }, codec: SseCodec( @@ -7507,7 +7674,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 146, + funcId: 150, )!; }, codec: SseCodec( @@ -7544,7 +7711,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 147, + funcId: 151, )!; }, codec: SseCodec( @@ -7581,7 +7748,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 148, + funcId: 152, )!; }, codec: SseCodec( @@ -7617,7 +7784,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 149, + funcId: 153, )!; }, codec: SseCodec( @@ -7653,7 +7820,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 150, + funcId: 154, )!; }, codec: SseCodec( @@ -7691,7 +7858,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 151, + funcId: 155, )!; }, codec: SseCodec( @@ -7731,7 +7898,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 152, + funcId: 156, )!; }, codec: SseCodec( @@ -7770,7 +7937,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 153, + funcId: 157, )!; }, codec: SseCodec( @@ -7809,7 +7976,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 154, + funcId: 158, )!; }, codec: SseCodec( @@ -7848,7 +8015,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 155, + funcId: 159, )!; }, codec: SseCodec( @@ -7886,7 +8053,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 156, + funcId: 160, )!; }, codec: SseCodec( @@ -7924,7 +8091,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 157, + funcId: 161, )!; }, codec: SseCodec( @@ -7960,7 +8127,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 158, + funcId: 162, )!; }, codec: SseCodec( @@ -7998,7 +8165,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 159, + funcId: 163, )!; }, codec: SseCodec( @@ -8035,7 +8202,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 160, + funcId: 164, )!; }, codec: SseCodec( @@ -8073,7 +8240,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 161, + funcId: 165, )!; }, codec: SseCodec( @@ -8111,7 +8278,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 162, + funcId: 166, )!; }, codec: SseCodec( @@ -8150,7 +8317,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 163, + funcId: 167, )!; }, codec: SseCodec( @@ -8190,7 +8357,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 164, + funcId: 168, )!; }, codec: SseCodec( @@ -8229,7 +8396,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 165, + funcId: 169, )!; }, codec: SseCodec( @@ -8272,7 +8439,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 166, + funcId: 170, )!; }, codec: SseCodec( @@ -8311,7 +8478,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 167, + funcId: 171, )!; }, codec: SseCodec( @@ -8342,7 +8509,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 168, + funcId: 172, port: port_, ); }, @@ -8370,7 +8537,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 169, + funcId: 173, port: port_, ); }, @@ -8403,7 +8570,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 170, + funcId: 174, port: port_, ); }, @@ -8444,7 +8611,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 171, + funcId: 175, port: port_, ); }, @@ -8484,7 +8651,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 172, + funcId: 176, port: port_, ); }, @@ -8525,7 +8692,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 173, + funcId: 177, port: port_, ); }, @@ -8565,7 +8732,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 174, + funcId: 178, port: port_, ); }, @@ -8594,7 +8761,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 175, + funcId: 179, port: port_, ); }, @@ -8625,7 +8792,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 176, + funcId: 180, port: port_, ); }, @@ -8660,7 +8827,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 177, + funcId: 181, port: port_, ); }, @@ -8698,7 +8865,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 178, + funcId: 182, port: port_, ); }, @@ -8738,7 +8905,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 179, + funcId: 183, port: port_, ); }, @@ -8773,7 +8940,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 180, + funcId: 184, port: port_, ); }, @@ -8810,7 +8977,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 181, + funcId: 185, port: port_, ); }, @@ -8853,7 +9020,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 182, + funcId: 186, port: port_, ); }, @@ -8905,7 +9072,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 183, + funcId: 187, port: port_, ); }, @@ -8934,7 +9101,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 184, + funcId: 188, port: port_, ); }, @@ -8965,7 +9132,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 185, + funcId: 189, port: port_, ); }, @@ -9006,7 +9173,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 186, + funcId: 190, port: port_, ); }, @@ -9042,7 +9209,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 187, + funcId: 191, port: port_, ); }, @@ -9076,7 +9243,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 188, + funcId: 192, port: port_, ); }, @@ -9111,7 +9278,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 189, + funcId: 193, port: port_, ); }, @@ -9162,7 +9329,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 190, + funcId: 194, port: port_, ); }, @@ -9218,7 +9385,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 191, + funcId: 195, port: port_, ); }, @@ -9247,7 +9414,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 192, + funcId: 196, port: port_, ); }, @@ -9276,7 +9443,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 193, + funcId: 197, port: port_, ); }, @@ -9309,7 +9476,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 194, + funcId: 198, port: port_, ); }, @@ -9339,7 +9506,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 195, + funcId: 199, port: port_, ); }, @@ -9366,7 +9533,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 196, + funcId: 200, port: port_, ); }, @@ -9393,7 +9560,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 197, + funcId: 201, port: port_, ); }, @@ -9420,7 +9587,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 198, + funcId: 202, port: port_, ); }, @@ -9447,7 +9614,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 199, + funcId: 203, port: port_, ); }, @@ -9483,7 +9650,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 200, + funcId: 204, port: port_, ); }, @@ -9513,7 +9680,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 201, + funcId: 205, port: port_, ); }, @@ -9541,7 +9708,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 202, + funcId: 206, port: port_, ); }, @@ -9576,7 +9743,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 203, + funcId: 207, port: port_, ); }, @@ -9615,7 +9782,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 204, + funcId: 208, port: port_, ); }, @@ -9651,7 +9818,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 205, + funcId: 209, port: port_, ); }, @@ -9673,7 +9840,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - Future crateGetMaxWithdrawableAmount({ + Future crateGetMaxWithdrawableAmount({ required FederationId federationId, required String address, }) { @@ -9689,12 +9856,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 206, + funcId: 210, port: port_, ); }, codec: SseCodec( - decodeSuccessData: sse_decode_u_64, + decodeSuccessData: + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote, decodeErrorData: sse_decode_ecash_app_error, ), constMeta: kCrateGetMaxWithdrawableAmountConstMeta, @@ -9719,7 +9887,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 207, + funcId: 211, port: port_, ); }, @@ -9754,7 +9922,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 208, + funcId: 212, port: port_, ); }, @@ -9790,7 +9958,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 209, + funcId: 213, port: port_, ); }, @@ -9820,7 +9988,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 210, + funcId: 214, port: port_, ); }, @@ -9848,7 +10016,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 211, + funcId: 215, port: port_, ); }, @@ -9875,7 +10043,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 212, + funcId: 216, port: port_, ); }, @@ -9908,7 +10076,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 213, + funcId: 217, port: port_, ); }, @@ -9937,7 +10105,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 214, + funcId: 218, port: port_, ); }, @@ -9964,7 +10132,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 215, + funcId: 219, port: port_, ); }, @@ -9994,7 +10162,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 216, + funcId: 220, port: port_, ); }, @@ -10033,7 +10201,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 217, + funcId: 221, port: port_, ); }, @@ -10072,7 +10240,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 218, + funcId: 222, port: port_, ); }, @@ -10111,7 +10279,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 219, + funcId: 223, port: port_, ); }, @@ -10149,7 +10317,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 220, + funcId: 224, port: port_, ); }, @@ -10188,7 +10356,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 221, + funcId: 225, port: port_, ); }, @@ -10229,7 +10397,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 222, + funcId: 226, port: port_, ); }, @@ -10272,7 +10440,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 223, + funcId: 227, port: port_, ); }, @@ -10312,7 +10480,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 224, + funcId: 228, port: port_, ); }, @@ -10351,7 +10519,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 225, + funcId: 229, port: port_, ); }, @@ -10392,7 +10560,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 226, + funcId: 230, port: port_, ); }, @@ -10431,7 +10599,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 227, + funcId: 231, port: port_, ); }, @@ -10460,7 +10628,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 228, + funcId: 232, port: port_, ); }, @@ -10487,7 +10655,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 229, + funcId: 233, port: port_, ); }, @@ -10514,7 +10682,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 230, + funcId: 234, port: port_, ); }, @@ -10542,7 +10710,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 231, + funcId: 235, port: port_, ); }, @@ -10570,7 +10738,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 232, + funcId: 236, )!; }, codec: SseCodec( @@ -10601,7 +10769,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 233, + funcId: 237, port: port_, ); }, @@ -10635,7 +10803,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 234, + funcId: 238, port: port_, ); }, @@ -10667,7 +10835,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 235, + funcId: 239, port: port_, ); }, @@ -10706,7 +10874,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 236, + funcId: 240, port: port_, ); }, @@ -10738,7 +10906,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 237, + funcId: 241, port: port_, ); }, @@ -10768,7 +10936,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 238, + funcId: 242, port: port_, ); }, @@ -10802,7 +10970,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 239, + funcId: 243, port: port_, ); }, @@ -10843,7 +11011,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 240, + funcId: 244, port: port_, ); }, @@ -10881,7 +11049,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 241, + funcId: 245, port: port_, ); }, @@ -10921,7 +11089,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 242, + funcId: 246, port: port_, ); }, @@ -10964,7 +11132,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 243, + funcId: 247, )!; }, codec: SseCodec( @@ -10999,7 +11167,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 244, + funcId: 248, port: port_, ); }, @@ -11033,7 +11201,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 245, + funcId: 249, port: port_, ); }, @@ -11069,7 +11237,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 246, + funcId: 250, port: port_, ); }, @@ -11099,7 +11267,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 247, + funcId: 251, port: port_, ); }, @@ -11144,7 +11312,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 248, + funcId: 252, port: port_, ); }, @@ -11198,7 +11366,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 249, + funcId: 253, port: port_, ); }, @@ -11227,7 +11395,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 250, + funcId: 254, port: port_, ); }, @@ -11260,7 +11428,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 251, + funcId: 255, port: port_, ); }, @@ -11304,7 +11472,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 252, + funcId: 256, port: port_, ); }, @@ -11355,7 +11523,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 253, + funcId: 257, port: port_, ); }, @@ -11385,7 +11553,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 254, + funcId: 258, port: port_, ); }, @@ -11423,7 +11591,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 255, + funcId: 259, port: port_, ); }, @@ -11458,7 +11626,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 256, + funcId: 260, port: port_, ); }, @@ -11489,7 +11657,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 257, + funcId: 261, port: port_, ); }, @@ -11536,7 +11704,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 258, + funcId: 262, port: port_, ); }, @@ -11594,7 +11762,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 259, + funcId: 263, port: port_, ); }, @@ -11627,7 +11795,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 260, + funcId: 264, port: port_, ); }, @@ -11660,7 +11828,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 261, + funcId: 265, port: port_, ); }, @@ -11690,7 +11858,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 262, + funcId: 266, port: port_, ); }, @@ -11729,7 +11897,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 263, + funcId: 267, port: port_, ); }, @@ -11759,7 +11927,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 264, + funcId: 268, port: port_, ); }, @@ -11789,7 +11957,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 265, + funcId: 269, port: port_, ); }, @@ -11819,7 +11987,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 266, + funcId: 270, port: port_, ); }, @@ -11851,7 +12019,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 267, + funcId: 271, port: port_, ); }, @@ -11882,7 +12050,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 268, + funcId: 272, port: port_, ); }, @@ -11918,7 +12086,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 269, + funcId: 273, port: port_, ); }, @@ -11952,7 +12120,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 270, + funcId: 274, port: port_, ); }, @@ -11995,7 +12163,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 271, + funcId: 275, port: port_, ); }, @@ -12037,7 +12205,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 272, + funcId: 276, port: port_, ); }, @@ -12070,7 +12238,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 273, + funcId: 277, port: port_, ); }, @@ -12109,7 +12277,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 274, + funcId: 278, port: port_, ); }, @@ -12139,7 +12307,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 275, + funcId: 279, port: port_, ); }, @@ -12167,7 +12335,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 276, + funcId: 280, port: port_, ); }, @@ -12202,7 +12370,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 277, + funcId: 281, port: port_, ); }, @@ -12248,7 +12416,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 278, + funcId: 282, port: port_, ); }, @@ -12290,7 +12458,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 279, + funcId: 283, port: port_, ); }, @@ -12340,6 +12508,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { get rust_arc_decrement_strong_count_Database => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerDatabase; + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_EcashAppResultMaxWithdrawQuote => + wire.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuote => + wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote; + RustArcIncrementStrongCountFnType get rust_arc_increment_strong_count_EcashAppResultOobNotesWrapper => wire.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper; @@ -12380,14 +12556,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { get rust_arc_decrement_strong_count_EcashAppResultWithdrawFeesResponse => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultWithdrawFeesResponse; - RustArcIncrementStrongCountFnType - get rust_arc_increment_strong_count_EcashAppResultU64 => - wire.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64; - - RustArcDecrementStrongCountFnType - get rust_arc_decrement_strong_count_EcashAppResultU64 => - wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64; - RustArcIncrementStrongCountFnType get rust_arc_increment_strong_count_EventBusMultimintEvent => wire.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent; @@ -12452,6 +12620,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { get rust_arc_decrement_strong_count_LightningAddressKey => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerLightningAddressKey; + RustArcIncrementStrongCountFnType + get rust_arc_increment_strong_count_MaxWithdrawQuote => + wire.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote; + + RustArcDecrementStrongCountFnType + get rust_arc_decrement_strong_count_MaxWithdrawQuote => + wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote; + RustArcIncrementStrongCountFnType get rust_arc_increment_strong_count_Multimint => wire.rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint; @@ -12598,6 +12774,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return DatabaseImpl.frbInternalDcoDecode(raw as List); } + @protected + EcashAppResultMaxWithdrawQuote + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return EcashAppResultMaxWithdrawQuoteImpl.frbInternalDcoDecode( + raw as List, + ); + } + @protected EcashAppResultOobNotesWrapper dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -12651,15 +12838,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } - @protected - EcashAppResultU64 - dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - dynamic raw, - ) { - // Codec=Dco (DartCObject based), see doc to use other codecs - return EcashAppResultU64Impl.frbInternalDcoDecode(raw as List); - } - @protected EventBusMultimintEvent dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -12738,6 +12916,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return LightningAddressKeyImpl.frbInternalDcoDecode(raw as List); } + @protected + MaxWithdrawQuote + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalDcoDecode(raw as List); + } + @protected Multimint dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -12892,7 +13079,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { dynamic raw, ) { // Codec=Dco (DartCObject based), see doc to use other codecs - return LightningAddressKeyImpl.frbInternalDcoDecode(raw as List); + return LightningAddressKeyImpl.frbInternalDcoDecode(raw as List); + } + + @protected + MaxWithdrawQuote + dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalDcoDecode(raw as List); } @protected @@ -13014,6 +13210,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return LightningAddressKeyImpl.frbInternalDcoDecode(raw as List); } + @protected + MaxWithdrawQuote + dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalDcoDecode(raw as List); + } + @protected Multimint dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -13113,6 +13318,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return DatabaseImpl.frbInternalDcoDecode(raw as List); } + @protected + EcashAppResultMaxWithdrawQuote + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return EcashAppResultMaxWithdrawQuoteImpl.frbInternalDcoDecode( + raw as List, + ); + } + @protected EcashAppResultOobNotesWrapper dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -13166,15 +13382,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } - @protected - EcashAppResultU64 - dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - dynamic raw, - ) { - // Codec=Dco (DartCObject based), see doc to use other codecs - return EcashAppResultU64Impl.frbInternalDcoDecode(raw as List); - } - @protected EventBusMultimintEvent dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -13253,6 +13460,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return LightningAddressKeyImpl.frbInternalDcoDecode(raw as List); } + @protected + MaxWithdrawQuote + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalDcoDecode(raw as List); + } + @protected Multimint dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -15143,6 +15359,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + EcashAppResultMaxWithdrawQuote + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return EcashAppResultMaxWithdrawQuoteImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), + sse_decode_i_32(deserializer), + ); + } + @protected EcashAppResultOobNotesWrapper sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -15203,18 +15431,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } - @protected - EcashAppResultU64 - sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - SseDeserializer deserializer, - ) { - // Codec=Sse (Serialization based), see doc to use other codecs - return EcashAppResultU64Impl.frbInternalSseDecode( - sse_decode_usize(deserializer), - sse_decode_i_32(deserializer), - ); - } - @protected EventBusMultimintEvent sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -15311,6 +15527,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + MaxWithdrawQuote + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), + sse_decode_i_32(deserializer), + ); + } + @protected Multimint sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -15515,6 +15743,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + MaxWithdrawQuote + sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), + sse_decode_i_32(deserializer), + ); + } + @protected Multimint sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -15671,6 +15911,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + MaxWithdrawQuote + sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), + sse_decode_i_32(deserializer), + ); + } + @protected Multimint sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -15803,6 +16055,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + EcashAppResultMaxWithdrawQuote + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return EcashAppResultMaxWithdrawQuoteImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), + sse_decode_i_32(deserializer), + ); + } + @protected EcashAppResultOobNotesWrapper sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -15863,18 +16127,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } - @protected - EcashAppResultU64 - sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - SseDeserializer deserializer, - ) { - // Codec=Sse (Serialization based), see doc to use other codecs - return EcashAppResultU64Impl.frbInternalSseDecode( - sse_decode_usize(deserializer), - sse_decode_i_32(deserializer), - ); - } - @protected EventBusMultimintEvent sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -15971,6 +16223,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + MaxWithdrawQuote + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + return MaxWithdrawQuoteImpl.frbInternalSseDecode( + sse_decode_usize(deserializer), + sse_decode_i_32(deserializer), + ); + } + @protected Multimint sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -18231,6 +18495,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + EcashAppResultMaxWithdrawQuote self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as EcashAppResultMaxWithdrawQuoteImpl).frbInternalSseEncode( + move: true, + ), + serializer, + ); + } + @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -18302,19 +18581,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } - @protected - void - sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - EcashAppResultU64 self, - SseSerializer serializer, - ) { - // Codec=Sse (Serialization based), see doc to use other codecs - sse_encode_usize( - (self as EcashAppResultU64Impl).frbInternalSseEncode(move: true), - serializer, - ); - } - @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -18419,6 +18685,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MaxWithdrawQuoteImpl).frbInternalSseEncode(move: true), + serializer, + ); + } + @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -18640,6 +18919,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + void + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MaxWithdrawQuoteImpl).frbInternalSseEncode(move: false), + serializer, + ); + } + @protected void sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -18809,6 +19101,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + void + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MaxWithdrawQuoteImpl).frbInternalSseEncode(move: false), + serializer, + ); + } + @protected void sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -18952,6 +19257,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + EcashAppResultMaxWithdrawQuote self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as EcashAppResultMaxWithdrawQuoteImpl).frbInternalSseEncode( + move: null, + ), + serializer, + ); + } + @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -19023,19 +19343,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } - @protected - void - sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - EcashAppResultU64 self, - SseSerializer serializer, - ) { - // Codec=Sse (Serialization based), see doc to use other codecs - sse_encode_usize( - (self as EcashAppResultU64Impl).frbInternalSseEncode(move: null), - serializer, - ); - } - @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -19140,6 +19447,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_usize( + (self as MaxWithdrawQuoteImpl).frbInternalSseEncode(move: null), + serializer, + ); + } + @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -21290,6 +21610,38 @@ class DatabaseImpl extends RustOpaque implements Database { ); } +@sealed +class EcashAppResultMaxWithdrawQuoteImpl extends RustOpaque + implements EcashAppResultMaxWithdrawQuote { + // Not to be used by end users + EcashAppResultMaxWithdrawQuoteImpl.frbInternalDcoDecode(List wire) + : super.frbInternalDcoDecode(wire, _kStaticData); + + // Not to be used by end users + EcashAppResultMaxWithdrawQuoteImpl.frbInternalSseDecode( + BigInt ptr, + int externalSizeOnNative, + ) : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData); + + static final _kStaticData = RustArcStaticData( + rustArcIncrementStrongCount: + RustLib + .instance + .api + .rust_arc_increment_strong_count_EcashAppResultMaxWithdrawQuote, + rustArcDecrementStrongCount: + RustLib + .instance + .api + .rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuote, + rustArcDecrementStrongCountPtr: + RustLib + .instance + .api + .rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuotePtr, + ); +} + @sealed class EcashAppResultOobNotesWrapperImpl extends RustOpaque implements EcashAppResultOobNotesWrapper { @@ -21418,31 +21770,6 @@ class EcashAppResultStringImpl extends RustOpaque ); } -@sealed -class EcashAppResultU64Impl extends RustOpaque implements EcashAppResultU64 { - // Not to be used by end users - EcashAppResultU64Impl.frbInternalDcoDecode(List wire) - : super.frbInternalDcoDecode(wire, _kStaticData); - - // Not to be used by end users - EcashAppResultU64Impl.frbInternalSseDecode( - BigInt ptr, - int externalSizeOnNative, - ) : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData); - - static final _kStaticData = RustArcStaticData( - rustArcIncrementStrongCount: - RustLib.instance.api.rust_arc_increment_strong_count_EcashAppResultU64, - rustArcDecrementStrongCount: - RustLib.instance.api.rust_arc_decrement_strong_count_EcashAppResultU64, - rustArcDecrementStrongCountPtr: - RustLib - .instance - .api - .rust_arc_decrement_strong_count_EcashAppResultU64Ptr, - ); -} - @sealed class EcashAppResultWithdrawFeesResponseImpl extends RustOpaque implements EcashAppResultWithdrawFeesResponse { @@ -21905,6 +22232,49 @@ class LightningAddressKeyImpl extends RustOpaque ); } +@sealed +class MaxWithdrawQuoteImpl extends RustOpaque implements MaxWithdrawQuote { + // Not to be used by end users + MaxWithdrawQuoteImpl.frbInternalDcoDecode(List wire) + : super.frbInternalDcoDecode(wire, _kStaticData); + + // Not to be used by end users + MaxWithdrawQuoteImpl.frbInternalSseDecode( + BigInt ptr, + int externalSizeOnNative, + ) : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData); + + static final _kStaticData = RustArcStaticData( + rustArcIncrementStrongCount: + RustLib.instance.api.rust_arc_increment_strong_count_MaxWithdrawQuote, + rustArcDecrementStrongCount: + RustLib.instance.api.rust_arc_decrement_strong_count_MaxWithdrawQuote, + rustArcDecrementStrongCountPtr: + RustLib + .instance + .api + .rust_arc_decrement_strong_count_MaxWithdrawQuotePtr, + ); + + BigInt get amountSats => RustLib.instance.api + .crateMultimintMaxWithdrawQuoteAutoAccessorGetAmountSats(that: this); + + WithdrawFeesResponse get fees => RustLib.instance.api + .crateMultimintMaxWithdrawQuoteAutoAccessorGetFees(that: this); + + set amountSats(BigInt amountSats) => RustLib.instance.api + .crateMultimintMaxWithdrawQuoteAutoAccessorSetAmountSats( + that: this, + amountSats: amountSats, + ); + + set fees(WithdrawFeesResponse fees) => + RustLib.instance.api.crateMultimintMaxWithdrawQuoteAutoAccessorSetFees( + that: this, + fees: fees, + ); +} + @sealed class MultimintImpl extends RustOpaque implements Multimint { // Not to be used by end users @@ -22155,7 +22525,7 @@ class MultimintImpl extends RustOpaque implements Multimint { federationId: federationId, ); - Future getMaxWithdrawableAmount({ + Future getMaxWithdrawableAmount({ required FederationId federationId, required String address, }) => RustLib.instance.api.crateMultimintMultimintGetMaxWithdrawableAmount( diff --git a/lib/frb_generated.io.dart b/lib/frb_generated.io.dart index 63658f9d..dcffb41c 100644 --- a/lib/frb_generated.io.dart +++ b/lib/frb_generated.io.dart @@ -39,6 +39,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_DatabasePtr => wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerDatabasePtr; + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuotePtr => + wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuotePtr; + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_EcashAppResultOobNotesWrapperPtr => wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapperPtr; @@ -59,10 +63,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { get rust_arc_decrement_strong_count_EcashAppResultWithdrawFeesResponsePtr => wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultWithdrawFeesResponsePtr; - CrossPlatformFinalizerArg - get rust_arc_decrement_strong_count_EcashAppResultU64Ptr => - wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64Ptr; - CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_EventBusMultimintEventPtr => wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEventPtr; @@ -95,6 +95,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { get rust_arc_decrement_strong_count_LightningAddressKeyPtr => wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerLightningAddressKeyPtr; + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_MaxWithdrawQuotePtr => + wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuotePtr; + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_MultimintPtr => wire._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimintPtr; @@ -171,6 +175,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + EcashAppResultMaxWithdrawQuote + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + dynamic raw, + ); + @protected EcashAppResultOobNotesWrapper dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -201,12 +211,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); - @protected - EcashAppResultU64 - dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - dynamic raw, - ); - @protected EventBusMultimintEvent dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -255,6 +259,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -357,6 +367,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -435,6 +451,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -501,6 +523,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + EcashAppResultMaxWithdrawQuote + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + dynamic raw, + ); + @protected EcashAppResultOobNotesWrapper dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -531,12 +559,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); - @protected - EcashAppResultU64 - dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - dynamic raw, - ); - @protected EventBusMultimintEvent dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -585,6 +607,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1243,6 +1271,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + EcashAppResultMaxWithdrawQuote + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected EcashAppResultOobNotesWrapper sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -1273,12 +1307,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); - @protected - EcashAppResultU64 - sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - SseDeserializer deserializer, - ); - @protected EventBusMultimintEvent sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -1327,6 +1355,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1429,6 +1463,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1507,6 +1547,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1573,6 +1619,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + EcashAppResultMaxWithdrawQuote + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected EcashAppResultOobNotesWrapper sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -1603,12 +1655,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); - @protected - EcashAppResultU64 - sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - SseDeserializer deserializer, - ); - @protected EventBusMultimintEvent sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -1657,6 +1703,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2392,6 +2444,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + EcashAppResultMaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -2427,13 +2486,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); - @protected - void - sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - EcashAppResultU64 self, - SseSerializer serializer, - ); - @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -2490,6 +2542,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2609,6 +2668,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2700,6 +2766,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2777,6 +2850,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + EcashAppResultMaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -2812,13 +2892,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); - @protected - void - sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - EcashAppResultU64 self, - SseSerializer serializer, - ); - @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -2875,6 +2948,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -3884,6 +3964,40 @@ class RustLibWire implements BaseWire { _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerDatabasePtr .asFunction)>(); + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ffi.Pointer ptr, + ) { + return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr, + ); + } + + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuotePtr = + _lookup)>>( + 'frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote', + ); + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote = + _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuotePtr + .asFunction)>(); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ffi.Pointer ptr, + ) { + return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr, + ); + } + + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuotePtr = + _lookup)>>( + 'frbgen_ecashapp_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote', + ); + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote = + _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuotePtr + .asFunction)>(); + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( ffi.Pointer ptr, @@ -4054,40 +4168,6 @@ class RustLibWire implements BaseWire { _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultWithdrawFeesResponsePtr .asFunction)>(); - void - rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ffi.Pointer ptr, - ) { - return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr, - ); - } - - late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64Ptr = - _lookup)>>( - 'frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64', - ); - late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64 = - _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64Ptr - .asFunction)>(); - - void - rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ffi.Pointer ptr, - ) { - return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr, - ); - } - - late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64Ptr = - _lookup)>>( - 'frbgen_ecashapp_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64', - ); - late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64 = - _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64Ptr - .asFunction)>(); - void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( ffi.Pointer ptr, @@ -4360,6 +4440,40 @@ class RustLibWire implements BaseWire { _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerLightningAddressKeyPtr .asFunction)>(); + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ffi.Pointer ptr, + ) { + return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr, + ); + } + + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuotePtr = + _lookup)>>( + 'frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote', + ); + late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote = + _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuotePtr + .asFunction)>(); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ffi.Pointer ptr, + ) { + return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr, + ); + } + + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuotePtr = + _lookup)>>( + 'frbgen_ecashapp_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote', + ); + late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote = + _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuotePtr + .asFunction)>(); + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( ffi.Pointer ptr, diff --git a/lib/frb_generated.web.dart b/lib/frb_generated.web.dart index 11ab9d09..30c82274 100644 --- a/lib/frb_generated.web.dart +++ b/lib/frb_generated.web.dart @@ -41,6 +41,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_DatabasePtr => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerDatabase; + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_EcashAppResultMaxWithdrawQuotePtr => + wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote; + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_EcashAppResultOobNotesWrapperPtr => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper; @@ -61,10 +65,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { get rust_arc_decrement_strong_count_EcashAppResultWithdrawFeesResponsePtr => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultWithdrawFeesResponse; - CrossPlatformFinalizerArg - get rust_arc_decrement_strong_count_EcashAppResultU64Ptr => - wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64; - CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_EventBusMultimintEventPtr => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent; @@ -97,6 +97,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { get rust_arc_decrement_strong_count_LightningAddressKeyPtr => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerLightningAddressKey; + CrossPlatformFinalizerArg + get rust_arc_decrement_strong_count_MaxWithdrawQuotePtr => + wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote; + CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_MultimintPtr => wire.rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint; @@ -173,6 +177,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + EcashAppResultMaxWithdrawQuote + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + dynamic raw, + ); + @protected EcashAppResultOobNotesWrapper dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -203,12 +213,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); - @protected - EcashAppResultU64 - dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - dynamic raw, - ); - @protected EventBusMultimintEvent dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -257,6 +261,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -359,6 +369,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -437,6 +453,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -503,6 +525,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + EcashAppResultMaxWithdrawQuote + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + dynamic raw, + ); + @protected EcashAppResultOobNotesWrapper dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -533,12 +561,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); - @protected - EcashAppResultU64 - dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - dynamic raw, - ); - @protected EventBusMultimintEvent dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -587,6 +609,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { dynamic raw, ); + @protected + MaxWithdrawQuote + dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + dynamic raw, + ); + @protected Multimint dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1245,6 +1273,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + EcashAppResultMaxWithdrawQuote + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected EcashAppResultOobNotesWrapper sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -1275,12 +1309,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); - @protected - EcashAppResultU64 - sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - SseDeserializer deserializer, - ); - @protected EventBusMultimintEvent sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -1329,6 +1357,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1431,6 +1465,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1509,6 +1549,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -1575,6 +1621,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + EcashAppResultMaxWithdrawQuote + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected EcashAppResultOobNotesWrapper sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -1605,12 +1657,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); - @protected - EcashAppResultU64 - sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - SseDeserializer deserializer, - ); - @protected EventBusMultimintEvent sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -1659,6 +1705,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseDeserializer deserializer, ); + @protected + MaxWithdrawQuote + sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + SseDeserializer deserializer, + ); + @protected Multimint sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2394,6 +2446,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + EcashAppResultMaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -2429,13 +2488,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); - @protected - void - sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - EcashAppResultU64 self, - SseSerializer serializer, - ); - @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -2492,6 +2544,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2611,6 +2670,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2702,6 +2768,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -2779,6 +2852,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + EcashAppResultMaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( @@ -2814,13 +2894,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); - @protected - void - sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - EcashAppResultU64 self, - SseSerializer serializer, - ); - @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( @@ -2877,6 +2950,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { SseSerializer serializer, ); + @protected + void + sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + MaxWithdrawQuote self, + SseSerializer serializer, + ); + @protected void sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( @@ -3805,6 +3885,22 @@ class RustLibWire implements BaseWire { ptr, ); + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + int ptr, + ) => wasmModule + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr, + ); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + int ptr, + ) => wasmModule + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr, + ); + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( int ptr, @@ -3885,22 +3981,6 @@ class RustLibWire implements BaseWire { ptr, ); - void - rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - int ptr, - ) => wasmModule - .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr, - ); - - void - rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - int ptr, - ) => wasmModule - .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr, - ); - void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( int ptr, @@ -4029,6 +4109,22 @@ class RustLibWire implements BaseWire { ptr, ); + void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + int ptr, + ) => wasmModule + .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr, + ); + + void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + int ptr, + ) => wasmModule + .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr, + ); + void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( int ptr, @@ -4284,6 +4380,16 @@ extension type RustLibWasmModule._(JSObject _) implements JSObject { int ptr, ); + external void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + int ptr, + ); + + external void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + int ptr, + ); + external void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( int ptr, @@ -4334,16 +4440,6 @@ extension type RustLibWasmModule._(JSObject _) implements JSObject { int ptr, ); - external void - rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - int ptr, - ); - - external void - rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - int ptr, - ); - external void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( int ptr, @@ -4424,6 +4520,16 @@ extension type RustLibWasmModule._(JSObject _) implements JSObject { int ptr, ); + external void + rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + int ptr, + ); + + external void + rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + int ptr, + ); + external void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( int ptr, diff --git a/lib/lib.dart b/lib/lib.dart index 23f4b0d9..a6838d96 100644 --- a/lib/lib.dart +++ b/lib/lib.dart @@ -402,7 +402,7 @@ Future awaitWithdraw({ operationId: operationId, ); -Future getMaxWithdrawableAmount({ +Future getMaxWithdrawableAmount({ required FederationId federationId, required String address, }) => RustLib.instance.api.crateGetMaxWithdrawableAmount( diff --git a/lib/multimint.dart b/lib/multimint.dart index 15c0309e..768ffc2d 100644 --- a/lib/multimint.dart +++ b/lib/multimint.dart @@ -13,7 +13,7 @@ part 'multimint.freezed.dart'; // These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_expiry_timestamp`, `get_federation`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_successor_invite`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `join_federation_inner`, `join_federation_on`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `migrate_federation_meta_v3`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `register_federation`, `release_ln_address`, `remove_recovery_progress_cache`, `retire_recovery_client`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `shutdown_client`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_federation_teardown`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` // These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ClientType`, `JoinedFederation`, `LNAddressRegisterRequest`, `LNAddressRemoveRequest`, `OnChainWithdrawalMeta`, `WrappedEcash` -// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` +// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` // These functions are ignored (category: IgnoreBecauseExplicitAttribute): `federation_network` // These functions have error during generation (see debug logs or enable `stop_on_error: true` for more details): `subscribe_peer_status` @@ -32,6 +32,9 @@ abstract class Amount implements RustOpaqueInterface {} // Rust type: RustOpaqueMoi> abstract class Bolt11Invoice implements RustOpaqueInterface {} +// Rust type: RustOpaqueMoi>> +abstract class EcashAppResultMaxWithdrawQuote implements RustOpaqueInterface {} + // Rust type: RustOpaqueMoi>> abstract class EcashAppResultOobNotesWrapper implements RustOpaqueInterface {} @@ -48,9 +51,6 @@ abstract class EcashAppResultString implements RustOpaqueInterface {} abstract class EcashAppResultWithdrawFeesResponse implements RustOpaqueInterface {} -// Rust type: RustOpaqueMoi>> -abstract class EcashAppResultU64 implements RustOpaqueInterface {} - // Rust type: RustOpaqueMoi> abstract class FederationMeta implements RustOpaqueInterface { BigInt? get expiryTimestamp; @@ -108,6 +108,17 @@ abstract class FederationSelector implements RustOpaqueInterface { // Rust type: RustOpaqueMoi> abstract class FinalReceiveOperationState implements RustOpaqueInterface {} +// Rust type: RustOpaqueMoi> +abstract class MaxWithdrawQuote implements RustOpaqueInterface { + BigInt get amountSats; + + WithdrawFeesResponse get fees; + + set amountSats(BigInt amountSats); + + set fees(WithdrawFeesResponse fees); +} + // Rust type: RustOpaqueMoi> abstract class Multimint implements RustOpaqueInterface { Future ackSeedPhrase(); @@ -252,7 +263,7 @@ abstract class Multimint implements RustOpaqueInterface { required FederationId federationId, }); - Future getMaxWithdrawableAmount({ + Future getMaxWithdrawableAmount({ required FederationId federationId, required String address, }); diff --git a/lib/onchain_send.dart b/lib/onchain_send.dart index c3eae72e..a9582f46 100644 --- a/lib/onchain_send.dart +++ b/lib/onchain_send.dart @@ -92,19 +92,16 @@ class _OnchainSendState extends State { try { if (widget.withdrawalMode == WithdrawalMode.maxBalance) { - final maxAmount = await getMaxWithdrawableAmount( + // Sized and priced in one quote, so the send pays exactly the miner + // fee the amount was sized against. + final quote = await getMaxWithdrawableAmount( federationId: widget.fed.federationId, address: _addressController.text.trim(), ); - - final feesResponse = await calculateWithdrawFees( - federationId: widget.fed.federationId, - address: _addressController.text.trim(), - amountSats: maxAmount, - ); + final feesResponse = quote.fees; setState(() { - _actualWithdrawalAmount = maxAmount; + _actualWithdrawalAmount = quote.amountSats; _feeAmountSats = feesResponse.feeAmount; _federationFeeMsats = feesResponse.federationFeeMsats; _feeRateSatsPerVbyte = feesResponse.feeRateSatsPerVb; diff --git a/lib/screens/federation_expiry_screen.dart b/lib/screens/federation_expiry_screen.dart index ade50eee..c59397e7 100644 --- a/lib/screens/federation_expiry_screen.dart +++ b/lib/screens/federation_expiry_screen.dart @@ -97,6 +97,8 @@ class FederationExpiryScreen extends StatefulWidget { State createState() => _FederationExpiryScreenState(); } +final _oneSatMsats = BigInt.from(1000); + class _FederationExpiryScreenState extends State { late BigInt? _balanceMsats = widget.balanceMsats; late String? _lightningAddress = widget.lightningAddress; @@ -183,7 +185,8 @@ class _FederationExpiryScreenState extends State { expiryTimestamp != null ? expiryDateTime(expiryTimestamp) : null; final hasExpired = expiry != null && expiry.isBefore(DateTime.now()); final hasSuccessor = widget.successorInvite != null; - final hasBalance = _balanceMsats != null && _balanceMsats! > BigInt.zero; + // Below one sat there is nothing an on-chain send can carry. + final hasBalance = _balanceMsats != null && _balanceMsats! >= _oneSatMsats; final lightningAddress = _lightningAddress; final bitcoinDisplay = context.select( (prefs) => prefs.bitcoinDisplay, diff --git a/rust/ecashapp/src/frb_generated.rs b/rust/ecashapp/src/frb_generated.rs index 947c4371..c30aeab3 100644 --- a/rust/ecashapp/src/frb_generated.rs +++ b/rust/ecashapp/src/frb_generated.rs @@ -43,7 +43,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.9.0"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1834095429; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1847422546; // Section: executor @@ -2282,6 +2282,200 @@ fn wire__crate__db__LightningAddressKey_auto_accessor_set_federation_id_impl( }, ) } +fn wire__crate__multimint__MaxWithdrawQuote_auto_accessor_get_amount_sats_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MaxWithdrawQuote_auto_accessor_get_amount_sats", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()), + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok(api_that_guard.amount_sats.clone())?; + Ok(output_ok) + })()) + }, + ) +} +fn wire__crate__multimint__MaxWithdrawQuote_auto_accessor_get_fees_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MaxWithdrawQuote_auto_accessor_get_fees", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()), + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok(api_that_guard.fees.clone())?; + Ok(output_ok) + })()) + }, + ) +} +fn wire__crate__multimint__MaxWithdrawQuote_auto_accessor_set_amount_sats_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MaxWithdrawQuote_auto_accessor_set_amount_sats", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_amount_sats = ::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref_mut()), + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok({ + { + api_that_guard.amount_sats = api_amount_sats; + }; + })?; + Ok(output_ok) + })()) + }, + ) +} +fn wire__crate__multimint__MaxWithdrawQuote_auto_accessor_set_fees_impl( + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "MaxWithdrawQuote_auto_accessor_set_fees", + port: None, + mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_fees = ::sse_decode(&mut deserializer); + deserializer.end(); + transform_result_sse::<_, ()>((move || { + let mut api_that_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, true, + ), + ]); + for i in decode_indices_ { + match i { + 0 => api_that_guard = Some(api_that.lockable_decode_sync_ref_mut()), + _ => unreachable!(), + } + } + let mut api_that_guard = api_that_guard.unwrap(); + let output_ok = Result::<_, ()>::Ok({ + { + api_that_guard.fees = api_fees; + }; + })?; + Ok(output_ok) + })()) + }, + ) +} fn wire__crate__multimint__Multimint_ack_seed_phrase_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -15447,6 +15641,9 @@ flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::for_generated::RustAutoOpaqueInner ); +flutter_rust_bridge::frb_generated_moi_arc_impl_value!( + flutter_rust_bridge::for_generated::RustAutoOpaqueInner> +); flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::for_generated::RustAutoOpaqueInner> ); @@ -15462,9 +15659,6 @@ flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::for_generated::RustAutoOpaqueInner> ); -flutter_rust_bridge::frb_generated_moi_arc_impl_value!( - flutter_rust_bridge::for_generated::RustAutoOpaqueInner> -); flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::for_generated::RustAutoOpaqueInner> ); @@ -15489,6 +15683,9 @@ flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::for_generated::RustAutoOpaqueInner ); +flutter_rust_bridge::frb_generated_moi_arc_impl_value!( + flutter_rust_bridge::for_generated::RustAutoOpaqueInner +); flutter_rust_bridge::frb_generated_moi_arc_impl_value!( flutter_rust_bridge::for_generated::RustAutoOpaqueInner ); @@ -15579,6 +15776,18 @@ impl SseDecode for Database { } } +impl SseDecode for EcashAppResult { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = , + >, + >>::sse_decode(deserializer); + return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner); + } +} + impl SseDecode for EcashAppResult { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -15633,16 +15842,6 @@ impl SseDecode for EcashAppResult { } } -impl SseDecode for EcashAppResult { - // Codec=Sse (Serialization based), see doc to use other codecs - fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { - let mut inner = >, - >>::sse_decode(deserializer); - return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner); - } -} - impl SseDecode for EventBus { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -15723,6 +15922,16 @@ impl SseDecode for LightningAddressKey { } } +impl SseDecode for MaxWithdrawQuote { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = , + >>::sse_decode(deserializer); + return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner); + } +} + impl SseDecode for Multimint { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -15883,7 +16092,7 @@ impl SseDecode impl SseDecode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -15895,7 +16104,7 @@ impl SseDecode impl SseDecode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -15907,7 +16116,7 @@ impl SseDecode impl SseDecode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -15919,7 +16128,7 @@ impl SseDecode impl SseDecode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -15931,9 +16140,7 @@ impl SseDecode impl SseDecode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner< - EcashAppResult, - >, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -15944,7 +16151,11 @@ impl SseDecode } impl SseDecode - for RustOpaqueMoi>> + for RustOpaqueMoi< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + EcashAppResult, + >, + > { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -16039,6 +16250,16 @@ impl SseDecode } } +impl SseDecode + for RustOpaqueMoi> +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut inner = ::sse_decode(deserializer); + return decode_rust_opaque_moi(inner); + } +} + impl SseDecode for RustOpaqueMoi> { @@ -18001,562 +18222,564 @@ fn pde_ffi_dispatcher_primary_impl( ) { // Codec=Pde (Serialization + dispatch), see doc to use other codecs match func_id { - 47 => wire__crate__multimint__Multimint_ack_seed_phrase_impl( + 51 => wire__crate__multimint__Multimint_ack_seed_phrase_impl( port, ptr, rust_vec_len, data_len, ), - 48 => wire__crate__multimint__Multimint_allocate_deposit_address_impl( + 52 => wire__crate__multimint__Multimint_allocate_deposit_address_impl( port, ptr, rust_vec_len, data_len, ), - 49 => wire__crate__multimint__Multimint_await_ecash_reissue_impl( + 53 => wire__crate__multimint__Multimint_await_ecash_reissue_impl( port, ptr, rust_vec_len, data_len, ), - 50 => wire__crate__multimint__Multimint_await_ecash_send_impl( + 54 => wire__crate__multimint__Multimint_await_ecash_send_impl( port, ptr, rust_vec_len, data_len, ), - 51 => { + 55 => { wire__crate__multimint__Multimint_await_receive_impl(port, ptr, rust_vec_len, data_len) } - 52 => wire__crate__multimint__Multimint_await_send_impl(port, ptr, rust_vec_len, data_len), - 53 => { + 56 => wire__crate__multimint__Multimint_await_send_impl(port, ptr, rust_vec_len, data_len), + 57 => { wire__crate__multimint__Multimint_await_withdraw_impl(port, ptr, rust_vec_len, data_len) } - 54 => wire__crate__multimint__Multimint_balance_impl(port, ptr, rust_vec_len, data_len), - 55 => wire__crate__multimint__Multimint_calculate_ecash_reissue_fees_impl( + 58 => wire__crate__multimint__Multimint_balance_impl(port, ptr, rust_vec_len, data_len), + 59 => wire__crate__multimint__Multimint_calculate_ecash_reissue_fees_impl( port, ptr, rust_vec_len, data_len, ), - 56 => wire__crate__multimint__Multimint_calculate_ecash_send_fees_impl( + 60 => wire__crate__multimint__Multimint_calculate_ecash_send_fees_impl( port, ptr, rust_vec_len, data_len, ), - 57 => wire__crate__multimint__Multimint_calculate_withdraw_fees_impl( + 61 => wire__crate__multimint__Multimint_calculate_withdraw_fees_impl( port, ptr, rust_vec_len, data_len, ), - 58 => wire__crate__multimint__Multimint_check_ecash_spent_impl( + 62 => wire__crate__multimint__Multimint_check_ecash_spent_impl( port, ptr, rust_vec_len, data_len, ), - 59 => wire__crate__multimint__Multimint_check_ln_address_availability_impl( + 63 => wire__crate__multimint__Multimint_check_ln_address_availability_impl( port, ptr, rust_vec_len, data_len, ), - 60 => wire__crate__multimint__Multimint_compute_all_gateway_previews_impl( + 64 => wire__crate__multimint__Multimint_compute_all_gateway_previews_impl( port, ptr, rust_vec_len, data_len, ), - 61 => wire__crate__multimint__Multimint_compute_receive_amount_with_fees_impl( + 65 => wire__crate__multimint__Multimint_compute_receive_amount_with_fees_impl( port, ptr, rust_vec_len, data_len, ), - 62 => wire__crate__multimint__Multimint_contains_client_impl( + 66 => wire__crate__multimint__Multimint_contains_client_impl( port, ptr, rust_vec_len, data_len, ), - 63 => wire__crate__multimint__Multimint_federations_impl(port, ptr, rust_vec_len, data_len), - 64 => { + 67 => wire__crate__multimint__Multimint_federations_impl(port, ptr, rust_vec_len, data_len), + 68 => { wire__crate__multimint__Multimint_get_addresses_impl(port, ptr, rust_vec_len, data_len) } - 65 => wire__crate__multimint__Multimint_get_all_btc_prices_impl( + 69 => wire__crate__multimint__Multimint_get_all_btc_prices_impl( port, ptr, rust_vec_len, data_len, ), - 66 => wire__crate__multimint__Multimint_get_all_invite_codes_impl( + 70 => wire__crate__multimint__Multimint_get_all_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 67 => wire__crate__multimint__Multimint_get_bitcoin_display_impl( + 71 => wire__crate__multimint__Multimint_get_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 68 => { + 72 => { wire__crate__multimint__Multimint_get_btc_price_impl(port, ptr, rust_vec_len, data_len) } - 69 => wire__crate__multimint__Multimint_get_cached_federation_meta_impl( + 73 => wire__crate__multimint__Multimint_get_cached_federation_meta_impl( port, ptr, rust_vec_len, data_len, ), - 70 => wire__crate__multimint__Multimint_get_federation_order_impl( + 74 => wire__crate__multimint__Multimint_get_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 71 => wire__crate__multimint__Multimint_get_fiat_currency_impl( + 75 => wire__crate__multimint__Multimint_get_fiat_currency_impl( port, ptr, rust_vec_len, data_len, ), - 72 => wire__crate__multimint__Multimint_get_invite_code_impl( + 76 => wire__crate__multimint__Multimint_get_invite_code_impl( port, ptr, rust_vec_len, data_len, ), - 73 => wire__crate__multimint__Multimint_get_ln_address_config_impl( + 77 => wire__crate__multimint__Multimint_get_ln_address_config_impl( port, ptr, rust_vec_len, data_len, ), - 74 => wire__crate__multimint__Multimint_get_max_withdrawable_amount_impl( + 78 => wire__crate__multimint__Multimint_get_max_withdrawable_amount_impl( port, ptr, rust_vec_len, data_len, ), - 75 => { + 79 => { wire__crate__multimint__Multimint_get_mnemonic_impl(port, ptr, rust_vec_len, data_len) } - 76 => wire__crate__multimint__Multimint_get_note_summary_impl( + 80 => wire__crate__multimint__Multimint_get_note_summary_impl( port, ptr, rust_vec_len, data_len, ), - 77 => wire__crate__multimint__Multimint_get_pegin_fee_quote_impl( + 81 => wire__crate__multimint__Multimint_get_pegin_fee_quote_impl( port, ptr, rust_vec_len, data_len, ), - 78 => wire__crate__multimint__Multimint_get_recovery_progress_impl( + 82 => wire__crate__multimint__Multimint_get_recovery_progress_impl( port, ptr, rust_vec_len, data_len, ), - 79 => { + 83 => { wire__crate__multimint__Multimint_get_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 80 => wire__crate__multimint__Multimint_guardian_add_gateway_impl( + 84 => wire__crate__multimint__Multimint_guardian_add_gateway_impl( port, ptr, rust_vec_len, data_len, ), - 81 => { + 85 => { wire__crate__multimint__Multimint_guardian_audit_impl(port, ptr, rust_vec_len, data_len) } - 82 => wire__crate__multimint__Multimint_guardian_backup_statistics_impl( + 86 => wire__crate__multimint__Multimint_guardian_backup_statistics_impl( port, ptr, rust_vec_len, data_len, ), - 83 => wire__crate__multimint__Multimint_guardian_list_gateways_impl( + 87 => wire__crate__multimint__Multimint_guardian_list_gateways_impl( port, ptr, rust_vec_len, data_len, ), - 84 => { + 88 => { wire__crate__multimint__Multimint_guardian_login_impl(port, ptr, rust_vec_len, data_len) } - 85 => wire__crate__multimint__Multimint_guardian_meta_accept_impl( + 89 => wire__crate__multimint__Multimint_guardian_meta_accept_impl( port, ptr, rust_vec_len, data_len, ), - 86 => wire__crate__multimint__Multimint_guardian_meta_propose_field_impl( + 90 => wire__crate__multimint__Multimint_guardian_meta_propose_field_impl( port, ptr, rust_vec_len, data_len, ), - 87 => wire__crate__multimint__Multimint_guardian_meta_state_impl( + 91 => wire__crate__multimint__Multimint_guardian_meta_state_impl( port, ptr, rust_vec_len, data_len, ), - 88 => wire__crate__multimint__Multimint_guardian_meta_withdraw_impl( + 92 => wire__crate__multimint__Multimint_guardian_meta_withdraw_impl( port, ptr, rust_vec_len, data_len, ), - 89 => wire__crate__multimint__Multimint_guardian_remove_gateway_impl( + 93 => wire__crate__multimint__Multimint_guardian_remove_gateway_impl( port, ptr, rust_vec_len, data_len, ), - 90 => wire__crate__multimint__Multimint_guardian_status_impl( + 94 => wire__crate__multimint__Multimint_guardian_status_impl( port, ptr, rust_vec_len, data_len, ), - 91 => wire__crate__multimint__Multimint_has_seed_phrase_ack_impl( + 95 => wire__crate__multimint__Multimint_has_seed_phrase_ack_impl( port, ptr, rust_vec_len, data_len, ), - 92 => wire__crate__multimint__Multimint_join_federation_impl( + 96 => wire__crate__multimint__Multimint_join_federation_impl( port, ptr, rust_vec_len, data_len, ), - 93 => wire__crate__multimint__Multimint_leave_federation_impl( + 97 => wire__crate__multimint__Multimint_leave_federation_impl( port, ptr, rust_vec_len, data_len, ), - 94 => wire__crate__multimint__Multimint_max_lightning_send_impl( + 98 => wire__crate__multimint__Multimint_max_lightning_send_impl( port, ptr, rust_vec_len, data_len, ), - 95 => wire__crate__multimint__Multimint_new_impl(port, ptr, rust_vec_len, data_len), - 96 => wire__crate__multimint__Multimint_parse_ecash_impl(port, ptr, rust_vec_len, data_len), - 97 => wire__crate__multimint__Multimint_probe_invoice_is_loopback_impl( + 99 => wire__crate__multimint__Multimint_new_impl(port, ptr, rust_vec_len, data_len), + 100 => { + wire__crate__multimint__Multimint_parse_ecash_impl(port, ptr, rust_vec_len, data_len) + } + 101 => wire__crate__multimint__Multimint_probe_invoice_is_loopback_impl( port, ptr, rust_vec_len, data_len, ), - 98 => wire__crate__multimint__Multimint_receive_impl(port, ptr, rust_vec_len, data_len), - 99 => wire__crate__multimint__Multimint_recheck_address_impl( + 102 => wire__crate__multimint__Multimint_receive_impl(port, ptr, rust_vec_len, data_len), + 103 => wire__crate__multimint__Multimint_recheck_address_impl( port, ptr, rust_vec_len, data_len, ), - 100 => wire__crate__multimint__Multimint_recover_ln_address_impl( + 104 => wire__crate__multimint__Multimint_recover_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 101 => wire__crate__multimint__Multimint_refresh_connections_impl( + 105 => wire__crate__multimint__Multimint_refresh_connections_impl( port, ptr, rust_vec_len, data_len, ), - 102 => wire__crate__multimint__Multimint_refresh_federation_meta_impl( + 106 => wire__crate__multimint__Multimint_refresh_federation_meta_impl( port, ptr, rust_vec_len, data_len, ), - 103 => wire__crate__multimint__Multimint_register_ln_address_impl( + 107 => wire__crate__multimint__Multimint_register_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 104 => { + 108 => { wire__crate__multimint__Multimint_reissue_ecash_impl(port, ptr, rust_vec_len, data_len) } - 105 => wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( + 109 => wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( port, ptr, rust_vec_len, data_len, ), - 106 => wire__crate__multimint__Multimint_remove_ln_address_impl( + 110 => wire__crate__multimint__Multimint_remove_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 107 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), - 108 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), - 109 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( + 111 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), + 112 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), + 113 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 110 => wire__crate__multimint__Multimint_set_federation_order_impl( + 114 => wire__crate__multimint__Multimint_set_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 111 => wire__crate__multimint__Multimint_set_fiat_currency_impl( + 115 => wire__crate__multimint__Multimint_set_fiat_currency_impl( port, ptr, rust_vec_len, data_len, ), - 112 => { + 116 => { wire__crate__multimint__Multimint_set_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 113 => { + 117 => { wire__crate__multimint__Multimint_transactions_impl(port, ptr, rust_vec_len, data_len) } - 114 => { + 118 => { wire__crate__multimint__Multimint_wallet_summary_impl(port, ptr, rust_vec_len, data_len) } - 115 => wire__crate__multimint__Multimint_withdraw_to_address_impl( + 119 => wire__crate__multimint__Multimint_withdraw_to_address_impl( port, ptr, rust_vec_len, data_len, ), - 116 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( + 120 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 117 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( + 121 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( port, ptr, rust_vec_len, data_len, ), - 118 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( + 122 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( port, ptr, rust_vec_len, data_len, ), - 119 => { + 123 => { wire__crate__nostr__NostrClient_get_all_contacts_impl(port, ptr, rust_vec_len, data_len) } - 120 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( + 124 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 121 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), - 122 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( + 125 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), + 126 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 123 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( + 127 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( port, ptr, rust_vec_len, data_len, ), - 124 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( + 128 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 125 => wire__crate__nostr__NostrClient_get_public_federations_impl( + 129 => wire__crate__nostr__NostrClient_get_public_federations_impl( port, ptr, rust_vec_len, data_len, ), - 126 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), - 127 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( + 130 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), + 131 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 128 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), - 129 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), - 130 => wire__crate__nostr__NostrClient_paginate_contacts_impl( + 132 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), + 133 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), + 134 => wire__crate__nostr__NostrClient_paginate_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 131 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( + 135 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 132 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( + 136 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 133 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), - 134 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( + 137 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), + 138 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 135 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( + 139 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 136 => { + 140 => { wire__crate__nostr__NostrClient_sync_contacts_impl(port, ptr, rust_vec_len, data_len) } - 137 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 141 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( + 141 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 145 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( port, ptr, rust_vec_len, data_len, ), - 168 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), - 169 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), - 170 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), - 171 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), - 172 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), - 173 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), - 174 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), - 175 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), - 176 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), - 177 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), - 178 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), - 179 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), - 180 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), - 181 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), - 182 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), - 183 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), - 184 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), - 185 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), - 186 => { + 172 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), + 173 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), + 174 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), + 175 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), + 176 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), + 177 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), + 178 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), + 179 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), + 180 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), + 181 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), + 182 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), + 183 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), + 184 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), + 185 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), + 186 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), + 187 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), + 188 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), + 189 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), + 190 => { wire__crate__compute_receive_amount_with_fees_impl(port, ptr, rust_vec_len, data_len) } - 187 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), - 188 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), - 189 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), - 190 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 191 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), - 192 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), - 193 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 194 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), - 195 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), - 196 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), - 197 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 198 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), - 199 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), - 200 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 201 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), - 202 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 203 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), - 204 => { + 191 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), + 192 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), + 193 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), + 194 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 195 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), + 196 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), + 197 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 198 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), + 199 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), + 200 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), + 201 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 202 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), + 203 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), + 204 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 205 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), + 206 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 207 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), + 208 => { wire__crate__get_invoice_from_lnaddress_or_lnurl_impl(port, ptr, rust_vec_len, data_len) } - 205 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), - 206 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), - 207 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), - 208 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 209 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), - 210 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 211 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 212 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 213 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), - 214 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), - 215 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 216 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), - 217 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), - 218 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), - 219 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), - 220 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), - 221 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), - 222 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), - 223 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), - 224 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), - 225 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), - 226 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), - 227 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), - 228 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), - 229 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), - 230 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), - 231 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), - 233 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), - 234 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), - 235 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), - 236 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), - 237 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), - 238 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), - 239 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), - 240 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), - 241 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), - 242 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), - 244 => { + 209 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), + 210 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), + 211 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), + 212 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 213 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), + 214 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 215 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 216 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 217 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), + 218 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), + 219 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 220 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), + 221 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), + 222 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), + 223 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), + 224 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), + 225 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), + 226 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), + 227 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), + 228 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), + 229 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), + 230 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), + 231 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), + 232 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), + 233 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), + 234 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), + 235 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), + 237 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), + 238 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), + 239 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), + 240 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), + 241 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), + 242 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), + 243 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), + 244 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), + 245 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), + 246 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), + 248 => { wire__crate__parse_scanned_text_for_federation_impl(port, ptr, rust_vec_len, data_len) } - 245 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), - 246 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), - 247 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), - 248 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), - 249 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), - 250 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), - 251 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 252 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), - 253 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), - 254 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), - 255 => wire__crate__remove_ln_address_impl(port, ptr, rust_vec_len, data_len), - 256 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 257 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), - 258 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), - 259 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), - 260 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 261 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), - 262 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 263 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 264 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 265 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 266 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), - 267 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 268 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), - 269 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), - 270 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), - 271 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), - 272 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 273 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), - 274 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), - 275 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 276 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), - 277 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), - 278 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), - 279 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), + 249 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), + 250 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), + 251 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), + 252 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), + 253 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), + 254 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), + 255 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 256 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), + 257 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), + 258 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), + 259 => wire__crate__remove_ln_address_impl(port, ptr, rust_vec_len, data_len), + 260 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 261 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), + 262 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), + 263 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), + 264 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 265 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), + 266 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 267 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 268 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 269 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 270 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), + 271 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 272 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), + 273 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), + 274 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), + 275 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), + 276 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 277 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), + 278 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), + 279 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 280 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), + 281 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), + 282 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), + 283 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -18799,145 +19022,165 @@ fn pde_ffi_dispatcher_sync_impl( rust_vec_len, data_len, ), - 138 => { + 47 => wire__crate__multimint__MaxWithdrawQuote_auto_accessor_get_amount_sats_impl( + ptr, + rust_vec_len, + data_len, + ), + 48 => wire__crate__multimint__MaxWithdrawQuote_auto_accessor_get_fees_impl( + ptr, + rust_vec_len, + data_len, + ), + 49 => wire__crate__multimint__MaxWithdrawQuote_auto_accessor_set_amount_sats_impl( + ptr, + rust_vec_len, + data_len, + ), + 50 => wire__crate__multimint__MaxWithdrawQuote_auto_accessor_set_fees_impl( + ptr, + rust_vec_len, + data_len, + ), + 142 => { wire__crate__fountain__OobNotesDecoder_add_fragment_impl(ptr, rust_vec_len, data_len) } - 139 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), - 140 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), - 142 => { + 143 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), + 144 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), + 146 => { wire__crate__multimint__OobNotesWrapper_amount_msats_impl(ptr, rust_vec_len, data_len) } - 143 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), - 144 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( + 147 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), + 148 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( ptr, rust_vec_len, data_len, ), - 145 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( + 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( ptr, rust_vec_len, data_len, ), - 146 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( + 150 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( ptr, rust_vec_len, data_len, ), - 147 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( + 151 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 148 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( + 152 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( ptr, rust_vec_len, data_len, ), - 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( + 153 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( ptr, rust_vec_len, data_len, ), - 150 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( + 154 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( ptr, rust_vec_len, data_len, ), - 151 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( + 155 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( ptr, rust_vec_len, data_len, ), - 152 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( + 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( ptr, rust_vec_len, data_len, ), - 153 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( + 157 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( ptr, rust_vec_len, data_len, ), - 154 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( + 158 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 155 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( + 159 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( ptr, rust_vec_len, data_len, ), - 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( + 160 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( ptr, rust_vec_len, data_len, ), - 157 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( + 161 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( ptr, rust_vec_len, data_len, ), - 158 => { + 162 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 159 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( + 163 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 160 => { + 164 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 161 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( + 165 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( ptr, rust_vec_len, data_len, ), - 162 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( + 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 163 => { + 167 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 164 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( + 168 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 165 => { + 169 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( + 170 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( ptr, rust_vec_len, data_len, ), - 167 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( + 171 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 232 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), - 243 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), + 236 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), + 247 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -19004,6 +19247,26 @@ impl flutter_rust_bridge::IntoIntoDart> for Database { } } +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for FrbWrapper> { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0) + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive + for FrbWrapper> +{ +} + +impl flutter_rust_bridge::IntoIntoDart>> + for EcashAppResult +{ + fn into_into_dart(self) -> FrbWrapper> { + self.into() + } +} + // Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for FrbWrapper> { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { @@ -19104,24 +19367,6 @@ impl flutter_rust_bridge::IntoIntoDart> { - fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { - flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0) - .into_dart() - } -} -impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive - for FrbWrapper> -{ -} - -impl flutter_rust_bridge::IntoIntoDart>> for EcashAppResult { - fn into_into_dart(self) -> FrbWrapper> { - self.into() - } -} - // Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for FrbWrapper> { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { @@ -19263,6 +19508,21 @@ impl flutter_rust_bridge::IntoIntoDart> for Ligh } } +// Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for FrbWrapper { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0) + .into_dart() + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for FrbWrapper {} + +impl flutter_rust_bridge::IntoIntoDart> for MaxWithdrawQuote { + fn into_into_dart(self) -> FrbWrapper { + self.into() + } +} + // Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for FrbWrapper { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { @@ -20801,6 +21061,20 @@ impl SseEncode for Database { } } +impl SseEncode for EcashAppResult { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + , + >, + >>::sse_encode( + flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), + serializer, + ); + } +} + impl SseEncode for EcashAppResult { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -20865,13 +21139,6 @@ impl SseEncode for EcashAppResult { } } -impl SseEncode for EcashAppResult { - // Codec=Sse (Serialization based), see doc to use other codecs - fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { - >>>::sse_encode(flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), serializer); - } -} - impl SseEncode for EventBus { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -20943,6 +21210,13 @@ impl SseEncode for LightningAddressKey { } } +impl SseEncode for MaxWithdrawQuote { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + >>::sse_encode(flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), serializer); + } +} + impl SseEncode for Multimint { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -21081,7 +21355,7 @@ impl SseEncode impl SseEncode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -21094,7 +21368,7 @@ impl SseEncode impl SseEncode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -21107,7 +21381,7 @@ impl SseEncode impl SseEncode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -21120,7 +21394,7 @@ impl SseEncode impl SseEncode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -21133,9 +21407,7 @@ impl SseEncode impl SseEncode for RustOpaqueMoi< - flutter_rust_bridge::for_generated::RustAutoOpaqueInner< - EcashAppResult, - >, + flutter_rust_bridge::for_generated::RustAutoOpaqueInner>, > { // Codec=Sse (Serialization based), see doc to use other codecs @@ -21147,7 +21419,11 @@ impl SseEncode } impl SseEncode - for RustOpaqueMoi>> + for RustOpaqueMoi< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + EcashAppResult, + >, + > { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -21251,6 +21527,17 @@ impl SseEncode } } +impl SseEncode + for RustOpaqueMoi> +{ + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + let (ptr, size) = self.sse_encode_raw(); + ::sse_encode(ptr, serializer); + ::sse_encode(size, serializer); + } +} + impl SseEncode for RustOpaqueMoi> { @@ -23018,6 +23305,28 @@ mod io { MoiArc::>::decrement_strong_count(ptr as _); } + #[unsafe(no_mangle)] + pub extern "C" fn frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + EcashAppResult, + >, + >::increment_strong_count(ptr as _); + } + + #[unsafe(no_mangle)] + pub extern "C" fn frbgen_ecashapp_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + EcashAppResult, + >, + >::decrement_strong_count(ptr as _); + } + #[unsafe(no_mangle)] pub extern "C" fn frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( ptr: *const std::ffi::c_void, @@ -23112,20 +23421,6 @@ mod io { >::decrement_strong_count(ptr as _); } - #[unsafe(no_mangle)] - pub extern "C" fn frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr: *const std::ffi::c_void, - ) { - MoiArc::>>::increment_strong_count(ptr as _); - } - - #[unsafe(no_mangle)] - pub extern "C" fn frbgen_ecashapp_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr: *const std::ffi::c_void, - ) { - MoiArc::>>::decrement_strong_count(ptr as _); - } - #[unsafe(no_mangle)] pub extern "C" fn frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( ptr: *const std::ffi::c_void, @@ -23238,6 +23533,20 @@ mod io { MoiArc::>::decrement_strong_count(ptr as _); } + #[unsafe(no_mangle)] + pub extern "C" fn frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::>::increment_strong_count(ptr as _); + } + + #[unsafe(no_mangle)] + pub extern "C" fn frbgen_ecashapp_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::>::decrement_strong_count(ptr as _); + } + #[unsafe(no_mangle)] pub extern "C" fn frbgen_ecashapp_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( ptr: *const std::ffi::c_void, @@ -23506,6 +23815,28 @@ mod web { MoiArc::>::decrement_strong_count(ptr as _); } + #[wasm_bindgen] + pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + EcashAppResult, + >, + >::increment_strong_count(ptr as _); + } + + #[wasm_bindgen] + pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::< + flutter_rust_bridge::for_generated::RustAutoOpaqueInner< + EcashAppResult, + >, + >::decrement_strong_count(ptr as _); + } + #[wasm_bindgen] pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultOOBNotesWrapper( ptr: *const std::ffi::c_void, @@ -23600,20 +23931,6 @@ mod web { >::decrement_strong_count(ptr as _); } - #[wasm_bindgen] - pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr: *const std::ffi::c_void, - ) { - MoiArc::>>::increment_strong_count(ptr as _); - } - - #[wasm_bindgen] - pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEcashAppResultu64( - ptr: *const std::ffi::c_void, - ) { - MoiArc::>>::decrement_strong_count(ptr as _); - } - #[wasm_bindgen] pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerEventBusMultimintEvent( ptr: *const std::ffi::c_void, @@ -23726,6 +24043,20 @@ mod web { MoiArc::>::decrement_strong_count(ptr as _); } + #[wasm_bindgen] + pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::>::increment_strong_count(ptr as _); + } + + #[wasm_bindgen] + pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMaxWithdrawQuote( + ptr: *const std::ffi::c_void, + ) { + MoiArc::>::decrement_strong_count(ptr as _); + } + #[wasm_bindgen] pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( ptr: *const std::ffi::c_void, diff --git a/rust/ecashapp/src/lib.rs b/rust/ecashapp/src/lib.rs index 7b347134..8bd5cce0 100644 --- a/rust/ecashapp/src/lib.rs +++ b/rust/ecashapp/src/lib.rs @@ -32,7 +32,7 @@ use lnurl_client::LnurlWithdrawParams; use multimint::{ EcashSendFees, FederationMeta, FederationSelector, GuardianAuditSummary, GuardianBackupStatistics, GuardianMetaState, GuardianStatusSummary, LightningSendOutcome, - LogLevel, Multimint, MultimintCreation, MultimintEvent, OOBNotesWrapper, + LogLevel, MaxWithdrawQuote, Multimint, MultimintCreation, MultimintEvent, OOBNotesWrapper, PaymentPreviewWithGateways, PeginFeeQuote, ReceiveAmount, RecoveryModule, ReissueFees, Transaction, Utxo, WithdrawFees, WithdrawFeesResponse, }; @@ -818,7 +818,7 @@ pub async fn await_withdraw( pub async fn get_max_withdrawable_amount( federation_id: &FederationId, address: String, -) -> Result { +) -> Result { let multimint = get_multimint(); multimint .get_max_withdrawable_amount(federation_id, address) diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index f7916f80..7b78e979 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -224,6 +224,16 @@ pub enum WithdrawFees { V2 { fee_sats: u64 }, } +/// A "send everything" on-chain sweep: the largest amount that still funds +/// once every fee is paid, with the quote it was sized against. The two go to +/// `withdraw_to_address` as a pair, so the send pays exactly the miner fee the +/// amount assumed. +#[derive(Clone, PartialEq, Serialize, Debug)] +pub struct MaxWithdrawQuote { + pub amount_sats: u64, + pub fees: WithdrawFeesResponse, +} + pub struct ReissueFees { pub total_msats: u64, pub input_msats: u64, @@ -5257,7 +5267,7 @@ impl Multimint { &self, federation_id: &FederationId, address: String, - ) -> EcashAppResult { + ) -> EcashAppResult { let client = self.get_client(federation_id).await?; self.wallet_handler .get_max_withdrawable_amount(&client, address) diff --git a/rust/ecashapp/src/wallet/mod.rs b/rust/ecashapp/src/wallet/mod.rs index 68564768..b4aaa47b 100644 --- a/rust/ecashapp/src/wallet/mod.rs +++ b/rust/ecashapp/src/wallet/mod.rs @@ -37,7 +37,8 @@ use crate::{ get_event_bus, info_to_flutter, multimint::{ AwaitingConfsEvent, ClaimedEvent, ConfirmedEvent, DepositEventKind, JoinedFederation, - MempoolEvent, MultimintEvent, OnChainWithdrawalMeta, WithdrawFees, WithdrawFeesResponse, + MaxWithdrawQuote, MempoolEvent, MultimintEvent, OnChainWithdrawalMeta, WithdrawFees, + WithdrawFeesResponse, }, payment_error_to_flutter, }; @@ -882,50 +883,12 @@ impl WalletHandler { } if let Ok(walletv2) = client.get_first_module::() { - // walletv2 charges a flat send fee; the on-chain tx is always - // 1-in/1-out, so its vbytes are a per-federation constant taken from - // the wallet config. - let address = bitcoin::Address::from_str(&address) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - address - .require_network(walletv2.get_network()) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - - let fee_sats = walletv2 + Self::require_walletv2_address(client, &address)?; + let fee = walletv2 .send_fee() .await - .map_err(EcashAppError::from_display)? - .to_sat(); - let tx_size_vbytes = Self::walletv2_send_tx_vbytes(client).await?; - let fee_rate_sats_per_vb = if tx_size_vbytes > 0 { - fee_sats as f64 / f64::from(tx_size_vbytes) - } else { - 0.0 - }; - - // The amount is bounded above, but `fee_sats` is federation-reported - // and could still push the sum past `u64::MAX`. - let funded_sats = amount_sats.checked_add(fee_sats).ok_or_else(|| { - EcashAppError::other(format!( - "withdrawal amount {amount_sats} sats plus network fee {fee_sats} sats is out of range" - )) - })?; - - // Federation fee for funding the on-chain output (withdrawal amount - // plus the miner fee) from ecash. Display-only, so degrade to 0. - let federation_fee_msats = walletv2 - .send_fee_quote(bitcoin::Amount::from_sat(funded_sats)) - .await - .map(|q| q.total().get_bitcoin().msats) - .unwrap_or(0); - - return Ok(WithdrawFeesResponse { - fee_amount: fee_sats, - fee_rate_sats_per_vb, - tx_size_vbytes, - federation_fee_msats, - fees: WithdrawFees::V2 { fee_sats }, - }); + .map_err(EcashAppError::from_display)?; + return Self::walletv2_withdraw_fees(client, amount_sats, fee).await; } let wallet_module = client @@ -969,6 +932,69 @@ impl WalletHandler { }) } + /// Parses `address` and checks it belongs to the walletv2 federation's + /// network. + fn require_walletv2_address( + client: &ClientHandleArc, + address: &str, + ) -> EcashAppResult { + let walletv2 = client + .get_first_module::() + .map_err(|e| EcashAppError::other(format!("walletv2 module unavailable: {e:#}")))?; + let address = bitcoin::Address::from_str(address) + .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; + address + .require_network(walletv2.get_network()) + .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string())) + } + + /// Prices a walletv2 send of `amount_sats` at the given miner `fee`. + /// + /// walletv2 charges a flat send fee; the on-chain tx is always 1-in/1-out, + /// so its vbytes are a per-federation constant taken from the wallet + /// config. Takes the fee rather than fetching it so that a sweep is priced + /// at the very fee it was sized against. + async fn walletv2_withdraw_fees( + client: &ClientHandleArc, + amount_sats: u64, + fee: bitcoin::Amount, + ) -> EcashAppResult { + let walletv2 = client + .get_first_module::() + .map_err(|e| EcashAppError::other(format!("walletv2 module unavailable: {e:#}")))?; + let fee_sats = fee.to_sat(); + let tx_size_vbytes = Self::walletv2_send_tx_vbytes(client).await?; + let fee_rate_sats_per_vb = if tx_size_vbytes > 0 { + fee_sats as f64 / f64::from(tx_size_vbytes) + } else { + 0.0 + }; + + // The amount is bounded above by the caller, but `fee_sats` is + // federation-reported and could still push the sum past `u64::MAX`. + let funded_sats = amount_sats.checked_add(fee_sats).ok_or_else(|| { + EcashAppError::other(format!( + "withdrawal amount {amount_sats} sats plus network fee {fee_sats} sats is out of range" + )) + })?; + + // Federation fee for funding the on-chain output (withdrawal amount + // plus the miner fee) from ecash. Display-only, so degrade to 0. + let federation_fee_msats = walletv2 + .send_fee_quote(bitcoin::Amount::from_sat(funded_sats)) + .await + .map(|q| q.total().get_bitcoin().msats) + .unwrap_or(0); + + Ok(WithdrawFeesResponse { + fee_amount: fee_sats, + fee_rate_sats_per_vb, + tx_size_vbytes, + federation_fee_msats, + fees: WithdrawFees::V2 { fee_sats }, + }) + } + /// Reads the federation's constant pegout transaction size (vbytes) from the /// walletv2 client config. walletv2 peg-outs are always 1-in/1-out, so this /// is a per-federation constant. @@ -1104,42 +1130,55 @@ impl WalletHandler { Ok(txid) } - /// Returns the largest amount that can be sent to `address` after fees. + /// Sizes a sweep of the whole balance to `address` and prices it, in one + /// quote. The amount and its fees go to [`Self::withdraw_to_address`] + /// together, so the send pays exactly the miner fee the amount assumed. pub(crate) async fn get_max_withdrawable_amount( &self, client: &ClientHandleArc, address: String, - ) -> EcashAppResult { + ) -> EcashAppResult { if let Ok(walletv2) = client.get_first_module::() { - let address = bitcoin::Address::from_str(&address) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - address - .require_network(walletv2.get_network()) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; + Self::require_walletv2_address(client, &address)?; - let balance_sats = client + let balance = client .get_balance_for_btc() .await - .map_err(EcashAppError::from_display)? - .msats - / 1000; - let fee_sats = walletv2 + .map_err(EcashAppError::from_display)?; + let fee = walletv2 .send_fee() .await - .map_err(EcashAppError::from_display)? - .to_sat(); - let max = balance_sats - .checked_sub(fee_sats) - .ok_or_else(|| EcashAppError::other("Not enough funds to pay fees"))?; - return Ok(max); + .map_err(EcashAppError::from_display)?; + + // Sending `value` funds an output of `value + fee` from ecash, and + // the federation charges its own fees on top of that: the wallet + // output fee, the mint's input and change fees, dust. Subtracting + // the miner fee alone therefore sized a sweep the client could + // never fund. fedimint finds the largest value that still funds by + // searching its real fee quote, since those fees move in steps + // with note selection and change rather than linearly. + // + // The quote below is priced at this same `fee` on purpose: the + // required feerate rises with each pending federation + // transaction, and a value sized against a stale one is rejected. + let amount = walletv2 + .max_sendable_amount(balance, fee) + .await + .map_err(EcashAppError::from_display)?; + let fees = Self::walletv2_withdraw_fees(client, amount.to_sat(), fee).await?; + return Ok(MaxWithdrawQuote { + amount_sats: amount.to_sat(), + fees, + }); } + // walletv1 still sizes against the miner fee alone. let wallet_module = client .get_first_module::() .map_err(|e| EcashAppError::other(format!("wallet module unavailable: {e:#}")))?; - let address = bitcoin::Address::from_str(&address) + let parsed = bitcoin::Address::from_str(&address) .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - let address = address + let parsed = parsed .require_network(wallet_module.get_network()) .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; let balance = bitcoin::Amount::from_sat( @@ -1151,14 +1190,18 @@ impl WalletHandler { / 1000, ); let fees = wallet_module - .get_withdraw_fees(&address, balance) + .get_withdraw_fees(&parsed, balance) .await .map_err(EcashAppError::from_display)?; let max_withdrawable = balance .checked_sub(fees.amount()) .ok_or_else(|| EcashAppError::other("Not enough funds to pay fees"))?; - Ok(max_withdrawable.to_sat()) + let amount_sats = max_withdrawable.to_sat(); + let fees = self + .calculate_withdraw_fees(client, address, amount_sats) + .await?; + Ok(MaxWithdrawQuote { amount_sats, fees }) } } diff --git a/test/federation_expiry_screen_test.dart b/test/federation_expiry_screen_test.dart index a48f4e26..48d977fb 100644 --- a/test/federation_expiry_screen_test.dart +++ b/test/federation_expiry_screen_test.dart @@ -145,12 +145,20 @@ void main() { lessThan(top(tester, en.federationExpiryManageLightningAddress)), ); + // Anything under a whole sat cannot go on-chain, so it is not offered. await pumpScreen( tester, expiryTimestamp: inAMonth, - balanceMsats: BigInt.zero, + balanceMsats: BigInt.from(999), ); expect(find.text(en.federationExpirySendOnchain), findsNothing); + + await pumpScreen( + tester, + expiryTimestamp: inAMonth, + balanceMsats: BigInt.from(1000), + ); + expect(find.text(en.federationExpirySendOnchain), findsOneWidget); }); testWidgets( From 41412d46274c5087040dd1a786676337b7cb7693 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Tue, 15 Sep 2026 10:07:04 -0500 Subject: [PATCH 05/17] fix: walletv1 max sweep --- rust/ecashapp/src/wallet/mod.rs | 93 ++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/rust/ecashapp/src/wallet/mod.rs b/rust/ecashapp/src/wallet/mod.rs index b4aaa47b..341b7681 100644 --- a/rust/ecashapp/src/wallet/mod.rs +++ b/rust/ecashapp/src/wallet/mod.rs @@ -16,7 +16,7 @@ use fedimint_core::{ }; use fedimint_eventlog::Event; use fedimint_wallet_client::{ - api::WalletFederationApi, client_db::TweakIdx, DepositStateV2, WalletClientModule, + api::WalletFederationApi, client_db::TweakIdx, DepositStateV2, PegOutFees, WalletClientModule, WalletOperationMeta, WalletOperationMetaVariant, WithdrawState, }; use fedimint_walletv2_client::{ @@ -894,20 +894,48 @@ impl WalletHandler { let wallet_module = client .get_first_module::() .map_err(|e| EcashAppError::other(format!("wallet module unavailable: {e:#}")))?; - let address = bitcoin::Address::from_str(&address) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - let address = address - .require_network(wallet_module.get_network()) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - let amount = bitcoin::Amount::from_sat(amount_sats); - let fees = wallet_module - .get_withdraw_fees(&address, amount) + let parsed = Self::require_walletv1_address(client, &address)?; + let peg_out_fees = wallet_module + .get_withdraw_fees(&parsed, bitcoin::Amount::from_sat(amount_sats)) .await .map_err(EcashAppError::from_display)?; - let meta = OnChainWithdrawalMeta::from_peg_out_fees(&fees); + Self::walletv1_withdraw_fees(client, amount_sats, peg_out_fees).await + } - // The amount is bounded above, but `fee_sats` is federation-reported and - // could still push the sum past `u64::MAX`. + /// Parses `address` and checks it belongs to the walletv1 federation's + /// network. + fn require_walletv1_address( + client: &ClientHandleArc, + address: &str, + ) -> EcashAppResult { + let wallet_module = client + .get_first_module::() + .map_err(|e| EcashAppError::other(format!("wallet module unavailable: {e:#}")))?; + let address = bitcoin::Address::from_str(address) + .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; + address + .require_network(wallet_module.get_network()) + .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string())) + } + + /// Prices a walletv1 peg-out of `amount_sats` at the given `peg_out_fees`. + /// + /// Takes the fees rather than quoting them so that a sweep is priced at + /// the very fees it was sized against: the federation rebuilds the peg-out + /// for the exact amount submitted and rejects a declared weight that does + /// not match what it computed. + async fn walletv1_withdraw_fees( + client: &ClientHandleArc, + amount_sats: u64, + peg_out_fees: PegOutFees, + ) -> EcashAppResult { + let wallet_module = client + .get_first_module::() + .map_err(|e| EcashAppError::other(format!("wallet module unavailable: {e:#}")))?; + let meta = OnChainWithdrawalMeta::from_peg_out_fees(&peg_out_fees); + + // The amount is bounded above by the caller, but `fee_sats` is + // federation-reported and could still push the sum past `u64::MAX`. let funded_sats = amount_sats.checked_add(meta.fee_sats).ok_or_else(|| { EcashAppError::other(format!( "withdrawal amount {amount_sats} sats plus network fee {} sats is out of range", @@ -928,7 +956,7 @@ impl WalletHandler { fee_rate_sats_per_vb: meta.fee_rate_sats_per_vb, tx_size_vbytes: meta.tx_size_vb, federation_fee_msats, - fees: WithdrawFees::V1(fees), + fees: WithdrawFees::V1(peg_out_fees), }) } @@ -1172,35 +1200,28 @@ impl WalletHandler { }); } - // walletv1 still sizes against the miner fee alone. let wallet_module = client .get_first_module::() .map_err(|e| EcashAppError::other(format!("wallet module unavailable: {e:#}")))?; - let parsed = bitcoin::Address::from_str(&address) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - let parsed = parsed - .require_network(wallet_module.get_network()) - .map_err(|e| EcashAppError::InvalidBitcoinAddress(e.to_string()))?; - let balance = bitcoin::Amount::from_sat( - client - .get_balance_for_btc() - .await - .map_err(EcashAppError::from_display)? - .msats - / 1000, - ); - let fees = wallet_module - .get_withdraw_fees(&parsed, balance) + let parsed = Self::require_walletv1_address(client, &address)?; + let balance = client + .get_balance_for_btc() .await .map_err(EcashAppError::from_display)?; - let max_withdrawable = balance - .checked_sub(fees.amount()) - .ok_or_else(|| EcashAppError::other("Not enough funds to pay fees"))?; - let amount_sats = max_withdrawable.to_sat(); - let fees = self - .calculate_withdraw_fees(client, address, amount_sats) - .await?; + // As for walletv2: the peg-out output is funded from ecash and the + // federation charges its own fees on top, so fedimint searches its real + // fee quote for the largest amount that still funds. It hands back the + // peg-out fees re-quoted at that amount, and those must go to the send + // unchanged: the guardians rebuild the transaction for the exact amount + // and reject a declared weight that differs. A v1 sweep sizes against + // an upper-bound miner fee, so it can leave a small remainder behind. + let (amount, peg_out_fees) = wallet_module + .max_withdrawable_amount(&parsed, balance) + .await + .map_err(EcashAppError::from_display)?; + let amount_sats = amount.to_sat(); + let fees = Self::walletv1_withdraw_fees(client, amount_sats, peg_out_fees).await?; Ok(MaxWithdrawQuote { amount_sats, fees }) } } From 8fe499e8081ce1be2b7b6944331dd981204c4504 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Tue, 15 Sep 2026 10:32:28 -0500 Subject: [PATCH 06/17] feat: prevent receives and lightning address registrations on expiring federation --- lib/l10n/app_en.arb | 9 +++ lib/l10n/app_es.arb | 3 + lib/ln_address.dart | 78 +++++++++++++++++++++++-- lib/screens/dashboard.dart | 18 +++++- lib/screens/federation_info_screen.dart | 11 +++- 5 files changed, 111 insertions(+), 8 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 6898dabe..406a784b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2244,6 +2244,15 @@ "federationExpiryManageLightningAddress": "Manage Lightning Address", "@federationExpiryManageLightningAddress": {}, + "federationExpiryReceiveDisabled": "This federation is shutting down, so it can no longer receive funds.", + "@federationExpiryReceiveDisabled": {}, + + "lnAddressRegistrationClosed": "This federation is shutting down, so new Lightning Addresses can't be registered on it.", + "@lnAddressRegistrationClosed": {}, + + "lnAddressRemoveCurrent": "This federation is shutting down. Please remove the current one.", + "@lnAddressRemoveCurrent": {}, + "federationExpiryFindFederation": "Find a federation", "@federationExpiryFindFederation": {}, diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 28ad5f84..0109bf5b 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -659,6 +659,9 @@ "federationExpiryStepLeave": "Abandona esta federación cuando hayas sacado tu saldo y eliminado tu Dirección Lightning.", "federationExpirySendOnchain": "Enviar on-chain", "federationExpiryManageLightningAddress": "Gestionar Dirección Lightning", + "federationExpiryReceiveDisabled": "Esta federación va a cerrar, así que ya no puede recibir fondos.", + "lnAddressRegistrationClosed": "Esta federación va a cerrar, así que no se pueden registrar nuevas Direcciones Lightning en ella.", + "lnAddressRemoveCurrent": "Esta federación va a cerrar. Por favor, elimina la actual.", "federationExpiryFindFederation": "Buscar una federación", diff --git a/lib/ln_address.dart b/lib/ln_address.dart index 23032e5f..6e9818a5 100644 --- a/lib/ln_address.dart +++ b/lib/ln_address.dart @@ -61,6 +61,21 @@ class _LightningAddressScreenState extends State { /// Only then is there something to remove. LightningAddressConfig? _existingConfig; + /// Federations whose guardians have set a shutdown date, read for every + /// federation before the form can show, so the registration lock never + /// depends on which federation was selected last or by whom. Keyed by the + /// same instances the dropdown offers. + final Set _expiringFederations = {}; + + /// True while the selected federation is shutting down: new registrations + /// are closed and only removal stays available. + bool get _selectedFederationExpiring => + _expiringFederations.contains(_selectedFederation); + + /// Set once the user picks a federation, so the initializer's sweep through + /// the list stops overriding that choice. + bool _userPickedFederation = false; + @override void initState() { super.initState(); @@ -99,15 +114,41 @@ class _LightningAddressScreenState extends State { } } + /// Whether [fed]'s guardians have set a shutdown date. Unreadable meta + /// counts as not shutting down, which is how the screen behaved before. + Future _isExpiring(FederationSelector fed) async { + try { + final meta = await getFederationMeta(federationId: fed.federationId); + return meta.expiryTimestamp != null; + } catch (e) { + AppLogger.instance.warn("Could not read federation meta: $e"); + return false; + } + } + Future _initialize() async { _usernameController.addListener(_onUsernameChanged); + + // Before the form can show: which federations are shutting down. + final candidates = [ + for (final (fed, recovering) in widget.federations) + if (!recovering) fed, + ]; + final expiring = await Future.wait(candidates.map(_isExpiring)); + if (!mounted) return; + setState(() { + for (final (index, fed) in candidates.indexed) { + if (expiring[index]) _expiringFederations.add(fed); + } + }); + await _updateDomains(); // The caller's federation, if it named one the dropdown can show. final wanted = widget.initialFederationId; if (wanted != null) { for (final (fed, recovering) in widget.federations) { - if (recovering) continue; + if (recovering || _userPickedFederation) continue; final id = await federationIdToString(federationId: fed.federationId); if (id == wanted) { await _onFederationSet(fed); @@ -119,6 +160,8 @@ class _LightningAddressScreenState extends State { // Otherwise the first federation that already has an address. if (widget.federations.isNotEmpty) { for (final fed in widget.federations) { + // A choice the user made meanwhile wins over this sweep. + if (_userPickedFederation) break; if (await _onFederationSet(fed.$1)) { break; } @@ -172,6 +215,7 @@ class _LightningAddressScreenState extends State { } Future _onRegisteredPressed() async { + if (_selectedFederationExpiring) return; setState(() => _registering = true); try { final username = _usernameController.text.trim(); @@ -275,6 +319,7 @@ class _LightningAddressScreenState extends State { } final meta = await getFederationMeta(federationId: fed.federationId); + if (!mounted || _selectedFederation != fed) return hasConfig; if (meta.recurringdApi != null) { setState(() { _recurringdApi = meta.recurringdApi!; @@ -306,6 +351,10 @@ class _LightningAddressScreenState extends State { children: [ if (_domains.isNotEmpty) ...[ DropdownButtonFormField( + // A form field reads initialValue once, so it is recreated when + // the selection changes under it; otherwise the initializer's + // pick was never shown and the field looked unset. + key: ValueKey(_selectedFederation), decoration: InputDecoration( labelText: context.l10n.selectAFederation, ), @@ -320,6 +369,7 @@ class _LightningAddressScreenState extends State { ) .toList(), onChanged: (value) { + _userPickedFederation = true; _onFederationSet(value); _onUsernameChanged(); }, @@ -331,6 +381,7 @@ class _LightningAddressScreenState extends State { flex: 3, child: TextFormField( controller: _usernameController, + enabled: !_selectedFederationExpiring, decoration: InputDecoration(labelText: context.l10n.username), ), ), @@ -353,11 +404,14 @@ class _LightningAddressScreenState extends State { ), ) .toList(), - onChanged: (value) { - setState(() { - _selectedDomain = value; - }); - }, + onChanged: + _selectedFederationExpiring + ? null + : (value) { + setState(() { + _selectedDomain = value; + }); + }, ), ), ], @@ -417,12 +471,24 @@ class _LightningAddressScreenState extends State { ), ), ), + if (_selectedFederationExpiring) + Padding( + padding: const EdgeInsets.only(top: 16), + child: Text( + _existingConfig != null + ? context.l10n.lnAddressRemoveCurrent + : context.l10n.lnAddressRegistrationClosed, + textAlign: TextAlign.center, + style: TextStyle(color: Theme.of(context).colorScheme.error), + ), + ), const SizedBox(height: 32), Center( child: ElevatedButton( onPressed: (_selectedFederation != null && _status is LNAddressStatus_Available && + !_selectedFederationExpiring && !_registering) ? () { _onRegisteredPressed(); diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 8607f16f..43b1294e 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -18,6 +18,7 @@ import 'package:ecashapp/screens/transactions_screen.dart'; import 'package:ecashapp/onchain_receive.dart'; import 'package:ecashapp/scan.dart'; import 'package:ecashapp/theme.dart'; +import 'package:ecashapp/toast.dart'; import 'package:ecashapp/models.dart'; import 'package:ecashapp/screens/federation_expiry_screen.dart'; @@ -73,6 +74,10 @@ class _DashboardState extends State { bool get _isShuttingDown => _expiryTimestamp != null || _successorInvite != null; + /// Once the guardians have set a shutdown date, taking in more funds only + /// deepens the hole the user has to dig out of; receiving is closed. + bool get _receiveDisabled => _expiryTimestamp != null; + List _recentTransactions = []; bool _isLoadingTransactions = true; @@ -426,6 +431,15 @@ class _DashboardState extends State { } void _onReceivePressed() async { + if (_receiveDisabled) { + ToastService().show( + message: context.l10n.federationExpiryReceiveDisabled, + duration: const Duration(seconds: 5), + onTap: () {}, + icon: const Icon(Icons.error), + ); + return; + } if (_selectedPaymentType == PaymentType.lightning) { await Navigator.push( context, @@ -562,7 +576,9 @@ class _DashboardState extends State { SpeedDialChild( child: const Icon(Icons.download), label: context.l10n.receive, - backgroundColor: Colors.green, + // Greyed rather than hidden: the tap explains why. + backgroundColor: + _receiveDisabled ? Colors.grey : Colors.green, onTap: () => _scheduleAction(_onReceivePressed), ), if (balanceMsats != null && balanceMsats! > BigInt.zero) ...[ diff --git a/lib/screens/federation_info_screen.dart b/lib/screens/federation_info_screen.dart index 8930b2ee..b2c3cadb 100644 --- a/lib/screens/federation_info_screen.dart +++ b/lib/screens/federation_info_screen.dart @@ -63,6 +63,11 @@ class _FederationInfoScreenState extends State { String? _welcomeMessage; String? _imageUrl; + /// Shutdown date the guardians published, if any. A federation with one + /// takes no new Lightning Address registrations, so the automatic claim + /// after joining is skipped. + BigInt? _expiryTimestamp; + // Joinable preview loading state. bool _isLoadingMeta = false; Object? _loadError; @@ -111,6 +116,7 @@ class _FederationInfoScreenState extends State { _fed = meta.selector; _welcomeMessage = meta.welcome; _imageUrl = meta.picture; + _expiryTimestamp = meta.expiryTimestamp; }); } catch (e) { AppLogger.instance.warn("Could not reload federation meta: $e"); @@ -130,6 +136,7 @@ class _FederationInfoScreenState extends State { _fed = meta.selector; _welcomeMessage = meta.welcome; _imageUrl = meta.picture; + _expiryTimestamp = meta.expiryTimestamp; _isLoadingMeta = false; }); _subscribePeers(); @@ -303,7 +310,9 @@ class _FederationInfoScreenState extends State { AppLogger.instance.error("Could not backup Nostr invite codes: $e"); } - await _claimLnAddress(fed); + if (_expiryTimestamp == null) { + await _claimLnAddress(fed); + } if (widget.ecash != null) { _redeemEcash(widget.ecash!); From d420473aa880e6a8abdd37dba684d9d24d9740f1 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Tue, 15 Sep 2026 10:53:26 -0500 Subject: [PATCH 07/17] feat: add expiration banner to preview screen --- lib/l10n/app_en.arb | 12 +- lib/l10n/app_es.arb | 8 +- lib/screens/federation_info_screen.dart | 60 ++++++++- lib/widgets/federation_expiry_banner.dart | 142 +++++++++++++--------- test/federation_expiry_banner_test.dart | 40 +++++- 5 files changed, 193 insertions(+), 69 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 406a784b..7ce97a58 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2127,7 +2127,7 @@ "federationExpiryBannerTitle": "This federation is shutting down", "@federationExpiryBannerTitle": {}, - "federationExpiryBannerSubtitle": "Closes on {date}. Tap for details.", + "federationExpiryBannerSubtitle": "Closes on {date}.", "@federationExpiryBannerSubtitle": { "placeholders": { "date": { @@ -2136,7 +2136,7 @@ } }, - "federationExpiryBannerSubtitlePast": "Closed on {date}. Tap for details.", + "federationExpiryBannerSubtitlePast": "Closed on {date}.", "@federationExpiryBannerSubtitlePast": { "placeholders": { "date": { @@ -2145,9 +2145,15 @@ } }, - "federationExpiryBannerSubtitleSuccessor": "The guardians named a successor federation. Tap for details.", + "federationExpiryBannerSubtitleSuccessor": "The guardians named a successor federation.", "@federationExpiryBannerSubtitleSuccessor": {}, + "federationExpiryBannerTap": "Tap for details.", + "@federationExpiryBannerTap": {}, + + "federationExpiryBannerJoinHint": "Join only to recover funds you already hold here.", + "@federationExpiryBannerJoinHint": {}, + "federationExpiryTitle": "Federation shutdown", "@federationExpiryTitle": {}, diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 0109bf5b..d9ce0612 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -615,11 +615,13 @@ "federationExpiryBannerTitle": "Esta federación va a cerrar", - "federationExpiryBannerSubtitle": "Cierra el {date}. Toca para ver detalles.", + "federationExpiryBannerSubtitle": "Cierra el {date}.", - "federationExpiryBannerSubtitlePast": "Cerró el {date}. Toca para ver detalles.", + "federationExpiryBannerSubtitlePast": "Cerró el {date}.", - "federationExpiryBannerSubtitleSuccessor": "Los guardianes nombraron una federación sucesora. Toca para ver detalles.", + "federationExpiryBannerSubtitleSuccessor": "Los guardianes nombraron una federación sucesora.", + "federationExpiryBannerTap": "Toca para ver detalles.", + "federationExpiryBannerJoinHint": "Únete solo para recuperar fondos que ya tengas aquí.", "federationExpiryTitle": "Cierre de la federación", diff --git a/lib/screens/federation_info_screen.dart b/lib/screens/federation_info_screen.dart index b2c3cadb..7fc8012f 100644 --- a/lib/screens/federation_info_screen.dart +++ b/lib/screens/federation_info_screen.dart @@ -8,6 +8,7 @@ import 'package:ecashapp/multimint.dart'; import 'package:ecashapp/nwc.dart'; import 'package:ecashapp/toast.dart'; import 'package:ecashapp/utils.dart'; +import 'package:ecashapp/widgets/federation_expiry_banner.dart'; import 'package:ecashapp/widgets/gateways.dart'; import 'package:ecashapp/widgets/leave_federation_dialog.dart'; import 'package:flutter/material.dart'; @@ -63,10 +64,10 @@ class _FederationInfoScreenState extends State { String? _welcomeMessage; String? _imageUrl; - /// Shutdown date the guardians published, if any. A federation with one - /// takes no new Lightning Address registrations, so the automatic claim - /// after joining is skipped. + /// Shutdown announcement the guardians published, if any, for the banner + /// on a joinable preview. BigInt? _expiryTimestamp; + String? _successorInvite; // Joinable preview loading state. bool _isLoadingMeta = false; @@ -86,6 +87,27 @@ class _FederationInfoScreenState extends State { _imageUrl = widget.imageUrl; _subscribePeers(); _subscribeMetaUpdates(); + // A preview opened from a scanned or pasted invite arrives with the + // federation already resolved and skips _loadMeta, so the shutdown + // notice has to be read here or it is never shown. + if (widget.joinable) _loadShutdownNotice(); + } + } + + /// Reads the guardians' shutdown announcement for a joinable preview whose + /// caller supplied the federation itself. Same cached meta the caller used. + Future _loadShutdownNotice() async { + final inviteCode = widget.inviteCode; + if (inviteCode == null) return; + try { + final meta = await getFederationMeta(inviteCode: inviteCode); + if (!mounted) return; + setState(() { + _expiryTimestamp = meta.expiryTimestamp; + _successorInvite = meta.successorInvite; + }); + } catch (e) { + AppLogger.instance.warn("Could not read federation meta: $e"); } } @@ -117,6 +139,7 @@ class _FederationInfoScreenState extends State { _welcomeMessage = meta.welcome; _imageUrl = meta.picture; _expiryTimestamp = meta.expiryTimestamp; + _successorInvite = meta.successorInvite; }); } catch (e) { AppLogger.instance.warn("Could not reload federation meta: $e"); @@ -137,6 +160,7 @@ class _FederationInfoScreenState extends State { _welcomeMessage = meta.welcome; _imageUrl = meta.picture; _expiryTimestamp = meta.expiryTimestamp; + _successorInvite = meta.successorInvite; _isLoadingMeta = false; }); _subscribePeers(); @@ -310,7 +334,11 @@ class _FederationInfoScreenState extends State { AppLogger.instance.error("Could not backup Nostr invite codes: $e"); } - if (_expiryTimestamp == null) { + // A federation with a shutdown date takes no new Lightning Address + // registrations. Decided from a fresh read of the joined federation's + // meta rather than from preview state, which depends on how the preview + // was opened and on whether its load had finished. + if (!await _isShuttingDown(fed)) { await _claimLnAddress(fed); } @@ -340,6 +368,19 @@ class _FederationInfoScreenState extends State { } } + /// Whether [fed]'s guardians have set a shutdown date. When the meta cannot + /// be read this errs on the side of not claiming: an address registered on a + /// federation that is closing is worse than one the user claims by hand. + Future _isShuttingDown(FederationSelector fed) async { + try { + final meta = await getFederationMeta(federationId: fed.federationId); + return meta.expiryTimestamp != null; + } catch (e) { + AppLogger.instance.warn("Could not read federation meta: $e"); + return true; + } + } + Future _claimLnAddress(FederationSelector fed) async { String defaultLnAddress = "https://ecash.love"; String defaultRecurringd = "https://recurring.ecash.love"; @@ -971,6 +1012,17 @@ class _FederationInfoScreenState extends State { ), ), ), + // Someone about to join should see this before anything + // else. Joining stays possible: they may hold funds here + // that they need to recover or move out. + if (widget.joinable && + (_expiryTimestamp != null || _successorInvite != null)) + FederationExpiryBanner( + expiryTimestamp: _expiryTimestamp, + onTap: null, + compact: false, + note: context.l10n.federationExpiryBannerJoinHint, + ), if (_welcomeMessage != null) ...[ const SizedBox(height: 8), Text( diff --git a/lib/widgets/federation_expiry_banner.dart b/lib/widgets/federation_expiry_banner.dart index 0d20a6fb..111c01cb 100644 --- a/lib/widgets/federation_expiry_banner.dart +++ b/lib/widgets/federation_expiry_banner.dart @@ -45,34 +45,58 @@ double _lineHeight(BuildContext context, TextStyle? style) { return height; } -/// Loud, tappable warning that the guardians have announced this federation's -/// shutdown, by publishing a date, naming a successor, or both. +/// Loud warning that the guardians have announced this federation's shutdown, +/// by publishing a date, naming a successor, or both. /// -/// Sits directly under the balance on the dashboard, in the error colour, and -/// stays put while the transaction list scrolls: the point is that it cannot -/// be missed by someone who only ever glances at their balance. +/// On the dashboard it sits directly under the balance, in the error colour, +/// stays put while the transaction list scrolls and opens the details on tap: +/// the point is that it cannot be missed by someone who only ever glances at +/// their balance. On a join preview it is informational ([onTap] null), lays +/// out at its natural height ([compact] false) and carries a [note] telling +/// the reader why they might still want to join. class FederationExpiryBanner extends StatelessWidget { /// Unix seconds the guardians published as the shutdown time. Null when they /// only named a successor, which changes the wording but not the urgency. final BigInt? expiryTimestamp; - final VoidCallback onTap; + + /// Opens the details. Null makes the banner informational: no chevron, no + /// "tap for details". + final VoidCallback? onTap; + + /// True for the fixed, single-line layout the pinned dashboard header needs + /// (see [federationExpiryBannerExtent]); false lets the second line wrap. + final bool compact; + + /// Extra sentence appended to the second line. + final String? note; const FederationExpiryBanner({ super.key, required this.expiryTimestamp, required this.onTap, + this.compact = true, + this.note, }); String _subtitle(BuildContext context) { + final l10n = context.l10n; final expiryTimestamp = this.expiryTimestamp; + final String base; if (expiryTimestamp == null) { - return context.l10n.federationExpiryBannerSubtitleSuccessor; + base = l10n.federationExpiryBannerSubtitleSuccessor; + } else { + final expiry = expiryDateTime(expiryTimestamp); + final date = DateFormat.yMMMd().format(expiry); + base = + expiry.isBefore(DateTime.now()) + ? l10n.federationExpiryBannerSubtitlePast(date) + : l10n.federationExpiryBannerSubtitle(date); } - final expiry = expiryDateTime(expiryTimestamp); - final date = DateFormat.yMMMd().format(expiry); - return expiry.isBefore(DateTime.now()) - ? context.l10n.federationExpiryBannerSubtitlePast(date) - : context.l10n.federationExpiryBannerSubtitle(date); + return [ + base, + if (onTap != null) l10n.federationExpiryBannerTap, + if (note != null) note!, + ].join(' '); } @override @@ -80,56 +104,62 @@ class FederationExpiryBanner extends StatelessWidget { final theme = Theme.of(context); final warning = theme.colorScheme.error; - return Padding( - padding: const EdgeInsets.only(top: 8), - child: SizedBox( - height: federationExpiryBannerExtent(context) - 8, - child: Material( - color: warning.withValues(alpha: 0.12), - borderRadius: BorderRadius.circular(12), - child: InkWell( - onTap: onTap, + final card = Material( + color: warning.withValues(alpha: 0.12), + borderRadius: BorderRadius.circular(12), + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), + decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all(color: warning.withValues(alpha: 0.5)), - ), - child: Row( - children: [ - Icon(Icons.warning_amber_rounded, color: warning, size: 24), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - context.l10n.federationExpiryBannerTitle, - style: _titleStyle( - theme.textTheme, - )?.copyWith(color: warning), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 2), - Text( - _subtitle(context), - style: _subtitleStyle(theme.textTheme), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], + border: Border.all(color: warning.withValues(alpha: 0.5)), + ), + child: Row( + children: [ + Icon(Icons.warning_amber_rounded, color: warning, size: 24), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + context.l10n.federationExpiryBannerTitle, + style: _titleStyle( + theme.textTheme, + )?.copyWith(color: warning), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 2), + Text( + _subtitle(context), + style: _subtitleStyle(theme.textTheme), + maxLines: compact ? 1 : 3, + overflow: TextOverflow.ellipsis, ), - ), - Icon(Icons.chevron_right, color: warning, size: 20), - ], + ], + ), ), - ), + if (onTap != null) + Icon(Icons.chevron_right, color: warning, size: 20), + ], ), ), ), ); + + return Padding( + padding: const EdgeInsets.only(top: 8), + child: + compact + ? SizedBox( + height: federationExpiryBannerExtent(context) - 8, + child: card, + ) + : card, + ); } } diff --git a/test/federation_expiry_banner_test.dart b/test/federation_expiry_banner_test.dart index d62d406b..55d89482 100644 --- a/test/federation_expiry_banner_test.dart +++ b/test/federation_expiry_banner_test.dart @@ -100,7 +100,10 @@ void main() { tester.element(find.byType(FederationExpiryBanner)), ); expect( - find.text(l10n.federationExpiryBannerSubtitle(bannerDate(inAMonth))), + find.text( + '${l10n.federationExpiryBannerSubtitle(bannerDate(inAMonth))} ' + '${l10n.federationExpiryBannerTap}', + ), findsOneWidget, ); }); @@ -118,7 +121,8 @@ void main() { ); expect( find.text( - l10n.federationExpiryBannerSubtitlePast(bannerDate(lastWeek)), + '${l10n.federationExpiryBannerSubtitlePast(bannerDate(lastWeek))} ' + '${l10n.federationExpiryBannerTap}', ), findsOneWidget, ); @@ -132,11 +136,41 @@ void main() { tester.element(find.byType(FederationExpiryBanner)), ); expect( - find.text(l10n.federationExpiryBannerSubtitleSuccessor), + find.text( + '${l10n.federationExpiryBannerSubtitleSuccessor} ' + '${l10n.federationExpiryBannerTap}', + ), findsOneWidget, ); }); + testWidgets('reads as information on a join preview', (tester) async { + await tester.pumpWidget( + harness( + FederationExpiryBanner( + expiryTimestamp: inAMonth, + onTap: null, + compact: false, + note: 'Join only to recover funds you already hold here.', + ), + textScale: 1.3, + ), + ); + expect(tester.takeException(), isNull); + final l10n = AppLocalizations.of( + tester.element(find.byType(FederationExpiryBanner)), + ); + // No promise of details that a tap cannot deliver, and no chevron. + expect(find.textContaining(l10n.federationExpiryBannerTap), findsNothing); + expect(find.byIcon(Icons.chevron_right), findsNothing); + // The note is there and the line was allowed to wrap rather than clip. + final subtitle = tester.renderObject( + find.textContaining('recover funds'), + ); + expect(subtitle.size.height, greaterThan(subtitle.textSize.height / 2)); + expect(subtitle.textSize.height, greaterThan(20 * 1.3)); + }); + testWidgets('is tappable across its whole surface', (tester) async { var taps = 0; await tester.pumpWidget( From 5c0149bcc3afba22bddfbae51e05b2a1ddec4845 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 11:08:02 -0500 Subject: [PATCH 08/17] fix: dont overwrite meta when it fails to retrieve --- lib/multimint.dart | 7 +- rust/ecashapp/src/multimint.rs | 236 +++++++++++++++++++++++++-------- 2 files changed, 184 insertions(+), 59 deletions(-) diff --git a/lib/multimint.dart b/lib/multimint.dart index 768ffc2d..641b42df 100644 --- a/lib/multimint.dart +++ b/lib/multimint.dart @@ -11,10 +11,11 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; import 'package:freezed_annotation/freezed_annotation.dart' hide protected; part 'multimint.freezed.dart'; -// These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_expiry_timestamp`, `get_federation`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_successor_invite`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `join_federation_inner`, `join_federation_on`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `migrate_federation_meta_v3`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `register_federation`, `release_ln_address`, `remove_recovery_progress_cache`, `retire_recovery_client`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `shutdown_client`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_federation_teardown`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` -// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ClientType`, `JoinedFederation`, `LNAddressRegisterRequest`, `LNAddressRemoveRequest`, `OnChainWithdrawalMeta`, `WrappedEcash` -// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` +// These functions are ignored because they are not marked as `pub`: `aggregate_recovery_progress`, `await_receive_lnv1`, `await_receive_lnv2`, `await_send_lnv1`, `await_send_lnv2`, `backup`, `build_client`, `cache_btc_price`, `cache_federation_meta`, `check_for_update`, `compute_send_fees`, `extract_recipient_pk_from_lnv2_lnurl`, `finish_active_subscriptions`, `from_cached`, `from_json`, `from_peg_out_fees`, `get_client_database`, `get_client`, `get_ecash_amount_from_meta`, `get_expiry_timestamp`, `get_federation`, `get_lnv1_amount_from_meta`, `get_lnv1_receive_tx`, `get_lnv1_send_tx`, `get_lnv2_amount_from_meta`, `get_mintv2_receive_amount`, `get_or_build_temp_client`, `get_recurringd_federations`, `get_successor_invite`, `get_url`, `gross_invoice_for_contract`, `guardian_admin_api`, `guardian_bitcoin_status`, `guardian_lnv2_module_api`, `guardian_meta_consensus`, `guardian_meta_module_api`, `guardian_meta_submit`, `init_recovery_progress_cache`, `invoice_is_loopback`, `is_invalid_guardian_auth`, `is_newer_version`, `join_federation_inner`, `join_federation_on`, `list_gateways`, `lnv1_update_gateway_cache`, `lnv2_gateways`, `load_clients`, `meta_fields_after_fetch`, `migrate_federation_meta_v3`, `pay_lnv1`, `pay_lnv2`, `read_meta_msats`, `read_meta_string`, `read_meta_u64`, `read_meta_url`, `receive_lnv1`, `receive_lnv2`, `recovery_module_for_kind`, `register_federation`, `release_ln_address`, `remove_recovery_progress_cache`, `retire_recovery_client`, `run_cache_stage`, `run_migrations`, `send_federation_fee`, `shutdown_client`, `sign_challenge`, `skip_unrenderable`, `solve_gross_for_net`, `spawn_await_ecash_reissue`, `spawn_await_ecash_send`, `spawn_await_mintv2_receive`, `spawn_await_receive`, `spawn_await_recurringd_receive`, `spawn_await_send`, `spawn_await_withdraw`, `spawn_backfill_recipient_pk`, `spawn_cache_task`, `spawn_federation_teardown`, `spawn_lnv2_event_listener`, `spawn_recovery_progress`, `spawn_recurring_invoice_listener`, `update_recovery_progress_cache`, `validate_receive_fee`, `wait_for_recovery`, `wallet_network` +// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `ClientType`, `JoinedFederation`, `LNAddressRegisterRequest`, `LNAddressRemoveRequest`, `MetaFetch`, `MetaFields`, `OnChainWithdrawalMeta`, `WrappedEcash` +// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `assert_receiver_is_total_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `cmp`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_decode_partial_from_finite_reader`, `consensus_encode`, `consensus_encode`, `consensus_encode`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `partial_cmp` // These functions are ignored (category: IgnoreBecauseExplicitAttribute): `federation_network` +// These functions are ignored (category: IgnoreBecauseOwnerTyShouldIgnore): `default` // These functions have error during generation (see debug logs or enable `stop_on_error: true` for more details): `subscribe_peer_status` OobNotesWrapper? parseOobNotes({required String notes}) => diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index 7b78e979..8c920e7a 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -947,6 +947,81 @@ impl OnChainWithdrawalMeta { } } +/// What a refresh learned about a federation's meta-module value. +#[flutter_rust_bridge::frb(ignore)] +enum MetaFetch { + /// The guardians have a consensus value; these are its fields. + Value(serde_json::Value), + /// The federation has no meta module, or its guardians have set no value: + /// there genuinely is nothing announced. + Unset, + /// The guardians could not be asked, or answered with something that does + /// not parse. What they last announced is still the best information. + Unavailable, +} + +/// The meta-derived part of a [`FederationMeta`], apart from the guardian list +/// and timestamps that every refresh recomputes on its own. +#[derive(Debug, Default, PartialEq)] +#[flutter_rust_bridge::frb(ignore)] +struct MetaFields { + /// Name the guardians set, when the meta names one. + federation_name: Option, + picture: Option, + welcome: Option, + recurringd_api: Option, + lnaddress_api: Option, + expiry_timestamp: Option, + successor_invite: Option, +} + +#[flutter_rust_bridge::frb(ignore)] +impl MetaFields { + fn from_json(meta: &serde_json::Value) -> Self { + Self { + federation_name: meta + .get(META_FEDERATION_NAME_KEY) + .and_then(serde_json::Value::as_str) + .filter(|name| !name.is_empty()) + .map(ToString::to_string), + picture: Multimint::get_url("fedi:federation_icon_url", meta), + welcome: meta + .get("welcome_message") + .and_then(serde_json::Value::as_str) + .map(ToString::to_string), + recurringd_api: Multimint::get_url("recurringd_api", meta), + lnaddress_api: Multimint::get_url("lnaddress_api", meta), + expiry_timestamp: Multimint::get_expiry_timestamp(meta), + successor_invite: Multimint::get_successor_invite(meta), + } + } + + fn from_cached(cached: &FederationMeta) -> Self { + Self { + federation_name: Some(cached.selector.federation_name.clone()), + picture: cached.picture.clone(), + welcome: cached.welcome.clone(), + recurringd_api: cached.recurringd_api.clone(), + lnaddress_api: cached.lnaddress_api.clone(), + expiry_timestamp: cached.expiry_timestamp, + successor_invite: cached.successor_invite.clone(), + } + } +} + +/// Which meta fields a refresh should persist: what the guardians say now, +/// nothing when they say nothing, and what they last said when they cannot be +/// asked. The last case matters most during a shutdown, when guardians go +/// offline: a blank record there would drop the announcement, take the +/// banner down and reopen receiving on the strength of a failed request. +fn meta_fields_after_fetch(fetch: &MetaFetch, cached: Option<&FederationMeta>) -> MetaFields { + match fetch { + MetaFetch::Value(meta) => MetaFields::from_json(meta), + MetaFetch::Unset => MetaFields::default(), + MetaFetch::Unavailable => cached.map(MetaFields::from_cached).unwrap_or_default(), + } +} + /// Schema v3: re-encodes every cached `FederationMeta` written in the layout /// before `expiry_timestamp` and `successor_invite` existed, with both unset. /// Entries already in the current layout are left alone; anything else is @@ -1942,26 +2017,30 @@ impl Multimint { }); } - // Fetch the federation's meta-module consensus value (when the module - // exists and a value has been set). Guardians can change fields like the - // federation name here, so we prefer it over the static config below. - let meta_json = match client.get_first_module::() { + // Fetch the federation's meta-module consensus value. Guardians can + // change fields like the federation name here, so it is preferred + // over the static config below. A failed or unparseable fetch is kept + // apart from "no value set": only the latter means nothing is + // announced. + let meta_fetch = match client.get_first_module::() { Ok(meta) => match meta.get_consensus_value(DEFAULT_META_KEY).await { - Ok(Some(value)) => value.value.to_json().ok(), - _ => None, + Ok(Some(value)) => match value.value.to_json() { + Ok(json) => MetaFetch::Value(json), + Err(_) => MetaFetch::Unavailable, + }, + Ok(None) => MetaFetch::Unset, + Err(_) => MetaFetch::Unavailable, }, - Err(_) => None, + Err(_) => MetaFetch::Unset, }; + let fields = meta_fields_after_fetch(&meta_fetch, cached_meta.as_ref()); // Prefer the federation name set in the meta module so guardian-driven // name changes are reflected, falling back to the name baked into the // config when the meta module is absent or has no name set. - let federation_name = meta_json - .as_ref() - .and_then(|meta| meta.get(META_FEDERATION_NAME_KEY)) - .and_then(serde_json::Value::as_str) - .filter(|name| !name.is_empty()) - .map(ToString::to_string) + let federation_name = fields + .federation_name + .clone() .unwrap_or_else(|| config.global.federation_name().unwrap_or("").to_string()); let selector = FederationSelector { @@ -1975,41 +2054,16 @@ impl Multimint { .expect("Cannot be before epoch") .as_millis() as u64; - let federation_meta = match meta_json { - Some(meta) => { - let welcome = meta - .get("welcome_message") - .and_then(serde_json::Value::as_str) - .map(ToString::to_string); - let picture = Self::get_url("fedi:federation_icon_url", &meta); - let recurringd_api = Self::get_url("recurringd_api", &meta); - let lnaddress_api = Self::get_url("lnaddress_api", &meta); - let expiry_timestamp = Self::get_expiry_timestamp(&meta); - let successor_invite = Self::get_successor_invite(&meta); - - FederationMeta { - picture, - welcome, - guardians, - selector, - last_updated, - recurringd_api, - lnaddress_api, - expiry_timestamp, - successor_invite, - } - } - None => FederationMeta { - picture: None, - welcome: None, - guardians, - selector, - last_updated, - recurringd_api: None, - lnaddress_api: None, - expiry_timestamp: None, - successor_invite: None, - }, + let federation_meta = FederationMeta { + picture: fields.picture, + welcome: fields.welcome, + guardians, + selector, + last_updated, + recurringd_api: fields.recurringd_api, + lnaddress_api: fields.lnaddress_api, + expiry_timestamp: fields.expiry_timestamp, + successor_invite: fields.successor_invite, }; let mut dbtx = self.db.begin_transaction().await; @@ -2028,11 +2082,6 @@ impl Multimint { dbtx.insert_entry(&FederationMetaKey { federation_id }, &federation_meta) .await; dbtx.commit_tx().await; - info_to_flutter(format!( - "Updated meta for {}", - federation_meta.selector.federation_name - )) - .await; // Notify the UI only when something it renders actually changed. This // runs on a timer, and `last_updated` differs on every pass, so @@ -2048,6 +2097,23 @@ impl Multimint { } None => true, }; + + // The same rule for the log: a refresh that found nothing new is the + // common case on this timer and not worth a line. + if matches!(meta_fetch, MetaFetch::Unavailable) { + info_to_flutter(format!( + "Could not refresh meta for {}; keeping what the guardians last announced", + federation_meta.selector.federation_name + )) + .await; + } else if changed { + info_to_flutter(format!( + "Updated meta for {}", + federation_meta.selector.federation_name + )) + .await; + } + if changed { get_event_bus() .publish(MultimintEvent::MetaUpdated(federation_id.to_string())) @@ -7231,11 +7297,69 @@ mod tests { use crate::db::{FederationMetaKey, FederationMetaKeyPrefix, FederationMetaV1}; use crate::multimint::{ - aggregate_recovery_progress, gross_invoice_for_contract, migrate_federation_meta_v3, - recovery_module_for_kind, FederationSelector, Guardian, Multimint, RecoveryModule, - MAX_GATEWAY_PPM, + aggregate_recovery_progress, gross_invoice_for_contract, meta_fields_after_fetch, + migrate_federation_meta_v3, recovery_module_for_kind, FederationMeta, FederationSelector, + Guardian, MetaFetch, MetaFields, Multimint, RecoveryModule, MAX_GATEWAY_PPM, }; + /// A cached entry from before the guardians went quiet: shutdown announced. + fn announced_meta() -> FederationMeta { + FederationMeta { + picture: Some("https://example.com/icon.png".to_string()), + welcome: Some("closing soon".to_string()), + guardians: vec![], + selector: FederationSelector { + federation_name: "Old Fed".to_string(), + federation_id: FederationId::dummy(), + network: Some("bitcoin".to_string()), + }, + last_updated: 42, + recurringd_api: Some("https://recurringd.example.com/".to_string()), + lnaddress_api: None, + expiry_timestamp: Some(1_767_225_600), + successor_invite: Some("fed11successor".to_string()), + } + } + + #[test] + fn meta_refresh_keeps_the_announcement_while_guardians_are_unreachable() { + let cached = announced_meta(); + let fields = meta_fields_after_fetch(&MetaFetch::Unavailable, Some(&cached)); + assert_eq!(fields.expiry_timestamp, cached.expiry_timestamp); + assert_eq!(fields.successor_invite, cached.successor_invite); + assert_eq!(fields.welcome, cached.welcome); + assert_eq!(fields.picture, cached.picture); + assert_eq!(fields.recurringd_api, cached.recurringd_api); + assert_eq!( + fields.federation_name.as_deref(), + Some(cached.selector.federation_name.as_str()) + ); + + // With nothing cached there is nothing to keep. + assert_eq!( + meta_fields_after_fetch(&MetaFetch::Unavailable, None), + MetaFields::default() + ); + } + + #[test] + fn meta_refresh_clears_the_announcement_only_when_the_guardians_say_so() { + let cached = announced_meta(); + + // The guardians answered and have no meta at all. + assert_eq!( + meta_fields_after_fetch(&MetaFetch::Unset, Some(&cached)), + MetaFields::default() + ); + + // The guardians answered with a value that no longer announces one. + let fetch = MetaFetch::Value(json!({ "welcome_message": "back to normal" })); + let fields = meta_fields_after_fetch(&fetch, Some(&cached)); + assert_eq!(fields.expiry_timestamp, None); + assert_eq!(fields.successor_invite, None); + assert_eq!(fields.welcome.as_deref(), Some("back to normal")); + } + #[tokio::test] async fn migration_v3_re_encodes_old_entries_and_drops_the_rest() { let db = Database::new(MemDatabase::new(), ModuleDecoderRegistry::default()); From a7ef25734453d9b16e4a96b842cee326fab7ee13 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 11:11:44 -0500 Subject: [PATCH 09/17] fix: timestamping issue --- rust/ecashapp/src/multimint.rs | 40 +++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index 8c920e7a..5ccafdbb 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -131,6 +131,13 @@ const META_FEDERATION_EXPIRY_TIMESTAMP_KEY: &str = "federation_expiry_timestamp" /// Well-known meta field: invite code of the federation users should migrate /// to before the shutdown. See fedimint `docs/meta_fields/federation_successor.md`. const META_FEDERATION_SUCCESSOR_KEY: &str = "federation_successor"; +/// Largest expiry (unix seconds) the UI can render. Dart's `DateTime` spans +/// 100,000,000 days either side of the epoch, i.e. 8.64e15 milliseconds, and +/// the Dart side multiplies the seconds by 1000 before building one; a larger +/// value throws while the dashboard is being built and takes the wallet +/// screen down with it. Such a value is a malformed guardian entry, so it is +/// dropped here rather than passed on. +const MAX_RENDERABLE_EXPIRY_SECS: u64 = 8_640_000_000_000; const CACHE_UPDATE_INTERVAL_SECS: u64 = 30; const PRICE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 5; const FEDERATION_BACKUP_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 60 * 24; @@ -1932,13 +1939,15 @@ impl Multimint { /// guardian dashboard writes it as a JSON *string* (`"1767225600"`) while /// `Client::get_meta_expiration_timestamp` reads a JSON *number*, so both /// spellings are accepted. Anything else (negative, fractional, - /// non-numeric) is treated as unset rather than surfacing a bogus date. + /// non-numeric, or past [`MAX_RENDERABLE_EXPIRY_SECS`]) is treated as + /// unset rather than surfacing a bogus date. fn get_expiry_timestamp(meta: &serde_json::Value) -> Option { - match meta.get(META_FEDERATION_EXPIRY_TIMESTAMP_KEY)? { - serde_json::Value::Number(n) => n.as_u64(), - serde_json::Value::String(s) => s.trim().parse::().ok(), - _ => None, - } + let secs = match meta.get(META_FEDERATION_EXPIRY_TIMESTAMP_KEY)? { + serde_json::Value::Number(n) => n.as_u64()?, + serde_json::Value::String(s) => s.trim().parse::().ok()?, + _ => return None, + }; + (secs <= MAX_RENDERABLE_EXPIRY_SECS).then_some(secs) } /// Reads `federation_successor` from the meta JSON, keeping it only when it @@ -7437,6 +7446,25 @@ mod tests { ); } + #[test] + fn expiry_timestamp_rejects_dates_the_ui_cannot_render() { + // The boundary is Dart's DateTime limit, in seconds; one past it would + // throw in the dashboard header. + let at_limit = json!({ "federation_expiry_timestamp": 8_640_000_000_000_u64 }); + assert_eq!( + Multimint::get_expiry_timestamp(&at_limit), + Some(8_640_000_000_000) + ); + for value in [ + json!(8_640_000_000_001_u64), + json!("18446744073709551615"), + json!(u64::MAX), + ] { + let meta = json!({ "federation_expiry_timestamp": value }); + assert_eq!(Multimint::get_expiry_timestamp(&meta), None, "{meta}"); + } + } + #[test] fn expiry_timestamp_rejects_garbage() { for value in [ From cf02bf64f629e148054abd75328567de545ff330 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 11:57:45 -0500 Subject: [PATCH 10/17] fix: show spinner if not loaded yet --- lib/screens/federation_expiry_screen.dart | 36 +++++++++--- test/federation_expiry_screen_test.dart | 67 ++++++++++++++++++++--- 2 files changed, 87 insertions(+), 16 deletions(-) diff --git a/lib/screens/federation_expiry_screen.dart b/lib/screens/federation_expiry_screen.dart index c59397e7..e4399ac3 100644 --- a/lib/screens/federation_expiry_screen.dart +++ b/lib/screens/federation_expiry_screen.dart @@ -103,9 +103,20 @@ class _FederationExpiryScreenState extends State { late BigInt? _balanceMsats = widget.balanceMsats; late String? _lightningAddress = widget.lightningAddress; + /// False until the loaders have answered once. The dashboard hands over + /// whatever it had loaded when the banner was tapped, which can be nothing + /// yet, and a missing balance or address must not read as "nothing to do". + bool _loaded = false; + /// One step's flow at a time; every link is disabled while one runs. bool _busy = false; + @override + void initState() { + super.initState(); + _refresh(); + } + /// Runs a step's flow, then re-reads what it may have changed so the list /// reflects the new state when the user lands back here. Future _run(Future Function() flow) async { @@ -136,6 +147,7 @@ class _FederationExpiryScreenState extends State { setState(() { _balanceMsats = balance; _lightningAddress = address; + _loaded = true; }); } @@ -297,15 +309,21 @@ class _FederationExpiryScreenState extends State { ), ), const SizedBox(height: 12), - for (final (index, step) in steps.indexed) - _Step( - number: index + 1, - text: step.text, - actionLabel: step.action, - icon: step.icon, - destructive: step.destructive, - onPressed: _busy ? null : step.onTap, - ), + if (!_loaded) + const Padding( + padding: EdgeInsets.symmetric(vertical: 24), + child: Center(child: CircularProgressIndicator()), + ) + else + for (final (index, step) in steps.indexed) + _Step( + number: index + 1, + text: step.text, + actionLabel: step.action, + icon: step.icon, + destructive: step.destructive, + onPressed: _busy ? null : step.onTap, + ), ], ), ), diff --git a/test/federation_expiry_screen_test.dart b/test/federation_expiry_screen_test.dart index 48d977fb..55ce3d30 100644 --- a/test/federation_expiry_screen_test.dart +++ b/test/federation_expiry_screen_test.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:ecashapp/generated/app_localizations.dart'; import 'package:ecashapp/providers/preferences_provider.dart'; import 'package:ecashapp/screens/federation_expiry_screen.dart'; @@ -73,7 +75,16 @@ void main() { final lastWeek = unixSeconds( DateTime.now().subtract(const Duration(days: 7)), ); - const address = 'alice@example.com'; + const address_ = 'alice@example.com'; + const address = address_; + + /// Tall enough that the whole list, links included, is laid out. + void tallView(WidgetTester tester) { + tester.view.physicalSize = const Size(800, 3000); + tester.view.devicePixelRatio = 1.0; + addTearDown(tester.view.resetPhysicalSize); + addTearDown(tester.view.resetDevicePixelRatio); + } Future pumpScreen( WidgetTester tester, { @@ -82,11 +93,7 @@ void main() { BigInt? balanceMsats, String? lightningAddress, }) async { - // Tall enough that the whole list, links included, is laid out. - tester.view.physicalSize = const Size(800, 3000); - tester.view.devicePixelRatio = 1.0; - addTearDown(tester.view.resetPhysicalSize); - addTearDown(tester.view.resetDevicePixelRatio); + tallView(tester); final flows = Flows() @@ -112,10 +119,56 @@ void main() { ), ), ); - await tester.pump(); + // Lets the loaders answer on entry, so the checklist is showing. + await tester.pumpAndSettle(); return flows; } + testWidgets('reads its inputs on entry rather than trusting the snapshot', ( + tester, + ) async { + tallView(tester); + final balance = Completer(); + final address = Completer(); + await tester.pumpWidget( + harness( + FederationExpiryScreen( + key: UniqueKey(), + federationName: 'Old Fed', + expiryTimestamp: inAMonth, + successorInvite: null, + // The dashboard had loaded neither yet when the banner was tapped. + balanceMsats: null, + lightningAddress: null, + loadBalance: () => balance.future, + loadLightningAddress: () => address.future, + onSendOnchain: () async {}, + onOpenLightningAddress: () async {}, + onJoin: (_, _) {}, + onLeaveFederation: () async {}, + ), + ), + ); + await tester.pump(); + + // Nothing is concluded from the empty snapshot: no steps yet, a spinner. + expect(find.byType(CircularProgressIndicator), findsOneWidget); + expect(find.text(en.leaveFederation), findsNothing); + expect(find.text(en.federationExpirySendOnchain), findsNothing); + + balance.complete(BigInt.from(21_000)); + address.complete(address_); + await tester.pumpAndSettle(); + + expect(find.byType(CircularProgressIndicator), findsNothing); + expect(find.text(en.federationExpirySendOnchain), findsOneWidget); + expect( + find.text(en.federationExpiryManageLightningAddress), + findsOneWidget, + ); + expect(find.text(en.leaveFederation), findsOneWidget); + }); + double top(WidgetTester tester, String text) => tester.getTopLeft(find.text(text)).dy; From 855f380f182bce8b6a6ed9e10b4bbc7368e92edb Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 12:06:45 -0500 Subject: [PATCH 11/17] fix: fetch federation expiry instead of relying on cache --- lib/frb_generated.dart | 535 +++++++++++++--------- lib/lib.dart | 3 + lib/multimint.dart | 12 + lib/screens/federation_info_screen.dart | 19 +- rust/ecashapp/src/frb_generated.rs | 574 +++++++++++++++--------- rust/ecashapp/src/lib.rs | 6 + rust/ecashapp/src/multimint.rs | 26 ++ 7 files changed, 735 insertions(+), 440 deletions(-) diff --git a/lib/frb_generated.dart b/lib/frb_generated.dart index 3d57110c..c478d1b9 100644 --- a/lib/frb_generated.dart +++ b/lib/frb_generated.dart @@ -69,7 +69,7 @@ class RustLib extends BaseEntrypoint { String get codegenVersion => '2.9.0'; @override - int get rustContentHash => 1847422546; + int get rustContentHash => 470711718; static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig( @@ -410,6 +410,11 @@ abstract class RustLibApi extends BaseApi { required Multimint that, }); + Future crateMultimintMultimintFetchFederationExpiry({ + required Multimint that, + required FederationId federationId, + }); + Future> crateMultimintMultimintGetAddresses({ required Multimint that, required FederationId federationId, @@ -1079,6 +1084,10 @@ abstract class RustLibApi extends BaseApi { Future> crateFederations(); + Future crateFetchFederationExpiry({ + required FederationId federationId, + }); + Future crateFetchLnurlWithdraw({required String url}); Future> crateGetAddresses({ @@ -4222,7 +4231,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - Future> crateMultimintMultimintGetAddresses({ + Future crateMultimintMultimintFetchFederationExpiry({ required Multimint that, required FederationId federationId, }) { @@ -4245,6 +4254,47 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { port: port_, ); }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_box_autoadd_u_64, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kCrateMultimintMultimintFetchFederationExpiryConstMeta, + argValues: [that, federationId], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateMultimintMultimintFetchFederationExpiryConstMeta => + const TaskConstMeta( + debugName: "Multimint_fetch_federation_expiry", + argNames: ["that", "federationId"], + ); + + @override + Future> crateMultimintMultimintGetAddresses({ + required Multimint that, + required FederationId federationId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMultimint( + that, + serializer, + ); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationId( + federationId, + serializer, + ); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 69, + port: port_, + ); + }, codec: SseCodec( decodeSuccessData: sse_decode_list_record_string_opt_box_autoadd_u_64_opt_box_autoadd_u_64, @@ -4278,7 +4328,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 69, + funcId: 70, port: port_, ); }, @@ -4314,7 +4364,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 70, + funcId: 71, port: port_, ); }, @@ -4350,7 +4400,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 71, + funcId: 72, port: port_, ); }, @@ -4386,7 +4436,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 72, + funcId: 73, port: port_, ); }, @@ -4429,7 +4479,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 73, + funcId: 74, port: port_, ); }, @@ -4466,7 +4516,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 74, + funcId: 75, port: port_, ); }, @@ -4503,7 +4553,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 75, + funcId: 76, port: port_, ); }, @@ -4546,7 +4596,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 76, + funcId: 77, port: port_, ); }, @@ -4587,7 +4637,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 77, + funcId: 78, port: port_, ); }, @@ -4632,7 +4682,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 78, + funcId: 79, port: port_, ); }, @@ -4669,7 +4719,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 79, + funcId: 80, port: port_, ); }, @@ -4710,7 +4760,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 80, + funcId: 81, port: port_, ); }, @@ -4751,7 +4801,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 81, + funcId: 82, port: port_, ); }, @@ -4794,7 +4844,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 82, + funcId: 83, port: port_, ); }, @@ -4829,7 +4879,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 83, + funcId: 84, port: port_, ); }, @@ -4876,7 +4926,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 84, + funcId: 85, port: port_, ); }, @@ -4921,7 +4971,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 85, + funcId: 86, port: port_, ); }, @@ -4967,7 +5017,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 86, + funcId: 87, port: port_, ); }, @@ -5010,7 +5060,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 87, + funcId: 88, port: port_, ); }, @@ -5055,7 +5105,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 88, + funcId: 89, port: port_, ); }, @@ -5102,7 +5152,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 89, + funcId: 90, port: port_, ); }, @@ -5151,7 +5201,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 90, + funcId: 91, port: port_, ); }, @@ -5203,7 +5253,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 91, + funcId: 92, port: port_, ); }, @@ -5248,7 +5298,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 92, + funcId: 93, port: port_, ); }, @@ -5295,7 +5345,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 93, + funcId: 94, port: port_, ); }, @@ -5340,7 +5390,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 94, + funcId: 95, port: port_, ); }, @@ -5376,7 +5426,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 95, + funcId: 96, port: port_, ); }, @@ -5416,7 +5466,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 96, + funcId: 97, port: port_, ); }, @@ -5458,7 +5508,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 97, + funcId: 98, port: port_, ); }, @@ -5508,7 +5558,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 98, + funcId: 99, port: port_, ); }, @@ -5546,7 +5596,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 99, + funcId: 100, port: port_, ); }, @@ -5592,7 +5642,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 100, + funcId: 101, port: port_, ); }, @@ -5645,7 +5695,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 101, + funcId: 102, port: port_, ); }, @@ -5701,7 +5751,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 102, + funcId: 103, port: port_, ); }, @@ -5763,7 +5813,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 103, + funcId: 104, port: port_, ); }, @@ -5808,7 +5858,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 104, + funcId: 105, port: port_, ); }, @@ -5844,7 +5894,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 105, + funcId: 106, port: port_, ); }, @@ -5885,7 +5935,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 106, + funcId: 107, port: port_, ); }, @@ -5935,7 +5985,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 107, + funcId: 108, port: port_, ); }, @@ -5994,7 +6044,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 108, + funcId: 109, port: port_, ); }, @@ -6033,7 +6083,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 109, + funcId: 110, port: port_, ); }, @@ -6076,7 +6126,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 110, + funcId: 111, port: port_, ); }, @@ -6134,7 +6184,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 111, + funcId: 112, port: port_, ); }, @@ -6200,7 +6250,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 112, + funcId: 113, port: port_, ); }, @@ -6239,7 +6289,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 113, + funcId: 114, port: port_, ); }, @@ -6280,7 +6330,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 114, + funcId: 115, port: port_, ); }, @@ -6318,7 +6368,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 115, + funcId: 116, port: port_, ); }, @@ -6356,7 +6406,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 116, + funcId: 117, port: port_, ); }, @@ -6403,7 +6453,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 117, + funcId: 118, port: port_, ); }, @@ -6452,7 +6502,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 118, + funcId: 119, port: port_, ); }, @@ -6504,7 +6554,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 119, + funcId: 120, port: port_, ); }, @@ -6557,7 +6607,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 120, + funcId: 121, port: port_, ); }, @@ -6593,7 +6643,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 121, + funcId: 122, port: port_, ); }, @@ -6631,7 +6681,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 122, + funcId: 123, port: port_, ); }, @@ -6667,7 +6717,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 123, + funcId: 124, port: port_, ); }, @@ -6703,7 +6753,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 124, + funcId: 125, port: port_, ); }, @@ -6741,7 +6791,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 125, + funcId: 126, port: port_, ); }, @@ -6777,7 +6827,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 126, + funcId: 127, port: port_, ); }, @@ -6815,7 +6865,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 127, + funcId: 128, port: port_, ); }, @@ -6850,7 +6900,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 128, + funcId: 129, port: port_, ); }, @@ -6889,7 +6939,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 129, + funcId: 130, port: port_, ); }, @@ -6926,7 +6976,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 130, + funcId: 131, port: port_, ); }, @@ -6962,7 +7012,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 131, + funcId: 132, port: port_, ); }, @@ -7000,7 +7050,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 132, + funcId: 133, port: port_, ); }, @@ -7040,7 +7090,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 133, + funcId: 134, port: port_, ); }, @@ -7080,7 +7130,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 134, + funcId: 135, port: port_, ); }, @@ -7122,7 +7172,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 135, + funcId: 136, port: port_, ); }, @@ -7163,7 +7213,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 136, + funcId: 137, port: port_, ); }, @@ -7201,7 +7251,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 137, + funcId: 138, port: port_, ); }, @@ -7241,7 +7291,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 138, + funcId: 139, port: port_, ); }, @@ -7286,7 +7336,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 139, + funcId: 140, port: port_, ); }, @@ -7320,7 +7370,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 140, + funcId: 141, port: port_, ); }, @@ -7358,7 +7408,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 141, + funcId: 142, port: port_, ); }, @@ -7396,7 +7446,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 142, + funcId: 143, )!; }, codec: SseCodec( @@ -7426,7 +7476,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 143, + funcId: 144, )!; }, codec: SseCodec( @@ -7459,7 +7509,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 144, + funcId: 145, )!; }, codec: SseCodec( @@ -7495,7 +7545,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 145, + funcId: 146, port: port_, ); }, @@ -7531,7 +7581,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 146, + funcId: 147, )!; }, codec: SseCodec( @@ -7566,7 +7616,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 147, + funcId: 148, )!; }, codec: SseCodec( @@ -7601,7 +7651,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 148, + funcId: 149, )!; }, codec: SseCodec( @@ -7636,7 +7686,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 149, + funcId: 150, )!; }, codec: SseCodec( @@ -7674,7 +7724,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 150, + funcId: 151, )!; }, codec: SseCodec( @@ -7711,7 +7761,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 151, + funcId: 152, )!; }, codec: SseCodec( @@ -7748,7 +7798,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 152, + funcId: 153, )!; }, codec: SseCodec( @@ -7784,7 +7834,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 153, + funcId: 154, )!; }, codec: SseCodec( @@ -7820,7 +7870,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 154, + funcId: 155, )!; }, codec: SseCodec( @@ -7858,7 +7908,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 155, + funcId: 156, )!; }, codec: SseCodec( @@ -7898,7 +7948,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 156, + funcId: 157, )!; }, codec: SseCodec( @@ -7937,7 +7987,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 157, + funcId: 158, )!; }, codec: SseCodec( @@ -7976,7 +8026,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 158, + funcId: 159, )!; }, codec: SseCodec( @@ -8015,7 +8065,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 159, + funcId: 160, )!; }, codec: SseCodec( @@ -8053,7 +8103,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 160, + funcId: 161, )!; }, codec: SseCodec( @@ -8091,7 +8141,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 161, + funcId: 162, )!; }, codec: SseCodec( @@ -8127,7 +8177,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 162, + funcId: 163, )!; }, codec: SseCodec( @@ -8165,7 +8215,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 163, + funcId: 164, )!; }, codec: SseCodec( @@ -8202,7 +8252,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 164, + funcId: 165, )!; }, codec: SseCodec( @@ -8240,7 +8290,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 165, + funcId: 166, )!; }, codec: SseCodec( @@ -8278,7 +8328,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 166, + funcId: 167, )!; }, codec: SseCodec( @@ -8317,7 +8367,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 167, + funcId: 168, )!; }, codec: SseCodec( @@ -8357,7 +8407,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 168, + funcId: 169, )!; }, codec: SseCodec( @@ -8396,7 +8446,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 169, + funcId: 170, )!; }, codec: SseCodec( @@ -8439,7 +8489,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 170, + funcId: 171, )!; }, codec: SseCodec( @@ -8478,7 +8528,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 171, + funcId: 172, )!; }, codec: SseCodec( @@ -8509,7 +8559,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 172, + funcId: 173, port: port_, ); }, @@ -8537,7 +8587,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 173, + funcId: 174, port: port_, ); }, @@ -8570,7 +8620,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 174, + funcId: 175, port: port_, ); }, @@ -8611,7 +8661,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 175, + funcId: 176, port: port_, ); }, @@ -8651,7 +8701,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 176, + funcId: 177, port: port_, ); }, @@ -8692,7 +8742,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 177, + funcId: 178, port: port_, ); }, @@ -8732,7 +8782,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 178, + funcId: 179, port: port_, ); }, @@ -8761,7 +8811,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 179, + funcId: 180, port: port_, ); }, @@ -8792,7 +8842,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 180, + funcId: 181, port: port_, ); }, @@ -8827,7 +8877,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 181, + funcId: 182, port: port_, ); }, @@ -8865,7 +8915,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 182, + funcId: 183, port: port_, ); }, @@ -8905,7 +8955,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 183, + funcId: 184, port: port_, ); }, @@ -8940,7 +8990,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 184, + funcId: 185, port: port_, ); }, @@ -8977,7 +9027,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 185, + funcId: 186, port: port_, ); }, @@ -9020,7 +9070,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 186, + funcId: 187, port: port_, ); }, @@ -9072,7 +9122,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 187, + funcId: 188, port: port_, ); }, @@ -9101,7 +9151,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 188, + funcId: 189, port: port_, ); }, @@ -9132,7 +9182,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 189, + funcId: 190, port: port_, ); }, @@ -9173,7 +9223,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 190, + funcId: 191, port: port_, ); }, @@ -9209,7 +9259,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 191, + funcId: 192, port: port_, ); }, @@ -9243,7 +9293,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 192, + funcId: 193, port: port_, ); }, @@ -9278,7 +9328,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 193, + funcId: 194, port: port_, ); }, @@ -9329,7 +9379,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 194, + funcId: 195, port: port_, ); }, @@ -9385,7 +9435,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 195, + funcId: 196, port: port_, ); }, @@ -9414,7 +9464,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 196, + funcId: 197, port: port_, ); }, @@ -9433,6 +9483,41 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { TaskConstMeta get kCrateFederationsConstMeta => const TaskConstMeta(debugName: "federations", argNames: []); + @override + Future crateFetchFederationExpiry({ + required FederationId federationId, + }) { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { + final serializer = SseSerializer(generalizedFrbRustBinding); + sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerFederationId( + federationId, + serializer, + ); + pdeCallFfi( + generalizedFrbRustBinding, + serializer, + funcId: 198, + port: port_, + ); + }, + codec: SseCodec( + decodeSuccessData: sse_decode_opt_box_autoadd_u_64, + decodeErrorData: sse_decode_AnyhowException, + ), + constMeta: kCrateFetchFederationExpiryConstMeta, + argValues: [federationId], + apiImpl: this, + ), + ); + } + + TaskConstMeta get kCrateFetchFederationExpiryConstMeta => const TaskConstMeta( + debugName: "fetch_federation_expiry", + argNames: ["federationId"], + ); + @override Future crateFetchLnurlWithdraw({required String url}) { return handler.executeNormal( @@ -9443,7 +9528,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 197, + funcId: 199, port: port_, ); }, @@ -9476,7 +9561,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 198, + funcId: 200, port: port_, ); }, @@ -9506,7 +9591,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 199, + funcId: 201, port: port_, ); }, @@ -9533,7 +9618,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 200, + funcId: 202, port: port_, ); }, @@ -9560,7 +9645,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 201, + funcId: 203, port: port_, ); }, @@ -9587,7 +9672,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 202, + funcId: 204, port: port_, ); }, @@ -9614,7 +9699,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 203, + funcId: 205, port: port_, ); }, @@ -9650,7 +9735,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 204, + funcId: 206, port: port_, ); }, @@ -9680,7 +9765,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 205, + funcId: 207, port: port_, ); }, @@ -9708,7 +9793,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 206, + funcId: 208, port: port_, ); }, @@ -9743,7 +9828,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 207, + funcId: 209, port: port_, ); }, @@ -9782,7 +9867,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 208, + funcId: 210, port: port_, ); }, @@ -9818,7 +9903,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 209, + funcId: 211, port: port_, ); }, @@ -9856,7 +9941,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 210, + funcId: 212, port: port_, ); }, @@ -9887,7 +9972,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 211, + funcId: 213, port: port_, ); }, @@ -9922,7 +10007,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 212, + funcId: 214, port: port_, ); }, @@ -9958,7 +10043,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 213, + funcId: 215, port: port_, ); }, @@ -9988,7 +10073,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 214, + funcId: 216, port: port_, ); }, @@ -10016,7 +10101,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 215, + funcId: 217, port: port_, ); }, @@ -10043,7 +10128,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 216, + funcId: 218, port: port_, ); }, @@ -10076,7 +10161,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 217, + funcId: 219, port: port_, ); }, @@ -10105,7 +10190,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 218, + funcId: 220, port: port_, ); }, @@ -10132,7 +10217,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 219, + funcId: 221, port: port_, ); }, @@ -10162,7 +10247,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 220, + funcId: 222, port: port_, ); }, @@ -10201,7 +10286,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 221, + funcId: 223, port: port_, ); }, @@ -10240,7 +10325,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 222, + funcId: 224, port: port_, ); }, @@ -10279,7 +10364,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 223, + funcId: 225, port: port_, ); }, @@ -10317,7 +10402,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 224, + funcId: 226, port: port_, ); }, @@ -10356,7 +10441,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 225, + funcId: 227, port: port_, ); }, @@ -10397,7 +10482,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 226, + funcId: 228, port: port_, ); }, @@ -10440,7 +10525,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 227, + funcId: 229, port: port_, ); }, @@ -10480,7 +10565,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 228, + funcId: 230, port: port_, ); }, @@ -10519,7 +10604,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 229, + funcId: 231, port: port_, ); }, @@ -10560,7 +10645,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 230, + funcId: 232, port: port_, ); }, @@ -10599,7 +10684,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 231, + funcId: 233, port: port_, ); }, @@ -10628,7 +10713,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 232, + funcId: 234, port: port_, ); }, @@ -10655,7 +10740,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 233, + funcId: 235, port: port_, ); }, @@ -10682,7 +10767,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 234, + funcId: 236, port: port_, ); }, @@ -10710,7 +10795,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 235, + funcId: 237, port: port_, ); }, @@ -10738,7 +10823,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 236, + funcId: 238, )!; }, codec: SseCodec( @@ -10769,7 +10854,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 237, + funcId: 239, port: port_, ); }, @@ -10803,7 +10888,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 238, + funcId: 240, port: port_, ); }, @@ -10835,7 +10920,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 239, + funcId: 241, port: port_, ); }, @@ -10874,7 +10959,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 240, + funcId: 242, port: port_, ); }, @@ -10906,7 +10991,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 241, + funcId: 243, port: port_, ); }, @@ -10936,7 +11021,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 242, + funcId: 244, port: port_, ); }, @@ -10970,7 +11055,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 243, + funcId: 245, port: port_, ); }, @@ -11011,7 +11096,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 244, + funcId: 246, port: port_, ); }, @@ -11049,7 +11134,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 245, + funcId: 247, port: port_, ); }, @@ -11089,7 +11174,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 246, + funcId: 248, port: port_, ); }, @@ -11132,7 +11217,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 247, + funcId: 249, )!; }, codec: SseCodec( @@ -11167,7 +11252,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 248, + funcId: 250, port: port_, ); }, @@ -11201,7 +11286,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 249, + funcId: 251, port: port_, ); }, @@ -11237,7 +11322,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 250, + funcId: 252, port: port_, ); }, @@ -11267,7 +11352,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 251, + funcId: 253, port: port_, ); }, @@ -11312,7 +11397,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 252, + funcId: 254, port: port_, ); }, @@ -11366,7 +11451,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 253, + funcId: 255, port: port_, ); }, @@ -11395,7 +11480,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 254, + funcId: 256, port: port_, ); }, @@ -11428,7 +11513,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 255, + funcId: 257, port: port_, ); }, @@ -11472,7 +11557,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 256, + funcId: 258, port: port_, ); }, @@ -11523,7 +11608,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 257, + funcId: 259, port: port_, ); }, @@ -11553,7 +11638,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 258, + funcId: 260, port: port_, ); }, @@ -11591,7 +11676,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 259, + funcId: 261, port: port_, ); }, @@ -11626,7 +11711,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 260, + funcId: 262, port: port_, ); }, @@ -11657,7 +11742,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 261, + funcId: 263, port: port_, ); }, @@ -11704,7 +11789,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 262, + funcId: 264, port: port_, ); }, @@ -11762,7 +11847,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 263, + funcId: 265, port: port_, ); }, @@ -11795,7 +11880,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 264, + funcId: 266, port: port_, ); }, @@ -11828,7 +11913,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 265, + funcId: 267, port: port_, ); }, @@ -11858,7 +11943,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 266, + funcId: 268, port: port_, ); }, @@ -11897,7 +11982,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 267, + funcId: 269, port: port_, ); }, @@ -11927,7 +12012,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 268, + funcId: 270, port: port_, ); }, @@ -11957,7 +12042,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 269, + funcId: 271, port: port_, ); }, @@ -11987,7 +12072,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 270, + funcId: 272, port: port_, ); }, @@ -12019,7 +12104,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 271, + funcId: 273, port: port_, ); }, @@ -12050,7 +12135,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 272, + funcId: 274, port: port_, ); }, @@ -12086,7 +12171,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 273, + funcId: 275, port: port_, ); }, @@ -12120,7 +12205,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 274, + funcId: 276, port: port_, ); }, @@ -12163,7 +12248,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 275, + funcId: 277, port: port_, ); }, @@ -12205,7 +12290,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 276, + funcId: 278, port: port_, ); }, @@ -12238,7 +12323,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 277, + funcId: 279, port: port_, ); }, @@ -12277,7 +12362,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 278, + funcId: 280, port: port_, ); }, @@ -12307,7 +12392,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 279, + funcId: 281, port: port_, ); }, @@ -12335,7 +12420,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 280, + funcId: 282, port: port_, ); }, @@ -12370,7 +12455,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 281, + funcId: 283, port: port_, ); }, @@ -12416,7 +12501,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 282, + funcId: 284, port: port_, ); }, @@ -12458,7 +12543,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { pdeCallFfi( generalizedFrbRustBinding, serializer, - funcId: 283, + funcId: 285, port: port_, ); }, @@ -22474,6 +22559,22 @@ class MultimintImpl extends RustOpaque implements Multimint { Future> federations() => RustLib.instance.api.crateMultimintMultimintFederations(that: this); + /// Asks a joined federation's guardians for the shutdown date they have + /// set right now, as a single consensus query. `Ok(None)` means none is + /// set. + /// + /// For a one-off decision this beats the alternatives: the cached meta can + /// be weeks stale for a federation that was previewed long ago and only + /// now joined (previews never refresh a cached row), while a full + /// `refresh_federation_meta` also probes every guardian for its version, + /// one after another and unbounded, which is slowest exactly when a + /// federation is winding down. + Future fetchFederationExpiry({required FederationId federationId}) => + RustLib.instance.api.crateMultimintMultimintFetchFederationExpiry( + that: this, + federationId: federationId, + ); + Future> getAddresses({ required FederationId federationId, }) => RustLib.instance.api.crateMultimintMultimintGetAddresses( diff --git a/lib/lib.dart b/lib/lib.dart index a6838d96..d6f7f70a 100644 --- a/lib/lib.dart +++ b/lib/lib.dart @@ -235,6 +235,9 @@ Future getFederationMeta({ federationId: federationId, ); +Future fetchFederationExpiry({required FederationId federationId}) => + RustLib.instance.api.crateFetchFederationExpiry(federationId: federationId); + Future refreshFederationMeta({ required FederationId federationId, }) => diff --git a/lib/multimint.dart b/lib/multimint.dart index 641b42df..9d453db6 100644 --- a/lib/multimint.dart +++ b/lib/multimint.dart @@ -233,6 +233,18 @@ abstract class Multimint implements RustOpaqueInterface { Future> federations(); + /// Asks a joined federation's guardians for the shutdown date they have + /// set right now, as a single consensus query. `Ok(None)` means none is + /// set. + /// + /// For a one-off decision this beats the alternatives: the cached meta can + /// be weeks stale for a federation that was previewed long ago and only + /// now joined (previews never refresh a cached row), while a full + /// `refresh_federation_meta` also probes every guardian for its version, + /// one after another and unbounded, which is slowest exactly when a + /// federation is winding down. + Future fetchFederationExpiry({required FederationId federationId}); + Future> getAddresses({ required FederationId federationId, }); diff --git a/lib/screens/federation_info_screen.dart b/lib/screens/federation_info_screen.dart index 7fc8012f..adb74a80 100644 --- a/lib/screens/federation_info_screen.dart +++ b/lib/screens/federation_info_screen.dart @@ -368,15 +368,22 @@ class _FederationInfoScreenState extends State { } } - /// Whether [fed]'s guardians have set a shutdown date. When the meta cannot - /// be read this errs on the side of not claiming: an address registered on a - /// federation that is closing is worse than one the user claims by hand. + /// Whether [fed]'s guardians have set a shutdown date, asked of them + /// directly in one round trip rather than read from the cache, which can be + /// weeks old for a federation previewed long before it was joined. When + /// they cannot be asked this errs on the side of not claiming: an address + /// registered on a federation that is closing is worse than one the user + /// claims by hand. Future _isShuttingDown(FederationSelector fed) async { try { - final meta = await getFederationMeta(federationId: fed.federationId); - return meta.expiryTimestamp != null; + final expiry = await fetchFederationExpiry( + federationId: fed.federationId, + ); + return expiry != null; } catch (e) { - AppLogger.instance.warn("Could not read federation meta: $e"); + AppLogger.instance.warn( + "Could not ask the federation for its expiry: $e", + ); return true; } } diff --git a/rust/ecashapp/src/frb_generated.rs b/rust/ecashapp/src/frb_generated.rs index c30aeab3..127aa9b1 100644 --- a/rust/ecashapp/src/frb_generated.rs +++ b/rust/ecashapp/src/frb_generated.rs @@ -43,7 +43,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_auto_opaque = RustAutoOpaqueMoi, ); pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.9.0"; -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1847422546; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 470711718; // Section: executor @@ -3764,6 +3764,81 @@ fn wire__crate__multimint__Multimint_federations_impl( }, ) } +fn wire__crate__multimint__Multimint_fetch_federation_expiry_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "Multimint_fetch_federation_expiry", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_that = , + >>::sse_decode(&mut deserializer); + let api_federation_id = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| async move { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || async move { + let mut api_that_guard = None; + let mut api_federation_id_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order( + vec![ + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_that, 0, false, + ), + flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_federation_id, + 1, + false, + ), + ], + ); + for i in decode_indices_ { + match i { + 0 => { + api_that_guard = + Some(api_that.lockable_decode_async_ref().await) + } + 1 => { + api_federation_id_guard = + Some(api_federation_id.lockable_decode_async_ref().await) + } + _ => unreachable!(), + } + } + let api_that_guard = api_that_guard.unwrap(); + let api_federation_id_guard = api_federation_id_guard.unwrap(); + let output_ok = crate::multimint::Multimint::fetch_federation_expiry( + &*api_that_guard, + &*api_federation_id_guard, + ) + .await?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} fn wire__crate__multimint__Multimint_get_addresses_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -11545,6 +11620,64 @@ fn wire__crate__federations_impl( }, ) } +fn wire__crate__fetch_federation_expiry_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, + ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, + rust_vec_len_: i32, + data_len_: i32, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( + flutter_rust_bridge::for_generated::TaskInfo { + debug_name: "fetch_federation_expiry", + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, + }, + move || { + let message = unsafe { + flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire( + ptr_, + rust_vec_len_, + data_len_, + ) + }; + let mut deserializer = + flutter_rust_bridge::for_generated::SseDeserializer::new(message); + let api_federation_id = , + >>::sse_decode(&mut deserializer); + deserializer.end(); + move |context| async move { + transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || async move { + let mut api_federation_id_guard = None; + let decode_indices_ = + flutter_rust_bridge::for_generated::lockable_compute_decode_order( + vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new( + &api_federation_id, + 0, + false, + )], + ); + for i in decode_indices_ { + match i { + 0 => { + api_federation_id_guard = + Some(api_federation_id.lockable_decode_async_ref().await) + } + _ => unreachable!(), + } + } + let api_federation_id_guard = api_federation_id_guard.unwrap(); + let output_ok = + crate::fetch_federation_expiry(&*api_federation_id_guard).await?; + Ok(output_ok) + })() + .await, + ) + } + }, + ) +} fn wire__crate__fetch_lnurl_withdraw_impl( port_: flutter_rust_bridge::for_generated::MessagePort, ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr, @@ -18303,483 +18436,490 @@ fn pde_ffi_dispatcher_primary_impl( data_len, ), 67 => wire__crate__multimint__Multimint_federations_impl(port, ptr, rust_vec_len, data_len), - 68 => { + 68 => wire__crate__multimint__Multimint_fetch_federation_expiry_impl( + port, + ptr, + rust_vec_len, + data_len, + ), + 69 => { wire__crate__multimint__Multimint_get_addresses_impl(port, ptr, rust_vec_len, data_len) } - 69 => wire__crate__multimint__Multimint_get_all_btc_prices_impl( + 70 => wire__crate__multimint__Multimint_get_all_btc_prices_impl( port, ptr, rust_vec_len, data_len, ), - 70 => wire__crate__multimint__Multimint_get_all_invite_codes_impl( + 71 => wire__crate__multimint__Multimint_get_all_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 71 => wire__crate__multimint__Multimint_get_bitcoin_display_impl( + 72 => wire__crate__multimint__Multimint_get_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 72 => { + 73 => { wire__crate__multimint__Multimint_get_btc_price_impl(port, ptr, rust_vec_len, data_len) } - 73 => wire__crate__multimint__Multimint_get_cached_federation_meta_impl( + 74 => wire__crate__multimint__Multimint_get_cached_federation_meta_impl( port, ptr, rust_vec_len, data_len, ), - 74 => wire__crate__multimint__Multimint_get_federation_order_impl( + 75 => wire__crate__multimint__Multimint_get_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 75 => wire__crate__multimint__Multimint_get_fiat_currency_impl( + 76 => wire__crate__multimint__Multimint_get_fiat_currency_impl( port, ptr, rust_vec_len, data_len, ), - 76 => wire__crate__multimint__Multimint_get_invite_code_impl( + 77 => wire__crate__multimint__Multimint_get_invite_code_impl( port, ptr, rust_vec_len, data_len, ), - 77 => wire__crate__multimint__Multimint_get_ln_address_config_impl( + 78 => wire__crate__multimint__Multimint_get_ln_address_config_impl( port, ptr, rust_vec_len, data_len, ), - 78 => wire__crate__multimint__Multimint_get_max_withdrawable_amount_impl( + 79 => wire__crate__multimint__Multimint_get_max_withdrawable_amount_impl( port, ptr, rust_vec_len, data_len, ), - 79 => { + 80 => { wire__crate__multimint__Multimint_get_mnemonic_impl(port, ptr, rust_vec_len, data_len) } - 80 => wire__crate__multimint__Multimint_get_note_summary_impl( + 81 => wire__crate__multimint__Multimint_get_note_summary_impl( port, ptr, rust_vec_len, data_len, ), - 81 => wire__crate__multimint__Multimint_get_pegin_fee_quote_impl( + 82 => wire__crate__multimint__Multimint_get_pegin_fee_quote_impl( port, ptr, rust_vec_len, data_len, ), - 82 => wire__crate__multimint__Multimint_get_recovery_progress_impl( + 83 => wire__crate__multimint__Multimint_get_recovery_progress_impl( port, ptr, rust_vec_len, data_len, ), - 83 => { + 84 => { wire__crate__multimint__Multimint_get_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 84 => wire__crate__multimint__Multimint_guardian_add_gateway_impl( + 85 => wire__crate__multimint__Multimint_guardian_add_gateway_impl( port, ptr, rust_vec_len, data_len, ), - 85 => { + 86 => { wire__crate__multimint__Multimint_guardian_audit_impl(port, ptr, rust_vec_len, data_len) } - 86 => wire__crate__multimint__Multimint_guardian_backup_statistics_impl( + 87 => wire__crate__multimint__Multimint_guardian_backup_statistics_impl( port, ptr, rust_vec_len, data_len, ), - 87 => wire__crate__multimint__Multimint_guardian_list_gateways_impl( + 88 => wire__crate__multimint__Multimint_guardian_list_gateways_impl( port, ptr, rust_vec_len, data_len, ), - 88 => { + 89 => { wire__crate__multimint__Multimint_guardian_login_impl(port, ptr, rust_vec_len, data_len) } - 89 => wire__crate__multimint__Multimint_guardian_meta_accept_impl( + 90 => wire__crate__multimint__Multimint_guardian_meta_accept_impl( port, ptr, rust_vec_len, data_len, ), - 90 => wire__crate__multimint__Multimint_guardian_meta_propose_field_impl( + 91 => wire__crate__multimint__Multimint_guardian_meta_propose_field_impl( port, ptr, rust_vec_len, data_len, ), - 91 => wire__crate__multimint__Multimint_guardian_meta_state_impl( + 92 => wire__crate__multimint__Multimint_guardian_meta_state_impl( port, ptr, rust_vec_len, data_len, ), - 92 => wire__crate__multimint__Multimint_guardian_meta_withdraw_impl( + 93 => wire__crate__multimint__Multimint_guardian_meta_withdraw_impl( port, ptr, rust_vec_len, data_len, ), - 93 => wire__crate__multimint__Multimint_guardian_remove_gateway_impl( + 94 => wire__crate__multimint__Multimint_guardian_remove_gateway_impl( port, ptr, rust_vec_len, data_len, ), - 94 => wire__crate__multimint__Multimint_guardian_status_impl( + 95 => wire__crate__multimint__Multimint_guardian_status_impl( port, ptr, rust_vec_len, data_len, ), - 95 => wire__crate__multimint__Multimint_has_seed_phrase_ack_impl( + 96 => wire__crate__multimint__Multimint_has_seed_phrase_ack_impl( port, ptr, rust_vec_len, data_len, ), - 96 => wire__crate__multimint__Multimint_join_federation_impl( + 97 => wire__crate__multimint__Multimint_join_federation_impl( port, ptr, rust_vec_len, data_len, ), - 97 => wire__crate__multimint__Multimint_leave_federation_impl( + 98 => wire__crate__multimint__Multimint_leave_federation_impl( port, ptr, rust_vec_len, data_len, ), - 98 => wire__crate__multimint__Multimint_max_lightning_send_impl( + 99 => wire__crate__multimint__Multimint_max_lightning_send_impl( port, ptr, rust_vec_len, data_len, ), - 99 => wire__crate__multimint__Multimint_new_impl(port, ptr, rust_vec_len, data_len), - 100 => { + 100 => wire__crate__multimint__Multimint_new_impl(port, ptr, rust_vec_len, data_len), + 101 => { wire__crate__multimint__Multimint_parse_ecash_impl(port, ptr, rust_vec_len, data_len) } - 101 => wire__crate__multimint__Multimint_probe_invoice_is_loopback_impl( + 102 => wire__crate__multimint__Multimint_probe_invoice_is_loopback_impl( port, ptr, rust_vec_len, data_len, ), - 102 => wire__crate__multimint__Multimint_receive_impl(port, ptr, rust_vec_len, data_len), - 103 => wire__crate__multimint__Multimint_recheck_address_impl( + 103 => wire__crate__multimint__Multimint_receive_impl(port, ptr, rust_vec_len, data_len), + 104 => wire__crate__multimint__Multimint_recheck_address_impl( port, ptr, rust_vec_len, data_len, ), - 104 => wire__crate__multimint__Multimint_recover_ln_address_impl( + 105 => wire__crate__multimint__Multimint_recover_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 105 => wire__crate__multimint__Multimint_refresh_connections_impl( + 106 => wire__crate__multimint__Multimint_refresh_connections_impl( port, ptr, rust_vec_len, data_len, ), - 106 => wire__crate__multimint__Multimint_refresh_federation_meta_impl( + 107 => wire__crate__multimint__Multimint_refresh_federation_meta_impl( port, ptr, rust_vec_len, data_len, ), - 107 => wire__crate__multimint__Multimint_register_ln_address_impl( + 108 => wire__crate__multimint__Multimint_register_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 108 => { + 109 => { wire__crate__multimint__Multimint_reissue_ecash_impl(port, ptr, rust_vec_len, data_len) } - 109 => wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( + 110 => wire__crate__multimint__Multimint_rejoin_from_backup_invites_impl( port, ptr, rust_vec_len, data_len, ), - 110 => wire__crate__multimint__Multimint_remove_ln_address_impl( + 111 => wire__crate__multimint__Multimint_remove_ln_address_impl( port, ptr, rust_vec_len, data_len, ), - 111 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), - 112 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), - 113 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( + 112 => wire__crate__multimint__Multimint_send_impl(port, ptr, rust_vec_len, data_len), + 113 => wire__crate__multimint__Multimint_send_ecash_impl(port, ptr, rust_vec_len, data_len), + 114 => wire__crate__multimint__Multimint_set_bitcoin_display_impl( port, ptr, rust_vec_len, data_len, ), - 114 => wire__crate__multimint__Multimint_set_federation_order_impl( + 115 => wire__crate__multimint__Multimint_set_federation_order_impl( port, ptr, rust_vec_len, data_len, ), - 115 => wire__crate__multimint__Multimint_set_fiat_currency_impl( + 116 => wire__crate__multimint__Multimint_set_fiat_currency_impl( port, ptr, rust_vec_len, data_len, ), - 116 => { + 117 => { wire__crate__multimint__Multimint_set_show_msats_impl(port, ptr, rust_vec_len, data_len) } - 117 => { + 118 => { wire__crate__multimint__Multimint_transactions_impl(port, ptr, rust_vec_len, data_len) } - 118 => { + 119 => { wire__crate__multimint__Multimint_wallet_summary_impl(port, ptr, rust_vec_len, data_len) } - 119 => wire__crate__multimint__Multimint_withdraw_to_address_impl( + 120 => wire__crate__multimint__Multimint_withdraw_to_address_impl( port, ptr, rust_vec_len, data_len, ), - 120 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( + 121 => wire__crate__nostr__NostrClient_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 121 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( + 122 => wire__crate__nostr__NostrClient_clear_contacts_and_stop_sync_impl( port, ptr, rust_vec_len, data_len, ), - 122 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( + 123 => wire__crate__nostr__NostrClient_fetch_nostr_profiles_impl( port, ptr, rust_vec_len, data_len, ), - 123 => { + 124 => { wire__crate__nostr__NostrClient_get_all_contacts_impl(port, ptr, rust_vec_len, data_len) } - 124 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( + 125 => wire__crate__nostr__NostrClient_get_backup_invite_codes_impl( port, ptr, rust_vec_len, data_len, ), - 125 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), - 126 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( + 126 => wire__crate__nostr__NostrClient_get_contact_impl(port, ptr, rust_vec_len, data_len), + 127 => wire__crate__nostr__NostrClient_get_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 127 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( + 128 => wire__crate__nostr__NostrClient_get_follows_for_pubkey_impl( port, ptr, rust_vec_len, data_len, ), - 128 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( + 129 => wire__crate__nostr__NostrClient_get_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 129 => wire__crate__nostr__NostrClient_get_public_federations_impl( + 130 => wire__crate__nostr__NostrClient_get_public_federations_impl( port, ptr, rust_vec_len, data_len, ), - 130 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), - 131 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( + 131 => wire__crate__nostr__NostrClient_get_relays_impl(port, ptr, rust_vec_len, data_len), + 132 => wire__crate__nostr__NostrClient_has_imported_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 132 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), - 133 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), - 134 => wire__crate__nostr__NostrClient_paginate_contacts_impl( + 133 => wire__crate__nostr__NostrClient_insert_relay_impl(port, ptr, rust_vec_len, data_len), + 134 => wire__crate__nostr__NostrClient_new_impl(port, ptr, rust_vec_len, data_len), + 135 => wire__crate__nostr__NostrClient_paginate_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 135 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( + 136 => wire__crate__nostr__NostrClient_paginate_search_contacts_impl( port, ptr, rust_vec_len, data_len, ), - 136 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( + 137 => wire__crate__nostr__NostrClient_remove_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 137 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), - 138 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( + 138 => wire__crate__nostr__NostrClient_remove_relay_impl(port, ptr, rust_vec_len, data_len), + 139 => wire__crate__nostr__NostrClient_set_contact_sync_config_impl( port, ptr, rust_vec_len, data_len, ), - 139 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( + 140 => wire__crate__nostr__NostrClient_set_nwc_connection_info_impl( port, ptr, rust_vec_len, data_len, ), - 140 => { + 141 => { wire__crate__nostr__NostrClient_sync_contacts_impl(port, ptr, rust_vec_len, data_len) } - 141 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 145 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( + 142 => wire__crate__nostr__NostrClient_verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 146 => wire__crate__fountain__OobNotesEncoder_next_fragment_impl( port, ptr, rust_vec_len, data_len, ), - 172 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), - 173 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), - 174 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), - 175 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), - 176 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), - 177 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), - 178 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), - 179 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), - 180 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), - 181 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), - 182 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), - 183 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), - 184 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), - 185 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), - 186 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), - 187 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), - 188 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), - 189 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), - 190 => { + 173 => wire__crate__ack_seed_phrase_impl(port, ptr, rust_vec_len, data_len), + 174 => wire__crate__add_recovery_relay_impl(port, ptr, rust_vec_len, data_len), + 175 => wire__crate__allocate_deposit_address_impl(port, ptr, rust_vec_len, data_len), + 176 => wire__crate__await_ecash_reissue_impl(port, ptr, rust_vec_len, data_len), + 177 => wire__crate__await_receive_impl(port, ptr, rust_vec_len, data_len), + 178 => wire__crate__await_send_impl(port, ptr, rust_vec_len, data_len), + 179 => wire__crate__await_withdraw_impl(port, ptr, rust_vec_len, data_len), + 180 => wire__crate__backup_invite_codes_impl(port, ptr, rust_vec_len, data_len), + 181 => wire__crate__balance_impl(port, ptr, rust_vec_len, data_len), + 182 => wire__crate__calculate_ecash_reissue_fees_impl(port, ptr, rust_vec_len, data_len), + 183 => wire__crate__calculate_ecash_send_fees_impl(port, ptr, rust_vec_len, data_len), + 184 => wire__crate__calculate_withdraw_fees_impl(port, ptr, rust_vec_len, data_len), + 185 => wire__crate__change_pin_code_impl(port, ptr, rust_vec_len, data_len), + 186 => wire__crate__check_ecash_spent_impl(port, ptr, rust_vec_len, data_len), + 187 => wire__crate__check_ln_address_availability_impl(port, ptr, rust_vec_len, data_len), + 188 => wire__crate__claim_random_ln_address_impl(port, ptr, rust_vec_len, data_len), + 189 => wire__crate__clear_contacts_and_stop_sync_impl(port, ptr, rust_vec_len, data_len), + 190 => wire__crate__clear_pin_code_impl(port, ptr, rust_vec_len, data_len), + 191 => { wire__crate__compute_receive_amount_with_fees_impl(port, ptr, rust_vec_len, data_len) } - 191 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), - 192 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), - 193 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), - 194 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 195 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), - 196 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), - 197 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), - 198 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), - 199 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), - 200 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), - 201 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 202 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), - 203 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), - 204 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 205 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), - 206 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 207 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), - 208 => { + 192 => wire__crate__db__connector_default_impl(port, ptr, rust_vec_len, data_len), + 193 => wire__crate__create_multimint_from_words_impl(port, ptr, rust_vec_len, data_len), + 194 => wire__crate__create_new_multimint_impl(port, ptr, rust_vec_len, data_len), + 195 => wire__crate__execute_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 196 => wire__crate__federation_id_to_string_impl(port, ptr, rust_vec_len, data_len), + 197 => wire__crate__federations_impl(port, ptr, rust_vec_len, data_len), + 198 => wire__crate__fetch_federation_expiry_impl(port, ptr, rust_vec_len, data_len), + 199 => wire__crate__fetch_lnurl_withdraw_impl(port, ptr, rust_vec_len, data_len), + 200 => wire__crate__get_addresses_impl(port, ptr, rust_vec_len, data_len), + 201 => wire__crate__get_all_btc_prices_impl(port, ptr, rust_vec_len, data_len), + 202 => wire__crate__get_all_contacts_impl(port, ptr, rust_vec_len, data_len), + 203 => wire__crate__get_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 204 => wire__crate__get_btc_price_impl(port, ptr, rust_vec_len, data_len), + 205 => wire__crate__get_event_bus_impl(port, ptr, rust_vec_len, data_len), + 206 => wire__crate__get_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 207 => wire__crate__get_federation_order_impl(port, ptr, rust_vec_len, data_len), + 208 => wire__crate__get_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 209 => wire__crate__get_invite_code_impl(port, ptr, rust_vec_len, data_len), + 210 => { wire__crate__get_invoice_from_lnaddress_or_lnurl_impl(port, ptr, rust_vec_len, data_len) } - 209 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), - 210 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), - 211 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), - 212 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 213 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), - 214 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 215 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 216 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 217 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), - 218 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), - 219 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 220 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), - 221 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), - 222 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), - 223 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), - 224 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), - 225 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), - 226 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), - 227 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), - 228 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), - 229 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), - 230 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), - 231 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), - 232 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), - 233 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), - 234 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), - 235 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), - 237 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), - 238 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), - 239 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), - 240 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), - 241 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), - 242 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), - 243 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), - 244 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), - 245 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), - 246 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), - 248 => { + 211 => wire__crate__get_ln_address_config_impl(port, ptr, rust_vec_len, data_len), + 212 => wire__crate__get_max_withdrawable_amount_impl(port, ptr, rust_vec_len, data_len), + 213 => wire__crate__get_mnemonic_impl(port, ptr, rust_vec_len, data_len), + 214 => wire__crate__get_module_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 215 => wire__crate__get_note_summary_impl(port, ptr, rust_vec_len, data_len), + 216 => wire__crate__get_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 217 => wire__crate__get_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 218 => wire__crate__get_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 219 => wire__crate__get_pegin_fee_quote_impl(port, ptr, rust_vec_len, data_len), + 220 => wire__crate__get_relays_impl(port, ptr, rust_vec_len, data_len), + 221 => wire__crate__get_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 222 => wire__crate__get_show_msats_impl(port, ptr, rust_vec_len, data_len), + 223 => wire__crate__guardian_add_gateway_impl(port, ptr, rust_vec_len, data_len), + 224 => wire__crate__guardian_audit_impl(port, ptr, rust_vec_len, data_len), + 225 => wire__crate__guardian_backup_statistics_impl(port, ptr, rust_vec_len, data_len), + 226 => wire__crate__guardian_list_gateways_impl(port, ptr, rust_vec_len, data_len), + 227 => wire__crate__guardian_login_impl(port, ptr, rust_vec_len, data_len), + 228 => wire__crate__guardian_meta_accept_impl(port, ptr, rust_vec_len, data_len), + 229 => wire__crate__guardian_meta_propose_field_impl(port, ptr, rust_vec_len, data_len), + 230 => wire__crate__guardian_meta_state_impl(port, ptr, rust_vec_len, data_len), + 231 => wire__crate__guardian_meta_withdraw_impl(port, ptr, rust_vec_len, data_len), + 232 => wire__crate__guardian_remove_gateway_impl(port, ptr, rust_vec_len, data_len), + 233 => wire__crate__guardian_status_impl(port, ptr, rust_vec_len, data_len), + 234 => wire__crate__has_imported_contacts_impl(port, ptr, rust_vec_len, data_len), + 235 => wire__crate__has_pin_code_impl(port, ptr, rust_vec_len, data_len), + 236 => wire__crate__has_seed_phrase_ack_impl(port, ptr, rust_vec_len, data_len), + 237 => wire__crate__insert_relay_impl(port, ptr, rust_vec_len, data_len), + 239 => wire__crate__join_federation_impl(port, ptr, rust_vec_len, data_len), + 240 => wire__crate__leave_federation_impl(port, ptr, rust_vec_len, data_len), + 241 => wire__crate__list_federations_from_nostr_impl(port, ptr, rust_vec_len, data_len), + 242 => wire__crate__list_gateways_impl(port, ptr, rust_vec_len, data_len), + 243 => wire__crate__list_ln_address_domains_impl(port, ptr, rust_vec_len, data_len), + 244 => wire__crate__listen_for_nwc_blocking_impl(port, ptr, rust_vec_len, data_len), + 245 => wire__crate__load_multimint_impl(port, ptr, rust_vec_len, data_len), + 246 => wire__crate__max_lightning_send_impl(port, ptr, rust_vec_len, data_len), + 247 => wire__crate__paginate_contacts_impl(port, ptr, rust_vec_len, data_len), + 248 => wire__crate__paginate_search_contacts_impl(port, ptr, rust_vec_len, data_len), + 250 => { wire__crate__parse_scanned_text_for_federation_impl(port, ptr, rust_vec_len, data_len) } - 249 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), - 250 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), - 251 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), - 252 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), - 253 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), - 254 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), - 255 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), - 256 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), - 257 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), - 258 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), - 259 => wire__crate__remove_ln_address_impl(port, ptr, rust_vec_len, data_len), - 260 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 261 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), - 262 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), - 263 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), - 264 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), - 265 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), - 266 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), - 267 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), - 268 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), - 269 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), - 270 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), - 271 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), - 272 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), - 273 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), - 274 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), - 275 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), - 276 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), - 277 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), - 278 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), - 279 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), - 280 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), - 281 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), - 282 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), - 283 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), + 251 => wire__crate__parsed_scanned_text_impl(port, ptr, rust_vec_len, data_len), + 252 => wire__crate__payment_preview_with_gateways_impl(port, ptr, rust_vec_len, data_len), + 253 => wire__crate__pin_lockout_seconds_impl(port, ptr, rust_vec_len, data_len), + 254 => wire__crate__receive_impl(port, ptr, rust_vec_len, data_len), + 255 => wire__crate__recheck_address_impl(port, ptr, rust_vec_len, data_len), + 256 => wire__crate__refresh_connections_impl(port, ptr, rust_vec_len, data_len), + 257 => wire__crate__refresh_federation_meta_impl(port, ptr, rust_vec_len, data_len), + 258 => wire__crate__register_ln_address_impl(port, ptr, rust_vec_len, data_len), + 259 => wire__crate__reissue_ecash_impl(port, ptr, rust_vec_len, data_len), + 260 => wire__crate__rejoin_from_backup_invites_impl(port, ptr, rust_vec_len, data_len), + 261 => wire__crate__remove_ln_address_impl(port, ptr, rust_vec_len, data_len), + 262 => wire__crate__remove_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 263 => wire__crate__remove_relay_impl(port, ptr, rust_vec_len, data_len), + 264 => wire__crate__send_impl(port, ptr, rust_vec_len, data_len), + 265 => wire__crate__send_ecash_impl(port, ptr, rust_vec_len, data_len), + 266 => wire__crate__set_bitcoin_display_impl(port, ptr, rust_vec_len, data_len), + 267 => wire__crate__set_federation_order_impl(port, ptr, rust_vec_len, data_len), + 268 => wire__crate__set_fiat_currency_impl(port, ptr, rust_vec_len, data_len), + 269 => wire__crate__set_nwc_connection_info_impl(port, ptr, rust_vec_len, data_len), + 270 => wire__crate__set_nwc_daily_budget_sats_impl(port, ptr, rust_vec_len, data_len), + 271 => wire__crate__set_nwc_max_payment_sats_impl(port, ptr, rust_vec_len, data_len), + 272 => wire__crate__set_pin_code_impl(port, ptr, rust_vec_len, data_len), + 273 => wire__crate__set_require_pin_for_spending_impl(port, ptr, rust_vec_len, data_len), + 274 => wire__crate__set_show_msats_impl(port, ptr, rust_vec_len, data_len), + 275 => wire__crate__subscribe_deposits_impl(port, ptr, rust_vec_len, data_len), + 276 => wire__crate__subscribe_multimint_events_impl(port, ptr, rust_vec_len, data_len), + 277 => wire__crate__subscribe_peer_status_impl(port, ptr, rust_vec_len, data_len), + 278 => wire__crate__subscribe_recovery_progress_impl(port, ptr, rust_vec_len, data_len), + 279 => wire__crate__sync_contacts_impl(port, ptr, rust_vec_len, data_len), + 280 => wire__crate__transactions_impl(port, ptr, rust_vec_len, data_len), + 281 => wire__crate__verify_nip05_impl(port, ptr, rust_vec_len, data_len), + 282 => wire__crate__verify_pin_impl(port, ptr, rust_vec_len, data_len), + 283 => wire__crate__wallet_summary_impl(port, ptr, rust_vec_len, data_len), + 284 => wire__crate__withdraw_to_address_impl(port, ptr, rust_vec_len, data_len), + 285 => wire__crate__word_list_impl(port, ptr, rust_vec_len, data_len), _ => unreachable!(), } } @@ -19042,145 +19182,145 @@ fn pde_ffi_dispatcher_sync_impl( rust_vec_len, data_len, ), - 142 => { + 143 => { wire__crate__fountain__OobNotesDecoder_add_fragment_impl(ptr, rust_vec_len, data_len) } - 143 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), - 144 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), - 146 => { + 144 => wire__crate__fountain__OobNotesDecoder_new_impl(ptr, rust_vec_len, data_len), + 145 => wire__crate__fountain__OobNotesEncoder_new_impl(ptr, rust_vec_len, data_len), + 147 => { wire__crate__multimint__OobNotesWrapper_amount_msats_impl(ptr, rust_vec_len, data_len) } - 147 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), - 148 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( + 148 => wire__crate__multimint__OobNotesWrapper_to_string_impl(ptr, rust_vec_len, data_len), + 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_about_impl( ptr, rust_vec_len, data_len, ), - 149 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( + 150 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_id_impl( ptr, rust_vec_len, data_len, ), - 150 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( + 151 => wire__crate__nostr__PublicFederation_auto_accessor_get_federation_name_impl( ptr, rust_vec_len, data_len, ), - 151 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( + 152 => wire__crate__nostr__PublicFederation_auto_accessor_get_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 152 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( + 153 => wire__crate__nostr__PublicFederation_auto_accessor_get_modules_impl( ptr, rust_vec_len, data_len, ), - 153 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( + 154 => wire__crate__nostr__PublicFederation_auto_accessor_get_network_impl( ptr, rust_vec_len, data_len, ), - 154 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( + 155 => wire__crate__nostr__PublicFederation_auto_accessor_get_picture_impl( ptr, rust_vec_len, data_len, ), - 155 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( + 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_about_impl( ptr, rust_vec_len, data_len, ), - 156 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( + 157 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_id_impl( ptr, rust_vec_len, data_len, ), - 157 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( + 158 => wire__crate__nostr__PublicFederation_auto_accessor_set_federation_name_impl( ptr, rust_vec_len, data_len, ), - 158 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( + 159 => wire__crate__nostr__PublicFederation_auto_accessor_set_invite_codes_impl( ptr, rust_vec_len, data_len, ), - 159 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( + 160 => wire__crate__nostr__PublicFederation_auto_accessor_set_modules_impl( ptr, rust_vec_len, data_len, ), - 160 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( + 161 => wire__crate__nostr__PublicFederation_auto_accessor_set_network_impl( ptr, rust_vec_len, data_len, ), - 161 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( + 162 => wire__crate__nostr__PublicFederation_auto_accessor_set_picture_impl( ptr, rust_vec_len, data_len, ), - 162 => { + 163 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 163 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( + 164 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 164 => { + 165 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 165 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( + 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_fees_impl( ptr, rust_vec_len, data_len, ), - 166 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( + 167 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_get_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 167 => { + 168 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_federation_fee_msats_impl( ptr, rust_vec_len, data_len, ) } - 168 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( + 169 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_amount_impl( ptr, rust_vec_len, data_len, ), - 169 => { + 170 => { wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fee_rate_sats_per_vb_impl( ptr, rust_vec_len, data_len, ) } - 170 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( + 171 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_fees_impl( ptr, rust_vec_len, data_len, ), - 171 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( + 172 => wire__crate__multimint__WithdrawFeesResponse_auto_accessor_set_tx_size_vbytes_impl( ptr, rust_vec_len, data_len, ), - 236 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), - 247 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), + 238 => wire__crate__multimint__is_mintv2_ecash_impl(ptr, rust_vec_len, data_len), + 249 => wire__crate__multimint__parse_oob_notes_impl(ptr, rust_vec_len, data_len), _ => unreachable!(), } } diff --git a/rust/ecashapp/src/lib.rs b/rust/ecashapp/src/lib.rs index 8bd5cce0..26e88a50 100644 --- a/rust/ecashapp/src/lib.rs +++ b/rust/ecashapp/src/lib.rs @@ -539,6 +539,12 @@ pub async fn get_federation_meta( .await } +#[frb] +pub async fn fetch_federation_expiry(federation_id: &FederationId) -> anyhow::Result> { + let multimint = get_multimint(); + multimint.fetch_federation_expiry(federation_id).await +} + #[frb] pub async fn refresh_federation_meta( federation_id: &FederationId, diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index 5ccafdbb..4235052e 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -1906,6 +1906,32 @@ impl Multimint { .await) } + /// Asks a joined federation's guardians for the shutdown date they have + /// set right now, as a single consensus query. `Ok(None)` means none is + /// set. + /// + /// For a one-off decision this beats the alternatives: the cached meta can + /// be weeks stale for a federation that was previewed long ago and only + /// now joined (previews never refresh a cached row), while a full + /// `refresh_federation_meta` also probes every guardian for its version, + /// one after another and unbounded, which is slowest exactly when a + /// federation is winding down. + pub async fn fetch_federation_expiry( + &self, + federation_id: &FederationId, + ) -> anyhow::Result> { + let client = self.get_client(federation_id).await?; + let meta = client.get_first_module::()?; + let Some(value) = meta.get_consensus_value(DEFAULT_META_KEY).await? else { + return Ok(None); + }; + let json = value + .value + .to_json() + .context("federation meta is not valid JSON")?; + Ok(Self::get_expiry_timestamp(&json)) + } + /// Refetch and re-cache a federation's meta immediately, bypassing both the /// cached value and the periodic refresh task. Used after a guardian action /// changes meta consensus, so the app reflects it without waiting out the From 868c1ec34cd33e6ad7f261928adb3ec151b1dc04 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 12:11:53 -0500 Subject: [PATCH 12/17] fix: remove LN address from correct server --- lib/frb_generated.dart | 38 ++++++++++-------------------- lib/lib.dart | 9 ++----- lib/ln_address.dart | 7 +++--- lib/multimint.dart | 8 +++---- rust/ecashapp/src/frb_generated.rs | 7 +----- rust/ecashapp/src/lib.rs | 9 ++----- rust/ecashapp/src/multimint.rs | 23 +++++++++--------- 7 files changed, 35 insertions(+), 66 deletions(-) diff --git a/lib/frb_generated.dart b/lib/frb_generated.dart index c478d1b9..858538be 100644 --- a/lib/frb_generated.dart +++ b/lib/frb_generated.dart @@ -669,7 +669,6 @@ abstract class RustLibApi extends BaseApi { Future crateMultimintMultimintRemoveLnAddress({ required Multimint that, required FederationId federationId, - required String lnAddressApi, }); Future crateMultimintMultimintSend({ @@ -1345,10 +1344,7 @@ abstract class RustLibApi extends BaseApi { Future crateRejoinFromBackupInvites(); - Future crateRemoveLnAddress({ - required FederationId federationId, - required String lnAddressApi, - }); + Future crateRemoveLnAddress({required FederationId federationId}); Future crateRemoveNwcConnectionInfo({ required FederationId federationId, @@ -6108,7 +6104,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { Future crateMultimintMultimintRemoveLnAddress({ required Multimint that, required FederationId federationId, - required String lnAddressApi, }) { return handler.executeNormal( NormalTask( @@ -6122,7 +6117,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { federationId, serializer, ); - sse_encode_String(lnAddressApi, serializer); pdeCallFfi( generalizedFrbRustBinding, serializer, @@ -6135,7 +6129,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeErrorData: sse_decode_AnyhowException, ), constMeta: kCrateMultimintMultimintRemoveLnAddressConstMeta, - argValues: [that, federationId, lnAddressApi], + argValues: [that, federationId], apiImpl: this, ), ); @@ -6144,7 +6138,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { TaskConstMeta get kCrateMultimintMultimintRemoveLnAddressConstMeta => const TaskConstMeta( debugName: "Multimint_remove_ln_address", - argNames: ["that", "federationId", "lnAddressApi"], + argNames: ["that", "federationId"], ); @override @@ -11660,10 +11654,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - Future crateRemoveLnAddress({ - required FederationId federationId, - required String lnAddressApi, - }) { + Future crateRemoveLnAddress({required FederationId federationId}) { return handler.executeNormal( NormalTask( callFfi: (port_) { @@ -11672,7 +11663,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { federationId, serializer, ); - sse_encode_String(lnAddressApi, serializer); pdeCallFfi( generalizedFrbRustBinding, serializer, @@ -11685,7 +11675,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { decodeErrorData: sse_decode_AnyhowException, ), constMeta: kCrateRemoveLnAddressConstMeta, - argValues: [federationId, lnAddressApi], + argValues: [federationId], apiImpl: this, ), ); @@ -11693,7 +11683,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { TaskConstMeta get kCrateRemoveLnAddressConstMeta => const TaskConstMeta( debugName: "remove_ln_address", - argNames: ["federationId", "lnAddressApi"], + argNames: ["federationId"], ); @override @@ -23001,15 +22991,13 @@ class MultimintImpl extends RustOpaque implements Multimint { ); /// Gives up the Lightning Address registered for a federation, on the - /// server and locally. Errors when none is registered. - Future removeLnAddress({ - required FederationId federationId, - required String lnAddressApi, - }) => RustLib.instance.api.crateMultimintMultimintRemoveLnAddress( - that: this, - federationId: federationId, - lnAddressApi: lnAddressApi, - ); + /// server it was registered with and locally. Errors when none is + /// registered. + Future removeLnAddress({required FederationId federationId}) => + RustLib.instance.api.crateMultimintMultimintRemoveLnAddress( + that: this, + federationId: federationId, + ); Future send({ required FederationId federationId, diff --git a/lib/lib.dart b/lib/lib.dart index d6f7f70a..6f7c4257 100644 --- a/lib/lib.dart +++ b/lib/lib.dart @@ -514,13 +514,8 @@ Future registerLnAddress({ domain: domain, ); -Future removeLnAddress({ - required FederationId federationId, - required String lnAddressApi, -}) => RustLib.instance.api.crateRemoveLnAddress( - federationId: federationId, - lnAddressApi: lnAddressApi, -); +Future removeLnAddress({required FederationId federationId}) => + RustLib.instance.api.crateRemoveLnAddress(federationId: federationId); Future getInviteCode({ required FederationId federationId, diff --git a/lib/ln_address.dart b/lib/ln_address.dart index 6e9818a5..8b5f3fce 100644 --- a/lib/ln_address.dart +++ b/lib/ln_address.dart @@ -266,10 +266,9 @@ class _LightningAddressScreenState extends State { setState(() => _removing = true); try { - await removeLnAddress( - federationId: fed.federationId, - lnAddressApi: _lnAddressApi, - ); + // The endpoint the address lives on is stored with it; the screen's + // current API may point somewhere else. + await removeLnAddress(federationId: fed.federationId); if (!mounted) return; widget.onLnAddressChanged(fed, false); Navigator.of(context).pop(); diff --git a/lib/multimint.dart b/lib/multimint.dart index 9d453db6..3cd6daf0 100644 --- a/lib/multimint.dart +++ b/lib/multimint.dart @@ -521,11 +521,9 @@ abstract class Multimint implements RustOpaqueInterface { }); /// Gives up the Lightning Address registered for a federation, on the - /// server and locally. Errors when none is registered. - Future removeLnAddress({ - required FederationId federationId, - required String lnAddressApi, - }); + /// server it was registered with and locally. Errors when none is + /// registered. + Future removeLnAddress({required FederationId federationId}); Future send({ required FederationId federationId, diff --git a/rust/ecashapp/src/frb_generated.rs b/rust/ecashapp/src/frb_generated.rs index 127aa9b1..570b7577 100644 --- a/rust/ecashapp/src/frb_generated.rs +++ b/rust/ecashapp/src/frb_generated.rs @@ -6913,7 +6913,6 @@ fn wire__crate__multimint__Multimint_remove_ln_address_impl( let api_federation_id = , >>::sse_decode(&mut deserializer); - let api_ln_address_api = ::sse_decode(&mut deserializer); deserializer.end(); move |context| async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( @@ -6951,7 +6950,6 @@ fn wire__crate__multimint__Multimint_remove_ln_address_impl( let output_ok = crate::multimint::Multimint::remove_ln_address( &*api_that_guard, &*api_federation_id_guard, - api_ln_address_api, ) .await?; Ok(output_ok) @@ -14674,7 +14672,6 @@ fn wire__crate__remove_ln_address_impl( let api_federation_id = , >>::sse_decode(&mut deserializer); - let api_ln_address_api = ::sse_decode(&mut deserializer); deserializer.end(); move |context| async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>( @@ -14698,9 +14695,7 @@ fn wire__crate__remove_ln_address_impl( } } let api_federation_id_guard = api_federation_id_guard.unwrap(); - let output_ok = - crate::remove_ln_address(&*api_federation_id_guard, api_ln_address_api) - .await?; + let output_ok = crate::remove_ln_address(&*api_federation_id_guard).await?; Ok(output_ok) })() .await, diff --git a/rust/ecashapp/src/lib.rs b/rust/ecashapp/src/lib.rs index 26e88a50..e5ad34ad 100644 --- a/rust/ecashapp/src/lib.rs +++ b/rust/ecashapp/src/lib.rs @@ -1052,14 +1052,9 @@ pub async fn register_ln_address( } #[frb] -pub async fn remove_ln_address( - federation_id: &FederationId, - ln_address_api: String, -) -> anyhow::Result<()> { +pub async fn remove_ln_address(federation_id: &FederationId) -> anyhow::Result<()> { let multimint = get_multimint(); - multimint - .remove_ln_address(federation_id, ln_address_api) - .await + multimint.remove_ln_address(federation_id).await } #[frb] diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index 4235052e..4c587957 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -5738,9 +5738,13 @@ impl Multimint { &self, federation_id: &FederationId, config: &LightningAddressConfig, - ln_address_api: &str, ) -> anyhow::Result<()> { - let safe_ln_address_api = SafeUrl::parse(ln_address_api)?; + // The address, and the token that authorises deleting it, belong to + // the server it was registered with, which the config records. The + // screen's current endpoint can be a different server entirely (a + // custom one from the Advanced form, or a federation that has since + // changed its `lnaddress_api`), where the delete would be refused. + let safe_ln_address_api = config.ln_address_api.clone(); let remove_request = LNAddressRemoveRequest { username: config.username.clone(), domain: config.domain.clone(), @@ -5776,18 +5780,14 @@ impl Multimint { } /// Gives up the Lightning Address registered for a federation, on the - /// server and locally. Errors when none is registered. - pub async fn remove_ln_address( - &self, - federation_id: &FederationId, - ln_address_api: String, - ) -> anyhow::Result<()> { + /// server it was registered with and locally. Errors when none is + /// registered. + pub async fn remove_ln_address(&self, federation_id: &FederationId) -> anyhow::Result<()> { let config = self .get_ln_address_config(federation_id) .await .context("No Lightning Address is registered for this federation")?; - self.release_ln_address(federation_id, &config, &ln_address_api) - .await + self.release_ln_address(federation_id, &config).await } /// Register LNURL/LN Address @@ -5811,8 +5811,7 @@ impl Multimint { .await }; if let Some(config) = existing_config { - self.release_ln_address(federation_id, &config, &ln_address_api) - .await?; + self.release_ln_address(federation_id, &config).await?; } let client = self From 20b284e37088721c70eb84d6c274feb016dd2900 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 12:22:08 -0500 Subject: [PATCH 13/17] fix: soften successor language --- lib/l10n/app_en.arb | 6 ++++++ lib/l10n/app_es.arb | 2 ++ lib/screens/federation_info_screen.dart | 7 ++++++- lib/widgets/federation_expiry_banner.dart | 6 +++++- test/federation_expiry_banner_test.dart | 6 ++++++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 7ce97a58..e2720606 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2127,6 +2127,9 @@ "federationExpiryBannerTitle": "This federation is shutting down", "@federationExpiryBannerTitle": {}, + "federationExpiryBannerTitleSuccessor": "This federation has a successor", + "@federationExpiryBannerTitleSuccessor": {}, + "federationExpiryBannerSubtitle": "Closes on {date}.", "@federationExpiryBannerSubtitle": { "placeholders": { @@ -2154,6 +2157,9 @@ "federationExpiryBannerJoinHint": "Join only to recover funds you already hold here.", "@federationExpiryBannerJoinHint": {}, + "federationExpiryBannerSuccessorJoinHint": "Unless you hold funds here, consider joining the successor instead.", + "@federationExpiryBannerSuccessorJoinHint": {}, + "federationExpiryTitle": "Federation shutdown", "@federationExpiryTitle": {}, diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index d9ce0612..bbde0c1c 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -614,6 +614,7 @@ "nwcDailyBudgetDialogBody": "Lo máximo que una app vinculada puede gastar en total durante 24 horas. El conteo empieza con su primer pago y se reinicia 24 horas después.", "federationExpiryBannerTitle": "Esta federación va a cerrar", + "federationExpiryBannerTitleSuccessor": "Esta federación tiene una sucesora", "federationExpiryBannerSubtitle": "Cierra el {date}.", @@ -622,6 +623,7 @@ "federationExpiryBannerSubtitleSuccessor": "Los guardianes nombraron una federación sucesora.", "federationExpiryBannerTap": "Toca para ver detalles.", "federationExpiryBannerJoinHint": "Únete solo para recuperar fondos que ya tengas aquí.", + "federationExpiryBannerSuccessorJoinHint": "A menos que tengas fondos aquí, considera unirte a la sucesora.", "federationExpiryTitle": "Cierre de la federación", diff --git a/lib/screens/federation_info_screen.dart b/lib/screens/federation_info_screen.dart index adb74a80..a8e89b06 100644 --- a/lib/screens/federation_info_screen.dart +++ b/lib/screens/federation_info_screen.dart @@ -1028,7 +1028,12 @@ class _FederationInfoScreenState extends State { expiryTimestamp: _expiryTimestamp, onTap: null, compact: false, - note: context.l10n.federationExpiryBannerJoinHint, + note: + _expiryTimestamp != null + ? context.l10n.federationExpiryBannerJoinHint + : context + .l10n + .federationExpiryBannerSuccessorJoinHint, ), if (_welcomeMessage != null) ...[ const SizedBox(height: 8), diff --git a/lib/widgets/federation_expiry_banner.dart b/lib/widgets/federation_expiry_banner.dart index 111c01cb..bdb49ff9 100644 --- a/lib/widgets/federation_expiry_banner.dart +++ b/lib/widgets/federation_expiry_banner.dart @@ -126,7 +126,11 @@ class FederationExpiryBanner extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - context.l10n.federationExpiryBannerTitle, + // A successor with no date is a recommendation to move, + // not a shutdown; the locks treat it that way too. + expiryTimestamp == null + ? context.l10n.federationExpiryBannerTitleSuccessor + : context.l10n.federationExpiryBannerTitle, style: _titleStyle( theme.textTheme, )?.copyWith(color: warning), diff --git a/test/federation_expiry_banner_test.dart b/test/federation_expiry_banner_test.dart index 55d89482..ad9f566c 100644 --- a/test/federation_expiry_banner_test.dart +++ b/test/federation_expiry_banner_test.dart @@ -135,6 +135,12 @@ void main() { final l10n = AppLocalizations.of( tester.element(find.byType(FederationExpiryBanner)), ); + // A successor alone is not a shutdown, and the title must not say so. + expect( + find.text(l10n.federationExpiryBannerTitleSuccessor), + findsOneWidget, + ); + expect(find.text(l10n.federationExpiryBannerTitle), findsNothing); expect( find.text( '${l10n.federationExpiryBannerSubtitleSuccessor} ' From 722b0c4c8defc6501efd637a9f34fd3385004ab3 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 13:47:15 -0500 Subject: [PATCH 14/17] fix: treat no meta module as unset --- rust/ecashapp/src/multimint.rs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/rust/ecashapp/src/multimint.rs b/rust/ecashapp/src/multimint.rs index 4c587957..1d233ba6 100644 --- a/rust/ecashapp/src/multimint.rs +++ b/rust/ecashapp/src/multimint.rs @@ -1921,6 +1921,16 @@ impl Multimint { federation_id: &FederationId, ) -> anyhow::Result> { let client = self.get_client(federation_id).await?; + // An older federation without a meta module cannot have set a date. + // Checked up front, because the lookup below reports an absent module + // as an error indistinguishable from a real failure, and the caller + // treats errors as "do not claim". + if client + .get_first_instance(&fedimint_meta_client::common::KIND) + .is_none() + { + return Ok(None); + } let meta = client.get_first_module::()?; let Some(value) = meta.get_consensus_value(DEFAULT_META_KEY).await? else { return Ok(None); @@ -2057,16 +2067,26 @@ impl Multimint { // over the static config below. A failed or unparseable fetch is kept // apart from "no value set": only the latter means nothing is // announced. - let meta_fetch = match client.get_first_module::() { - Ok(meta) => match meta.get_consensus_value(DEFAULT_META_KEY).await { - Ok(Some(value)) => match value.value.to_json() { - Ok(json) => MetaFetch::Value(json), + let meta_fetch = if client + .get_first_instance(&fedimint_meta_client::common::KIND) + .is_none() + { + // No meta module means nothing can be announced. + MetaFetch::Unset + } else { + match client.get_first_module::() { + Ok(meta) => match meta.get_consensus_value(DEFAULT_META_KEY).await { + Ok(Some(value)) => match value.value.to_json() { + Ok(json) => MetaFetch::Value(json), + Err(_) => MetaFetch::Unavailable, + }, + Ok(None) => MetaFetch::Unset, Err(_) => MetaFetch::Unavailable, }, - Ok(None) => MetaFetch::Unset, + // The module is there but could not be resolved, which says + // nothing about the guardians' value. Err(_) => MetaFetch::Unavailable, - }, - Err(_) => MetaFetch::Unset, + } }; let fields = meta_fields_after_fetch(&meta_fetch, cached_meta.as_ref()); From 18240a2162b7d36e0336ce825e8dda94935243cf Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 13:50:52 -0500 Subject: [PATCH 15/17] chore: error handling when leaving a federation --- lib/screens/dashboard.dart | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 43b1294e..eb53ece2 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -322,6 +322,9 @@ class _DashboardState extends State { ), ).then((_) { // The checklist may have moved the balance or dropped the address. + // It may also have left the federation, in which case this dashboard + // is on its way out and there is nothing left to reload for. + if (!mounted) return; _loadBalance(); _loadLightningAddress(); _loadRecentTransactions(); @@ -391,10 +394,19 @@ class _DashboardState extends State { Future _loadRecentTransactions() async { if (recovering) return; - final txs = await transactions( - federationId: widget.fed.federationId, - modules: _getModulesForPaymentType(), - ); + final List txs; + try { + txs = await transactions( + federationId: widget.fed.federationId, + modules: _getModulesForPaymentType(), + ); + } catch (e) { + // Expected when the federation was left while this screen is still up: + // the leave dialog pops its routes before the app root has swapped the + // dashboard out, so a reload can still land here. Keep the last list. + AppLogger.instance.warn('Could not load transactions: $e'); + return; + } if (!mounted) return; setState(() { _recentTransactions = txs.take(20).toList(); From 964b1ff4607d6219536651e5a15179e33f5a6499 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 14:23:26 -0500 Subject: [PATCH 16/17] fix: only show recommended steps when loading succeeds --- lib/screens/federation_expiry_screen.dart | 12 ++++++--- test/federation_expiry_screen_test.dart | 33 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/screens/federation_expiry_screen.dart b/lib/screens/federation_expiry_screen.dart index e4399ac3..189a88f1 100644 --- a/lib/screens/federation_expiry_screen.dart +++ b/lib/screens/federation_expiry_screen.dart @@ -103,9 +103,10 @@ class _FederationExpiryScreenState extends State { late BigInt? _balanceMsats = widget.balanceMsats; late String? _lightningAddress = widget.lightningAddress; - /// False until the loaders have answered once. The dashboard hands over + /// False until both loaders have succeeded once. The dashboard hands over /// whatever it had loaded when the banner was tapped, which can be nothing - /// yet, and a missing balance or address must not read as "nothing to do". + /// yet, and neither a missing value nor a failed read may pass for + /// "nothing to do" while Leave sits below. bool _loaded = false; /// One step's flow at a time; every link is disabled while one runs. @@ -133,21 +134,26 @@ class _FederationExpiryScreenState extends State { Future _refresh() async { var balance = _balanceMsats; var address = _lightningAddress; + var complete = true; try { balance = await widget.loadBalance(); } catch (e) { + complete = false; AppLogger.instance.warn('Could not refresh balance: $e'); } try { address = await widget.loadLightningAddress(); } catch (e) { + complete = false; AppLogger.instance.warn('Could not refresh Lightning Address: $e'); } if (!mounted) return; setState(() { _balanceMsats = balance; _lightningAddress = address; - _loaded = true; + // Only a pair of successful reads settles which steps apply. Once + // settled, a later failed refresh keeps the last known values. + if (complete) _loaded = true; }); } diff --git a/test/federation_expiry_screen_test.dart b/test/federation_expiry_screen_test.dart index 55ce3d30..63b6d676 100644 --- a/test/federation_expiry_screen_test.dart +++ b/test/federation_expiry_screen_test.dart @@ -124,6 +124,39 @@ void main() { return flows; } + testWidgets('does not settle the checklist on a failed read', ( + tester, + ) async { + tallView(tester); + await tester.pumpWidget( + harness( + FederationExpiryScreen( + key: UniqueKey(), + federationName: 'Old Fed', + expiryTimestamp: inAMonth, + successorInvite: null, + balanceMsats: null, + lightningAddress: null, + loadBalance: () async => throw Exception('federation unreachable'), + loadLightningAddress: () async => address_, + onSendOnchain: () async {}, + onOpenLightningAddress: () async {}, + onJoin: (_, _) {}, + onLeaveFederation: () async {}, + ), + ), + ); + // The spinner never settles, so pump a few frames instead. + for (var i = 0; i < 5; i++) { + await tester.pump(const Duration(milliseconds: 100)); + } + + // A failed read is not "nothing to move": still loading, no Leave. + expect(find.byType(CircularProgressIndicator), findsOneWidget); + expect(find.text(en.federationExpirySendOnchain), findsNothing); + expect(find.text(en.leaveFederation), findsNothing); + }); + testWidgets('reads its inputs on entry rather than trusting the snapshot', ( tester, ) async { From cc80d38af3cc112b1b75a246f4d427638b1f42a0 Mon Sep 17 00:00:00 2001 From: m1sterc001guy Date: Wed, 16 Sep 2026 14:29:41 -0500 Subject: [PATCH 17/17] fix: move remove Lightning Address button --- lib/ln_address.dart | 114 ++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/lib/ln_address.dart b/lib/ln_address.dart index 8b5f3fce..c5465326 100644 --- a/lib/ln_address.dart +++ b/lib/ln_address.dart @@ -348,31 +348,33 @@ class _LightningAddressScreenState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (_domains.isNotEmpty) ...[ - DropdownButtonFormField( - // A form field reads initialValue once, so it is recreated when - // the selection changes under it; otherwise the initializer's - // pick was never shown and the field looked unset. - key: ValueKey(_selectedFederation), - decoration: InputDecoration( - labelText: context.l10n.selectAFederation, - ), - initialValue: _selectedFederation, - items: - feds - .map( - (f) => DropdownMenuItem( - value: f, - child: Text(f.federationName), - ), - ) - .toList(), - onChanged: (value) { - _userPickedFederation = true; - _onFederationSet(value); - _onUsernameChanged(); - }, + DropdownButtonFormField( + // A form field reads initialValue once, so it is recreated when + // the selection changes under it; otherwise the initializer's + // pick was never shown and the field looked unset. + key: ValueKey(_selectedFederation), + decoration: InputDecoration( + labelText: context.l10n.selectAFederation, ), + initialValue: _selectedFederation, + items: + feds + .map( + (f) => DropdownMenuItem( + value: f, + child: Text(f.federationName), + ), + ) + .toList(), + onChanged: (value) { + _userPickedFederation = true; + _onFederationSet(value); + _onUsernameChanged(); + }, + ), + // Registering needs the server's domain list; removing an address + // does not, so only the fields below depend on it. + if (_domains.isNotEmpty) ...[ const SizedBox(height: 24), Row( children: [ @@ -470,20 +472,36 @@ class _LightningAddressScreenState extends State { ), ), ), - if (_selectedFederationExpiring) - Padding( - padding: const EdgeInsets.only(top: 16), + ] else + Padding( + padding: const EdgeInsets.only(top: 24), + child: Center( child: Text( - _existingConfig != null - ? context.l10n.lnAddressRemoveCurrent - : context.l10n.lnAddressRegistrationClosed, + context.l10n.couldNotContactServer, textAlign: TextAlign.center, - style: TextStyle(color: Theme.of(context).colorScheme.error), + style: TextStyle( + color: Theme.of(context).colorScheme.error, + fontSize: 16, + ), ), ), - const SizedBox(height: 32), - Center( - child: ElevatedButton( + ), + if (_selectedFederationExpiring) + Padding( + padding: const EdgeInsets.only(top: 16), + child: Text( + _existingConfig != null + ? context.l10n.lnAddressRemoveCurrent + : context.l10n.lnAddressRegistrationClosed, + textAlign: TextAlign.center, + style: TextStyle(color: Theme.of(context).colorScheme.error), + ), + ), + const SizedBox(height: 32), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( onPressed: (_selectedFederation != null && _status is LNAddressStatus_Available && @@ -505,11 +523,9 @@ class _LightningAddressScreenState extends State { ) : Text(context.l10n.register), ), - ), - if (_existingConfig != null) ...[ - const SizedBox(height: 12), - Center( - child: TextButton.icon( + if (_existingConfig != null) ...[ + const SizedBox(width: 12), + TextButton.icon( onPressed: _removing ? null : _onRemovePressed, icon: const Icon(Icons.delete_outline), label: @@ -524,24 +540,10 @@ class _LightningAddressScreenState extends State { foregroundColor: Theme.of(context).colorScheme.error, ), ), - ), + ], ], - const SizedBox(height: 16), - ] else ...[ - Padding( - padding: const EdgeInsets.only(bottom: 24), - child: Center( - child: Text( - context.l10n.couldNotContactServer, - textAlign: TextAlign.center, - style: TextStyle( - color: Theme.of(context).colorScheme.error, - fontSize: 16, - ), - ), - ), - ), - ], + ), + const SizedBox(height: 16), GestureDetector( onTap: () { setState(() {