Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nostr-tools

Package Overview
Dependencies
Maintainers
1
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nostr-tools - npm Package Compare versions

Comparing version 2.0.1 to 2.0.2

lib/cjs/nip44.js

151

lib/cjs/index.js

@@ -48,2 +48,3 @@ "use strict";

nip42: () => nip42_exports,
nip44: () => nip44_exports,
nip47: () => nip47_exports,

@@ -379,5 +380,5 @@ nip57: () => nip57_exports,

// relay.ts
function relayConnect(url) {
async function relayConnect(url) {
const relay = new Relay(url);
relay.connect();
await relay.connect();
return relay;

@@ -1638,2 +1639,124 @@ }

// nip44.ts
var nip44_exports = {};
__export(nip44_exports, {
default: () => nip44_default,
v2: () => v2
});
var import_chacha = require("@noble/ciphers/chacha");
var import_utils9 = require("@noble/ciphers/utils");
var import_secp256k13 = require("@noble/curves/secp256k1");
var import_hkdf = require("@noble/hashes/hkdf");
var import_hmac = require("@noble/hashes/hmac");
var import_sha2562 = require("@noble/hashes/sha256");
var import_utils10 = require("@noble/hashes/utils");
var import_base3 = require("@scure/base");
var decoder = new TextDecoder();
var u = {
minPlaintextSize: 1,
maxPlaintextSize: 65535,
utf8Encode: import_utils10.utf8ToBytes,
utf8Decode(bytes) {
return decoder.decode(bytes);
},
getConversationKey(privkeyA, pubkeyB) {
const sharedX = import_secp256k13.secp256k1.getSharedSecret(privkeyA, "02" + pubkeyB).subarray(1, 33);
return (0, import_hkdf.extract)(import_sha2562.sha256, sharedX, "nip44-v2");
},
getMessageKeys(conversationKey, nonce) {
(0, import_utils9.ensureBytes)(conversationKey, 32);
(0, import_utils9.ensureBytes)(nonce, 32);
const keys = (0, import_hkdf.expand)(import_sha2562.sha256, conversationKey, nonce, 76);
return {
chacha_key: keys.subarray(0, 32),
chacha_nonce: keys.subarray(32, 44),
hmac_key: keys.subarray(44, 76)
};
},
calcPaddedLen(len) {
if (!Number.isSafeInteger(len) || len < 1)
throw new Error("expected positive integer");
if (len <= 32)
return 32;
const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1;
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
return chunk * (Math.floor((len - 1) / chunk) + 1);
},
writeU16BE(num) {
if (!Number.isSafeInteger(num) || num < u.minPlaintextSize || num > u.maxPlaintextSize)
throw new Error("invalid plaintext size: must be between 1 and 65535 bytes");
const arr = new Uint8Array(2);
new DataView(arr.buffer).setUint16(0, num, false);
return arr;
},
pad(plaintext) {
const unpadded = u.utf8Encode(plaintext);
const unpaddedLen = unpadded.length;
const prefix = u.writeU16BE(unpaddedLen);
const suffix = new Uint8Array(u.calcPaddedLen(unpaddedLen) - unpaddedLen);
return (0, import_utils10.concatBytes)(prefix, unpadded, suffix);
},
unpad(padded) {
const unpaddedLen = new DataView(padded.buffer).getUint16(0);
const unpadded = padded.subarray(2, 2 + unpaddedLen);
if (unpaddedLen < u.minPlaintextSize || unpaddedLen > u.maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + u.calcPaddedLen(unpaddedLen))
throw new Error("invalid padding");
return u.utf8Decode(unpadded);
},
hmacAad(key, message, aad) {
if (aad.length !== 32)
throw new Error("AAD associated data must be 32 bytes");
const combined = (0, import_utils10.concatBytes)(aad, message);
return (0, import_hmac.hmac)(import_sha2562.sha256, key, combined);
},
decodePayload(payload) {
if (typeof payload !== "string")
throw new Error("payload must be a valid string");
const plen = payload.length;
if (plen < 132 || plen > 87472)
throw new Error("invalid payload length: " + plen);
if (payload[0] === "#")
throw new Error("unknown encryption version");
let data;
try {
data = import_base3.base64.decode(payload);
} catch (error) {
throw new Error("invalid base64: " + error.message);
}
const dlen = data.length;
if (dlen < 99 || dlen > 65603)
throw new Error("invalid data length: " + dlen);
const vers = data[0];
if (vers !== 2)
throw new Error("unknown encryption version " + vers);
return {
nonce: data.subarray(1, 33),
ciphertext: data.subarray(33, -32),
mac: data.subarray(-32)
};
}
};
function encrypt2(plaintext, conversationKey, nonce = (0, import_utils10.randomBytes)(32)) {
const { chacha_key, chacha_nonce, hmac_key } = u.getMessageKeys(conversationKey, nonce);
const padded = u.pad(plaintext);
const ciphertext = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, padded);
const mac = u.hmacAad(hmac_key, ciphertext, nonce);
return import_base3.base64.encode((0, import_utils10.concatBytes)(new Uint8Array([2]), nonce, ciphertext, mac));
}
function decrypt2(payload, conversationKey) {
const { nonce, ciphertext, mac } = u.decodePayload(payload);
const { chacha_key, chacha_nonce, hmac_key } = u.getMessageKeys(conversationKey, nonce);
const calculatedMac = u.hmacAad(hmac_key, ciphertext, nonce);
if (!(0, import_utils9.equalBytes)(calculatedMac, mac))
throw new Error("invalid MAC");
const padded = (0, import_chacha.chacha20)(chacha_key, chacha_nonce, ciphertext);
return u.unpad(padded);
}
var v2 = {
utils: u,
encrypt: encrypt2,
decrypt: decrypt2
};
var nip44_default = { v2 };
// nip47.ts

@@ -1681,3 +1804,3 @@ var nip47_exports = {};

});
var import_base3 = require("@scure/base");
var import_base4 = require("@scure/base");
var _fetch4;

@@ -1696,4 +1819,4 @@ try {

if (lud06) {
let { words } = import_base3.bech32.decode(lud06, 1e3);
let data = import_base3.bech32.fromWords(words);
let { words } = import_base4.bech32.decode(lud06, 1e3);
let data = import_base4.bech32.fromWords(words);
lnurl = utf8Decoder.decode(data);

@@ -1794,9 +1917,9 @@ } else if (lud16) {

});
var import_utils10 = require("@noble/hashes/utils");
var import_sha2562 = require("@noble/hashes/sha256");
var import_base4 = require("@scure/base");
var import_utils12 = require("@noble/hashes/utils");
var import_sha2563 = require("@noble/hashes/sha256");
var import_base5 = require("@scure/base");
var _authorizationScheme = "Nostr ";
function hashPayload(payload) {
const hash = (0, import_sha2562.sha256)(utf8Encoder.encode(JSON.stringify(payload)));
return (0, import_utils10.bytesToHex)(hash);
const hash = (0, import_sha2563.sha256)(utf8Encoder.encode(JSON.stringify(payload)));
return (0, import_utils12.bytesToHex)(hash);
}

@@ -1814,7 +1937,7 @@ async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme = false, payload) {

if (payload) {
event.tags.push(["payload", (0, import_utils10.bytesToHex)((0, import_sha2562.sha256)(utf8Encoder.encode(JSON.stringify(payload))))]);
event.tags.push(["payload", (0, import_utils12.bytesToHex)((0, import_sha2563.sha256)(utf8Encoder.encode(JSON.stringify(payload))))]);
}
const signedEvent = await sign(event);
const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : "";
return authorizationScheme + import_base4.base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
return authorizationScheme + import_base5.base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
}

@@ -1835,3 +1958,3 @@ async function validateToken(token, url, method) {

token = token.replace(_authorizationScheme, "");
const eventB64 = utf8Decoder.decode(import_base4.base64.decode(token));
const eventB64 = utf8Decoder.decode(import_base5.base64.decode(token));
if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) {

@@ -1869,3 +1992,3 @@ throw new Error("Invalid token");

const payloadTag = event.tags.find((t) => t[0] === "payload");
const payloadHash = (0, import_utils10.bytesToHex)((0, import_sha2562.sha256)(utf8Encoder.encode(JSON.stringify(body))));
const payloadHash = (0, import_utils12.bytesToHex)((0, import_sha2563.sha256)(utf8Encoder.encode(JSON.stringify(body))));
if (payloadTag?.[1] !== payloadHash) {

@@ -1872,0 +1995,0 @@ throw new Error("Invalid payload tag hash, does not match request body hash");

4

lib/cjs/relay.js

@@ -264,5 +264,5 @@ "use strict";

// relay.ts
function relayConnect(url) {
async function relayConnect(url) {
const relay = new Relay(url);
relay.connect();
await relay.connect();
return relay;

@@ -269,0 +269,0 @@ }

@@ -324,5 +324,5 @@ var __defProp = Object.defineProperty;

// relay.ts
function relayConnect(url) {
async function relayConnect(url) {
const relay = new Relay(url);
relay.connect();
await relay.connect();
return relay;

@@ -1583,2 +1583,124 @@ }

// nip44.ts
var nip44_exports = {};
__export(nip44_exports, {
default: () => nip44_default,
v2: () => v2
});
import { chacha20 } from "@noble/ciphers/chacha";
import { ensureBytes, equalBytes } from "@noble/ciphers/utils";
import { secp256k1 as secp256k12 } from "@noble/curves/secp256k1";
import { extract as hkdf_extract, expand as hkdf_expand } from "@noble/hashes/hkdf";
import { hmac } from "@noble/hashes/hmac";
import { sha256 as sha2562 } from "@noble/hashes/sha256";
import { concatBytes as concatBytes2, randomBytes as randomBytes2, utf8ToBytes } from "@noble/hashes/utils";
import { base64 as base642 } from "@scure/base";
var decoder = new TextDecoder();
var u = {
minPlaintextSize: 1,
maxPlaintextSize: 65535,
utf8Encode: utf8ToBytes,
utf8Decode(bytes) {
return decoder.decode(bytes);
},
getConversationKey(privkeyA, pubkeyB) {
const sharedX = secp256k12.getSharedSecret(privkeyA, "02" + pubkeyB).subarray(1, 33);
return hkdf_extract(sha2562, sharedX, "nip44-v2");
},
getMessageKeys(conversationKey, nonce) {
ensureBytes(conversationKey, 32);
ensureBytes(nonce, 32);
const keys = hkdf_expand(sha2562, conversationKey, nonce, 76);
return {
chacha_key: keys.subarray(0, 32),
chacha_nonce: keys.subarray(32, 44),
hmac_key: keys.subarray(44, 76)
};
},
calcPaddedLen(len) {
if (!Number.isSafeInteger(len) || len < 1)
throw new Error("expected positive integer");
if (len <= 32)
return 32;
const nextPower = 1 << Math.floor(Math.log2(len - 1)) + 1;
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
return chunk * (Math.floor((len - 1) / chunk) + 1);
},
writeU16BE(num) {
if (!Number.isSafeInteger(num) || num < u.minPlaintextSize || num > u.maxPlaintextSize)
throw new Error("invalid plaintext size: must be between 1 and 65535 bytes");
const arr = new Uint8Array(2);
new DataView(arr.buffer).setUint16(0, num, false);
return arr;
},
pad(plaintext) {
const unpadded = u.utf8Encode(plaintext);
const unpaddedLen = unpadded.length;
const prefix = u.writeU16BE(unpaddedLen);
const suffix = new Uint8Array(u.calcPaddedLen(unpaddedLen) - unpaddedLen);
return concatBytes2(prefix, unpadded, suffix);
},
unpad(padded) {
const unpaddedLen = new DataView(padded.buffer).getUint16(0);
const unpadded = padded.subarray(2, 2 + unpaddedLen);
if (unpaddedLen < u.minPlaintextSize || unpaddedLen > u.maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== 2 + u.calcPaddedLen(unpaddedLen))
throw new Error("invalid padding");
return u.utf8Decode(unpadded);
},
hmacAad(key, message, aad) {
if (aad.length !== 32)
throw new Error("AAD associated data must be 32 bytes");
const combined = concatBytes2(aad, message);
return hmac(sha2562, key, combined);
},
decodePayload(payload) {
if (typeof payload !== "string")
throw new Error("payload must be a valid string");
const plen = payload.length;
if (plen < 132 || plen > 87472)
throw new Error("invalid payload length: " + plen);
if (payload[0] === "#")
throw new Error("unknown encryption version");
let data;
try {
data = base642.decode(payload);
} catch (error) {
throw new Error("invalid base64: " + error.message);
}
const dlen = data.length;
if (dlen < 99 || dlen > 65603)
throw new Error("invalid data length: " + dlen);
const vers = data[0];
if (vers !== 2)
throw new Error("unknown encryption version " + vers);
return {
nonce: data.subarray(1, 33),
ciphertext: data.subarray(33, -32),
mac: data.subarray(-32)
};
}
};
function encrypt2(plaintext, conversationKey, nonce = randomBytes2(32)) {
const { chacha_key, chacha_nonce, hmac_key } = u.getMessageKeys(conversationKey, nonce);
const padded = u.pad(plaintext);
const ciphertext = chacha20(chacha_key, chacha_nonce, padded);
const mac = u.hmacAad(hmac_key, ciphertext, nonce);
return base642.encode(concatBytes2(new Uint8Array([2]), nonce, ciphertext, mac));
}
function decrypt2(payload, conversationKey) {
const { nonce, ciphertext, mac } = u.decodePayload(payload);
const { chacha_key, chacha_nonce, hmac_key } = u.getMessageKeys(conversationKey, nonce);
const calculatedMac = u.hmacAad(hmac_key, ciphertext, nonce);
if (!equalBytes(calculatedMac, mac))
throw new Error("invalid MAC");
const padded = chacha20(chacha_key, chacha_nonce, ciphertext);
return u.unpad(padded);
}
var v2 = {
utils: u,
encrypt: encrypt2,
decrypt: decrypt2
};
var nip44_default = { v2 };
// nip47.ts

@@ -1738,7 +1860,7 @@ var nip47_exports = {};

import { bytesToHex as bytesToHex4 } from "@noble/hashes/utils";
import { sha256 as sha2562 } from "@noble/hashes/sha256";
import { base64 as base642 } from "@scure/base";
import { sha256 as sha2563 } from "@noble/hashes/sha256";
import { base64 as base643 } from "@scure/base";
var _authorizationScheme = "Nostr ";
function hashPayload(payload) {
const hash = sha2562(utf8Encoder.encode(JSON.stringify(payload)));
const hash = sha2563(utf8Encoder.encode(JSON.stringify(payload)));
return bytesToHex4(hash);

@@ -1757,7 +1879,7 @@ }

if (payload) {
event.tags.push(["payload", bytesToHex4(sha2562(utf8Encoder.encode(JSON.stringify(payload))))]);
event.tags.push(["payload", bytesToHex4(sha2563(utf8Encoder.encode(JSON.stringify(payload))))]);
}
const signedEvent = await sign(event);
const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : "";
return authorizationScheme + base642.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
return authorizationScheme + base643.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
}

@@ -1778,3 +1900,3 @@ async function validateToken(token, url, method) {

token = token.replace(_authorizationScheme, "");
const eventB64 = utf8Decoder.decode(base642.decode(token));
const eventB64 = utf8Decoder.decode(base643.decode(token));
if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) {

@@ -1812,3 +1934,3 @@ throw new Error("Invalid token");

const payloadTag = event.tags.find((t) => t[0] === "payload");
const payloadHash = bytesToHex4(sha2562(utf8Encoder.encode(JSON.stringify(body))));
const payloadHash = bytesToHex4(sha2563(utf8Encoder.encode(JSON.stringify(body))));
if (payloadTag?.[1] !== payloadHash) {

@@ -1846,2 +1968,3 @@ throw new Error("Invalid payload tag hash, does not match request body hash");

nip42_exports as nip42,
nip44_exports as nip44,
nip47_exports as nip47,

@@ -1848,0 +1971,0 @@ nip57_exports as nip57,

@@ -242,5 +242,5 @@ var __defProp = Object.defineProperty;

// relay.ts
function relayConnect(url) {
async function relayConnect(url) {
const relay = new Relay(url);
relay.connect();
await relay.connect();
return relay;

@@ -247,0 +247,0 @@ }

@@ -21,2 +21,3 @@ export * from './pure.ts';

export * as nip42 from './nip42.ts';
export * as nip44 from './nip44.ts';
export * as nip47 from './nip47.ts';

@@ -23,0 +24,0 @@ export * as nip57 from './nip57.ts';

import { type Event, EventTemplate } from './pure.ts';
import { type Filter } from './filter.ts';
export declare function relayConnect(url: string): Relay;
export declare function relayConnect(url: string): Promise<Relay>;
export declare class Relay {

@@ -5,0 +5,0 @@ readonly url: string;

{
"name": "nostr-tools",
"version": "2.0.1",
"version": "2.0.2",
"description": "Tools for making a Nostr client.",

@@ -57,2 +57,7 @@ "repository": {

},
"./nip44": {
"import": "./lib/esm/nip44.js",
"require": "./lib/cjs/nip44.js",
"types": "./lib/types/nip44.d.ts"
},
"./nip05": {

@@ -59,0 +64,0 @@ "import": "./lib/esm/nip05.js",

@@ -24,3 +24,3 @@ # ![](https://img.shields.io/github/actions/workflow/status/nbd-wtf/nostr-tools/test.yml) nostr-tools

let sk = generateSecretKey() // `sk` is a hex string
let sk = generateSecretKey() // `sk` is a Uint8Array
let pk = getPublicKey(sk) // `pk` is a hex string

@@ -27,0 +27,0 @@ ```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc