Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,87 @@
|
||||
// Generated, do not edit. sha256:e8c40c7f89911d6db87ea8c48a3cd675bb64d66a36f01a1148bfcf8fc28f29e5
|
||||
export const MEMO_MAX = 2000;
|
||||
|
||||
const HEX64 = /^[0-9a-f]{64}$/;
|
||||
const tag = (tags, name) => (Array.isArray(tags) ? tags.find(t => Array.isArray(t) && t[0] === name)?.[1] : undefined);
|
||||
|
||||
function zapRequest(memo) {
|
||||
let ev = memo;
|
||||
if (typeof memo === 'string') {
|
||||
const s = memo.trim();
|
||||
if (!s.startsWith('{')) return null;
|
||||
try { ev = JSON.parse(s); } catch { return null; }
|
||||
}
|
||||
if (!ev || typeof ev !== 'object' || Number(ev.kind) !== 9734) return null;
|
||||
return ev;
|
||||
}
|
||||
|
||||
export function zapContext(memo) {
|
||||
const ev = zapRequest(memo);
|
||||
if (!ev) return null;
|
||||
const hex = v => (typeof v === 'string' && HEX64.test(v.toLowerCase()) ? v.toLowerCase() : null);
|
||||
const message = typeof ev.content === 'string' ? ev.content.trim() : '';
|
||||
return { sender: hex(ev.pubkey), recipient: hex(tag(ev.tags, 'p')), message, note: hex(tag(ev.tags, 'e')) };
|
||||
}
|
||||
|
||||
export function compactMemo(memo) {
|
||||
const ev = zapRequest(memo);
|
||||
if (ev) {
|
||||
const tags = (Array.isArray(ev.tags) ? ev.tags : []).filter(t => Array.isArray(t) && (t[0] === 'p' || t[0] === 'e'))
|
||||
.map(t => [t[0], String(t[1] ?? '')]);
|
||||
const klein = { kind: 9734, pubkey: String(ev.pubkey ?? ''), content: String(ev.content ?? '').slice(0, 1000), tags };
|
||||
return JSON.stringify(klein).slice(0, MEMO_MAX);
|
||||
}
|
||||
if (typeof memo !== 'string') return null;
|
||||
const s = memo.trim();
|
||||
return s ? s.slice(0, MEMO_MAX) : null;
|
||||
}
|
||||
|
||||
const CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
|
||||
function polymod(values) {
|
||||
const GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||||
let chk = 1;
|
||||
for (const v of values) {
|
||||
const top = chk >> 25;
|
||||
chk = ((chk & 0x1ffffff) << 5) ^ v;
|
||||
for (let i = 0; i < 5; i++) if ((top >> i) & 1) chk ^= GEN[i];
|
||||
}
|
||||
return chk;
|
||||
}
|
||||
function toWords(bytes) {
|
||||
const out = [];
|
||||
let acc = 0, bits = 0;
|
||||
for (const b of bytes) {
|
||||
acc = (acc << 8) | b;
|
||||
bits += 8;
|
||||
while (bits >= 5) { bits -= 5; out.push((acc >> bits) & 31); }
|
||||
}
|
||||
if (bits > 0) out.push((acc << (5 - bits)) & 31);
|
||||
return out;
|
||||
}
|
||||
|
||||
export function npub(hex) {
|
||||
if (typeof hex !== 'string' || !HEX64.test(hex)) return null;
|
||||
const bytes = hex.match(/../g).map(h => parseInt(h, 16));
|
||||
const hrp = 'npub';
|
||||
const data = toWords(bytes);
|
||||
const expand = [...[...hrp].map(c => c.charCodeAt(0) >> 5), 0, ...[...hrp].map(c => c.charCodeAt(0) & 31)];
|
||||
const mod = polymod([...expand, ...data, 0, 0, 0, 0, 0, 0]) ^ 1;
|
||||
const checksum = Array.from({ length: 6 }, (_, i) => (mod >> (5 * (5 - i))) & 31);
|
||||
return `${hrp}1${[...data, ...checksum].map(w => CHARSET[w]).join('')}`;
|
||||
}
|
||||
|
||||
export function npubShort(hex) {
|
||||
const n = npub(hex);
|
||||
return n ? `${n.slice(0, 9)}…${n.slice(-4)}` : null;
|
||||
}
|
||||
|
||||
export function memoNote(memo, direction) {
|
||||
const z = zapContext(memo);
|
||||
if (z) {
|
||||
const wie = npubShort(direction === 'in' ? z.sender : z.recipient);
|
||||
const kop = `zap ${direction === 'in' ? 'from' : 'to'}${wie ? ` ${wie}` : ''}`;
|
||||
return z.message ? `${kop}: "${z.message}"` : kop;
|
||||
}
|
||||
const s = compactMemo(memo);
|
||||
return s ? s.slice(0, 200) : null;
|
||||
}
|
||||
Reference in new issue
Block a user