@nekosuneprojects/vector-sdk 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,22 +56,23 @@ client.on('error', (error) => {
56
56
  console.error('Bot error:', error);
57
57
  });
58
58
 
59
- client.on('message', async (channel, tags, message, self) => {
59
+ client.on('message', async (senderPubkey, tags, message, self) => {
60
60
  if (self) return;
61
61
 
62
- console.log(`${channel}: ${message}`);
62
+ const senderName = tags.displayName || senderPubkey;
63
+ console.log(`${senderName}: ${message}`);
63
64
 
64
65
  if (message.startsWith('!ping')) {
65
- await client.sendMessage(channel, 'pong');
66
+ await client.sendMessage(senderPubkey, 'pong');
66
67
  return;
67
68
  }
68
69
 
69
70
  if (message.startsWith('!upload')) {
70
71
  if (!process.env.UPLOAD_FILE_PATH) {
71
- await client.sendMessage(channel, 'Set UPLOAD_FILE_PATH to send a file.');
72
+ await client.sendMessage(senderPubkey, 'Set UPLOAD_FILE_PATH to send a file.');
72
73
  return;
73
74
  }
74
- await client.sendFile(channel, process.env.UPLOAD_FILE_PATH);
75
+ await client.sendFile(senderPubkey, process.env.UPLOAD_FILE_PATH);
75
76
  }
76
77
  });
77
78
 
package/dist/bot.js CHANGED
@@ -126,17 +126,19 @@ export class Channel {
126
126
  }
127
127
  async sendReaction(referenceId, emoji) {
128
128
  try {
129
- const event = finalizeEvent({
129
+ const rumor = {
130
130
  kind: kinds.Reaction,
131
131
  created_at: Math.floor(Date.now() / 1000),
132
132
  tags: [
133
133
  ['e', referenceId],
134
134
  ['p', this.recipient],
135
+ ['k', kinds.PrivateDirectMessage.toString()],
135
136
  ['ms', (Date.now() % 1000).toString()],
136
137
  ],
137
138
  content: emoji,
138
- }, this.baseBot.privateKeyBytes);
139
- await this.baseBot.client.publishEvent(event);
139
+ };
140
+ const wrapped = nip59.wrapEvent(rumor, this.baseBot.privateKeyBytes, this.recipient);
141
+ await this.baseBot.client.publishEvent(wrapped);
140
142
  return true;
141
143
  }
142
144
  catch (error) {
@@ -147,17 +149,19 @@ export class Channel {
147
149
  async sendTypingIndicator() {
148
150
  try {
149
151
  const now = Math.floor(Date.now() / 1000);
150
- const event = finalizeEvent({
152
+ const rumor = {
151
153
  kind: kinds.Application,
152
154
  created_at: now,
153
155
  tags: [
154
156
  ['p', this.recipient],
157
+ ['d', 'vector'],
155
158
  ['ms', (Date.now() % 1000).toString()],
156
- ['expiration', (now + 3600).toString()],
159
+ ['expiration', (now + 30).toString()],
157
160
  ],
158
161
  content: 'typing',
159
- }, this.baseBot.privateKeyBytes);
160
- await this.baseBot.client.publishEvent(event);
162
+ };
163
+ const wrapped = nip59.wrapEvent(rumor, this.baseBot.privateKeyBytes, this.recipient);
164
+ await this.baseBot.client.publishEvent(wrapped);
161
165
  return true;
162
166
  }
163
167
  catch (error) {
package/dist/client.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { SimplePool } from 'nostr-tools';
2
2
  import { finalizeEvent, getPublicKey } from 'nostr-tools/pure';
3
+ import WebSocket from 'ws';
3
4
  import { normalizePrivateKey } from './keys.js';
4
5
  const DEFAULT_RELAYS = [
5
6
  'wss://jskitty.cat/nostr',
@@ -7,9 +8,15 @@ const DEFAULT_RELAYS = [
7
8
  'wss://auth.nostr1.com',
8
9
  'wss://nostr.computingcache.com',
9
10
  ];
11
+ function ensureWebSocket() {
12
+ if (typeof globalThis.WebSocket === 'undefined') {
13
+ globalThis.WebSocket = WebSocket;
14
+ }
15
+ }
10
16
  export class VectorClient {
11
17
  constructor(keys, config) {
12
18
  this.pool = new SimplePool();
19
+ ensureWebSocket();
13
20
  const normalized = normalizePrivateKey(keys);
14
21
  this.privateKey = normalized.hex;
15
22
  this.privateKeyBytes = normalized.bytes;
package/dist/demo.js CHANGED
@@ -170,7 +170,7 @@ export class VectorBotClient extends EventEmitter {
170
170
  }
171
171
  async emitMessage(bot, pubkey, kind, rawEvent, content, wrapped) {
172
172
  const profile = await this.getProfile(bot, pubkey);
173
- this.emit('message', profile?.displayName || profile?.name || pubkey, {
173
+ this.emit('message', pubkey, {
174
174
  pubkey,
175
175
  kind,
176
176
  rawEvent,
package/dist/keys.js CHANGED
@@ -2,32 +2,43 @@ import { nip19 } from 'nostr-tools';
2
2
  import { bytesToHex, hexToBytes } from 'nostr-tools/utils';
3
3
  export class KeyFormatError extends Error {
4
4
  }
5
+ function stripNostrUriPrefix(value) {
6
+ const trimmed = value.trim();
7
+ if (trimmed.toLowerCase().startsWith('nostr:')) {
8
+ return trimmed.slice('nostr:'.length).trim();
9
+ }
10
+ return trimmed;
11
+ }
5
12
  export function normalizePrivateKey(privateKey) {
6
- const trimmed = privateKey.trim();
7
- if (trimmed.startsWith('nsec1')) {
8
- const decoded = nip19.decode(trimmed);
13
+ const trimmed = stripNostrUriPrefix(privateKey);
14
+ const lowered = trimmed.toLowerCase();
15
+ if (lowered.startsWith('nsec1')) {
16
+ const decoded = nip19.decode(lowered);
9
17
  if (decoded.type !== 'nsec') {
10
18
  throw new KeyFormatError('Invalid nsec private key');
11
19
  }
12
20
  return { hex: bytesToHex(decoded.data), bytes: decoded.data };
13
21
  }
14
- if (!/^[0-9a-fA-F]{64}$/.test(trimmed)) {
22
+ const hexCandidate = lowered.startsWith('0x') ? lowered.slice(2) : lowered;
23
+ if (!/^[0-9a-f]{64}$/.test(hexCandidate)) {
15
24
  throw new KeyFormatError('Private key must be a 32-byte hex string or nsec');
16
25
  }
17
- const hex = trimmed.toLowerCase();
26
+ const hex = hexCandidate;
18
27
  return { hex, bytes: hexToBytes(hex) };
19
28
  }
20
29
  export function normalizePublicKey(publicKey) {
21
- const trimmed = publicKey.trim();
22
- if (trimmed.startsWith('npub1')) {
23
- const decoded = nip19.decode(trimmed);
30
+ const trimmed = stripNostrUriPrefix(publicKey);
31
+ const lowered = trimmed.toLowerCase();
32
+ if (lowered.startsWith('npub1')) {
33
+ const decoded = nip19.decode(lowered);
24
34
  if (decoded.type !== 'npub') {
25
35
  throw new KeyFormatError('Invalid npub public key');
26
36
  }
27
37
  return decoded.data;
28
38
  }
29
- if (!/^[0-9a-fA-F]{64}$/.test(trimmed)) {
39
+ const hexCandidate = lowered.startsWith('0x') ? lowered.slice(2) : lowered;
40
+ if (!/^[0-9a-f]{64}$/.test(hexCandidate)) {
30
41
  throw new KeyFormatError('Public key must be a 32-byte hex string or npub');
31
42
  }
32
- return trimmed.toLowerCase();
43
+ return hexCandidate;
33
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nekosuneprojects/vector-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Node.js reimplementation of the Vector Bot SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,11 +35,13 @@
35
35
  "form-data": "^4.0.5",
36
36
  "mime-types": "^3.0.2",
37
37
  "node-fetch": "^3.3.1",
38
- "nostr-tools": "^2.19.4"
38
+ "nostr-tools": "^2.19.4",
39
+ "ws": "^8.18.3"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@types/mime-types": "^2.1.4",
42
43
  "@types/node": "^20.7.0",
44
+ "@types/ws": "^8.18.1",
43
45
  "typescript": "^5.5.2"
44
46
  }
45
47
  }