Skip to content

Commit

Permalink
chore: use nwc info event instead of nwa event
Browse files Browse the repository at this point in the history
  • Loading branch information
rolznz committed Feb 1, 2025
1 parent df1560a commit 58b42d7
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 54 deletions.
1 change: 0 additions & 1 deletion examples/nwc/client/nwa-accept.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ const nwaOptions = nwa.NWAClient.parseWalletAuthUrl(nwaUrl);

const createAppResponse = await client.createConnection({
pubkey: nwaOptions.appPubkey,
nwaSecret: nwaOptions.nwaSecret,
// TODO: below should come from nwaOptions
name: "NWA test " + new Date().toISOString(),
methods: [
Expand Down
2 changes: 1 addition & 1 deletion examples/nwc/client/nwa.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ console.info("Waiting for connection...");

await nwaClient.subscribe({
onSuccess: async (nwcClient) => {
console.info("NWA successful");
console.info("NWA successful", nwcClient.options);
const response = await nwcClient.getInfo();

console.info(response);
Expand Down
5 changes: 1 addition & 4 deletions src/NWAClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe("NWA URI", () => {
});

expect(nwaClient.connectionUri).toEqual(
`nostr+walletauth://${nwaClient.options.appPubkey}?relay=${encodeURIComponent(nwaClient.options.relayUrl)}&secret=${nwaClient.options.nwaSecret}`,
`nostr+walletauth://${nwaClient.options.appPubkey}?relay=${encodeURIComponent(nwaClient.options.relayUrl)}`,
);
});

Expand All @@ -21,8 +21,5 @@ describe("NWA URI", () => {
"e73575d76c731102aefd4eb6fb0ddfaaf335eabe60255a22e6ca5e7074eb4992",
);
expect(nwaOptions.relayUrl).toEqual("wss://relay.getalby.com/v1");
expect(nwaOptions.nwaSecret).toEqual(
"1d7d477e495e26851ec0a01d633ceb74fe3cee78a850186a3a978f0e63b285d4",
);
});
});
54 changes: 6 additions & 48 deletions src/NWAClient.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
import { generateSecretKey, getPublicKey, nip44, Relay } from "nostr-tools";
import { generateSecretKey, getPublicKey, Relay } from "nostr-tools";
import { Nip47NetworkError, NWCClient } from "./NWCClient";

export type NWAOptions = {
relayUrl: string;
appSecretKey?: string;
appPubkey: string;
nwaSecret: string;
};

export type NewNWAClientOptions = {
Expand All @@ -25,7 +24,6 @@ export class NWAClient {
relayUrl: options.relayUrl,
appSecretKey,
appPubkey: getPublicKey(hexToBytes(appSecretKey)),
nwaSecret: bytesToHex(generateSecretKey()),
};

if (!this.options.relayUrl) {
Expand All @@ -47,7 +45,7 @@ export class NWAClient {
* returns the NWA connection URI which should be given to the wallet
*/
get connectionUri() {
return `nostr+walletauth://${this.options.appPubkey}?relay=${encodeURIComponent(this.options.relayUrl)}&secret=${this.options.nwaSecret}`;
return `nostr+walletauth://${this.options.appPubkey}?relay=${encodeURIComponent(this.options.relayUrl)}`;
}

static parseWalletAuthUrl(walletAuthUrl: string): NWAOptions {
Expand All @@ -68,17 +66,11 @@ export class NWAClient {
throw new Error("No relay URL found in connection string");
}

const nwaSecret = url.searchParams.get("secret");
if (!nwaSecret) {
throw new Error("No secret found in connection string");
}

// TODO: support other params (commands/methods, budgets, limits etc.)

return {
relayUrl,
appPubkey,
nwaSecret,
};
}

Expand All @@ -97,9 +89,8 @@ export class NWAClient {
const sub = this.relay.subscribe(
[
{
// kinds: [33194], // NIP-04
kinds: [33195], // NIP-44
"#d": [this.options.appPubkey],
kinds: [13194], // NIP-47 info event
"#p": [this.options.appPubkey],
},
],
{
Expand All @@ -114,34 +105,13 @@ export class NWAClient {

sub.onevent = async (event) => {
try {
if (
event.tags.find((t) => t[0] === "d")?.[1] !== this.options.appPubkey
) {
throw new Error("Event with incorrect d tag");
}

const decryptedContent = await this.decrypt(
event.pubkey,
event.content,
);

type NWAContent = {
secret: string;
// TODO: should commands be included here? they can be fetched from get_info or the info event?
// commands: Nip47Method[];
lud16: string;
};

const nwaContent = JSON.parse(decryptedContent) as NWAContent;
if (nwaContent.secret !== this.options.nwaSecret) {
throw new Error("Incorrect secret for this app");
}
const lud16 = event.tags.find((t) => t[0] === "lud16")?.[1];
args.onSuccess(
new NWCClient({
relayUrl: this.options.relayUrl,
secret: this.options.appSecretKey,
walletPubkey: event.pubkey,
lud16: nwaContent.lud16,
lud16,
}),
);
unsub();
Expand All @@ -155,18 +125,6 @@ export class NWAClient {
};
}

private decrypt(walletServicePubkey: string, content: string) {
if (!this.options.appSecretKey) {
throw new Error("No app secret key set");
}

const key = nip44.getConversationKey(
hexToBytes(this.options.appSecretKey),
walletServicePubkey,
);
return nip44.decrypt(content, key);
}

private async _checkConnected() {
if (!this.options.appSecretKey) {
throw new Error("Missing secret key");
Expand Down

0 comments on commit 58b42d7

Please sign in to comment.