aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/nostr.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-03-23 10:18:40 -0700
committerAdam Soltys <[email protected]>2023-03-24 21:36:56 -0700
commiteec8d1605bd331e168649c35bbe2b2b2c1bb432d (patch)
tree11367f637976a86add5014f9f72a58f81f14f944 /src/lib/nostr.js
parente1fe2fb22efb74a855a2ba3ca5acb1bba774fa0f (diff)
downloadcoinos-ui-nostr-tools.tar.gz
coinos-ui-nostr-tools.zip
use nostr-toolsnostr-tools
Diffstat (limited to 'src/lib/nostr.js')
-rw-r--r--src/lib/nostr.js86
1 files changed, 23 insertions, 63 deletions
diff --git a/src/lib/nostr.js b/src/lib/nostr.js
index d72f48ef..1924643e 100644
--- a/src/lib/nostr.js
+++ b/src/lib/nostr.js
@@ -1,60 +1,39 @@
import { get } from 'svelte/store';
-import * as ecc from 'tiny-secp256k1';
-import { generateMnemonic, entropyToMnemonic, mnemonicToEntropy, mnemonicToSeedSync } from 'bip39';
import { Buffer } from 'buffer';
-import { bech32m } from 'bech32';
-import { bip32, fail, wait, post, stretch } from '$lib/utils';
-import { calculateId, signId } from 'nostr';
+import { fail, wait, post, stretch } from '$lib/utils';
import { decrypted, password as pw, passwordPrompt, pin, loginRedirect } from '$lib/store';
import { goto, invalidate } from '$app/navigation';
+import { getPublicKey, signEvent, getEventHash, nip04, nip06 } from 'nostr-tools';
+import { mnemonicToEntropy, entropyToMnemonic } from '@scure/bip39';
+import { wordlist } from '@scure/bip39/wordlists/english.js';
+import { bech32m } from '@scure/base';
-const { encode, decode, fromWords, toWords } = bech32m;
+const { generateSeedWords, privateKeyFromSeedWords } = nip06;
+const { encode, decode, toWords, fromWords } = bech32m;
export let generate = async (user) => {
- let password = get(pw);
- let mnemonic, key, seed, entropy, cipher, salt, child;
-
if (!get(pin)?.length === 6) return;
+ let password = get(pw);
- mnemonic = generateMnemonic();
- seed = mnemonicToSeedSync(mnemonic);
- entropy = mnemonicToEntropy(mnemonic);
- key = bip32.fromSeed(seed);
- child = key.derivePath("m/44'/1237'/0'/0/0");
- salt = crypto.getRandomValues(new Uint8Array(16));
+ let salt = crypto.getRandomValues(new Uint8Array(16));
+ let mnemonic = generateSeedWords();
+ let sk = privateKeyFromSeedWords(mnemonic);
let bytes = new Uint8Array(
await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: new Uint8Array(16) },
await stretch(password, salt),
- Uint8Array.from(Buffer.from(entropy, 'hex'))
+ Uint8Array.from(Buffer.from(mnemonicToEntropy(mnemonic, wordlist), 'hex'))
)
);
- user.pubkey = Buffer.from(ecc.xOnlyPointFromPoint(child.publicKey)).toString('hex');
+ user.pubkey = getPublicKey(sk);
user.cipher = encode('en', toWords(bytes), 180);
user.salt = Buffer.from(salt).toString('hex');
};
export let encrypt = async ({ message, recipient, user }) => {
- let sharedPoint = Buffer.from(
- ecc.pointMultiply(
- Uint8Array.from(Buffer.from('02' + recipient, 'hex')),
- Buffer.from(await getPrivateKey(user), 'hex')
- )
- );
-
- let iv = crypto.getRandomValues(new Uint8Array(16));
- let cipher = await crypto.subtle.encrypt(
- { name: 'AES-CBC', iv },
- await crypto.subtle.importKey('raw', sharedPoint.slice(1), 'AES-CBC', true, [
- 'encrypt',
- 'decrypt'
- ]),
- new TextEncoder().encode(message)
- );
-
- return Buffer.from(cipher).toString('base64') + '?iv=' + Buffer.from(iv).toString('base64');
+ return nip04.encrypt(await getPrivateKey(user), recipient, message);
};
export let decrypt = async ({ event, user }) => {
@@ -63,22 +42,8 @@ export let decrypt = async ({ event, user }) => {
let { content, pubkey, id } = event;
if (cache[id]) return cache[id];
if (pubkey === user.pubkey) pubkey = event.tags[0][1];
- pubkey = Uint8Array.from(Buffer.from('02' + pubkey, 'hex'));
-
- let sharedPoint = Buffer.from(
- ecc.pointMultiply(pubkey, Buffer.from(await getPrivateKey(user), 'hex'))
- );
- let [cipher, iv] = content.split('?iv=');
- cipher = Uint8Array.from(Buffer.from(cipher, 'base64'));
- iv = Uint8Array.from(Buffer.from(iv, 'base64'));
-
- let key = await crypto.subtle.importKey('raw', sharedPoint.slice(1), 'AES-CBC', true, [
- 'encrypt',
- 'decrypt'
- ]);
-
- let message = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, key, cipher);
+ let message = await nip04.decrypt(await getPrivateKey(user), pubkey, content);
cache[id] = Buffer.from(message).toString('utf8');
decrypted.set(cache);
@@ -111,27 +76,22 @@ let getPrivateKey = async (user) => {
password = get(pw);
let mnemonic, key, seed, entropy, child, privkey;
- entropy = Buffer.from(
+
+ entropy = new Uint8Array(
await crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: new Uint8Array(16) },
await stretch(password, Buffer.from(salt, 'hex')),
Uint8Array.from(fromWords(decode(cipher, 180).words))
- ),
- 'hex'
- ).toString('hex');
-
- mnemonic = entropyToMnemonic(entropy);
- seed = mnemonicToSeedSync(mnemonic);
- key = bip32.fromSeed(seed);
- child = key.derivePath("m/44'/1237'/0'/0/0");
+ )
+ );
- return child.privateKey;
+ mnemonic = entropyToMnemonic(entropy, wordlist);
+ return privateKeyFromSeedWords(mnemonic);
};
export let sign = async ({ event, user }) => {
- let privkey = await getPrivateKey(user);
- event.id = await calculateId(event);
- event.sig = await signId(privkey, event.id);
+ event.id = getEventHash(event);
+ event.sig = signEvent(event, await getPrivateKey(user));
};
export let send = (event) => {