Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/npm_and_yarn/nanoid-3.3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
rolznz authored Jan 13, 2025
2 parents 803c734 + e52ed21 commit 463dc33
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 20 deletions.
83 changes: 77 additions & 6 deletions src/NWCClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
nip04,
nip19,
nip44,
finalizeEvent,
generateSecretKey,
getEventHash,
Expand Down Expand Up @@ -206,6 +207,7 @@ export class Nip47ResponseDecodingError extends Nip47Error {}
export class Nip47ResponseValidationError extends Nip47Error {}
export class Nip47UnexpectedResponseError extends Nip47Error {}
export class Nip47NetworkError extends Nip47Error {}
export class Nip47UnsupportedVersionError extends Nip47Error {}

export const NWCs: Record<string, NWCOptions> = {
alby: {
Expand All @@ -232,6 +234,9 @@ export class NWCClient {
lud16: string | undefined;
walletPubkey: string;
options: NWCOptions;
version: string | undefined;

static SUPPORTED_VERSIONS = ["0.0", "1.0"];

static parseWalletConnectUrl(walletConnectUrl: string): NWCOptions {
// makes it possible to parse with URL in the different environments (browser/node/...)
Expand Down Expand Up @@ -328,6 +333,13 @@ export class NWCClient {
return getPublicKey(hexToBytes(this.secret));
}

get supportedVersion(): string {
if (!this.version) {
throw new Error("Missing version");
}
return this.version;
}

getPublicKey(): Promise<string> {
return Promise.resolve(this.publicKey);
}
Expand All @@ -352,15 +364,27 @@ export class NWCClient {
if (!this.secret) {
throw new Error("Missing secret");
}
const encrypted = await nip04.encrypt(this.secret, pubkey, content);
let encrypted;
if (this.supportedVersion === "0.0") {
encrypted = await nip04.encrypt(this.secret, pubkey, content);
} else {
const key = nip44.getConversationKey(hexToBytes(this.secret), pubkey);
encrypted = nip44.encrypt(content, key);
}
return encrypted;
}

async decrypt(pubkey: string, content: string) {
if (!this.secret) {
throw new Error("Missing secret");
}
const decrypted = await nip04.decrypt(this.secret, pubkey, content);
let decrypted;
if (this.supportedVersion === "0.0") {
decrypted = await nip04.decrypt(this.secret, pubkey, content);
} else {
const key = nip44.getConversationKey(hexToBytes(this.secret), pubkey);
decrypted = nip44.decrypt(content, key);
}
return decrypted;
}

Expand Down Expand Up @@ -467,6 +491,7 @@ export class NWCClient {
}

async getWalletServiceInfo(): Promise<{
versions: string[];
capabilities: Nip47Capability[];
notifications: Nip47NotificationType[];
}> {
Expand Down Expand Up @@ -503,7 +528,9 @@ export class NWCClient {
const notificationsTag = events[0].tags.find(
(t) => t[0] === "notifications",
);
const versionsTag = events[0].tags.find((t) => t[0] === "v");
return {
versions: versionsTag ? versionsTag[1]?.split(" ") : ["0.0"],
// delimiter is " " per spec, but Alby NWC originally returned ","
capabilities: content.split(/[ |,]/g) as Nip47Method[],
notifications: (notificationsTag?.[1]?.split(" ") ||
Expand Down Expand Up @@ -715,11 +742,13 @@ export class NWCClient {
while (subscribed) {
try {
await this._checkConnected();

await this._checkCompatibility();
sub = this.relay.subscribe(
[
{
kinds: [23196],
kinds: [
...(this.supportedVersion === "0.0" ? [23196] : [23197]),
],
authors: [this.walletPubkey],
"#p": [this.publicKey],
},
Expand Down Expand Up @@ -792,6 +821,7 @@ export class NWCClient {
resultValidator: (result: T) => boolean,
): Promise<T> {
await this._checkConnected();
await this._checkCompatibility();
return new Promise<T>((resolve, reject) => {
(async () => {
const command = {
Expand All @@ -805,7 +835,10 @@ export class NWCClient {
const eventTemplate: EventTemplate = {
kind: 23194,
created_at: Math.floor(Date.now() / 1000),
tags: [["p", this.walletPubkey]],
tags: [
["p", this.walletPubkey],
["v", this.supportedVersion],
],
content: encryptedCommand,
};

Expand Down Expand Up @@ -924,6 +957,7 @@ export class NWCClient {
resultValidator: (result: T) => boolean,
): Promise<(T & { dTag: string })[]> {
await this._checkConnected();
await this._checkCompatibility();
const results: (T & { dTag: string })[] = [];
return new Promise<(T & { dTag: string })[]>((resolve, reject) => {
(async () => {
Expand All @@ -938,7 +972,10 @@ export class NWCClient {
const eventTemplate: EventTemplate = {
kind: 23194,
created_at: Math.floor(Date.now() / 1000),
tags: [["p", this.walletPubkey]],
tags: [
["p", this.walletPubkey],
["v", this.supportedVersion],
],
content: encryptedCommand,
};

Expand Down Expand Up @@ -1065,6 +1102,7 @@ export class NWCClient {
})();
});
}

private async _checkConnected() {
if (!this.secret) {
throw new Error("Missing secret key");
Expand All @@ -1084,4 +1122,37 @@ export class NWCClient {
);
}
}

private async _checkCompatibility() {
if (!this.version) {
const walletServiceInfo = await this.getWalletServiceInfo();
const compatibleVersion = this.selectHighestCompatibleVersion(
walletServiceInfo.versions,
);
if (!compatibleVersion) {
throw new Nip47UnsupportedVersionError(
`no compatible version found between wallet and client`,
"UNSUPPORTED_VERSION",
);
}
if (compatibleVersion === "0.0") {
console.warn(
"NIP-04 encryption is about to be deprecated. Please upgrade your wallet service to use NIP-44 instead.",
);
}
this.version = compatibleVersion;
}
}

private selectHighestCompatibleVersion(
walletVersions: string[],
): string | null {
if (walletVersions.includes("1.0")) {
return "1.0";
}
if (walletVersions.includes("0.0")) {
return "0.0";
}
return null;
}
}
28 changes: 14 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1403,9 +1403,9 @@
integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==

"@getalby/lightning-tools@^5.0.1":
version "5.0.1"
resolved "https://registry.npmjs.org/@getalby/lightning-tools/-/lightning-tools-5.0.1.tgz"
integrity sha512-xoBfBYMQrJqwryU9fAYGIW6dzWRpdsAw8rroqTROba2bHdYT0ZvGnt4tjqXUhRswopR2X+wp1QeeWHZNL9A0Kg==
version "5.1.2"
resolved "https://registry.yarnpkg.com/@getalby/lightning-tools/-/lightning-tools-5.1.2.tgz#8a018e98d5c13097dd98d93192cf5e4e455f4c20"
integrity sha512-BwGm8eGbPh59BVa1gI5yJMantBl/Fdps6X4p1ZACnmxz9vDINX8/3aFoOnDlF7yyA2boXWCsReVQSr26Q2yjiQ==

"@humanwhocodes/config-array@^0.11.14":
version "0.11.14"
Expand Down Expand Up @@ -3861,9 +3861,9 @@ expect@^29.0.0, expect@^29.7.0:
jest-util "^29.7.0"

express@^4.18.2:
version "4.21.1"
resolved "https://registry.npmjs.org/express/-/express-4.21.1.tgz"
integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==
version "4.21.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32"
integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
Expand All @@ -3884,7 +3884,7 @@ express@^4.18.2:
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.10"
path-to-regexp "0.1.12"
proxy-addr "~2.0.7"
qs "6.13.0"
range-parser "~1.2.1"
Expand Down Expand Up @@ -6043,10 +6043,10 @@ path-platform@~0.11.15:
resolved "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz"
integrity sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==

[email protected].10:
version "0.1.10"
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz"
integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==
[email protected].12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7"
integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==

path-type@^4.0.0:
version "4.0.0"
Expand Down Expand Up @@ -7425,9 +7425,9 @@ typescript@^4.1.3:
integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==

typescript@^5.1.6:
version "5.5.4"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz"
integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==
version "5.7.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e"
integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==

umd@^3.0.0:
version "3.0.3"
Expand Down

0 comments on commit 463dc33

Please sign in to comment.