Skip to content

Commit 6553686

Browse files
committed
more nip67 code
1 parent 15c6797 commit 6553686

File tree

4 files changed

+79
-4
lines changed

4 files changed

+79
-4
lines changed

NNostr.Client/NNostr.Client.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Nullable>enable</Nullable>
77
<LangVersion>11</LangVersion>
88
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
9-
<PackageVersion>0.0.48</PackageVersion>
9+
<PackageVersion>0.0.49</PackageVersion>
1010
<Title>Nostr Client</Title>
1111
<Description>A client for Nostr</Description>
1212
<Copyright>MIT</Copyright>

NNostr.Client/NostrExtensions.cs

+7
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ public static NostrEvent SetReferencedEvent(this NostrEvent nostrEvent, string e
9393
public static void SetTag(this NostrEvent nostrEvent, string identifier, params string[] data) =>
9494
nostrEvent.SetTag<NostrEvent, NostrEventTag>(identifier, data);
9595

96+
public static NostrEvent SetTag(this NostrEvent nostrEvent, string identifier, string data)
97+
{
98+
nostrEvent.SetTag(identifier, new[] {data});
99+
return nostrEvent;
100+
101+
}
102+
96103
public static void SetTag<TNostrEvent, TEventTag>(this TNostrEvent nostrEvent, string identifier,
97104
params string[] data) where TNostrEvent : BaseNostrEvent<TEventTag> where TEventTag : NostrEventTag, new()
98105
{

NNostr.Client/Protocols/NIP67.cs

+66-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
13
using System.Web;
24
using NBitcoin.Secp256k1;
35

@@ -8,7 +10,7 @@ public static class NIP67
810
public static int EventKind = 33194;
911
public record NIP67UriPayload(
1012
ECXOnlyPubKey Pubkey,
11-
ECPrivKey Secret,
13+
string Secret,
1214
string[] Relays,
1315
string[] RequiredCommands,
1416
string[] OptionalCommands,
@@ -18,7 +20,7 @@ public record NIP67UriPayload(
1820
public override string ToString()
1921
{
2022
var result =
21-
$"nostr+walletauth://{Pubkey.ToHex()}?relay={string.Join("&relay=", Relays)}&secret={Secret.CreateXOnlyPubKey().ToHex()}&required_commands={string.Join(" ", RequiredCommands)}";
23+
$"{UriScheme}://{Pubkey.ToHex()}?relay={string.Join("&relay=", Relays)}&secret={Secret}&required_commands={string.Join(" ", RequiredCommands)}";
2224

2325
if(OptionalCommands.Length > 0)
2426
result += $"&optional_commands={string.Join(" ", OptionalCommands)}";
@@ -37,15 +39,76 @@ public override string ToString()
3739

3840
public static NIP67UriPayload ParseUri(Uri uri)
3941
{
42+
if (!uri.Scheme.Equals(UriScheme, StringComparison.InvariantCultureIgnoreCase))
43+
throw new ArgumentException("Invalid scheme", nameof(uri));
4044
var query = HttpUtility.ParseQueryString(uri.Query);
4145

4246
var relays = query.GetValues("relay") ?? Array.Empty<string>();
43-
var secret = NostrExtensions.ParseKey(query["secret"]);
47+
var secret = query["secret"];
4448
var requiredCommands = query.GetValues("required_commands")?.SelectMany(s => s.Split(" ")).Distinct().ToArray() ?? Array.Empty<string>();
4549
var optionalCommands = query.GetValues("optional_commands")?.SelectMany(s => s.Split(" ")).Distinct().ToArray() ?? Array.Empty<string>();
4650
var budget = query.GetValues("budget")?.FirstOrDefault();
4751
var identity = query.GetValues("identity")?.FirstOrDefault();
4852

4953
return new NIP67UriPayload(NostrExtensions.ParsePubKey(uri.Host), secret, relays, requiredCommands, optionalCommands, budget, identity);
5054
}
55+
56+
public record Nip67ConfirmationEventContent()
57+
{
58+
//format is :
59+
/*
60+
*{
61+
"secret": "b8a30fafa48d4795b6c0eec169a383de", // string, the secret from the URI
62+
"commands": [ // array of strings, commands that the wallet agrees to support
63+
"pay_invoice",
64+
"pay_keysend",
65+
"make_invoice",
66+
"lookup_invoice",
67+
"list_transactions",
68+
],
69+
"relay": "wss://relay.damus.io", // Optional string, alternative relay that the wallet will use
70+
"lud16": "[email protected]", // Optional string, user's lightning address
71+
}
72+
*
73+
*/
74+
[JsonPropertyName("secret")]
75+
public string Secret { get; set; }
76+
77+
[JsonPropertyName("commands")]
78+
public string[] Commands { get; set; }
79+
[JsonPropertyName("relay")]
80+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
81+
public string? Relay { get; set; }
82+
[JsonPropertyName("lud16")]
83+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
84+
public string? Lud16 { get; set; }
85+
86+
87+
}
88+
public static async Task<NostrEvent> ConstructNip67ConfirmationEvent(NIP67UriPayload payload,Nip67ConfirmationEventContent conf,ECPrivKey key)
89+
{
90+
var confirmationEvent = new NostrEvent()
91+
{
92+
Kind = EventKind,
93+
Content = JsonSerializer.Serialize(conf),
94+
95+
}.SetTag("d", payload.Pubkey.ToHex());
96+
await confirmationEvent.EncryptNip04EventAsync(key, null, true);
97+
return confirmationEvent;
98+
}
99+
100+
public static async Task<(Uri Nip47Url, Nip67ConfirmationEventContent Nip67Payload)> Nip47FromNip67Event(NostrEvent e, ECPrivKey key, Uri? relay = null)
101+
{
102+
if(e.Kind != EventKind)
103+
throw new ArgumentException("Invalid event kind", nameof(e));
104+
105+
var content = await e.DecryptNip04EventAsync(key, null, true);
106+
107+
var payload = JsonSerializer.Deserialize<Nip67ConfirmationEventContent>(content);
108+
relay ??= new Uri(payload.Relay ?? throw new ArgumentException("Relay is required"));
109+
110+
return (NIP47.CreateUri(e.GetPublicKey(), key,relay, lud16:payload.Lud16), payload);
111+
}
112+
113+
51114
}

NNostr.Tests/ClientTests.cs

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public NostrWalletCOnnectTests()
2323
public async Task CanParseUri()
2424
{
2525

26+
var nwa = "nostr+walletauth://58c79c9e299fc2f8f153774c88a7be24b65c59d65ed1bca4525c58c9c656c793?relay=wss%3A%2F%2Frelay.mutinywallet.com%2F&secret=96f6569301468799&required_commands=pay_invoice&identity=71bfa9cbf84110de617e959021b08c69524fcaa1033ffd062abd0ae2657ba24c";
27+
var nwaPayload = NIP67.ParseUri(new Uri(nwa));
28+
29+
30+
2631
var uri = new Uri("");
2732
var result = NIP47.ParseUri(uri);
2833

0 commit comments

Comments
 (0)