add 17 test cases for nip57 (#166)
This commit is contained in:
parent
ce73b96565
commit
74c77a2e9f
|
@ -0,0 +1,335 @@
|
||||||
|
const {bech32} = require('@scure/base')
|
||||||
|
const {
|
||||||
|
nip57,
|
||||||
|
generatePrivateKey,
|
||||||
|
getPublicKey,
|
||||||
|
finishEvent
|
||||||
|
} = require('./lib/nostr.cjs')
|
||||||
|
|
||||||
|
describe('getZapEndpoint', () => {
|
||||||
|
test('returns null if neither lud06 nor lud16 is present', async () => {
|
||||||
|
const metadata = {content: '{}'}
|
||||||
|
const result = await nip57.getZapEndpoint(metadata)
|
||||||
|
|
||||||
|
expect(result).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns null if fetch fails', async () => {
|
||||||
|
const fetchImplementation = jest.fn(() => Promise.reject(new Error()))
|
||||||
|
nip57.useFetchImplementation(fetchImplementation)
|
||||||
|
|
||||||
|
const metadata = {content: '{"lud16": "name@domain"}'}
|
||||||
|
const result = await nip57.getZapEndpoint(metadata)
|
||||||
|
|
||||||
|
expect(result).toBeNull()
|
||||||
|
expect(fetchImplementation).toHaveBeenCalledWith(
|
||||||
|
'https://domain/.well-known/lnurlp/name'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns null if the response does not allow Nostr payments', async () => {
|
||||||
|
const fetchImplementation = jest.fn(() =>
|
||||||
|
Promise.resolve({json: () => ({allowsNostr: false})})
|
||||||
|
)
|
||||||
|
nip57.useFetchImplementation(fetchImplementation)
|
||||||
|
|
||||||
|
const metadata = {content: '{"lud16": "name@domain"}'}
|
||||||
|
const result = await nip57.getZapEndpoint(metadata)
|
||||||
|
|
||||||
|
expect(result).toBeNull()
|
||||||
|
expect(fetchImplementation).toHaveBeenCalledWith(
|
||||||
|
'https://domain/.well-known/lnurlp/name'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns the callback URL if the response allows Nostr payments', async () => {
|
||||||
|
const fetchImplementation = jest.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
json: () => ({
|
||||||
|
allowsNostr: true,
|
||||||
|
nostrPubkey: 'pubkey',
|
||||||
|
callback: 'callback'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
nip57.useFetchImplementation(fetchImplementation)
|
||||||
|
|
||||||
|
const metadata = {content: '{"lud16": "name@domain"}'}
|
||||||
|
const result = await nip57.getZapEndpoint(metadata)
|
||||||
|
|
||||||
|
expect(result).toBe('callback')
|
||||||
|
expect(fetchImplementation).toHaveBeenCalledWith(
|
||||||
|
'https://domain/.well-known/lnurlp/name'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('makeZapRequest', () => {
|
||||||
|
test('throws an error if amount is not given', () => {
|
||||||
|
expect(() =>
|
||||||
|
nip57.makeZapRequest({
|
||||||
|
profile: 'profile',
|
||||||
|
event: null,
|
||||||
|
relays: [],
|
||||||
|
comment: ''
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('throws an error if profile is not given', () => {
|
||||||
|
expect(() =>
|
||||||
|
nip57.makeZapRequest({
|
||||||
|
event: null,
|
||||||
|
amount: 100,
|
||||||
|
relays: [],
|
||||||
|
comment: ''
|
||||||
|
})
|
||||||
|
).toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns a valid Zap request', () => {
|
||||||
|
const result = nip57.makeZapRequest({
|
||||||
|
profile: 'profile',
|
||||||
|
event: 'event',
|
||||||
|
amount: 100,
|
||||||
|
relays: ['relay1', 'relay2'],
|
||||||
|
comment: 'comment'
|
||||||
|
})
|
||||||
|
expect(result.kind).toBe(9734)
|
||||||
|
expect(result.created_at).toBeCloseTo(Date.now() / 1000, 0)
|
||||||
|
expect(result.content).toBe('comment')
|
||||||
|
expect(result.tags).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
['p', 'profile'],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
])
|
||||||
|
)
|
||||||
|
expect(result.tags).toContainEqual(['e', 'event'])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('validateZapRequest', () => {
|
||||||
|
test('returns an error message for invalid JSON', () => {
|
||||||
|
expect(nip57.validateZapRequest('invalid JSON')).toBe(
|
||||||
|
'Invalid zap request JSON.'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns an error message if the Zap request is not a valid Nostr event', () => {
|
||||||
|
const zapRequest = {
|
||||||
|
kind: 1234,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', 'profile'],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||||
|
'Zap request is not a valid Nostr event.'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns an error message if the signature on the Zap request is invalid', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
const publicKey = getPublicKey(privateKey)
|
||||||
|
|
||||||
|
const zapRequest = {
|
||||||
|
pubkey: publicKey,
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', publicKey],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||||
|
'Invalid signature on zap request.'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns an error message if the Zap request does not have a "p" tag', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
|
||||||
|
const zapRequest = finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||||
|
"Zap request doesn't have a 'p' tag."
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns an error message if the "p" tag on the Zap request is not valid hex', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
|
||||||
|
const zapRequest = finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', 'invalid hex'],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||||
|
"Zap request 'p' tag is not valid hex."
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns an error message if the "e" tag on the Zap request is not valid hex', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
const publicKey = getPublicKey(privateKey)
|
||||||
|
|
||||||
|
const zapRequest = finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', publicKey],
|
||||||
|
['e', 'invalid hex'],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||||
|
"Zap request 'e' tag is not valid hex."
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns an error message if the Zap request does not have a relays tag', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
const publicKey = getPublicKey(privateKey)
|
||||||
|
|
||||||
|
const zapRequest = finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', publicKey],
|
||||||
|
['amount', '100']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBe(
|
||||||
|
"Zap request doesn't have a 'relays' tag."
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns null for a valid Zap request', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
const publicKey = getPublicKey(privateKey)
|
||||||
|
|
||||||
|
const zapRequest = finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', publicKey],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(nip57.validateZapRequest(JSON.stringify(zapRequest))).toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('makeZapReceipt', () => {
|
||||||
|
test('returns a valid Zap receipt with a preimage', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
const publicKey = getPublicKey(privateKey)
|
||||||
|
|
||||||
|
const zapRequest = JSON.stringify(
|
||||||
|
finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', publicKey],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const preimage = 'preimage'
|
||||||
|
const bolt11 = 'bolt11'
|
||||||
|
const paidAt = new Date()
|
||||||
|
|
||||||
|
const result = nip57.makeZapReceipt({zapRequest, preimage, bolt11, paidAt})
|
||||||
|
|
||||||
|
expect(result.kind).toBe(9735)
|
||||||
|
expect(result.created_at).toBeCloseTo(paidAt.getTime() / 1000, 0)
|
||||||
|
expect(result.content).toBe('')
|
||||||
|
expect(result.tags).toContainEqual(['bolt11', bolt11])
|
||||||
|
expect(result.tags).toContainEqual(['description', zapRequest])
|
||||||
|
expect(result.tags).toContainEqual(['p', publicKey])
|
||||||
|
expect(result.tags).toContainEqual(['preimage', preimage])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('returns a valid Zap receipt without a preimage', () => {
|
||||||
|
const privateKey = generatePrivateKey()
|
||||||
|
const publicKey = getPublicKey(privateKey)
|
||||||
|
|
||||||
|
const zapRequest = JSON.stringify(
|
||||||
|
finishEvent(
|
||||||
|
{
|
||||||
|
kind: 9734,
|
||||||
|
created_at: Date.now() / 1000,
|
||||||
|
content: 'content',
|
||||||
|
tags: [
|
||||||
|
['p', publicKey],
|
||||||
|
['amount', '100'],
|
||||||
|
['relays', 'relay1', 'relay2']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
privateKey
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const bolt11 = 'bolt11'
|
||||||
|
const paidAt = new Date()
|
||||||
|
|
||||||
|
const result = nip57.makeZapReceipt({zapRequest, bolt11, paidAt})
|
||||||
|
|
||||||
|
expect(result.kind).toBe(9735)
|
||||||
|
expect(result.created_at).toBeCloseTo(paidAt.getTime() / 1000, 0)
|
||||||
|
expect(result.content).toBe('')
|
||||||
|
expect(result.tags).toContainEqual(['bolt11', bolt11])
|
||||||
|
expect(result.tags).toContainEqual(['description', zapRequest])
|
||||||
|
expect(result.tags).toContainEqual(['p', publicKey])
|
||||||
|
expect(result.tags).not.toContain('preimage')
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue