forked from nbd-wtf/nostr-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnip26.ts
69 lines (55 loc) · 2.42 KB
/
nip26.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { schnorr } from '@noble/curves/secp256k1'
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
import { sha256 } from '@noble/hashes/sha256'
import { utf8Encoder } from './utils.ts'
import { Event, getPublicKey } from './pure.ts'
export type Parameters = {
pubkey: string // the key to whom the delegation will be given
kind?: number
until?: number // delegation will only be valid until this date
since?: number // delegation will be valid from this date on
}
export type Delegation = {
from: string // the pubkey who signed the delegation
to: string // the pubkey that is allowed to use the delegation
cond: string // the string of conditions as they should be included in the event tag
sig: string
}
export function createDelegation(privateKey: string, parameters: Parameters): Delegation {
let conditions = []
if ((parameters.kind || -1) >= 0) conditions.push(`kind=${parameters.kind}`)
if (parameters.until) conditions.push(`created_at<${parameters.until}`)
if (parameters.since) conditions.push(`created_at>${parameters.since}`)
let cond = conditions.join('&')
if (cond === '') throw new Error('refusing to create a delegation without any conditions')
let sighash = sha256(utf8Encoder.encode(`nostr:delegation:${parameters.pubkey}:${cond}`))
let sig = bytesToHex(schnorr.sign(sighash, privateKey))
return {
from: getPublicKey(hexToBytes(privateKey)),
to: parameters.pubkey,
cond,
sig,
}
}
export function getDelegator(event: Event): string | null {
// find delegation tag
let tag = event.tags.find(tag => tag[0] === 'delegation' && tag.length >= 4)
if (!tag) return null
let pubkey = tag[1]
let cond = tag[2]
let sig = tag[3]
// check conditions
let conditions = cond.split('&')
for (let i = 0; i < conditions.length; i++) {
let [key, operator, value] = conditions[i].split(/\b/)
// the supported conditions are just 'kind' and 'created_at' for now
if (key === 'kind' && operator === '=' && event.kind === parseInt(value)) continue
else if (key === 'created_at' && operator === '<' && event.created_at < parseInt(value)) continue
else if (key === 'created_at' && operator === '>' && event.created_at > parseInt(value)) continue
else return null // invalid condition
}
// check signature
let sighash = sha256(utf8Encoder.encode(`nostr:delegation:${event.pubkey}:${cond}`))
if (!schnorr.verify(sig, sighash, pubkey)) return null
return pubkey
}