@openclaw/nostr 2026.10.10 → 2026.11.5-beta.1
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/dist/.setup/{channel-C2iK5Fjg.mjs → channel-DtlupG0V.mjs} +183 -354
- package/dist/.source-module-urls/434fb4e7afdaac23908221824ec325d8f61be72ba97af41567f2cb4ebe3ad38c.json +1 -1
- package/dist/api.js +19 -30
- package/dist/channel-plugin-api.js +1 -1
- package/dist/control-ui/049680efcde098838c4459d157e51b99515dceb24211e236f157fca0abbdb516/chunk-1.js +1 -0
- package/dist/control-ui/049680efcde098838c4459d157e51b99515dceb24211e236f157fca0abbdb516/index.js +1 -0
- package/dist/openclaw.plugin.json +40 -0
- package/node_modules/@solidjs/web/README.md +25 -0
- package/node_modules/@solidjs/web/dist/server.dev.js +5070 -0
- package/node_modules/@solidjs/web/dist/server.js +4722 -0
- package/node_modules/@solidjs/web/dist/server.observe.js +4877 -0
- package/node_modules/@solidjs/web/dist/web.dev.js +2516 -0
- package/node_modules/@solidjs/web/dist/web.js +2204 -0
- package/node_modules/@solidjs/web/dist/web.observe.js +2255 -0
- package/node_modules/@solidjs/web/frames/dist/assets.js +92 -0
- package/node_modules/@solidjs/web/frames/dist/client.dev.js +2108 -0
- package/node_modules/@solidjs/web/frames/dist/client.js +1927 -0
- package/node_modules/@solidjs/web/frames/dist/client.observe.js +2041 -0
- package/node_modules/@solidjs/web/frames/dist/regions.js +171 -0
- package/node_modules/@solidjs/web/frames/dist/server.dev.js +2549 -0
- package/node_modules/@solidjs/web/frames/dist/server.js +2547 -0
- package/node_modules/@solidjs/web/frames/dist/server.observe.js +2548 -0
- package/node_modules/@solidjs/web/frames/dist/trace.js +45 -0
- package/node_modules/@solidjs/web/frames/dist/wire.js +594 -0
- package/node_modules/@solidjs/web/frames/package.json +7 -0
- package/node_modules/@solidjs/web/node_modules/seroval/LICENSE +7 -0
- package/node_modules/@solidjs/web/node_modules/seroval/README.md +117 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/dev/index.cjs +3716 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/dev/index.d.cts +820 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/dev/index.d.ts +820 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/dev/index.js +3669 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/index.cjs +3700 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/index.d.cts +820 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/index.d.ts +820 -0
- package/node_modules/@solidjs/web/node_modules/seroval/dist/index.js +3653 -0
- package/node_modules/@solidjs/web/node_modules/seroval/package.json +77 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/LICENSE +7 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/README.md +50 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/index-BG4YWylA.d.cts +101 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/index.cjs +8 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/index.d.cts +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/index.d.ts +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/index.js +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/web-B1lHT9kZ.cjs +812 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/web.cjs +16 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/web.d.cts +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/web.d.ts +97 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/dev/web.js +693 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/index-BG4YWylA.d.cts +101 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/index.cjs +8 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/index.d.cts +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/index.d.ts +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/index.js +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/web-B1lHT9kZ.cjs +812 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/web.cjs +16 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/web.d.cts +2 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/web.d.ts +97 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/dist/web.js +693 -0
- package/node_modules/@solidjs/web/node_modules/seroval-plugins/package.json +81 -0
- package/node_modules/@solidjs/web/package.json +396 -0
- package/node_modules/@solidjs/web/performance-tracks/dist/performance-tracks.dev.js +679 -0
- package/node_modules/@solidjs/web/performance-tracks/dist/performance-tracks.js +6 -0
- package/node_modules/@solidjs/web/performance-tracks/dist/performance-tracks.observe.js +667 -0
- package/node_modules/@solidjs/web/performance-tracks/package.json +7 -0
- package/node_modules/@solidjs/web/performance-tracks/types/index.d.ts +69 -0
- package/node_modules/@solidjs/web/serialization/decode/package.json +7 -0
- package/node_modules/@solidjs/web/serialization/dist/decode.js +229 -0
- package/node_modules/@solidjs/web/serialization/dist/serialization.js +398 -0
- package/node_modules/@solidjs/web/serialization/package.json +7 -0
- package/node_modules/@solidjs/web/serialization/types/index.d.ts +109 -0
- package/node_modules/@solidjs/web/serialization/types/serializer-decode.d.ts +241 -0
- package/node_modules/@solidjs/web/server-functions/dist/client.dev.js +1462 -0
- package/node_modules/@solidjs/web/server-functions/dist/client.js +1305 -0
- package/node_modules/@solidjs/web/server-functions/dist/client.observe.js +1441 -0
- package/node_modules/@solidjs/web/server-functions/dist/rich-args.js +92 -0
- package/node_modules/@solidjs/web/server-functions/dist/server.dev.js +3619 -0
- package/node_modules/@solidjs/web/server-functions/dist/server.js +3526 -0
- package/node_modules/@solidjs/web/server-functions/dist/server.observe.js +3589 -0
- package/node_modules/@solidjs/web/server-functions/package.json +7 -0
- package/node_modules/@solidjs/web/server-functions/rich-args/package.json +7 -0
- package/node_modules/@solidjs/web/skills/server-components/SKILL.md +117 -0
- package/node_modules/@solidjs/web/storage/dist/storage.js +10 -0
- package/node_modules/@solidjs/web/storage/package.json +7 -0
- package/node_modules/@solidjs/web/storage/types/index.d.ts +28 -0
- package/node_modules/@solidjs/web/types/client.d.ts +391 -0
- package/node_modules/@solidjs/web/types/constants.d.ts +22 -0
- package/node_modules/@solidjs/web/types/cookies.d.ts +41 -0
- package/node_modules/@solidjs/web/types/diagnostics.d.ts +80 -0
- package/node_modules/@solidjs/web/types/frames/assets-tier.d.ts +78 -0
- package/node_modules/@solidjs/web/types/frames/client.d.ts +75 -0
- package/node_modules/@solidjs/web/types/frames/frame-client.d.ts +519 -0
- package/node_modules/@solidjs/web/types/frames/frame-container-plugin.d.ts +64 -0
- package/node_modules/@solidjs/web/types/frames/frame-morph.d.ts +29 -0
- package/node_modules/@solidjs/web/types/frames/frame-sink.d.ts +174 -0
- package/node_modules/@solidjs/web/types/frames/frame-transport.d.ts +301 -0
- package/node_modules/@solidjs/web/types/frames/regions-tier.d.ts +60 -0
- package/node_modules/@solidjs/web/types/frames/server.d.ts +52 -0
- package/node_modules/@solidjs/web/types/frames/trace-tier.d.ts +2 -0
- package/node_modules/@solidjs/web/types/frames/tree-rewrite.d.ts +39 -0
- package/node_modules/@solidjs/web/types/frames/wire-tier.d.ts +169 -0
- package/node_modules/@solidjs/web/types/head.d.ts +20 -0
- package/node_modules/@solidjs/web/types/index.d.ts +261 -0
- package/node_modules/@solidjs/web/types/index.server.d.ts +159 -0
- package/node_modules/@solidjs/web/types/jsx-properties.d.ts +93 -0
- package/node_modules/@solidjs/web/types/jsx.d.ts +4164 -0
- package/node_modules/@solidjs/web/types/observe.d.ts +535 -0
- package/node_modules/@solidjs/web/types/reconcile.d.ts +1 -0
- package/node_modules/@solidjs/web/types/render.d.ts +11 -0
- package/node_modules/@solidjs/web/types/request-error-hook.d.ts +5 -0
- package/node_modules/@solidjs/web/types/response.d.ts +122 -0
- package/node_modules/@solidjs/web/types/server-functions/argument-codec.d.ts +30 -0
- package/node_modules/@solidjs/web/types/server-functions/client.d.ts +277 -0
- package/node_modules/@solidjs/web/types/server-functions/flash.d.ts +36 -0
- package/node_modules/@solidjs/web/types/server-functions/registry.d.ts +105 -0
- package/node_modules/@solidjs/web/types/server-functions/rich-args.d.ts +1 -0
- package/node_modules/@solidjs/web/types/server-functions/server.d.ts +689 -0
- package/node_modules/@solidjs/web/types/server-functions/shared.d.ts +496 -0
- package/node_modules/@solidjs/web/types/server-functions/uploads.d.ts +50 -0
- package/node_modules/@solidjs/web/types/server-mock.d.ts +393 -0
- package/node_modules/@solidjs/web/types/server-observe.d.ts +86 -0
- package/node_modules/@solidjs/web/types/server.d.ts +693 -0
- package/node_modules/@solidjs/web/types/trace.d.ts +127 -0
- package/node_modules/solid-js/CHEATSHEET.md +750 -0
- package/node_modules/solid-js/README.md +77 -0
- package/node_modules/solid-js/diagnostics.json +605 -0
- package/node_modules/solid-js/dist/attribution.js +1 -0
- package/node_modules/solid-js/dist/container-trace.js +267 -0
- package/node_modules/solid-js/dist/internal.js +29 -0
- package/node_modules/solid-js/dist/refresh.dev.js +286 -0
- package/node_modules/solid-js/dist/refresh.js +35 -0
- package/node_modules/solid-js/dist/server.dev.js +3672 -0
- package/node_modules/solid-js/dist/server.js +3314 -0
- package/node_modules/solid-js/dist/server.observe.js +3500 -0
- package/node_modules/solid-js/dist/solid.dev.js +1740 -0
- package/node_modules/solid-js/dist/solid.js +1644 -0
- package/node_modules/solid-js/dist/solid.observe.js +1690 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/LICENSE +21 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/README.md +260 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/dev-shared.js +6136 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/dev.attribution.js +3481 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/dev.js +10245 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/affects-marks.js +86 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/affects.js +102 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/attribution.js +7 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/boundaries.js +622 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/action.js +174 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/async.js +792 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/attribution-costs.js +66 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/attribution-feedback.js +280 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/attribution-hooks.js +83 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/attribution-queries.js +43 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/attribution.js +3077 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/constants.js +241 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/context.js +63 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/core.js +1599 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/dev.js +394 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/effect.js +188 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/error-hooks.js +71 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/error.js +82 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/external.js +97 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/graph.js +162 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/heap.js +124 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/identities.js +62 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/invariants.js +12 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/lanes.js +752 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/owner.js +370 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/scheduler.js +1099 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/truth.js +45 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/core/verdict.js +408 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/deferred.js +187 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/flatten.js +79 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/from.js +248 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/index.js +69 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/map.js +589 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/reveal.js +212 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/signals.js +675 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/affects.js +142 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/edges.js +39 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/hooks.js +13 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/index.js +47 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/optimistic.js +617 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/projection.js +321 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/reconcile.js +275 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/store.js +2081 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/storePath.js +103 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/target.js +46 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/types.js +73 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/observe/store/utils.js +1058 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/affects-marks.js +86 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/affects.js +102 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/attribution.js +45 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/boundaries.js +606 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/action.js +164 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/async.js +763 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/attribution-hooks.js +3 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/constants.js +233 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/context.js +63 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/core.js +1546 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/dev.js +20 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/effect.js +173 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/error-hooks.js +71 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/error.js +82 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/external.js +97 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/graph.js +162 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/heap.js +124 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/identities.js +62 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/invariants.js +12 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/lanes.js +714 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/owner.js +365 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/scheduler.js +1054 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/truth.js +45 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/core/verdict.js +403 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/deferred.js +185 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/flatten.js +77 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/from.js +248 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/index.js +67 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/map.js +585 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/reveal.js +212 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/signals.js +669 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/affects.js +142 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/edges.js +39 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/hooks.js +13 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/index.js +45 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/optimistic.js +611 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/projection.js +307 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/reconcile.js +275 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/store.js +1974 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/storePath.js +103 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/target.js +43 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/types.js +73 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/prod/store/utils.js +1058 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/affects-marks.d.ts +14 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/affects.d.ts +28 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/attribution.d.ts +19 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/attribution.prod.d.ts +22 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/boundaries.d.ts +138 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/carved.d.ts +1 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/action.d.ts +70 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/async.d.ts +48 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/attribution-costs.d.ts +35 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/attribution-feedback.d.ts +133 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/attribution-hooks.d.ts +351 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/attribution-queries.d.ts +24 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/attribution.d.ts +916 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/constants.d.ts +226 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/context.d.ts +36 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/core.d.ts +365 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/dev.d.ts +568 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/effect.d.ts +30 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/error-hooks.d.ts +71 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/error.d.ts +64 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/external.d.ts +15 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/graph.d.ts +45 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/heap.d.ts +22 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/identities.d.ts +17 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/index.d.ts +17 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/invariants.d.ts +34 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/lanes.d.ts +64 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/owner.d.ts +142 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/scheduler.d.ts +397 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/truth.d.ts +16 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/types.d.ts +212 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/core/verdict.d.ts +37 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/deferred.d.ts +28 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/flatten.d.ts +8 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/from.d.ts +47 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/index.d.ts +32 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/map.d.ts +71 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/reveal.d.ts +19 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/signals.d.ts +738 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/affects.d.ts +12 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/edges.d.ts +9 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/hooks.d.ts +48 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/index.d.ts +46 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/optimistic.d.ts +24 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/projection.d.ts +19 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/reconcile.d.ts +3 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/store.d.ts +134 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/storePath.d.ts +58 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/target.d.ts +159 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/types.d.ts +98 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/dist/types/store/utils.d.ts +262 -0
- package/node_modules/solid-js/node_modules/@solidjs/signals/package.json +74 -0
- package/node_modules/solid-js/node_modules/csstype/LICENSE +19 -0
- package/node_modules/solid-js/node_modules/csstype/README.md +291 -0
- package/node_modules/solid-js/node_modules/csstype/index.d.ts +22569 -0
- package/node_modules/solid-js/node_modules/csstype/index.js.flow +6863 -0
- package/node_modules/solid-js/node_modules/csstype/package.json +70 -0
- package/node_modules/solid-js/node_modules/seroval/LICENSE +7 -0
- package/node_modules/solid-js/node_modules/seroval/README.md +117 -0
- package/node_modules/solid-js/node_modules/seroval/dist/dev/index.cjs +3716 -0
- package/node_modules/solid-js/node_modules/seroval/dist/dev/index.d.cts +820 -0
- package/node_modules/solid-js/node_modules/seroval/dist/dev/index.d.ts +820 -0
- package/node_modules/solid-js/node_modules/seroval/dist/dev/index.js +3669 -0
- package/node_modules/solid-js/node_modules/seroval/dist/index.cjs +3700 -0
- package/node_modules/solid-js/node_modules/seroval/dist/index.d.cts +820 -0
- package/node_modules/solid-js/node_modules/seroval/dist/index.d.ts +820 -0
- package/node_modules/solid-js/node_modules/seroval/dist/index.js +3653 -0
- package/node_modules/solid-js/node_modules/seroval/package.json +77 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/LICENSE +7 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/README.md +50 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/index-BG4YWylA.d.cts +101 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/index.cjs +8 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/index.d.cts +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/index.d.ts +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/index.js +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/web-B1lHT9kZ.cjs +812 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/web.cjs +16 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/web.d.cts +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/web.d.ts +97 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/dev/web.js +693 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/index-BG4YWylA.d.cts +101 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/index.cjs +8 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/index.d.cts +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/index.d.ts +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/index.js +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/web-B1lHT9kZ.cjs +812 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/web.cjs +16 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/web.d.cts +2 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/web.d.ts +97 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/dist/web.js +693 -0
- package/node_modules/solid-js/node_modules/seroval-plugins/package.json +81 -0
- package/node_modules/solid-js/package.json +142 -0
- package/node_modules/solid-js/skills/reactivity-diagnostics/SKILL.md +1023 -0
- package/node_modules/solid-js/skills/solid-2.0/SKILL.md +114 -0
- package/node_modules/solid-js/skills/solid-2.0-cheatsheet/SKILL.md +757 -0
- package/node_modules/solid-js/types/attribution.d.ts +11 -0
- package/node_modules/solid-js/types/client/component.d.ts +176 -0
- package/node_modules/solid-js/types/client/container-trace.d.ts +73 -0
- package/node_modules/solid-js/types/client/core.d.ts +186 -0
- package/node_modules/solid-js/types/client/dynamic.d.ts +55 -0
- package/node_modules/solid-js/types/client/flow.d.ts +323 -0
- package/node_modules/solid-js/types/client/hydration.d.ts +619 -0
- package/node_modules/solid-js/types/client/store-hydration.d.ts +1 -0
- package/node_modules/solid-js/types/console-footer.d.ts +2 -0
- package/node_modules/solid-js/types/from.d.ts +24 -0
- package/node_modules/solid-js/types/index.d.ts +35 -0
- package/node_modules/solid-js/types/internal.d.ts +190 -0
- package/node_modules/solid-js/types/recovery.d.ts +28 -0
- package/node_modules/solid-js/types/refresh/index.d.ts +76 -0
- package/node_modules/solid-js/types/server/component.d.ts +113 -0
- package/node_modules/solid-js/types/server/core.d.ts +48 -0
- package/node_modules/solid-js/types/server/diagnostics.d.ts +45 -0
- package/node_modules/solid-js/types/server/dynamic.d.ts +29 -0
- package/node_modules/solid-js/types/server/edges.d.ts +1 -0
- package/node_modules/solid-js/types/server/flow.d.ts +168 -0
- package/node_modules/solid-js/types/server/hydration.d.ts +52 -0
- package/node_modules/solid-js/types/server/index.d.ts +17 -0
- package/node_modules/solid-js/types/server/observe.d.ts +94 -0
- package/node_modules/solid-js/types/server/shared.d.ts +137 -0
- package/node_modules/solid-js/types/server/signals.d.ts +345 -0
- package/node_modules/solid-js/types/types.d.ts +15 -0
- package/node_modules/zod/package.json +1 -1
- package/node_modules/zod/src/v4/classic/tests/array.test.ts +27 -0
- package/node_modules/zod/src/v4/classic/tests/map.test.ts +7 -0
- package/node_modules/zod/src/v4/classic/tests/set.test.ts +6 -0
- package/node_modules/zod/src/v4/core/compile.ts +9 -0
- package/node_modules/zod/src/v4/core/schemas.ts +35 -1
- package/node_modules/zod/src/v4/core/util.ts +13 -0
- package/node_modules/zod/src/v4/core/versions.ts +1 -1
- package/node_modules/zod/v4/core/compile.cjs +8 -0
- package/node_modules/zod/v4/core/compile.js +8 -0
- package/node_modules/zod/v4/core/schemas.cjs +30 -0
- package/node_modules/zod/v4/core/schemas.d.cts +3 -1
- package/node_modules/zod/v4/core/schemas.d.ts +3 -1
- package/node_modules/zod/v4/core/schemas.js +30 -0
- package/node_modules/zod/v4/core/util.cjs +15 -0
- package/node_modules/zod/v4/core/util.d.cts +2 -0
- package/node_modules/zod/v4/core/util.d.ts +2 -0
- package/node_modules/zod/v4/core/util.js +14 -0
- package/node_modules/zod/v4/core/versions.cjs +1 -1
- package/node_modules/zod/v4/core/versions.js +1 -1
- package/openclaw.plugin.json +11 -0
- package/package.json +17 -5
|
@@ -4,8 +4,9 @@ import { n as NostrProfileSchema, t as nostrSetupPlugin } from "./channel.setup-
|
|
|
4
4
|
import { createScopedDmSecurityResolver, createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
5
5
|
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
6
6
|
import { missingTargetError } from "openclaw/plugin-sdk/channel-feedback";
|
|
7
|
-
import {
|
|
7
|
+
import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageAdapterFromOutbound, runPassiveAccountLifecycle } from "openclaw/plugin-sdk/channel-outbound";
|
|
8
8
|
import { DEFAULT_ACCOUNT_ID, formatPairingApproveHint } from "openclaw/plugin-sdk/channel-plugin-common";
|
|
9
|
+
import { buildChannelOutboundSessionRoute, stripChannelTargetPrefix } from "openclaw/plugin-sdk/core";
|
|
9
10
|
import { buildPassiveChannelStatusSummary, buildTrafficStatusSummary } from "openclaw/plugin-sdk/extension-shared";
|
|
10
11
|
import { collectStatusIssuesFromLastError, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
11
12
|
import { isRecord, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -19,23 +20,11 @@ import { decrypt, encrypt } from "nostr-tools/nip04";
|
|
|
19
20
|
import { createDirectDmPreCryptoGuardPolicy } from "openclaw/plugin-sdk/direct-dm-guard-policy";
|
|
20
21
|
import { captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
|
|
21
22
|
import { createFixedWindowRateLimiter } from "openclaw/plugin-sdk/webhook-ingress";
|
|
22
|
-
import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
|
|
23
|
+
import { isStateDatabaseAdmissionClosedError, retryAsync } from "openclaw/plugin-sdk/retry-runtime";
|
|
23
24
|
import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
24
25
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
25
26
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
26
27
|
import { withTimeout } from "openclaw/plugin-sdk/time-runtime";
|
|
27
|
-
import { buildChannelOutboundSessionRoute, stripChannelTargetPrefix } from "openclaw/plugin-sdk/core";
|
|
28
|
-
// extensions/nostr/src/metrics.ts
|
|
29
|
-
function createMetrics(onMetric) {
|
|
30
|
-
return { emit(name, value = 1, labels) {
|
|
31
|
-
onMetric?.({
|
|
32
|
-
name,
|
|
33
|
-
value,
|
|
34
|
-
timestamp: Date.now(),
|
|
35
|
-
labels
|
|
36
|
-
});
|
|
37
|
-
} };
|
|
38
|
-
}
|
|
39
28
|
// extensions/nostr/src/nostr-cursor.ts
|
|
40
29
|
const CURSOR_WRITE_RETRY_MS = [
|
|
41
30
|
0,
|
|
@@ -45,7 +34,6 @@ const CURSOR_WRITE_RETRY_MS = [
|
|
|
45
34
|
const CURSOR_RECOVERY_RETRY_MS = 1e3;
|
|
46
35
|
/** Tracks the largest EOSE-safe Nostr timestamp without skipping undurable relay events. */
|
|
47
36
|
function createNostrDurableCursor(options) {
|
|
48
|
-
const nowSec = options.nowSec ?? (() => Math.floor(Date.now() / 1e3));
|
|
49
37
|
let durableCandidate;
|
|
50
38
|
let transientReplayCeiling;
|
|
51
39
|
let backfillComplete = false;
|
|
@@ -57,7 +45,8 @@ function createNostrDurableCursor(options) {
|
|
|
57
45
|
recordDurableAppend: (event) => {
|
|
58
46
|
if (!Number.isSafeInteger(event.created_at)) return;
|
|
59
47
|
const previousSafeCandidate = safeCandidate();
|
|
60
|
-
|
|
48
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
49
|
+
durableCandidate = Math.max(durableCandidate ?? 0, Math.min(event.created_at, nowSec));
|
|
61
50
|
const nextSafeCandidate = safeCandidate();
|
|
62
51
|
return backfillComplete && nextSafeCandidate !== previousSafeCandidate ? nextSafeCandidate : void 0;
|
|
63
52
|
},
|
|
@@ -79,7 +68,6 @@ function createNostrCursorStateWriter(options) {
|
|
|
79
68
|
let desiredCursor = Math.max(options.minimumCursor, options.initialCursor);
|
|
80
69
|
let dirty = false;
|
|
81
70
|
let timer;
|
|
82
|
-
let writeTail = Promise.resolve();
|
|
83
71
|
let activeFlush;
|
|
84
72
|
let recoveryFlush;
|
|
85
73
|
const writeWithRetry = async (cursor) => {
|
|
@@ -94,27 +82,20 @@ function createNostrCursorStateWriter(options) {
|
|
|
94
82
|
throw new Error("Nostr cursor state write failed.", { cause: error });
|
|
95
83
|
}
|
|
96
84
|
};
|
|
97
|
-
const enqueueWrite = (cursor) => {
|
|
98
|
-
const write = writeTail.then(() => writeWithRetry(cursor));
|
|
99
|
-
writeTail = write.catch(() => void 0);
|
|
100
|
-
return write;
|
|
101
|
-
};
|
|
102
85
|
const clearTimer = () => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
timer = void 0;
|
|
106
|
-
}
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
timer = void 0;
|
|
107
88
|
};
|
|
108
89
|
const runFlush = async () => {
|
|
109
90
|
for (;;) {
|
|
110
91
|
if (!dirty) {
|
|
111
|
-
await
|
|
92
|
+
await Promise.resolve();
|
|
112
93
|
if (!dirty) return;
|
|
113
94
|
}
|
|
114
95
|
dirty = false;
|
|
115
96
|
const cursor = desiredCursor;
|
|
116
97
|
try {
|
|
117
|
-
await
|
|
98
|
+
await Promise.resolve().then(() => writeWithRetry(cursor));
|
|
118
99
|
} catch (error) {
|
|
119
100
|
dirty = true;
|
|
120
101
|
throw error;
|
|
@@ -154,6 +135,7 @@ function createNostrCursorStateWriter(options) {
|
|
|
154
135
|
await flush();
|
|
155
136
|
return;
|
|
156
137
|
} catch (error) {
|
|
138
|
+
if (isStateDatabaseAdmissionClosedError(error)) throw error;
|
|
157
139
|
options.onBackgroundError?.(error);
|
|
158
140
|
await sleepWithAbort(CURSOR_RECOVERY_RETRY_MS);
|
|
159
141
|
}
|
|
@@ -178,8 +160,7 @@ function inspectNostrIngressEvent(event) {
|
|
|
178
160
|
}
|
|
179
161
|
/** Convert the retired persisted LRU seed into durable completion tombstones. */
|
|
180
162
|
async function migrateNostrLegacyRecentEventIds(params) {
|
|
181
|
-
const migratedAt =
|
|
182
|
-
let migrated = 0;
|
|
163
|
+
const migratedAt = Date.now();
|
|
183
164
|
for (const eventId of new Set(params.eventIds)) {
|
|
184
165
|
if (!eventId.trim()) continue;
|
|
185
166
|
const result = await params.queue.enqueue(eventId, {
|
|
@@ -193,9 +174,7 @@ async function migrateNostrLegacyRecentEventIds(params) {
|
|
|
193
174
|
if (result.kind === "accepted" || result.kind === "pending" && result.record.payload.rawEvent === "") {
|
|
194
175
|
if (!await params.queue.complete(eventId, { completedAt: migratedAt })) throw new Error(`Failed to migrate Nostr replay event ${eventId}.`);
|
|
195
176
|
}
|
|
196
|
-
migrated += 1;
|
|
197
177
|
}
|
|
198
|
-
return migrated;
|
|
199
178
|
}
|
|
200
179
|
// extensions/nostr/src/runtime.ts
|
|
201
180
|
const { setRuntime: setNostrRuntime, getRuntime: getNostrRuntime } = createPluginRuntimeStore({
|
|
@@ -204,11 +183,6 @@ const { setRuntime: setNostrRuntime, getRuntime: getNostrRuntime } = createPlugi
|
|
|
204
183
|
});
|
|
205
184
|
// extensions/nostr/src/nostr-ingress.ts
|
|
206
185
|
const NOSTR_INGRESS_POLL_INTERVAL_MS = 500;
|
|
207
|
-
const NOSTR_INGRESS_APPEND_RETRY_MS = [
|
|
208
|
-
0,
|
|
209
|
-
100,
|
|
210
|
-
300
|
|
211
|
-
];
|
|
212
186
|
const NostrIngressAdmissionRejectedError = createChannelIngressError("NostrIngressAdmissionRejectedError", { withReason: true });
|
|
213
187
|
function deserializeNostrIngressEvent(rawEvent, claimedId) {
|
|
214
188
|
let parsed;
|
|
@@ -235,20 +209,35 @@ function createNostrIngress(options) {
|
|
|
235
209
|
};
|
|
236
210
|
const monitor = createChannelIngressMonitor({
|
|
237
211
|
queue: getQueue,
|
|
238
|
-
inspect: (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
212
|
+
inspect: ({ facts }) => facts,
|
|
213
|
+
inspectAsync: async ({ facts }, context) => {
|
|
214
|
+
if (context.phase === "admission") {
|
|
215
|
+
await monitorStart;
|
|
216
|
+
if (admissionFailure) throw admissionFailure;
|
|
217
|
+
const pending = await getQueue().listPending({ limit: options.maxPendingEvents });
|
|
218
|
+
const claims = await getQueue().listClaims();
|
|
219
|
+
if (pending.length + claims.length >= options.maxPendingEvents) throw new NostrIngressAdmissionRejectedError("backpressure", "Nostr event exceeds the durable ingress backlog.");
|
|
220
|
+
}
|
|
221
|
+
return facts;
|
|
244
222
|
},
|
|
245
223
|
payload: {
|
|
246
224
|
version: 1,
|
|
247
|
-
serialize: (
|
|
248
|
-
receivedAt,
|
|
249
|
-
rawEvent:
|
|
225
|
+
serialize: ({ payload }) => ({
|
|
226
|
+
receivedAt: payload.receivedAt,
|
|
227
|
+
rawEvent: payload.rawEvent
|
|
250
228
|
}),
|
|
251
|
-
deserialize: (body, { claim }) =>
|
|
229
|
+
deserialize: (body, { claim }) => {
|
|
230
|
+
const event = deserializeNostrIngressEvent(body.rawEvent, claim.id);
|
|
231
|
+
return {
|
|
232
|
+
event,
|
|
233
|
+
facts: inspectNostrIngressEvent(event),
|
|
234
|
+
receivedAt: body.receivedAt,
|
|
235
|
+
payload: {
|
|
236
|
+
version: 1,
|
|
237
|
+
...body
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
},
|
|
252
241
|
encode: ({ body }) => ({
|
|
253
242
|
version: 1,
|
|
254
243
|
...body
|
|
@@ -265,14 +254,19 @@ function createNostrIngress(options) {
|
|
|
265
254
|
},
|
|
266
255
|
createClaimError: (kind, claim) => new NostrIngressPermanentError("invalid-event", kind === "invalid-version" ? `Nostr ingress row ${claim.id} has an unsupported version.` : `Nostr ingress row ${claim.id} changed event identity.`)
|
|
267
256
|
},
|
|
268
|
-
deliver: options.deliver,
|
|
269
|
-
|
|
257
|
+
deliver: ({ event }, lifecycle) => options.deliver(event, lifecycle),
|
|
258
|
+
onDurableAdmission: ({ event }) => options.afterDurableAppend(event),
|
|
259
|
+
onAdmissionFailure: (_event, error) => {
|
|
260
|
+
if (error instanceof NostrIngressAdmissionRejectedError || error instanceof NostrIngressPermanentError) return;
|
|
261
|
+
admissionFailure ??= new Error(`Nostr durable admission failed: ${formatErrorMessage(error)}`, { cause: error });
|
|
262
|
+
throw admissionFailure;
|
|
263
|
+
},
|
|
264
|
+
pollIntervalMs: NOSTR_INGRESS_POLL_INTERVAL_MS,
|
|
270
265
|
retention: {
|
|
271
266
|
completedMaxEntries: 1e5,
|
|
272
267
|
failedMaxEntries: 1e5
|
|
273
268
|
},
|
|
274
269
|
drain: {
|
|
275
|
-
adoptionStallTimeoutMs: options.adoptionStallTimeoutMs ?? DEFAULT_INGRESS_ADOPTION_STALL_MS,
|
|
276
270
|
resolveNonRetryableFailure: (error) => error instanceof NostrIngressPermanentError ? {
|
|
277
271
|
reason: error.reason,
|
|
278
272
|
message: error.message
|
|
@@ -291,7 +285,6 @@ function createNostrIngress(options) {
|
|
|
291
285
|
if (!stopping) monitor.start();
|
|
292
286
|
})();
|
|
293
287
|
monitorStart.catch((error) => options.onError?.(error, "ingress drain"));
|
|
294
|
-
let admissionTail = Promise.resolve();
|
|
295
288
|
const prepareAdmission = (event) => {
|
|
296
289
|
const facts = inspectNostrIngressEvent(event);
|
|
297
290
|
const receivedAt = Date.now();
|
|
@@ -322,34 +315,8 @@ function createNostrIngress(options) {
|
|
|
322
315
|
payload
|
|
323
316
|
};
|
|
324
317
|
};
|
|
325
|
-
const admitOnce = async (prepared) => {
|
|
326
|
-
await monitorStart;
|
|
327
|
-
const pending = await getQueue().listPending({ limit: options.maxPendingEvents });
|
|
328
|
-
const claims = await getQueue().listClaims();
|
|
329
|
-
if (pending.length + claims.length >= options.maxPendingEvents) throw new NostrIngressAdmissionRejectedError("backpressure", "Nostr event exceeds the durable ingress backlog.");
|
|
330
|
-
try {
|
|
331
|
-
return await retryAsync(async () => {
|
|
332
|
-
const result = await getQueue().enqueue(prepared.facts.eventId, prepared.payload, {
|
|
333
|
-
receivedAt: prepared.receivedAt,
|
|
334
|
-
laneKey: prepared.facts.laneKey
|
|
335
|
-
});
|
|
336
|
-
options.afterDurableAppend(prepared.event);
|
|
337
|
-
monitor.requestDrain();
|
|
338
|
-
return result.kind === "accepted" ? "accepted" : "duplicate";
|
|
339
|
-
}, {
|
|
340
|
-
attempts: NOSTR_INGRESS_APPEND_RETRY_MS.length,
|
|
341
|
-
minDelayMs: 0,
|
|
342
|
-
delayMs: ({ attempt }) => NOSTR_INGRESS_APPEND_RETRY_MS[attempt] ?? 0,
|
|
343
|
-
sleep: (delayMs) => sleepWithAbort(delayMs)
|
|
344
|
-
});
|
|
345
|
-
} catch (error) {
|
|
346
|
-
throw new Error(`Nostr durable admission failed: ${formatErrorMessage(error)}`, { cause: error });
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
318
|
return {
|
|
350
|
-
ready:
|
|
351
|
-
await monitorStart;
|
|
352
|
-
},
|
|
319
|
+
ready: () => monitorStart,
|
|
353
320
|
receive: (event) => {
|
|
354
321
|
if (stopping) return Promise.reject(createStoppedError());
|
|
355
322
|
let prepared;
|
|
@@ -359,27 +326,15 @@ function createNostrIngress(options) {
|
|
|
359
326
|
return Promise.reject(error);
|
|
360
327
|
}
|
|
361
328
|
queuedAdmissions += 1;
|
|
362
|
-
|
|
363
|
-
if (admissionFailure) throw admissionFailure;
|
|
364
|
-
try {
|
|
365
|
-
return await admitOnce(prepared);
|
|
366
|
-
} catch (error) {
|
|
367
|
-
if (error instanceof NostrIngressAdmissionRejectedError || error instanceof NostrIngressPermanentError) throw error;
|
|
368
|
-
admissionFailure = error instanceof Error ? error : new Error(formatErrorMessage(error), { cause: error });
|
|
369
|
-
throw admissionFailure;
|
|
370
|
-
}
|
|
371
|
-
}).finally(() => {
|
|
329
|
+
return monitor.admit(prepared, { receivedAt: prepared.receivedAt }).then((result) => result.queueResult?.kind === "accepted" ? "accepted" : "duplicate").finally(() => {
|
|
372
330
|
queuedAdmissions -= 1;
|
|
373
331
|
});
|
|
374
|
-
admissionTail = settledAdmission.then(() => void 0, () => void 0);
|
|
375
|
-
return settledAdmission;
|
|
376
332
|
},
|
|
377
333
|
stop: () => {
|
|
378
334
|
if (stopTask) return stopTask;
|
|
379
335
|
stopping = true;
|
|
380
336
|
const pauseTask = monitor.pause();
|
|
381
337
|
stopTask = (async () => {
|
|
382
|
-
await admissionTail;
|
|
383
338
|
await monitorStart.catch(() => void 0);
|
|
384
339
|
await pauseTask;
|
|
385
340
|
await monitor.stop();
|
|
@@ -387,7 +342,6 @@ function createNostrIngress(options) {
|
|
|
387
342
|
return stopTask;
|
|
388
343
|
},
|
|
389
344
|
waitForIdle: async () => {
|
|
390
|
-
await admissionTail;
|
|
391
345
|
await monitorStart;
|
|
392
346
|
await monitor.waitForIdle();
|
|
393
347
|
}
|
|
@@ -456,67 +410,6 @@ async function publishProfile(pool, sk, relays, profile, lastPublishedAt) {
|
|
|
456
410
|
createdAt: event.created_at
|
|
457
411
|
};
|
|
458
412
|
}
|
|
459
|
-
// extensions/nostr/src/nostr-relay-subscription.ts
|
|
460
|
-
const DEFAULT_EOSE_CONFIRM_DEADLINE_MS = 1e4;
|
|
461
|
-
/** Separates real relay EOSE frames from nostr-tools timeout/close synthesis. */
|
|
462
|
-
function createNostrRelaySubscriptionGroup(options) {
|
|
463
|
-
const relays = [...new Set(options.relays)];
|
|
464
|
-
const subscriptions = [];
|
|
465
|
-
const deadlineTimers = /* @__PURE__ */ new Set();
|
|
466
|
-
let locallyClosing = false;
|
|
467
|
-
const backfillStatus = new Map(relays.map((relay) => [relay, "pending"]));
|
|
468
|
-
const settleBackfill = (relay, status) => {
|
|
469
|
-
if (backfillStatus.get(relay) !== "pending") return;
|
|
470
|
-
backfillStatus.set(relay, status);
|
|
471
|
-
if ([...backfillStatus.values()].some((value) => value === "pending")) return;
|
|
472
|
-
if ([...backfillStatus.values()].every((value) => value === "confirmed")) options.onBackfillComplete(relays);
|
|
473
|
-
};
|
|
474
|
-
const clearDeadlines = () => {
|
|
475
|
-
for (const timer of deadlineTimers) clearTimeout(timer);
|
|
476
|
-
deadlineTimers.clear();
|
|
477
|
-
};
|
|
478
|
-
return {
|
|
479
|
-
start: () => {
|
|
480
|
-
for (const relay of relays) {
|
|
481
|
-
let relayClosed = false;
|
|
482
|
-
let deadlineReached = false;
|
|
483
|
-
const deadlineTimer = setTimeout(() => {
|
|
484
|
-
deadlineTimers.delete(deadlineTimer);
|
|
485
|
-
deadlineReached = true;
|
|
486
|
-
settleBackfill(relay, "incomplete");
|
|
487
|
-
}, DEFAULT_EOSE_CONFIRM_DEADLINE_MS);
|
|
488
|
-
deadlineTimer.unref?.();
|
|
489
|
-
deadlineTimers.add(deadlineTimer);
|
|
490
|
-
subscriptions.push(options.pool.subscribeMany([relay], options.filter, {
|
|
491
|
-
onevent: options.onEvent,
|
|
492
|
-
oneose: () => {
|
|
493
|
-
queueMicrotask(() => {
|
|
494
|
-
if (!relayClosed && !deadlineReached) {
|
|
495
|
-
clearTimeout(deadlineTimer);
|
|
496
|
-
deadlineTimers.delete(deadlineTimer);
|
|
497
|
-
settleBackfill(relay, "confirmed");
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
},
|
|
501
|
-
onclose: (reasons) => {
|
|
502
|
-
relayClosed = true;
|
|
503
|
-
clearTimeout(deadlineTimer);
|
|
504
|
-
deadlineTimers.delete(deadlineTimer);
|
|
505
|
-
settleBackfill(relay, "incomplete");
|
|
506
|
-
if (!locallyClosing && !options.abort.aborted) options.onClose(relay, reasons.map(({ reason }) => reason));
|
|
507
|
-
},
|
|
508
|
-
maxWait: 11e3,
|
|
509
|
-
abort: options.abort
|
|
510
|
-
}));
|
|
511
|
-
}
|
|
512
|
-
},
|
|
513
|
-
close: async (reason) => {
|
|
514
|
-
locallyClosing = true;
|
|
515
|
-
clearDeadlines();
|
|
516
|
-
await Promise.all(subscriptions.map(async (subscription) => subscription.close(reason)));
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
413
|
// extensions/nostr/src/state-account-id.ts
|
|
521
414
|
function normalizeNostrStateAccountId(accountId) {
|
|
522
415
|
const trimmed = accountId?.trim();
|
|
@@ -526,31 +419,29 @@ function normalizeNostrStateAccountId(accountId) {
|
|
|
526
419
|
// extensions/nostr/src/nostr-state-store.ts
|
|
527
420
|
const STORE_VERSION = 2;
|
|
528
421
|
const PROFILE_STATE_VERSION = 1;
|
|
529
|
-
function openNostrBusStateStore(
|
|
422
|
+
function openNostrBusStateStore() {
|
|
530
423
|
return getNostrRuntime().state.openKeyedStore({
|
|
531
424
|
namespace: "bus-state",
|
|
532
|
-
maxEntries: 256
|
|
533
|
-
...env ? { env } : {}
|
|
425
|
+
maxEntries: 256
|
|
534
426
|
});
|
|
535
427
|
}
|
|
536
|
-
function openNostrProfileStateStore(
|
|
428
|
+
function openNostrProfileStateStore() {
|
|
537
429
|
return getNostrRuntime().state.openKeyedStore({
|
|
538
430
|
namespace: "profile-state",
|
|
539
|
-
maxEntries: 256
|
|
540
|
-
...env ? { env } : {}
|
|
431
|
+
maxEntries: 256
|
|
541
432
|
});
|
|
542
433
|
}
|
|
543
434
|
async function readNostrBusState(params) {
|
|
544
|
-
return await openNostrBusStateStore(
|
|
435
|
+
return await openNostrBusStateStore().lookup(normalizeNostrStateAccountId(params.accountId)) ?? null;
|
|
545
436
|
}
|
|
546
437
|
async function writeNostrBusState(params) {
|
|
547
438
|
const payload = {
|
|
548
439
|
version: STORE_VERSION,
|
|
549
440
|
lastProcessedAt: params.lastProcessedAt,
|
|
550
441
|
gatewayStartedAt: params.gatewayStartedAt,
|
|
551
|
-
recentEventIds:
|
|
442
|
+
recentEventIds: params.recentEventIds ?? []
|
|
552
443
|
};
|
|
553
|
-
await openNostrBusStateStore(
|
|
444
|
+
await openNostrBusStateStore().register(normalizeNostrStateAccountId(params.accountId), payload);
|
|
554
445
|
}
|
|
555
446
|
/**
|
|
556
447
|
* Determine the `since` timestamp for subscription.
|
|
@@ -564,7 +455,7 @@ function computeSinceTimestamp(state, nowSec = Math.floor(Date.now() / 1e3)) {
|
|
|
564
455
|
return Math.max(...candidates);
|
|
565
456
|
}
|
|
566
457
|
async function readNostrProfileState(params) {
|
|
567
|
-
return await openNostrProfileStateStore(
|
|
458
|
+
return await openNostrProfileStateStore().lookup(normalizeNostrStateAccountId(params.accountId)) ?? null;
|
|
568
459
|
}
|
|
569
460
|
async function writeNostrProfileState(params) {
|
|
570
461
|
const payload = {
|
|
@@ -573,109 +464,26 @@ async function writeNostrProfileState(params) {
|
|
|
573
464
|
lastPublishedEventId: params.lastPublishedEventId,
|
|
574
465
|
lastPublishResults: params.lastPublishResults
|
|
575
466
|
};
|
|
576
|
-
await openNostrProfileStateStore(
|
|
467
|
+
await openNostrProfileStateStore().register(normalizeNostrStateAccountId(params.accountId), payload);
|
|
577
468
|
}
|
|
578
469
|
// extensions/nostr/src/nostr-bus.ts
|
|
579
470
|
const STARTUP_LOOKBACK_SEC = 120;
|
|
580
471
|
const STATE_PERSIST_DEBOUNCE_MS = 5e3;
|
|
581
472
|
const NOSTR_INGRESS_ENVELOPE_OVERHEAD_BYTES = 16384;
|
|
582
473
|
const NOSTR_INGRESS_MAX_PENDING_EVENTS = 1e3;
|
|
583
|
-
const
|
|
584
|
-
const CIRCUIT_BREAKER_RESET_MS = 3e4;
|
|
585
|
-
const HEALTH_WINDOW_MS = 6e4;
|
|
586
|
-
function createCircuitBreaker(relay, metrics) {
|
|
587
|
-
const state = {
|
|
588
|
-
state: "closed",
|
|
589
|
-
failures: 0,
|
|
590
|
-
lastFailure: 0
|
|
591
|
-
};
|
|
592
|
-
return {
|
|
593
|
-
canAttempt() {
|
|
594
|
-
if (state.state === "open") {
|
|
595
|
-
if (Date.now() - state.lastFailure >= CIRCUIT_BREAKER_RESET_MS) {
|
|
596
|
-
state.state = "half_open";
|
|
597
|
-
metrics.emit("relay.circuit_breaker.half_open", 1, { relay });
|
|
598
|
-
return true;
|
|
599
|
-
}
|
|
600
|
-
return false;
|
|
601
|
-
}
|
|
602
|
-
return true;
|
|
603
|
-
},
|
|
604
|
-
recordSuccess() {
|
|
605
|
-
if (state.state === "half_open") {
|
|
606
|
-
state.state = "closed";
|
|
607
|
-
state.failures = 0;
|
|
608
|
-
metrics.emit("relay.circuit_breaker.close", 1, { relay });
|
|
609
|
-
} else if (state.state === "closed") state.failures = 0;
|
|
610
|
-
},
|
|
611
|
-
recordFailure() {
|
|
612
|
-
state.failures++;
|
|
613
|
-
state.lastFailure = Date.now();
|
|
614
|
-
if (state.state === "half_open" || state.state === "closed" && state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
615
|
-
state.state = "open";
|
|
616
|
-
metrics.emit("relay.circuit_breaker.open", 1, { relay });
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
function createRelayHealthTracker() {
|
|
622
|
-
const stats = /* @__PURE__ */ new Map();
|
|
623
|
-
function getOrCreate(relay) {
|
|
624
|
-
let s = stats.get(relay);
|
|
625
|
-
if (!s) {
|
|
626
|
-
s = {
|
|
627
|
-
successCount: 0,
|
|
628
|
-
failureCount: 0,
|
|
629
|
-
latencySum: 0,
|
|
630
|
-
lastSuccess: 0,
|
|
631
|
-
lastFailure: 0
|
|
632
|
-
};
|
|
633
|
-
stats.set(relay, s);
|
|
634
|
-
}
|
|
635
|
-
return s;
|
|
636
|
-
}
|
|
637
|
-
return {
|
|
638
|
-
recordSuccess(relay, latencyMs) {
|
|
639
|
-
const s = getOrCreate(relay);
|
|
640
|
-
s.successCount++;
|
|
641
|
-
s.latencySum += latencyMs;
|
|
642
|
-
s.lastSuccess = Date.now();
|
|
643
|
-
},
|
|
644
|
-
recordFailure(relay) {
|
|
645
|
-
const s = getOrCreate(relay);
|
|
646
|
-
s.failureCount++;
|
|
647
|
-
s.lastFailure = Date.now();
|
|
648
|
-
},
|
|
649
|
-
getScore(relay) {
|
|
650
|
-
const s = stats.get(relay);
|
|
651
|
-
if (!s) return .5;
|
|
652
|
-
const total = s.successCount + s.failureCount;
|
|
653
|
-
const successRate = s.successCount / total;
|
|
654
|
-
const now = Date.now();
|
|
655
|
-
const recencyBonus = s.lastSuccess > s.lastFailure ? Math.max(0, 1 - (now - s.lastSuccess) / HEALTH_WINDOW_MS) * .2 : 0;
|
|
656
|
-
const avgLatency = s.successCount > 0 ? s.latencySum / s.successCount : 1e3;
|
|
657
|
-
const latencyPenalty = Math.min(.2, avgLatency / 1e4);
|
|
658
|
-
return Math.max(0, Math.min(1, successRate + recencyBonus - latencyPenalty));
|
|
659
|
-
},
|
|
660
|
-
getSortedRelays(relays) {
|
|
661
|
-
return relays.toSorted((a, b) => this.getScore(b) - this.getScore(a));
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
}
|
|
474
|
+
const DEFAULT_EOSE_CONFIRM_DEADLINE_MS = 1e4;
|
|
665
475
|
/** Subscribe to NIP-04 encrypted DMs. */
|
|
666
476
|
async function startNostrBus(options) {
|
|
667
|
-
const { privateKey, relays = DEFAULT_RELAYS, onMessage, authorizeSender, onError, onEose,
|
|
477
|
+
const { privateKey, relays = DEFAULT_RELAYS, onMessage, authorizeSender, onError, onEose, onRejected } = options;
|
|
668
478
|
const sk = validatePrivateKey(privateKey);
|
|
669
479
|
const pk = getPublicKey(sk);
|
|
670
480
|
const pool = new SimplePool();
|
|
481
|
+
const admissionPubkeys = options.admissionPubkeys ? new Set(options.admissionPubkeys) : void 0;
|
|
671
482
|
pool.onRelayConnectionSuccess = options.onConnect;
|
|
672
483
|
const accountId = options.accountId ?? pk.slice(0, 16);
|
|
673
484
|
const gatewayStartedAt = Math.floor(Date.now() / 1e3);
|
|
674
|
-
const guardPolicy = createDirectDmPreCryptoGuardPolicy(
|
|
675
|
-
|
|
676
|
-
const circuitBreakers = /* @__PURE__ */ new Map();
|
|
677
|
-
const healthTracker = createRelayHealthTracker();
|
|
678
|
-
for (const relay of relays) circuitBreakers.set(relay, createCircuitBreaker(relay, metrics));
|
|
485
|
+
const guardPolicy = createDirectDmPreCryptoGuardPolicy();
|
|
486
|
+
let preferredRelay;
|
|
679
487
|
const state = await readNostrBusState({ accountId });
|
|
680
488
|
const baseSince = computeSinceTimestamp(state, gatewayStartedAt);
|
|
681
489
|
const since = Math.max(0, baseSince - STARTUP_LOOKBACK_SEC);
|
|
@@ -709,52 +517,44 @@ async function startNostrBus(options) {
|
|
|
709
517
|
maxRequests: guardPolicy.rateLimit.maxGlobalPerWindow,
|
|
710
518
|
maxTrackedKeys: 1
|
|
711
519
|
});
|
|
712
|
-
const
|
|
713
|
-
metrics.emit("memory.rate_limiter_entries", perSenderRateLimiter.size() + globalRateLimiter.size());
|
|
714
|
-
};
|
|
715
|
-
const rejectIfRateLimited = (limiter, key, metric) => {
|
|
716
|
-
updateRateLimiterSizeMetric();
|
|
520
|
+
const rejectIfRateLimited = (limiter, key) => {
|
|
717
521
|
const limited = limiter.isRateLimited(key);
|
|
718
|
-
if (limited)
|
|
719
|
-
metrics.emit(metric);
|
|
720
|
-
metrics.emit("event.rejected.rate_limited");
|
|
721
|
-
}
|
|
722
|
-
updateRateLimiterSizeMetric();
|
|
522
|
+
if (limited) onRejected?.("rate_limited");
|
|
723
523
|
return limited;
|
|
724
524
|
};
|
|
725
525
|
async function dispatchEvent(event, lifecycle) {
|
|
726
526
|
if (event.pubkey === pk) {
|
|
727
|
-
|
|
527
|
+
onRejected?.("self_message");
|
|
728
528
|
return;
|
|
729
529
|
}
|
|
730
530
|
if (event.created_at > Math.floor(Date.now() / 1e3) + guardPolicy.maxFutureSkewSec) {
|
|
731
|
-
|
|
531
|
+
onRejected?.("future");
|
|
732
532
|
throw new Error(`Nostr event ${event.id} is too far in the future.`);
|
|
733
533
|
}
|
|
734
534
|
if (!guardPolicy.allowedKinds.includes(event.kind)) {
|
|
735
|
-
|
|
535
|
+
onRejected?.("wrong_kind");
|
|
736
536
|
return;
|
|
737
537
|
}
|
|
738
538
|
if (!event.tags.some((tag) => tag[0] === "p" && tag[1] === pk)) {
|
|
739
|
-
|
|
539
|
+
onRejected?.("wrong_kind");
|
|
740
540
|
return;
|
|
741
541
|
}
|
|
742
542
|
const replyTo = async (text) => {
|
|
743
543
|
await sendEncryptedDm(event.pubkey, text, { replyToEventId: event.id });
|
|
744
544
|
};
|
|
745
545
|
if (Buffer.byteLength(event.content, "utf8") > guardPolicy.maxCiphertextBytes) {
|
|
746
|
-
if (rejectIfRateLimited(globalRateLimiter, "global"
|
|
747
|
-
|
|
546
|
+
if (rejectIfRateLimited(globalRateLimiter, "global")) throw new Error(`Nostr event ${event.id} hit the global rate limit.`);
|
|
547
|
+
onRejected?.("oversized_ciphertext");
|
|
748
548
|
return;
|
|
749
549
|
}
|
|
750
|
-
if (rejectIfRateLimited(globalRateLimiter, "global"
|
|
550
|
+
if (rejectIfRateLimited(globalRateLimiter, "global")) throw new Error(`Nostr event ${event.id} hit the global rate limit.`);
|
|
751
551
|
if (!verifyEvent(event)) {
|
|
752
|
-
|
|
552
|
+
onRejected?.("invalid_signature");
|
|
753
553
|
const error = new NostrIngressPermanentError("invalid-signature", `Nostr event ${event.id} has an invalid signature.`);
|
|
754
554
|
onError?.(error, `event ${event.id}`);
|
|
755
555
|
throw error;
|
|
756
556
|
}
|
|
757
|
-
if (rejectIfRateLimited(perSenderRateLimiter, event.pubkey
|
|
557
|
+
if (rejectIfRateLimited(perSenderRateLimiter, event.pubkey)) throw new Error(`Nostr sender ${event.pubkey} hit the rate limit.`);
|
|
758
558
|
if (authorizeSender) {
|
|
759
559
|
if (await authorizeSender({
|
|
760
560
|
senderPubkey: event.pubkey,
|
|
@@ -764,15 +564,13 @@ async function startNostrBus(options) {
|
|
|
764
564
|
let plaintext;
|
|
765
565
|
try {
|
|
766
566
|
plaintext = decrypt(sk, event.pubkey, event.content);
|
|
767
|
-
metrics.emit("decrypt.success");
|
|
768
567
|
} catch (error) {
|
|
769
|
-
|
|
770
|
-
metrics.emit("event.rejected.decrypt_failed");
|
|
568
|
+
onRejected?.("decrypt_failed");
|
|
771
569
|
onError?.(error, `decrypt from ${event.pubkey}`);
|
|
772
570
|
throw new NostrIngressPermanentError("decrypt-failed", `Nostr event ${event.id} could not be decrypted.`, { cause: error });
|
|
773
571
|
}
|
|
774
572
|
if (Buffer.byteLength(plaintext, "utf8") > guardPolicy.maxPlaintextBytes) {
|
|
775
|
-
|
|
573
|
+
onRejected?.("oversized_plaintext");
|
|
776
574
|
return;
|
|
777
575
|
}
|
|
778
576
|
if (lifecycle.abortSignal.aborted) throw new Error(`Nostr event ${event.id} stopped before dispatch.`);
|
|
@@ -780,7 +578,6 @@ async function startNostrBus(options) {
|
|
|
780
578
|
eventId: event.id,
|
|
781
579
|
createdAt: event.created_at
|
|
782
580
|
}, lifecycle);
|
|
783
|
-
metrics.emit("event.processed");
|
|
784
581
|
}
|
|
785
582
|
const dmFilter = {
|
|
786
583
|
kinds: [4],
|
|
@@ -788,13 +585,13 @@ async function startNostrBus(options) {
|
|
|
788
585
|
since
|
|
789
586
|
};
|
|
790
587
|
const relayAbort = new AbortController();
|
|
791
|
-
let
|
|
588
|
+
let closeRelaySubscriptions;
|
|
792
589
|
let relayStopPromise;
|
|
793
590
|
const stopRelays = (reason) => {
|
|
794
591
|
relayStopPromise ??= (async () => {
|
|
795
592
|
relayAbort.abort(reason);
|
|
796
593
|
try {
|
|
797
|
-
await
|
|
594
|
+
await closeRelaySubscriptions?.(reason);
|
|
798
595
|
} catch (error) {
|
|
799
596
|
onError?.(error, "close subscription");
|
|
800
597
|
} finally {
|
|
@@ -829,20 +626,17 @@ async function startNostrBus(options) {
|
|
|
829
626
|
if (cursor !== void 0) await cursorWriter.persistNow(cursor);
|
|
830
627
|
};
|
|
831
628
|
const handleRelayEvent = async (event) => {
|
|
832
|
-
metrics.emit("event.received");
|
|
833
629
|
if (typeof event.created_at === "number" && event.created_at < since) {
|
|
834
|
-
|
|
630
|
+
onRejected?.("stale");
|
|
835
631
|
return;
|
|
836
632
|
}
|
|
633
|
+
if (admissionPubkeys && !admissionPubkeys.has(event.pubkey)) return;
|
|
837
634
|
try {
|
|
838
|
-
|
|
635
|
+
await ingress.receive(event);
|
|
839
636
|
} catch (error) {
|
|
840
637
|
onError?.(error, `durable admission for event ${event.id}`);
|
|
841
638
|
if (error instanceof NostrIngressAdmissionRejectedError) {
|
|
842
|
-
if (error.reason === "rate-limited")
|
|
843
|
-
metrics.emit("rate_limit.global");
|
|
844
|
-
metrics.emit("event.rejected.rate_limited");
|
|
845
|
-
}
|
|
639
|
+
if (error.reason === "rate-limited") onRejected?.("rate_limited");
|
|
846
640
|
if (error.reason !== "oversized-event") try {
|
|
847
641
|
await persistTransientReplayCursor(event);
|
|
848
642
|
} catch (cursorError) {
|
|
@@ -873,30 +667,68 @@ async function startNostrBus(options) {
|
|
|
873
667
|
gatewayStartedAt: cursorStartedAt,
|
|
874
668
|
recentEventIds: []
|
|
875
669
|
});
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
670
|
+
/** Separates real relay EOSE frames from nostr-tools timeout/close synthesis. */
|
|
671
|
+
const subscriptionRelays = [...new Set(relays)];
|
|
672
|
+
const subscriptions = [];
|
|
673
|
+
const deadlineTimers = /* @__PURE__ */ new Set();
|
|
674
|
+
let locallyClosing = false;
|
|
675
|
+
const backfillStatus = new Map(subscriptionRelays.map((relay) => [relay, "pending"]));
|
|
676
|
+
const settleBackfill = (relay, status) => {
|
|
677
|
+
if (backfillStatus.get(relay) !== "pending") return;
|
|
678
|
+
backfillStatus.set(relay, status);
|
|
679
|
+
if ([...backfillStatus.values()].some((value) => value === "pending")) return;
|
|
680
|
+
if ([...backfillStatus.values()].every((value) => value === "confirmed")) backfillFinalizePromise ??= ingress.waitForIdle().then(() => {
|
|
681
|
+
const cursor = durableCursor.markBackfillComplete();
|
|
682
|
+
if (cursor !== void 0) cursorWriter.schedule(cursor);
|
|
683
|
+
onEose?.(subscriptionRelays.join(", "));
|
|
684
|
+
}).catch((error) => onError?.(error, "finalize relay backfill"));
|
|
685
|
+
};
|
|
686
|
+
closeRelaySubscriptions = async (reason) => {
|
|
687
|
+
locallyClosing = true;
|
|
688
|
+
for (const timer of deadlineTimers) clearTimeout(timer);
|
|
689
|
+
deadlineTimers.clear();
|
|
690
|
+
await Promise.all(subscriptions.map(async (subscription) => subscription.close(reason)));
|
|
691
|
+
};
|
|
692
|
+
const onRelayEvent = (event) => {
|
|
693
|
+
const task = handleRelayEvent(event);
|
|
694
|
+
if (options.trackIngressTask) options.trackIngressTask(task.then(() => ingress.waitForIdle()));
|
|
695
|
+
};
|
|
696
|
+
for (const relay of subscriptionRelays) {
|
|
697
|
+
let relayClosed = false;
|
|
698
|
+
let deadlineReached = false;
|
|
699
|
+
const deadlineTimer = setTimeout(() => {
|
|
700
|
+
deadlineTimers.delete(deadlineTimer);
|
|
701
|
+
deadlineReached = true;
|
|
702
|
+
settleBackfill(relay, "incomplete");
|
|
703
|
+
}, DEFAULT_EOSE_CONFIRM_DEADLINE_MS);
|
|
704
|
+
deadlineTimer.unref?.();
|
|
705
|
+
deadlineTimers.add(deadlineTimer);
|
|
706
|
+
subscriptions.push(pool.subscribeMany([relay], dmFilter, {
|
|
707
|
+
onevent: onRelayEvent,
|
|
708
|
+
oneose: () => {
|
|
709
|
+
queueMicrotask(() => {
|
|
710
|
+
if (!relayClosed && !deadlineReached) {
|
|
711
|
+
clearTimeout(deadlineTimer);
|
|
712
|
+
deadlineTimers.delete(deadlineTimer);
|
|
713
|
+
settleBackfill(relay, "confirmed");
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
},
|
|
717
|
+
onclose: (reasons) => {
|
|
718
|
+
relayClosed = true;
|
|
719
|
+
clearTimeout(deadlineTimer);
|
|
720
|
+
deadlineTimers.delete(deadlineTimer);
|
|
721
|
+
settleBackfill(relay, "incomplete");
|
|
722
|
+
if (!locallyClosing && !relayAbort.signal.aborted) {
|
|
723
|
+
const closeReasons = reasons.map(({ reason }) => reason);
|
|
724
|
+
options.onDisconnect?.(relay);
|
|
725
|
+
onError?.(/* @__PURE__ */ new Error(`Subscription closed: ${closeReasons.join(", ")}`), "subscription");
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
maxWait: 11e3,
|
|
729
|
+
abort: relayAbort.signal
|
|
730
|
+
}));
|
|
731
|
+
}
|
|
900
732
|
} catch (error) {
|
|
901
733
|
await Promise.allSettled([stopRelays("startup failed"), ingress.stop()]);
|
|
902
734
|
throw error;
|
|
@@ -946,22 +778,12 @@ async function startNostrBus(options) {
|
|
|
946
778
|
tags,
|
|
947
779
|
created_at: Math.floor(Date.now() / 1e3)
|
|
948
780
|
}, sk);
|
|
949
|
-
const sortedRelays =
|
|
781
|
+
const sortedRelays = relays.toSorted((left, right) => Number(right === preferredRelay) - Number(left === preferredRelay));
|
|
950
782
|
let lastError;
|
|
951
783
|
for (const relay of sortedRelays) {
|
|
952
784
|
sendOptions?.assertDirectAdapterHandoff?.();
|
|
953
|
-
const cb = circuitBreakers.get(relay);
|
|
954
|
-
if (cb && !cb.canAttempt()) continue;
|
|
955
|
-
const startTime = Date.now();
|
|
956
785
|
const recordFailure = (err) => {
|
|
957
786
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
958
|
-
const latency = Date.now() - startTime;
|
|
959
|
-
cb?.recordFailure();
|
|
960
|
-
healthTracker.recordFailure(relay);
|
|
961
|
-
metrics.emit("relay.error", 1, {
|
|
962
|
-
relay,
|
|
963
|
-
latency
|
|
964
|
-
});
|
|
965
787
|
onError?.(lastError, `publish to ${relay}`);
|
|
966
788
|
};
|
|
967
789
|
const connection = await pool.ensureRelay(relay, { connectionTimeout: pool.maxWaitForConnection }).catch((err) => {
|
|
@@ -980,9 +802,7 @@ async function startNostrBus(options) {
|
|
|
980
802
|
initiated = true;
|
|
981
803
|
return connection.publish(reply);
|
|
982
804
|
});
|
|
983
|
-
|
|
984
|
-
cb?.recordSuccess();
|
|
985
|
-
healthTracker.recordSuccess(relay, latency);
|
|
805
|
+
preferredRelay = relay;
|
|
986
806
|
return reply.id;
|
|
987
807
|
} catch (err) {
|
|
988
808
|
if (!initiated) throw err;
|
|
@@ -1023,6 +843,17 @@ function normalizeNostrSenderPubkey(value) {
|
|
|
1023
843
|
return null;
|
|
1024
844
|
}
|
|
1025
845
|
}
|
|
846
|
+
function resolveAdmissionPubkeys(account) {
|
|
847
|
+
if (account.config.dmPolicy !== "allowlist" || !account.config.allowFrom?.length) return;
|
|
848
|
+
const pubkeys = [];
|
|
849
|
+
for (const entry of account.config.allowFrom) {
|
|
850
|
+
if (typeof entry !== "string") return;
|
|
851
|
+
const normalized = normalizeNostrAllowEntry(entry);
|
|
852
|
+
if (!normalized || !/^[0-9a-f]{64}$/.test(normalized)) return;
|
|
853
|
+
pubkeys.push(normalized);
|
|
854
|
+
}
|
|
855
|
+
return [...new Set(pubkeys)];
|
|
856
|
+
}
|
|
1026
857
|
const nostrIngressIdentity = {
|
|
1027
858
|
key: "nostr-pubkey",
|
|
1028
859
|
normalizeEntry: normalizeNostrAllowEntry,
|
|
@@ -1093,6 +924,7 @@ async function startNostrGatewayAccount(ctx) {
|
|
|
1093
924
|
privateKey: account.privateKey,
|
|
1094
925
|
relays: account.relays,
|
|
1095
926
|
authorizeSender,
|
|
927
|
+
admissionPubkeys: resolveAdmissionPubkeys(account),
|
|
1096
928
|
onMessage: async (senderPubkey, text, reply, meta, lifecycle) => {
|
|
1097
929
|
const resolvedAccess = await resolveInboundAccess(senderPubkey, text);
|
|
1098
930
|
if (resolvedAccess.senderAccess.decision !== "allow") {
|
|
@@ -1163,11 +995,8 @@ async function startNostrGatewayAccount(ctx) {
|
|
|
1163
995
|
onEose: (relays) => {
|
|
1164
996
|
ctx.log?.debug?.(`[${account.accountId}] EOSE received from relays: ${relays}`);
|
|
1165
997
|
},
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
else if (event.name === "relay.circuit_breaker.open") ctx.log?.warn?.(`[${account.accountId}] Circuit breaker opened for relay: ${event.labels?.relay}`);
|
|
1169
|
-
else if (event.name === "relay.circuit_breaker.close") ctx.log?.info?.(`[${account.accountId}] Circuit breaker closed for relay: ${event.labels?.relay}`);
|
|
1170
|
-
else if (event.name === "relay.error") ctx.log?.debug?.(`[${account.accountId}] Relay error: ${event.labels?.relay}`);
|
|
998
|
+
onRejected: (reason) => {
|
|
999
|
+
ctx.log?.debug?.(`[${account.accountId}] Event rejected: ${reason}`);
|
|
1171
1000
|
}
|
|
1172
1001
|
});
|
|
1173
1002
|
activeBuses.set(account.accountId, bus);
|
|
@@ -1194,8 +1023,10 @@ const nostrPairingTextAdapter = {
|
|
|
1194
1023
|
}
|
|
1195
1024
|
},
|
|
1196
1025
|
notify: async ({ cfg, id, message, accountId }) => {
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1026
|
+
const aid = accountId ?? resolveDefaultNostrAccountId(cfg);
|
|
1027
|
+
const bus = activeBuses.get(aid);
|
|
1028
|
+
if (!bus) throw new Error(`Nostr bus not running for account ${aid}`);
|
|
1029
|
+
await bus.sendDm(id, message);
|
|
1199
1030
|
}
|
|
1200
1031
|
};
|
|
1201
1032
|
const nostrOutboundAdapter = {
|
|
@@ -1231,9 +1062,21 @@ const nostrOutboundAdapter = {
|
|
|
1231
1062
|
}
|
|
1232
1063
|
};
|
|
1233
1064
|
function getActiveNostrBuses() {
|
|
1234
|
-
return
|
|
1065
|
+
return activeBuses;
|
|
1066
|
+
}
|
|
1067
|
+
// extensions/nostr/src/channel.ts
|
|
1068
|
+
const NOSTR_TARGET_HINT = "<npub|hex pubkey|nostr:npub...>";
|
|
1069
|
+
function stripNostrTargetPrefix(target) {
|
|
1070
|
+
return target.trim().replace(/^nostr:/i, "");
|
|
1071
|
+
}
|
|
1072
|
+
function normalizeNostrTarget(target) {
|
|
1073
|
+
const cleaned = stripNostrTargetPrefix(target);
|
|
1074
|
+
try {
|
|
1075
|
+
return normalizePubkey(cleaned);
|
|
1076
|
+
} catch {
|
|
1077
|
+
return target.trim();
|
|
1078
|
+
}
|
|
1235
1079
|
}
|
|
1236
|
-
// extensions/nostr/src/session-route.ts
|
|
1237
1080
|
function resolveNostrOutboundSessionRoute(params) {
|
|
1238
1081
|
const rawTarget = stripChannelTargetPrefix(params.target, "nostr");
|
|
1239
1082
|
let target;
|
|
@@ -1257,27 +1100,6 @@ function resolveNostrOutboundSessionRoute(params) {
|
|
|
1257
1100
|
to: `nostr:${target}`
|
|
1258
1101
|
});
|
|
1259
1102
|
}
|
|
1260
|
-
// extensions/nostr/src/channel.ts
|
|
1261
|
-
const NOSTR_TARGET_HINT = "<npub|hex pubkey|nostr:npub...>";
|
|
1262
|
-
function stripNostrTargetPrefix(target) {
|
|
1263
|
-
return target.trim().replace(/^nostr:/i, "");
|
|
1264
|
-
}
|
|
1265
|
-
function normalizeNostrTarget(target) {
|
|
1266
|
-
const cleaned = stripNostrTargetPrefix(target);
|
|
1267
|
-
try {
|
|
1268
|
-
return normalizePubkey(cleaned);
|
|
1269
|
-
} catch {
|
|
1270
|
-
return target.trim();
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
function inferNostrTargetChatType(target) {
|
|
1274
|
-
try {
|
|
1275
|
-
normalizePubkey(stripNostrTargetPrefix(target));
|
|
1276
|
-
return "direct";
|
|
1277
|
-
} catch {
|
|
1278
|
-
return;
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
1103
|
const resolveNostrDmPolicy = createScopedDmSecurityResolver({
|
|
1282
1104
|
channelKey: "nostr",
|
|
1283
1105
|
resolvePolicy: (account) => account.config.dmPolicy,
|
|
@@ -1342,7 +1164,14 @@ const nostrPlugin = createChatChannelPlugin({
|
|
|
1342
1164
|
messaging: {
|
|
1343
1165
|
targetPrefixes: ["nostr"],
|
|
1344
1166
|
normalizeTarget: normalizeNostrTarget,
|
|
1345
|
-
inferTargetChatType: ({ to }) =>
|
|
1167
|
+
inferTargetChatType: ({ to }) => {
|
|
1168
|
+
try {
|
|
1169
|
+
normalizePubkey(stripNostrTargetPrefix(to));
|
|
1170
|
+
return "direct";
|
|
1171
|
+
} catch {
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1346
1175
|
targetResolver: {
|
|
1347
1176
|
looksLikeId: (input, normalized) => {
|
|
1348
1177
|
const trimmed = normalized?.trim() || stripNostrTargetPrefix(input);
|