mirror of
https://github.com/nostr-connect/connect.git
synced 2025-12-18 05:34:18 +01:00
add request & test
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { Thing } from '../src';
|
||||
|
||||
describe('it', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<Thing />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
||||
});
|
||||
116
test/connect.test.ts
Normal file
116
test/connect.test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { getPublicKey } from "nostr-tools";
|
||||
import { Connect, ConnectMessageType, GetPublicKeyResponse, Session } from "../src/index";
|
||||
|
||||
jest.setTimeout(5000);
|
||||
|
||||
describe('Nostr Connect', () => {
|
||||
it('connect', async () => {
|
||||
let resolvePaired: (arg0: boolean) => void;
|
||||
let resolveGetPublicKey: (arg0: boolean) => void;
|
||||
// web app (this is ephemeral and represents the currention session)
|
||||
const webSK = "5acff99d1ad3e1706360d213fd69203312d9b5e91a2d5f2e06100cc6f686e5b3";
|
||||
const webPK = getPublicKey(webSK);
|
||||
console.log('webPk', webPK);
|
||||
|
||||
|
||||
|
||||
const sessionWeb = new Session({
|
||||
target: webPK,
|
||||
relay: 'wss://nostr.vulpem.com',
|
||||
metadata: {
|
||||
name: 'My Website',
|
||||
description: 'lorem ipsum dolor sit amet',
|
||||
url: 'https://vulpem.com',
|
||||
icons: ['https://vulpem.com/1000x860-p-500.422be1bc.png'],
|
||||
}
|
||||
});
|
||||
sessionWeb.on(ConnectMessageType.PAIRED, (msg: any) => {
|
||||
expect(msg).toBeDefined();
|
||||
resolvePaired(true);
|
||||
});
|
||||
await sessionWeb.listen(webSK);
|
||||
|
||||
// mobile app (this can be a child key)
|
||||
const sessionMobile = Session.fromConnectURI(sessionWeb.connectURI);// 'nostr://connect?target=...&metadata=...'
|
||||
const mobileSK = "ed779ff047f99c95f732b22c9f8f842afb870c740aab591776ebc7b64e83cf6c";
|
||||
const mobilePK = getPublicKey(mobileSK);
|
||||
console.log('mobilePK', mobilePK);
|
||||
await sessionMobile.pair(mobileSK);
|
||||
|
||||
// we define the behavior of the mobile app for each requests
|
||||
sessionMobile.on(ConnectMessageType.GET_PUBLIC_KEY_REQUEST, async () => {
|
||||
const message: GetPublicKeyResponse = {
|
||||
type: ConnectMessageType.GET_PUBLIC_KEY_RESPONSE,
|
||||
value: {
|
||||
pubkey: mobilePK,
|
||||
}
|
||||
};
|
||||
const event = await sessionMobile.eventToBeSentToTarget(
|
||||
message,
|
||||
mobileSK
|
||||
);
|
||||
await sessionMobile.sendEvent(
|
||||
event,
|
||||
mobileSK
|
||||
);
|
||||
resolveGetPublicKey(true);
|
||||
});
|
||||
await sessionMobile.listen(mobileSK);
|
||||
|
||||
// The WebApp send the request and wait for the response
|
||||
// The WebApp fetch the public key sending request via session
|
||||
const connect = new Connect({
|
||||
session: sessionWeb,
|
||||
targetPrivateKey: webSK,
|
||||
});
|
||||
const response = await connect.sendMessage({
|
||||
type: ConnectMessageType.GET_PUBLIC_KEY_REQUEST,
|
||||
});
|
||||
expect(response).toBeDefined();
|
||||
|
||||
return expect(
|
||||
Promise.all([
|
||||
new Promise(resolve => {
|
||||
resolvePaired = resolve
|
||||
}),
|
||||
new Promise(resolve => {
|
||||
resolveGetPublicKey = resolve
|
||||
})
|
||||
])
|
||||
).resolves.toEqual([true, true])
|
||||
|
||||
/*
|
||||
expect(handler).toBeCalledTimes(1);
|
||||
expect(handler).toBeCalledWith({
|
||||
type: ConnectMessageType.PAIRED,
|
||||
value: {
|
||||
pubkey: mobilePK,
|
||||
}
|
||||
});
|
||||
|
||||
const pubkey = await connect.getPublicKey();
|
||||
expect(pubkey).toBe(mobilePK);
|
||||
const signedEvt = await connect.signEvent({});
|
||||
const relays = await connect.getRelays();
|
||||
|
||||
const plainText = "hello 🌍";
|
||||
const cipherText = await connect.nip04.encrypt(childPK, plainText);
|
||||
const plainText2 = await connect.nip04.decrypt(childPK, cipherText);
|
||||
expect(plainText === plainText2).toBeTruthy();
|
||||
|
||||
await connect.request({
|
||||
method: 'signSchnorr',
|
||||
params: [
|
||||
'0x000000',
|
||||
'0x000000'
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
sessionWeb.on(ConnectMessageType.UNPAIRED, () => {
|
||||
console.log('unpaired');
|
||||
});
|
||||
|
||||
*/
|
||||
});
|
||||
});
|
||||
67
test/request.test.ts
Normal file
67
test/request.test.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { nip04, Event } from 'nostr-tools';
|
||||
import { NostrRPC, NostrRPCServer, prepareEvent, prepareResponse } from '../src/request';
|
||||
|
||||
class Example extends NostrRPCServer {
|
||||
async ping(): Promise<string> {
|
||||
return 'pong';
|
||||
}
|
||||
}
|
||||
|
||||
jest.setTimeout(10000);
|
||||
|
||||
describe('Nostr RPC', () => {
|
||||
it('starts a server', async () => {
|
||||
const server = new Example({
|
||||
secretKey: "ed779ff047f99c95f732b22c9f8f842afb870c740aab591776ebc7b64e83cf6c",
|
||||
});
|
||||
const sub = await server.listen();
|
||||
sub.on('event', async (event: Event) => {
|
||||
let plaintext;
|
||||
let payload;
|
||||
try {
|
||||
plaintext = await nip04.decrypt(server.self.secret, event.pubkey, event.content);
|
||||
payload = JSON.parse(plaintext);
|
||||
} catch(ignore) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore all the events that are not NostrRPCRequest events
|
||||
if (!plaintext) return;
|
||||
if (!payload) return;
|
||||
if (!Object.keys(payload).includes('id') || !Object.keys(payload).includes('method') || !Object.keys(payload).includes('params')) return;
|
||||
|
||||
// handle request
|
||||
const response = {
|
||||
id: payload.id,
|
||||
result: "pong",
|
||||
error: null,
|
||||
}
|
||||
const body = prepareResponse(response.id, response.result, response.error);
|
||||
const responseEvent = await prepareEvent(server.self.secret, event.pubkey, body);
|
||||
|
||||
console.log('response to be sent', responseEvent)
|
||||
// send response via relay
|
||||
const pub = server.relay.publish(responseEvent);
|
||||
pub.on('failed', console.error);
|
||||
});
|
||||
|
||||
sub.on('eose', () => {
|
||||
sub.unsub();
|
||||
});
|
||||
|
||||
const client = new NostrRPC({
|
||||
secretKey: "5acff99d1ad3e1706360d213fd69203312d9b5e91a2d5f2e06100cc6f686e5b3",
|
||||
target: server.self.pubkey,
|
||||
});
|
||||
console.log(`from: ` + client.self.pubkey, `to: ` + server.self.pubkey);
|
||||
|
||||
await sleep(2000);
|
||||
|
||||
const result = await client.call({ method: 'ping' });
|
||||
console.log(result);
|
||||
})
|
||||
})
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
18
test/server.js
Normal file
18
test/server.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const {NostrRPCServer} = require('../src/request.js');
|
||||
|
||||
class Example extends NostrRPCServer {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
}
|
||||
async ping() {
|
||||
return 'pong';
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const server = new Example({
|
||||
secretKey: "ed779ff047f99c95f732b22c9f8f842afb870c740aab591776ebc7b64e83cf6c",
|
||||
});
|
||||
await server.listen();
|
||||
console.log('Server listening on port 3000');
|
||||
}
|
||||
10
test/setupTests.ts
Normal file
10
test/setupTests.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
//setupTests.tsx
|
||||
import crypto from "crypto";
|
||||
import { TextEncoder, TextDecoder } from "util";
|
||||
|
||||
global.TextEncoder = TextEncoder;
|
||||
(global as any).TextDecoder = TextDecoder;
|
||||
|
||||
Object.defineProperty(global.self, 'crypto', {
|
||||
value: crypto.webcrypto
|
||||
});
|
||||
Reference in New Issue
Block a user