feat(block2): Ğ1 — publish a Ğ1 address + 'Pay in Ğ1' in chat (levels 1-2)
The optional Ğ1 (free currency) integration, per g1-integration.md. - Profile: an optional 'Ğ1 address' field, persisted locally and published in your NIP-01 kind:0 metadata (separate from the Nostr key). - commons_core: UserProfile/ProfileTransport carry a 'g1' field (round-trip tested). - Chat: when the peer published a Ğ1 address, a 'Pay in Ğ1' app-bar action opens their wallet (url_launcher) so value moves in the wallet, not the app — copies the address as a fallback. No payment rails in-app (sharing-model §4.3). NOTE (vjrj): the wallet deep-link uses the Cesium web wallet as a universal fallback; swap the URI in chat_screen._payG1 for the Ğ1nkgo/Ğecko scheme you prefer. Analyzer clean (both packages); profile transport test covers g1.
This commit is contained in:
parent
d0d2ecb132
commit
d7136ec2c2
13 changed files with 138 additions and 14 deletions
|
|
@ -30,6 +30,7 @@ class ProfileScreen extends StatefulWidget {
|
|||
class _ProfileScreenState extends State<ProfileScreen> {
|
||||
final _name = TextEditingController();
|
||||
final _about = TextEditingController();
|
||||
final _g1 = TextEditingController();
|
||||
bool _loading = true;
|
||||
bool _saving = false;
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
Future<void> _load() async {
|
||||
_name.text = await widget.profileStore.name();
|
||||
_about.text = await widget.profileStore.about();
|
||||
_g1.text = await widget.profileStore.g1();
|
||||
if (mounted) setState(() => _loading = false);
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +59,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
final messenger = ScaffoldMessenger.of(context);
|
||||
final t = context.t;
|
||||
setState(() => _saving = true);
|
||||
await widget.profileStore.save(name: _name.text, about: _about.text);
|
||||
await widget.profileStore
|
||||
.save(name: _name.text, about: _about.text, g1: _g1.text);
|
||||
|
||||
// Best-effort publish to the network so peers see the name.
|
||||
final relays = await widget.settings.relayUrls();
|
||||
|
|
@ -67,6 +70,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
await session.profile.publish(
|
||||
name: _name.text.trim(),
|
||||
about: _about.text.trim(),
|
||||
g1: _g1.text.trim(),
|
||||
);
|
||||
await session.close();
|
||||
} catch (_) {
|
||||
|
|
@ -82,6 +86,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
void dispose() {
|
||||
_name.dispose();
|
||||
_about.dispose();
|
||||
_g1.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -116,6 +121,16 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
helperText: t.profile.aboutHint,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
key: const Key('profile.g1'),
|
||||
controller: _g1,
|
||||
decoration: InputDecoration(
|
||||
labelText: t.profile.g1,
|
||||
helperText: t.profile.g1Hint,
|
||||
helperMaxLines: 2,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
FilledButton(
|
||||
key: const Key('profile.save'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue