@welshman/net 0.0.38 → 0.0.39

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
@@ -2,19 +2,21 @@
2
2
 
3
3
  Utilities having to do with connection management and nostr messages.
4
4
 
5
- - `Connection` - a wrapper for `Socket` with send and receive queues, and a `ConnectionMeta` instance.
6
- - `ConnectionMeta` - tracks stats for a given `Connection`.
7
- - `Context` - an object containing a default `Pool` and global configuration options.
5
+ - `Connection` - the main api for dealing with relay connections
6
+ - `ConnectionAuth` - tracks auth status for a connection
7
+ - `ConnectionSender` - a send queue for connections
8
+ - `ConnectionState` - tracks pending publishes and requests for a connection
9
+ - `ConnectionStats` - tracks timing and error stats for a connection
10
+ - `Context` - provides default values for configuring `ctx.net`
8
11
  - `Executor` - implements common nostr flows on a given `target`
9
- - `Pool` - a thin wrapper around `Map` which stores `Connection`s.
10
- - `Publish` - utilities for publishing events.
11
- - `Socket` - a wrapper around isomorphic-ws that handles json parsing/serialization.
12
- - `Subscribe` - utilities for making requests against nostr relays.
13
- - `Tracker` - tracks which relays a given event was seen on.
12
+ - `Pool` - a thin wrapper around `Map` which stores `Connection`s
13
+ - `Publish` - utilities for publishing events
14
+ - `Socket` - a wrapper around isomorphic-ws that handles json parsing/serialization
15
+ - `Subscribe` - utilities for making requests against nostr relays
16
+ - `Tracker` - tracks which relays a given event was seen on
14
17
 
15
18
  Executor `target`s extend `Emitter`, and have a `send` method, a `cleanup` method, and a `connections` getter. They are intended to be passed to an `Executor` for use.
16
19
 
17
20
  - `targets/Multi` allows you to compose multiple targets together.
18
- - `targets/Plex` takes an array of urls and a `Connection` and sends and receives wrapped nostr messages over that connection.
19
21
  - `targets/Relay` takes a `Connection` and provides listeners for different verbs.
20
22
  - `targets/Relays` takes an array of `Connection`s and provides listeners for different verbs, merging all events into a single stream.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getDefaultNetContext = exports.defaultOptimizeSubscriptions = void 0;
3
+ exports.getDefaultNetContext = exports.isEventValid = exports.eventValidationScores = exports.defaultOptimizeSubscriptions = void 0;
4
4
  const lib_1 = require("@welshman/lib");
5
5
  const util_1 = require("@welshman/util");
6
6
  const Pool_1 = require("./Pool.cjs");
@@ -14,13 +14,30 @@ const defaultOptimizeSubscriptions = (subs) => (0, lib_1.uniq)(subs.flatMap(sub
14
14
  return { relays: [relay], filters };
15
15
  });
16
16
  exports.defaultOptimizeSubscriptions = defaultOptimizeSubscriptions;
17
+ exports.eventValidationScores = new Map();
18
+ const isEventValid = (url, event) => {
19
+ if (url === util_1.LOCAL_RELAY_URL)
20
+ return true;
21
+ const validCount = exports.eventValidationScores.get(url) || 0;
22
+ // The more events we've actually validated from this relay, the more we can trust it.
23
+ if (validCount > (0, lib_1.randomInt)(100, 1000))
24
+ true;
25
+ const isValid = (0, util_1.isSignedEvent)(event) && (0, util_1.hasValidSignature)(event);
26
+ // If the event was valid, increase the relay's score. If not, reset it
27
+ // Never validate less than 10% to make sure we're never totally checking out
28
+ if (!isValid || validCount < 900) {
29
+ exports.eventValidationScores.set(url, isValid ? validCount + 1 : 0);
30
+ }
31
+ return isValid;
32
+ };
33
+ exports.isEventValid = isEventValid;
17
34
  const getDefaultNetContext = (overrides = {}) => ({
18
35
  pool: new Pool_1.Pool(),
19
36
  authMode: ConnectionAuth_1.AuthMode.Implicit,
20
37
  onEvent: lib_1.noop,
21
38
  signEvent: lib_1.noop,
22
39
  isDeleted: (0, lib_1.always)(false),
23
- isValid: (url, event) => (0, util_1.isSignedEvent)(event) && (0, util_1.hasValidSignature)(event),
40
+ isValid: exports.isEventValid,
24
41
  getExecutor: (relays) => new Executor_1.Executor(new Relays_1.Relays(relays.map((relay) => lib_1.ctx.net.pool.get(relay)))),
25
42
  matchFilters: (url, filters, event) => (0, util_1.matchFilters)(filters, event),
26
43
  optimizeSubscriptions: exports.defaultOptimizeSubscriptions,
@@ -1 +1 @@
1
- {"version":3,"file":"Context.cjs","sourceRoot":"","sources":["../../src/Context.ts"],"names":[],"mappings":";;;AAAA,uCAAqD;AACrD,yCAA2F;AAE3F,qCAA2B;AAC3B,6CAAmC;AACnC,yDAAyC;AACzC,gDAAsC;AAe/B,MAAM,4BAA4B,GAAG,CAAC,IAAoB,EAAE,EAAE,CACnE,IAAA,UAAI,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;KAChD,GAAG,CAAC,KAAK,CAAC,EAAE;IACX,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,IAAA,mBAAY,EAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAE3E,OAAO,EAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAC,CAAA;AACnC,CAAC,CAAC,CAAA;AAPO,QAAA,4BAA4B,gCAOnC;AAEC,MAAM,oBAAoB,GAAG,CAAC,YAAiC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI,EAAE,IAAI,WAAI,EAAE;IAChB,QAAQ,EAAE,yBAAQ,CAAC,QAAQ;IAC3B,OAAO,EAAE,UAAI;IACb,SAAS,EAAE,UAAI;IACf,SAAS,EAAE,IAAA,YAAM,EAAC,KAAK,CAAC;IACxB,OAAO,EAAE,CAAC,GAAW,EAAE,KAAmB,EAAE,EAAE,CAAC,IAAA,oBAAa,EAAC,KAAK,CAAC,IAAI,IAAA,wBAAiB,EAAC,KAAK,CAAC;IAC/F,WAAW,EAAE,CAAC,MAAgB,EAAE,EAAE,CAAC,IAAI,mBAAQ,CAAC,IAAI,eAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,SAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnH,YAAY,EAAE,CAAC,GAAW,EAAE,OAAiB,EAAE,KAAmB,EAAE,EAAE,CAAC,IAAA,mBAAY,EAAC,OAAO,EAAE,KAAK,CAAC;IACnG,qBAAqB,EAAE,oCAA4B;IACnD,GAAG,SAAS;CACb,CAAC,CAAA;AAXW,QAAA,oBAAoB,wBAW/B"}
1
+ {"version":3,"file":"Context.cjs","sourceRoot":"","sources":["../../src/Context.ts"],"names":[],"mappings":";;;AAAA,uCAAgE;AAChE,yCAA4G;AAE5G,qCAA2B;AAC3B,6CAAmC;AACnC,yDAAyC;AACzC,gDAAsC;AAe/B,MAAM,4BAA4B,GAAG,CAAC,IAAoB,EAAE,EAAE,CACnE,IAAA,UAAI,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;KAChD,GAAG,CAAC,KAAK,CAAC,EAAE;IACX,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,IAAA,mBAAY,EAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAE3E,OAAO,EAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAC,CAAA;AACnC,CAAC,CAAC,CAAA;AAPO,QAAA,4BAA4B,gCAOnC;AAEO,QAAA,qBAAqB,GAAG,IAAI,GAAG,EAAkB,CAAA;AAEvD,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,KAAmB,EAAE,EAAE;IAC/D,IAAI,GAAG,KAAK,sBAAe;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,UAAU,GAAG,6BAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAEtD,sFAAsF;IACtF,IAAI,UAAU,GAAG,IAAA,eAAS,EAAC,GAAG,EAAE,IAAI,CAAC;QAAE,IAAI,CAAA;IAE3C,MAAM,OAAO,GAAG,IAAA,oBAAa,EAAC,KAAK,CAAC,IAAI,IAAA,wBAAiB,EAAC,KAAK,CAAC,CAAA;IAEhE,uEAAuE;IACvE,6EAA6E;IAC7E,IAAI,CAAC,OAAO,IAAI,UAAU,GAAG,GAAG,EAAE;QAChC,6BAAqB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAC7D;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAjBY,QAAA,YAAY,gBAiBxB;AAEM,MAAM,oBAAoB,GAAG,CAAC,YAAiC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI,EAAE,IAAI,WAAI,EAAE;IAChB,QAAQ,EAAE,yBAAQ,CAAC,QAAQ;IAC3B,OAAO,EAAE,UAAI;IACb,SAAS,EAAE,UAAI;IACf,SAAS,EAAE,IAAA,YAAM,EAAC,KAAK,CAAC;IACxB,OAAO,EAAE,oBAAY;IACrB,WAAW,EAAE,CAAC,MAAgB,EAAE,EAAE,CAAC,IAAI,mBAAQ,CAAC,IAAI,eAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,SAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnH,YAAY,EAAE,CAAC,GAAW,EAAE,OAAiB,EAAE,KAAmB,EAAE,EAAE,CAAC,IAAA,mBAAY,EAAC,OAAO,EAAE,KAAK,CAAC;IACnG,qBAAqB,EAAE,oCAA4B;IACnD,GAAG,SAAS;CACb,CAAC,CAAA;AAXW,QAAA,oBAAoB,wBAW/B"}
@@ -18,6 +18,8 @@ export declare const defaultOptimizeSubscriptions: (subs: Subscription[]) => {
18
18
  relays: string[];
19
19
  filters: Filter[];
20
20
  }[];
21
+ export declare const eventValidationScores: Map<string, number>;
22
+ export declare const isEventValid: (url: string, event: TrustedEvent) => boolean;
21
23
  export declare const getDefaultNetContext: (overrides?: Partial<NetContext>) => {
22
24
  pool: Pool;
23
25
  authMode: AuthMode;
@@ -1,5 +1,5 @@
1
- import { ctx, uniq, noop, always } from '@welshman/lib';
2
- import { matchFilters, unionFilters, isSignedEvent, hasValidSignature } from '@welshman/util';
1
+ import { ctx, randomInt, uniq, noop, always } from '@welshman/lib';
2
+ import { LOCAL_RELAY_URL, matchFilters, unionFilters, isSignedEvent, hasValidSignature } from '@welshman/util';
3
3
  import { Pool } from "./Pool.mjs";
4
4
  import { Executor } from "./Executor.mjs";
5
5
  import { AuthMode } from "./ConnectionAuth.mjs";
@@ -10,13 +10,29 @@ export const defaultOptimizeSubscriptions = (subs) => uniq(subs.flatMap(sub => s
10
10
  const filters = unionFilters(relaySubs.flatMap(sub => sub.request.filters));
11
11
  return { relays: [relay], filters };
12
12
  });
13
+ export const eventValidationScores = new Map();
14
+ export const isEventValid = (url, event) => {
15
+ if (url === LOCAL_RELAY_URL)
16
+ return true;
17
+ const validCount = eventValidationScores.get(url) || 0;
18
+ // The more events we've actually validated from this relay, the more we can trust it.
19
+ if (validCount > randomInt(100, 1000))
20
+ true;
21
+ const isValid = isSignedEvent(event) && hasValidSignature(event);
22
+ // If the event was valid, increase the relay's score. If not, reset it
23
+ // Never validate less than 10% to make sure we're never totally checking out
24
+ if (!isValid || validCount < 900) {
25
+ eventValidationScores.set(url, isValid ? validCount + 1 : 0);
26
+ }
27
+ return isValid;
28
+ };
13
29
  export const getDefaultNetContext = (overrides = {}) => ({
14
30
  pool: new Pool(),
15
31
  authMode: AuthMode.Implicit,
16
32
  onEvent: noop,
17
33
  signEvent: noop,
18
34
  isDeleted: always(false),
19
- isValid: (url, event) => isSignedEvent(event) && hasValidSignature(event),
35
+ isValid: isEventValid,
20
36
  getExecutor: (relays) => new Executor(new Relays(relays.map((relay) => ctx.net.pool.get(relay)))),
21
37
  matchFilters: (url, filters, event) => matchFilters(filters, event),
22
38
  optimizeSubscriptions: defaultOptimizeSubscriptions,
@@ -1 +1 @@
1
- {"version":3,"file":"Context.mjs","sourceRoot":"","sources":["../../src/Context.ts"],"names":[],"mappings":"OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,eAAe;OAC9C,EAAC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAC,MAAM,gBAAgB;OAEpF,EAAC,IAAI,EAAC;OACN,EAAC,QAAQ,EAAC;OACV,EAAC,QAAQ,EAAC;OACV,EAAC,MAAM,EAAC;AAef,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,IAAoB,EAAE,EAAE,CACnE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;KAChD,GAAG,CAAC,KAAK,CAAC,EAAE;IACX,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAE3E,OAAO,EAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAC,CAAA;AACnC,CAAC,CAAC,CAAA;AAEN,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,YAAiC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI,EAAE,IAAI,IAAI,EAAE;IAChB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;IAC3B,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;IACxB,OAAO,EAAE,CAAC,GAAW,EAAE,KAAmB,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC;IAC/F,WAAW,EAAE,CAAC,MAAgB,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnH,YAAY,EAAE,CAAC,GAAW,EAAE,OAAiB,EAAE,KAAmB,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC;IACnG,qBAAqB,EAAE,4BAA4B;IACnD,GAAG,SAAS;CACb,CAAC,CAAA"}
1
+ {"version":3,"file":"Context.mjs","sourceRoot":"","sources":["../../src/Context.ts"],"names":[],"mappings":"OAAO,EAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,eAAe;OACzD,EAAC,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAC,MAAM,gBAAgB;OAErG,EAAC,IAAI,EAAC;OACN,EAAC,QAAQ,EAAC;OACV,EAAC,QAAQ,EAAC;OACV,EAAC,MAAM,EAAC;AAef,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,IAAoB,EAAE,EAAE,CACnE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;KAChD,GAAG,CAAC,KAAK,CAAC,EAAE;IACX,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAE3E,OAAO,EAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAC,CAAA;AACnC,CAAC,CAAC,CAAA;AAEN,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAkB,CAAA;AAE9D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,KAAmB,EAAE,EAAE;IAC/D,IAAI,GAAG,KAAK,eAAe;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAEtD,sFAAsF;IACtF,IAAI,UAAU,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC;QAAE,IAAI,CAAA;IAE3C,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAEhE,uEAAuE;IACvE,6EAA6E;IAC7E,IAAI,CAAC,OAAO,IAAI,UAAU,GAAG,GAAG,EAAE;QAChC,qBAAqB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAC7D;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,YAAiC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI,EAAE,IAAI,IAAI,EAAE;IAChB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;IAC3B,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;IACxB,OAAO,EAAE,YAAY;IACrB,WAAW,EAAE,CAAC,MAAgB,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnH,YAAY,EAAE,CAAC,GAAW,EAAE,OAAiB,EAAE,KAAmB,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC;IACnG,qBAAqB,EAAE,4BAA4B;IACnD,GAAG,SAAS;CACb,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@welshman/net",
3
- "version": "0.0.38",
3
+ "version": "0.0.39",
4
4
  "author": "hodlbod",
5
5
  "license": "MIT",
6
6
  "description": "Utilities for connecting with nostr relays.",
@@ -33,8 +33,8 @@
33
33
  "typescript": "~5.1.6"
34
34
  },
35
35
  "dependencies": {
36
- "@welshman/lib": "~0.0.25",
37
- "@welshman/util": "~0.0.45",
36
+ "@welshman/lib": "~0.0.27",
37
+ "@welshman/util": "~0.0.46",
38
38
  "isomorphic-ws": "^5.0.0",
39
39
  "ws": "^8.16.0"
40
40
  }