@openclaw/nostr 2026.9.5 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{channel-ByGdjtr3.mjs → channel-D2d-FP8G.mjs} +116 -279
- package/dist/.setup/{config-schema-CkYd8ACn.mjs → config-schema-B3uU2qBS.mjs} +1 -3
- package/dist/.setup/setup-plugin-api-BhRAS2I1.mjs +2 -0
- package/dist/.setup/{setup-plugin-api-B7qtJE84.mjs → setup-plugin-api-Ci0XxWqb.mjs} +2 -1
- package/dist/api.js +34 -93
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +18 -130
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/zod/README.md +2 -2
- package/node_modules/zod/compile.cjs +19 -0
- package/node_modules/zod/index.cjs +19 -0
- package/node_modules/zod/locales/index.cjs +19 -0
- package/node_modules/zod/mini/index.cjs +19 -0
- package/node_modules/zod/package.json +8 -7
- package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
- package/node_modules/zod/src/v4/classic/external.ts +2 -0
- package/node_modules/zod/src/v4/classic/from-json-schema.ts +248 -25
- package/node_modules/zod/src/v4/classic/schemas.ts +243 -168
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +60 -9
- package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +6 -0
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
- package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +265 -0
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +112 -6
- package/node_modules/zod/src/v4/classic/tests/enum.test.ts +9 -0
- package/node_modules/zod/src/v4/classic/tests/error.test.ts +130 -1
- package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +157 -0
- package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +40 -2
- package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +27 -7
- package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +88 -56
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +39 -0
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +56 -0
- package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +3 -2
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
- package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +46 -1
- package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +95 -1
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +33 -1
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +234 -38
- package/node_modules/zod/src/v4/classic/tests/validate.test.ts +569 -0
- package/node_modules/zod/src/v4/core/api.ts +44 -28
- package/node_modules/zod/src/v4/core/checks.ts +62 -102
- package/node_modules/zod/src/v4/core/compile.ts +218 -93
- package/node_modules/zod/src/v4/core/core.ts +1 -3
- package/node_modules/zod/src/v4/core/doc.ts +6 -2
- package/node_modules/zod/src/v4/core/errors.ts +3 -6
- package/node_modules/zod/src/v4/core/json-schema-generator.ts +2 -2
- package/node_modules/zod/src/v4/core/json-schema-processors.ts +185 -81
- package/node_modules/zod/src/v4/core/memoizer.ts +75 -28
- package/node_modules/zod/src/v4/core/parse.ts +37 -16
- package/node_modules/zod/src/v4/core/regexes.ts +14 -4
- package/node_modules/zod/src/v4/core/schemas.ts +296 -132
- package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
- package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +35 -0
- package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
- package/node_modules/zod/src/v4/core/tests/compile.test.ts +399 -2
- package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
- package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
- package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
- package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +118 -16
- package/node_modules/zod/src/v4/core/to-json-schema.ts +9 -7
- package/node_modules/zod/src/v4/core/util.ts +218 -147
- package/node_modules/zod/src/v4/core/versions.ts +2 -2
- package/node_modules/zod/src/v4/locales/ar.ts +2 -0
- package/node_modules/zod/src/v4/locales/az.ts +2 -0
- package/node_modules/zod/src/v4/locales/be.ts +2 -0
- package/node_modules/zod/src/v4/locales/bg.ts +2 -0
- package/node_modules/zod/src/v4/locales/bn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ca.ts +2 -0
- package/node_modules/zod/src/v4/locales/ckb.ts +2 -0
- package/node_modules/zod/src/v4/locales/cs.ts +2 -0
- package/node_modules/zod/src/v4/locales/da.ts +2 -0
- package/node_modules/zod/src/v4/locales/de.ts +2 -0
- package/node_modules/zod/src/v4/locales/el.ts +2 -0
- package/node_modules/zod/src/v4/locales/en.ts +2 -0
- package/node_modules/zod/src/v4/locales/eo.ts +2 -0
- package/node_modules/zod/src/v4/locales/es.ts +2 -0
- package/node_modules/zod/src/v4/locales/fa.ts +2 -0
- package/node_modules/zod/src/v4/locales/fi.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr-CA.ts +2 -0
- package/node_modules/zod/src/v4/locales/fr.ts +2 -0
- package/node_modules/zod/src/v4/locales/gu.ts +2 -0
- package/node_modules/zod/src/v4/locales/he.ts +2 -0
- package/node_modules/zod/src/v4/locales/hi.ts +2 -0
- package/node_modules/zod/src/v4/locales/hr.ts +2 -0
- package/node_modules/zod/src/v4/locales/hu.ts +2 -0
- package/node_modules/zod/src/v4/locales/hy.ts +2 -0
- package/node_modules/zod/src/v4/locales/id.ts +2 -0
- package/node_modules/zod/src/v4/locales/index.ts +1 -0
- package/node_modules/zod/src/v4/locales/is.ts +2 -0
- package/node_modules/zod/src/v4/locales/it.ts +2 -0
- package/node_modules/zod/src/v4/locales/ja.ts +2 -0
- package/node_modules/zod/src/v4/locales/ka.ts +2 -0
- package/node_modules/zod/src/v4/locales/km.ts +2 -0
- package/node_modules/zod/src/v4/locales/kn.ts +2 -0
- package/node_modules/zod/src/v4/locales/ko.ts +2 -0
- package/node_modules/zod/src/v4/locales/lt.ts +2 -0
- package/node_modules/zod/src/v4/locales/mk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ms.ts +2 -0
- package/node_modules/zod/src/v4/locales/ne.ts +2 -0
- package/node_modules/zod/src/v4/locales/nl.ts +2 -0
- package/node_modules/zod/src/v4/locales/nn.ts +2 -0
- package/node_modules/zod/src/v4/locales/no.ts +2 -0
- package/node_modules/zod/src/v4/locales/ota.ts +2 -0
- package/node_modules/zod/src/v4/locales/pl.ts +2 -0
- package/node_modules/zod/src/v4/locales/ps.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt-BR.ts +2 -0
- package/node_modules/zod/src/v4/locales/pt.ts +2 -0
- package/node_modules/zod/src/v4/locales/ro.ts +2 -0
- package/node_modules/zod/src/v4/locales/ru.ts +2 -0
- package/node_modules/zod/src/v4/locales/sk.ts +2 -0
- package/node_modules/zod/src/v4/locales/sl.ts +2 -0
- package/node_modules/zod/src/v4/locales/sv.ts +2 -0
- package/node_modules/zod/src/v4/locales/ta.ts +2 -0
- package/node_modules/zod/src/v4/locales/tg.ts +135 -0
- package/node_modules/zod/src/v4/locales/th.ts +2 -0
- package/node_modules/zod/src/v4/locales/tk.ts +2 -0
- package/node_modules/zod/src/v4/locales/tr.ts +2 -0
- package/node_modules/zod/src/v4/locales/uk.ts +2 -0
- package/node_modules/zod/src/v4/locales/ur.ts +2 -0
- package/node_modules/zod/src/v4/locales/uz.ts +2 -0
- package/node_modules/zod/src/v4/locales/vi.ts +2 -0
- package/node_modules/zod/src/v4/locales/yo.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-CN.ts +2 -0
- package/node_modules/zod/src/v4/locales/zh-TW.ts +2 -0
- package/node_modules/zod/src/v4/mini/external.ts +2 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +32 -7
- package/node_modules/zod/src/v4/mini/tests/checks.test.ts +1 -1
- package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +86 -0
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +23 -0
- package/node_modules/zod/v3/ZodError.cjs +19 -0
- package/node_modules/zod/v3/errors.cjs +19 -0
- package/node_modules/zod/v3/external.cjs +19 -0
- package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
- package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
- package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
- package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
- package/node_modules/zod/v3/helpers/util.cjs +19 -0
- package/node_modules/zod/v3/index.cjs +19 -0
- package/node_modules/zod/v3/standard-schema.cjs +19 -0
- package/node_modules/zod/v3/types.cjs +19 -0
- package/node_modules/zod/v4/classic/checks.cjs +19 -0
- package/node_modules/zod/v4/classic/coerce.cjs +19 -0
- package/node_modules/zod/v4/classic/compat.cjs +19 -0
- package/node_modules/zod/v4/classic/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/classic/errors.cjs +19 -0
- package/node_modules/zod/v4/classic/external.cjs +22 -1
- package/node_modules/zod/v4/classic/external.d.cts +1 -1
- package/node_modules/zod/v4/classic/external.d.ts +1 -1
- package/node_modules/zod/v4/classic/external.js +1 -1
- package/node_modules/zod/v4/classic/from-json-schema.cjs +264 -24
- package/node_modules/zod/v4/classic/from-json-schema.js +245 -24
- package/node_modules/zod/v4/classic/in-out.cjs +19 -0
- package/node_modules/zod/v4/classic/index.cjs +19 -0
- package/node_modules/zod/v4/classic/iso.cjs +19 -0
- package/node_modules/zod/v4/classic/parse.cjs +19 -0
- package/node_modules/zod/v4/classic/schemas.cjs +100 -35
- package/node_modules/zod/v4/classic/schemas.d.cts +15 -1
- package/node_modules/zod/v4/classic/schemas.d.ts +15 -1
- package/node_modules/zod/v4/classic/schemas.js +77 -33
- package/node_modules/zod/v4/core/api.cjs +45 -22
- package/node_modules/zod/v4/core/api.d.cts +12 -6
- package/node_modules/zod/v4/core/api.d.ts +12 -6
- package/node_modules/zod/v4/core/api.js +25 -22
- package/node_modules/zod/v4/core/checks.cjs +51 -97
- package/node_modules/zod/v4/core/checks.d.cts +17 -1
- package/node_modules/zod/v4/core/checks.d.ts +17 -1
- package/node_modules/zod/v4/core/checks.js +31 -96
- package/node_modules/zod/v4/core/compile.cjs +173 -78
- package/node_modules/zod/v4/core/compile.d.cts +18 -4
- package/node_modules/zod/v4/core/compile.d.ts +18 -4
- package/node_modules/zod/v4/core/compile.js +154 -79
- package/node_modules/zod/v4/core/core.cjs +20 -1
- package/node_modules/zod/v4/core/core.js +1 -1
- package/node_modules/zod/v4/core/doc.cjs +26 -2
- package/node_modules/zod/v4/core/doc.js +7 -2
- package/node_modules/zod/v4/core/errors.cjs +21 -5
- package/node_modules/zod/v4/core/errors.js +2 -5
- package/node_modules/zod/v4/core/index.cjs +19 -0
- package/node_modules/zod/v4/core/json-schema-generator.cjs +20 -1
- package/node_modules/zod/v4/core/json-schema-generator.js +2 -2
- package/node_modules/zod/v4/core/json-schema-processors.cjs +188 -72
- package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
- package/node_modules/zod/v4/core/json-schema-processors.js +170 -74
- package/node_modules/zod/v4/core/json-schema.cjs +19 -0
- package/node_modules/zod/v4/core/memoizer.cjs +111 -23
- package/node_modules/zod/v4/core/memoizer.js +69 -23
- package/node_modules/zod/v4/core/parse.cjs +56 -16
- package/node_modules/zod/v4/core/parse.js +37 -16
- package/node_modules/zod/v4/core/regexes.cjs +31 -6
- package/node_modules/zod/v4/core/regexes.d.cts +3 -0
- package/node_modules/zod/v4/core/regexes.d.ts +3 -0
- package/node_modules/zod/v4/core/regexes.js +10 -4
- package/node_modules/zod/v4/core/registries.cjs +19 -0
- package/node_modules/zod/v4/core/schemas.cjs +302 -114
- package/node_modules/zod/v4/core/schemas.d.cts +28 -8
- package/node_modules/zod/v4/core/schemas.d.ts +28 -8
- package/node_modules/zod/v4/core/schemas.js +279 -113
- package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
- package/node_modules/zod/v4/core/to-json-schema.cjs +28 -7
- package/node_modules/zod/v4/core/to-json-schema.d.cts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.d.ts +4 -3
- package/node_modules/zod/v4/core/to-json-schema.js +7 -6
- package/node_modules/zod/v4/core/util.cjs +177 -143
- package/node_modules/zod/v4/core/util.d.cts +25 -4
- package/node_modules/zod/v4/core/util.d.ts +25 -4
- package/node_modules/zod/v4/core/util.js +156 -143
- package/node_modules/zod/v4/core/versions.cjs +21 -2
- package/node_modules/zod/v4/core/versions.d.cts +1 -1
- package/node_modules/zod/v4/core/versions.d.ts +1 -1
- package/node_modules/zod/v4/core/versions.js +2 -2
- package/node_modules/zod/v4/core/visit.cjs +19 -0
- package/node_modules/zod/v4/index.cjs +19 -0
- package/node_modules/zod/v4/locales/ar.cjs +2 -0
- package/node_modules/zod/v4/locales/ar.js +2 -0
- package/node_modules/zod/v4/locales/az.cjs +2 -0
- package/node_modules/zod/v4/locales/az.js +2 -0
- package/node_modules/zod/v4/locales/be.cjs +2 -0
- package/node_modules/zod/v4/locales/be.js +2 -0
- package/node_modules/zod/v4/locales/bg.cjs +2 -0
- package/node_modules/zod/v4/locales/bg.js +2 -0
- package/node_modules/zod/v4/locales/bn.cjs +2 -0
- package/node_modules/zod/v4/locales/bn.js +2 -0
- package/node_modules/zod/v4/locales/ca.cjs +2 -0
- package/node_modules/zod/v4/locales/ca.js +2 -0
- package/node_modules/zod/v4/locales/ckb.cjs +2 -0
- package/node_modules/zod/v4/locales/ckb.js +2 -0
- package/node_modules/zod/v4/locales/cs.cjs +2 -0
- package/node_modules/zod/v4/locales/cs.js +2 -0
- package/node_modules/zod/v4/locales/da.cjs +2 -0
- package/node_modules/zod/v4/locales/da.js +2 -0
- package/node_modules/zod/v4/locales/de.cjs +2 -0
- package/node_modules/zod/v4/locales/de.js +2 -0
- package/node_modules/zod/v4/locales/el.cjs +2 -0
- package/node_modules/zod/v4/locales/el.js +2 -0
- package/node_modules/zod/v4/locales/en.cjs +2 -0
- package/node_modules/zod/v4/locales/en.js +2 -0
- package/node_modules/zod/v4/locales/eo.cjs +2 -0
- package/node_modules/zod/v4/locales/eo.js +2 -0
- package/node_modules/zod/v4/locales/es.cjs +2 -0
- package/node_modules/zod/v4/locales/es.js +2 -0
- package/node_modules/zod/v4/locales/fa.cjs +2 -0
- package/node_modules/zod/v4/locales/fa.js +2 -0
- package/node_modules/zod/v4/locales/fi.cjs +2 -0
- package/node_modules/zod/v4/locales/fi.js +2 -0
- package/node_modules/zod/v4/locales/fr-CA.cjs +2 -0
- package/node_modules/zod/v4/locales/fr-CA.js +2 -0
- package/node_modules/zod/v4/locales/fr.cjs +2 -0
- package/node_modules/zod/v4/locales/fr.js +2 -0
- package/node_modules/zod/v4/locales/gu.cjs +2 -0
- package/node_modules/zod/v4/locales/gu.js +2 -0
- package/node_modules/zod/v4/locales/he.cjs +2 -0
- package/node_modules/zod/v4/locales/he.js +2 -0
- package/node_modules/zod/v4/locales/hi.cjs +2 -0
- package/node_modules/zod/v4/locales/hi.js +2 -0
- package/node_modules/zod/v4/locales/hr.cjs +2 -0
- package/node_modules/zod/v4/locales/hr.js +2 -0
- package/node_modules/zod/v4/locales/hu.cjs +2 -0
- package/node_modules/zod/v4/locales/hu.js +2 -0
- package/node_modules/zod/v4/locales/hy.cjs +2 -0
- package/node_modules/zod/v4/locales/hy.js +2 -0
- package/node_modules/zod/v4/locales/id.cjs +2 -0
- package/node_modules/zod/v4/locales/id.js +2 -0
- package/node_modules/zod/v4/locales/index.cjs +22 -1
- package/node_modules/zod/v4/locales/index.d.cts +1 -0
- package/node_modules/zod/v4/locales/index.d.ts +1 -0
- package/node_modules/zod/v4/locales/index.js +1 -0
- package/node_modules/zod/v4/locales/is.cjs +2 -0
- package/node_modules/zod/v4/locales/is.js +2 -0
- package/node_modules/zod/v4/locales/it.cjs +2 -0
- package/node_modules/zod/v4/locales/it.js +2 -0
- package/node_modules/zod/v4/locales/ja.cjs +2 -0
- package/node_modules/zod/v4/locales/ja.js +2 -0
- package/node_modules/zod/v4/locales/ka.cjs +2 -0
- package/node_modules/zod/v4/locales/ka.js +2 -0
- package/node_modules/zod/v4/locales/km.cjs +2 -0
- package/node_modules/zod/v4/locales/km.js +2 -0
- package/node_modules/zod/v4/locales/kn.cjs +2 -0
- package/node_modules/zod/v4/locales/kn.js +2 -0
- package/node_modules/zod/v4/locales/ko.cjs +2 -0
- package/node_modules/zod/v4/locales/ko.js +2 -0
- package/node_modules/zod/v4/locales/lt.cjs +2 -0
- package/node_modules/zod/v4/locales/lt.js +2 -0
- package/node_modules/zod/v4/locales/mk.cjs +2 -0
- package/node_modules/zod/v4/locales/mk.js +2 -0
- package/node_modules/zod/v4/locales/ms.cjs +2 -0
- package/node_modules/zod/v4/locales/ms.js +2 -0
- package/node_modules/zod/v4/locales/ne.cjs +2 -0
- package/node_modules/zod/v4/locales/ne.js +2 -0
- package/node_modules/zod/v4/locales/nl.cjs +2 -0
- package/node_modules/zod/v4/locales/nl.js +2 -0
- package/node_modules/zod/v4/locales/nn.cjs +2 -0
- package/node_modules/zod/v4/locales/nn.js +2 -0
- package/node_modules/zod/v4/locales/no.cjs +2 -0
- package/node_modules/zod/v4/locales/no.js +2 -0
- package/node_modules/zod/v4/locales/ota.cjs +2 -0
- package/node_modules/zod/v4/locales/ota.js +2 -0
- package/node_modules/zod/v4/locales/pl.cjs +2 -0
- package/node_modules/zod/v4/locales/pl.js +2 -0
- package/node_modules/zod/v4/locales/ps.cjs +2 -0
- package/node_modules/zod/v4/locales/ps.js +2 -0
- package/node_modules/zod/v4/locales/pt-BR.cjs +2 -0
- package/node_modules/zod/v4/locales/pt-BR.js +2 -0
- package/node_modules/zod/v4/locales/pt.cjs +2 -0
- package/node_modules/zod/v4/locales/pt.js +2 -0
- package/node_modules/zod/v4/locales/ro.cjs +2 -0
- package/node_modules/zod/v4/locales/ro.js +2 -0
- package/node_modules/zod/v4/locales/ru.cjs +2 -0
- package/node_modules/zod/v4/locales/ru.js +2 -0
- package/node_modules/zod/v4/locales/sk.cjs +2 -0
- package/node_modules/zod/v4/locales/sk.js +2 -0
- package/node_modules/zod/v4/locales/sl.cjs +2 -0
- package/node_modules/zod/v4/locales/sl.js +2 -0
- package/node_modules/zod/v4/locales/sv.cjs +2 -0
- package/node_modules/zod/v4/locales/sv.js +2 -0
- package/node_modules/zod/v4/locales/ta.cjs +2 -0
- package/node_modules/zod/v4/locales/ta.js +2 -0
- package/node_modules/zod/v4/locales/tg.cjs +144 -0
- package/node_modules/zod/v4/locales/tg.d.cts +5 -0
- package/node_modules/zod/v4/locales/tg.d.ts +4 -0
- package/node_modules/zod/v4/locales/tg.js +117 -0
- package/node_modules/zod/v4/locales/th.cjs +2 -0
- package/node_modules/zod/v4/locales/th.js +2 -0
- package/node_modules/zod/v4/locales/tk.cjs +2 -0
- package/node_modules/zod/v4/locales/tk.js +2 -0
- package/node_modules/zod/v4/locales/tr.cjs +2 -0
- package/node_modules/zod/v4/locales/tr.js +2 -0
- package/node_modules/zod/v4/locales/uk.cjs +2 -0
- package/node_modules/zod/v4/locales/uk.js +2 -0
- package/node_modules/zod/v4/locales/ur.cjs +2 -0
- package/node_modules/zod/v4/locales/ur.js +2 -0
- package/node_modules/zod/v4/locales/uz.cjs +2 -0
- package/node_modules/zod/v4/locales/uz.js +2 -0
- package/node_modules/zod/v4/locales/vi.cjs +2 -0
- package/node_modules/zod/v4/locales/vi.js +2 -0
- package/node_modules/zod/v4/locales/yo.cjs +2 -0
- package/node_modules/zod/v4/locales/yo.js +2 -0
- package/node_modules/zod/v4/locales/zh-CN.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-CN.js +2 -0
- package/node_modules/zod/v4/locales/zh-TW.cjs +2 -0
- package/node_modules/zod/v4/locales/zh-TW.js +2 -0
- package/node_modules/zod/v4/mini/checks.cjs +19 -0
- package/node_modules/zod/v4/mini/coerce.cjs +19 -0
- package/node_modules/zod/v4/mini/deep-partial.cjs +19 -0
- package/node_modules/zod/v4/mini/external.cjs +22 -1
- package/node_modules/zod/v4/mini/external.d.cts +1 -1
- package/node_modules/zod/v4/mini/external.d.ts +1 -1
- package/node_modules/zod/v4/mini/external.js +1 -1
- package/node_modules/zod/v4/mini/in-out.cjs +19 -0
- package/node_modules/zod/v4/mini/index.cjs +19 -0
- package/node_modules/zod/v4/mini/iso.cjs +19 -0
- package/node_modules/zod/v4/mini/parse.cjs +19 -0
- package/node_modules/zod/v4/mini/schemas.cjs +44 -8
- package/node_modules/zod/v4/mini/schemas.d.cts +6 -1
- package/node_modules/zod/v4/mini/schemas.d.ts +6 -1
- package/node_modules/zod/v4/mini/schemas.js +21 -6
- package/node_modules/zod/v4-mini/index.cjs +19 -0
- package/package.json +5 -5
- package/dist/.setup/inbound-direct-dm-runtime-DHn9NoYN.mjs +0 -2
- package/dist/.setup/setup-plugin-api-B7i5rR6T.mjs +0 -2
- package/dist/.setup/state-account-id-CvBZ9s6P.mjs +0 -8
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { a as listNostrAccountIds, c as normalizePubkey, n as nostrSetupContract, o as resolveDefaultNostrAccountId, r as nostrSetupWizard, s as resolveNostrAccount } from "./setup-surface-Dx8QxWSP.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { n as NostrProfileSchema, t as NostrConfigSchema } from "./config-schema-B3uU2qBS.mjs";
|
|
3
3
|
import { c as validatePrivateKey, l as DEFAULT_RELAYS } from "./setup-adapter-KJ_iGKiG.mjs";
|
|
4
|
-
import { t as normalizeNostrStateAccountId } from "./state-account-id-CvBZ9s6P.mjs";
|
|
5
4
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
6
5
|
import { createScopedDmSecurityResolver, createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
7
6
|
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
8
7
|
import { missingTargetError } from "openclaw/plugin-sdk/channel-feedback";
|
|
9
8
|
import { DEFAULT_INGRESS_ADOPTION_STALL_MS, bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageAdapterFromOutbound, runPassiveAccountLifecycle } from "openclaw/plugin-sdk/channel-outbound";
|
|
9
|
+
import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, formatPairingApproveHint } from "openclaw/plugin-sdk/channel-plugin-common";
|
|
10
10
|
import { buildPassiveChannelStatusSummary, buildTrafficStatusSummary } from "openclaw/plugin-sdk/extension-shared";
|
|
11
|
-
import { createComputedAccountStatusAdapter } from "openclaw/plugin-sdk/status-helpers";
|
|
12
|
-
import { isRecord
|
|
13
|
-
import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
11
|
+
import { collectStatusIssuesFromLastError, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
12
|
+
import { isRecord, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
14
13
|
import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
|
|
15
14
|
import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
16
15
|
import { channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
@@ -23,6 +22,7 @@ import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
|
|
|
23
22
|
import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
24
23
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
25
24
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
25
|
+
import { withTimeout } from "openclaw/plugin-sdk/time-runtime";
|
|
26
26
|
import { buildChannelOutboundSessionRoute, stripChannelTargetPrefix } from "openclaw/plugin-sdk/core";
|
|
27
27
|
//#region extensions/nostr/src/metrics.ts
|
|
28
28
|
function createZeroMetricsState() {
|
|
@@ -103,118 +103,59 @@ function createMetrics(onMetric) {
|
|
|
103
103
|
}
|
|
104
104
|
return relay;
|
|
105
105
|
}
|
|
106
|
+
const relayMetric = (update) => (value, relayUrl) => {
|
|
107
|
+
if (relayUrl) update(getOrCreateRelay(relayUrl), value);
|
|
108
|
+
};
|
|
109
|
+
const updates = /* @__PURE__ */ new Map([
|
|
110
|
+
["event.received", (value) => state.eventsReceived += value],
|
|
111
|
+
["event.processed", (value) => state.eventsProcessed += value],
|
|
112
|
+
["event.duplicate", (value) => state.eventsDuplicate += value],
|
|
113
|
+
["event.rejected.invalid_shape", (value) => state.eventsRejected.invalidShape += value],
|
|
114
|
+
["event.rejected.wrong_kind", (value) => state.eventsRejected.wrongKind += value],
|
|
115
|
+
["event.rejected.stale", (value) => state.eventsRejected.stale += value],
|
|
116
|
+
["event.rejected.future", (value) => state.eventsRejected.future += value],
|
|
117
|
+
["event.rejected.rate_limited", (value) => state.eventsRejected.rateLimited += value],
|
|
118
|
+
["event.rejected.invalid_signature", (value) => state.eventsRejected.invalidSignature += value],
|
|
119
|
+
["event.rejected.oversized_ciphertext", (value) => state.eventsRejected.oversizedCiphertext += value],
|
|
120
|
+
["event.rejected.oversized_plaintext", (value) => state.eventsRejected.oversizedPlaintext += value],
|
|
121
|
+
["event.rejected.decrypt_failed", (value) => state.eventsRejected.decryptFailed += value],
|
|
122
|
+
["event.rejected.self_message", (value) => state.eventsRejected.selfMessage += value],
|
|
123
|
+
["rate_limit.per_sender", (value) => state.rateLimiting.perSenderHits += value],
|
|
124
|
+
["rate_limit.global", (value) => state.rateLimiting.globalHits += value],
|
|
125
|
+
["decrypt.success", (value) => state.decrypt.success += value],
|
|
126
|
+
["decrypt.failure", (value) => state.decrypt.failure += value],
|
|
127
|
+
["memory.seen_tracker_size", (value) => state.memory.seenTrackerSize = value],
|
|
128
|
+
["memory.rate_limiter_entries", (value) => state.memory.rateLimiterEntries = value],
|
|
129
|
+
["relay.connect", relayMetric((relay, value) => relay.connects += value)],
|
|
130
|
+
["relay.disconnect", relayMetric((relay, value) => relay.disconnects += value)],
|
|
131
|
+
["relay.reconnect", relayMetric((relay, value) => relay.reconnects += value)],
|
|
132
|
+
["relay.error", relayMetric((relay, value) => relay.errors += value)],
|
|
133
|
+
["relay.message.event", relayMetric((relay, value) => relay.messagesReceived.event += value)],
|
|
134
|
+
["relay.message.eose", relayMetric((relay, value) => relay.messagesReceived.eose += value)],
|
|
135
|
+
["relay.message.closed", relayMetric((relay, value) => relay.messagesReceived.closed += value)],
|
|
136
|
+
["relay.message.notice", relayMetric((relay, value) => relay.messagesReceived.notice += value)],
|
|
137
|
+
["relay.message.ok", relayMetric((relay, value) => relay.messagesReceived.ok += value)],
|
|
138
|
+
["relay.message.auth", relayMetric((relay, value) => relay.messagesReceived.auth += value)],
|
|
139
|
+
["relay.circuit_breaker.open", relayMetric((relay, value) => {
|
|
140
|
+
relay.circuitBreakerState = "open";
|
|
141
|
+
relay.circuitBreakerOpens += value;
|
|
142
|
+
})],
|
|
143
|
+
["relay.circuit_breaker.close", relayMetric((relay, value) => {
|
|
144
|
+
relay.circuitBreakerState = "closed";
|
|
145
|
+
relay.circuitBreakerCloses += value;
|
|
146
|
+
})],
|
|
147
|
+
["relay.circuit_breaker.half_open", relayMetric((relay) => {
|
|
148
|
+
relay.circuitBreakerState = "half_open";
|
|
149
|
+
})]
|
|
150
|
+
]);
|
|
106
151
|
function emit(name, value = 1, labels) {
|
|
107
|
-
|
|
152
|
+
onMetric?.({
|
|
108
153
|
name,
|
|
109
154
|
value,
|
|
110
155
|
timestamp: Date.now(),
|
|
111
156
|
labels
|
|
112
157
|
});
|
|
113
|
-
|
|
114
|
-
switch (name) {
|
|
115
|
-
case "event.received":
|
|
116
|
-
state.eventsReceived += value;
|
|
117
|
-
break;
|
|
118
|
-
case "event.processed":
|
|
119
|
-
state.eventsProcessed += value;
|
|
120
|
-
break;
|
|
121
|
-
case "event.duplicate":
|
|
122
|
-
state.eventsDuplicate += value;
|
|
123
|
-
break;
|
|
124
|
-
case "event.rejected.invalid_shape":
|
|
125
|
-
state.eventsRejected.invalidShape += value;
|
|
126
|
-
break;
|
|
127
|
-
case "event.rejected.wrong_kind":
|
|
128
|
-
state.eventsRejected.wrongKind += value;
|
|
129
|
-
break;
|
|
130
|
-
case "event.rejected.stale":
|
|
131
|
-
state.eventsRejected.stale += value;
|
|
132
|
-
break;
|
|
133
|
-
case "event.rejected.future":
|
|
134
|
-
state.eventsRejected.future += value;
|
|
135
|
-
break;
|
|
136
|
-
case "event.rejected.rate_limited":
|
|
137
|
-
state.eventsRejected.rateLimited += value;
|
|
138
|
-
break;
|
|
139
|
-
case "event.rejected.invalid_signature":
|
|
140
|
-
state.eventsRejected.invalidSignature += value;
|
|
141
|
-
break;
|
|
142
|
-
case "event.rejected.oversized_ciphertext":
|
|
143
|
-
state.eventsRejected.oversizedCiphertext += value;
|
|
144
|
-
break;
|
|
145
|
-
case "event.rejected.oversized_plaintext":
|
|
146
|
-
state.eventsRejected.oversizedPlaintext += value;
|
|
147
|
-
break;
|
|
148
|
-
case "event.rejected.decrypt_failed":
|
|
149
|
-
state.eventsRejected.decryptFailed += value;
|
|
150
|
-
break;
|
|
151
|
-
case "event.rejected.self_message":
|
|
152
|
-
state.eventsRejected.selfMessage += value;
|
|
153
|
-
break;
|
|
154
|
-
case "relay.connect":
|
|
155
|
-
if (relayUrl) getOrCreateRelay(relayUrl).connects += value;
|
|
156
|
-
break;
|
|
157
|
-
case "relay.disconnect":
|
|
158
|
-
if (relayUrl) getOrCreateRelay(relayUrl).disconnects += value;
|
|
159
|
-
break;
|
|
160
|
-
case "relay.reconnect":
|
|
161
|
-
if (relayUrl) getOrCreateRelay(relayUrl).reconnects += value;
|
|
162
|
-
break;
|
|
163
|
-
case "relay.error":
|
|
164
|
-
if (relayUrl) getOrCreateRelay(relayUrl).errors += value;
|
|
165
|
-
break;
|
|
166
|
-
case "relay.message.event":
|
|
167
|
-
if (relayUrl) getOrCreateRelay(relayUrl).messagesReceived.event += value;
|
|
168
|
-
break;
|
|
169
|
-
case "relay.message.eose":
|
|
170
|
-
if (relayUrl) getOrCreateRelay(relayUrl).messagesReceived.eose += value;
|
|
171
|
-
break;
|
|
172
|
-
case "relay.message.closed":
|
|
173
|
-
if (relayUrl) getOrCreateRelay(relayUrl).messagesReceived.closed += value;
|
|
174
|
-
break;
|
|
175
|
-
case "relay.message.notice":
|
|
176
|
-
if (relayUrl) getOrCreateRelay(relayUrl).messagesReceived.notice += value;
|
|
177
|
-
break;
|
|
178
|
-
case "relay.message.ok":
|
|
179
|
-
if (relayUrl) getOrCreateRelay(relayUrl).messagesReceived.ok += value;
|
|
180
|
-
break;
|
|
181
|
-
case "relay.message.auth":
|
|
182
|
-
if (relayUrl) getOrCreateRelay(relayUrl).messagesReceived.auth += value;
|
|
183
|
-
break;
|
|
184
|
-
case "relay.circuit_breaker.open":
|
|
185
|
-
if (relayUrl) {
|
|
186
|
-
const r = getOrCreateRelay(relayUrl);
|
|
187
|
-
r.circuitBreakerState = "open";
|
|
188
|
-
r.circuitBreakerOpens += value;
|
|
189
|
-
}
|
|
190
|
-
break;
|
|
191
|
-
case "relay.circuit_breaker.close":
|
|
192
|
-
if (relayUrl) {
|
|
193
|
-
const r = getOrCreateRelay(relayUrl);
|
|
194
|
-
r.circuitBreakerState = "closed";
|
|
195
|
-
r.circuitBreakerCloses += value;
|
|
196
|
-
}
|
|
197
|
-
break;
|
|
198
|
-
case "relay.circuit_breaker.half_open":
|
|
199
|
-
if (relayUrl) getOrCreateRelay(relayUrl).circuitBreakerState = "half_open";
|
|
200
|
-
break;
|
|
201
|
-
case "rate_limit.per_sender":
|
|
202
|
-
state.rateLimiting.perSenderHits += value;
|
|
203
|
-
break;
|
|
204
|
-
case "rate_limit.global":
|
|
205
|
-
state.rateLimiting.globalHits += value;
|
|
206
|
-
break;
|
|
207
|
-
case "decrypt.success":
|
|
208
|
-
state.decrypt.success += value;
|
|
209
|
-
break;
|
|
210
|
-
case "decrypt.failure":
|
|
211
|
-
state.decrypt.failure += value;
|
|
212
|
-
break;
|
|
213
|
-
case "memory.seen_tracker_size":
|
|
214
|
-
state.memory.seenTrackerSize = value;
|
|
215
|
-
break;
|
|
216
|
-
case "memory.rate_limiter_entries": state.memory.rateLimiterEntries = value;
|
|
217
|
-
}
|
|
158
|
+
updates.get(name)?.(value, labels?.relay);
|
|
218
159
|
}
|
|
219
160
|
function getSnapshot() {
|
|
220
161
|
return createMetricsSnapshot(state);
|
|
@@ -384,7 +325,7 @@ function requiredString(value, field) {
|
|
|
384
325
|
throw new NostrIngressPermanentError("invalid-event", `Nostr event is missing ${field}.`);
|
|
385
326
|
}
|
|
386
327
|
function inspectNostrIngressEvent(event) {
|
|
387
|
-
if (!
|
|
328
|
+
if (!isRecord(event)) throw new NostrIngressPermanentError("invalid-event", "Nostr event must be an object.");
|
|
388
329
|
return {
|
|
389
330
|
eventId: requiredString(event.id, "id"),
|
|
390
331
|
laneKey: `direct:${requiredString(event.pubkey, "pubkey")}`
|
|
@@ -433,8 +374,7 @@ function deserializeNostrIngressEvent(rawEvent, claimedId) {
|
|
|
433
374
|
} catch (error) {
|
|
434
375
|
throw new NostrIngressPermanentError("invalid-event", `Nostr ingress row ${claimedId} contains invalid JSON.`, { cause: error });
|
|
435
376
|
}
|
|
436
|
-
if (!
|
|
437
|
-
if (typeof parsed.kind !== "number" || typeof parsed.created_at !== "number" || typeof parsed.content !== "string" || typeof parsed.sig !== "string" || !Array.isArray(parsed.tags)) throw new NostrIngressPermanentError("invalid-event", `Nostr ingress row ${claimedId} has an invalid event shape.`);
|
|
377
|
+
if (!isRecord(parsed) || typeof parsed.kind !== "number" || typeof parsed.created_at !== "number" || typeof parsed.content !== "string" || typeof parsed.sig !== "string" || !Array.isArray(parsed.tags)) throw new NostrIngressPermanentError("invalid-event", `Nostr ingress row ${claimedId} has an invalid event shape.`);
|
|
438
378
|
return parsed;
|
|
439
379
|
}
|
|
440
380
|
function createNostrIngress(options) {
|
|
@@ -482,7 +422,7 @@ function createNostrIngress(options) {
|
|
|
482
422
|
},
|
|
483
423
|
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.`)
|
|
484
424
|
},
|
|
485
|
-
deliver:
|
|
425
|
+
deliver: options.deliver,
|
|
486
426
|
pollIntervalMs: options.pollIntervalMs ?? NOSTR_INGRESS_POLL_INTERVAL_MS,
|
|
487
427
|
retention: {
|
|
488
428
|
completedMaxEntries: 1e5,
|
|
@@ -612,6 +552,16 @@ function createNostrIngress(options) {
|
|
|
612
552
|
}
|
|
613
553
|
//#endregion
|
|
614
554
|
//#region extensions/nostr/src/nostr-profile-core.ts
|
|
555
|
+
const PROFILE_FIELDS = [
|
|
556
|
+
["name", "name"],
|
|
557
|
+
["displayName", "display_name"],
|
|
558
|
+
["about", "about"],
|
|
559
|
+
["picture", "picture"],
|
|
560
|
+
["banner", "banner"],
|
|
561
|
+
["website", "website"],
|
|
562
|
+
["nip05", "nip05"],
|
|
563
|
+
["lud16", "lud16"]
|
|
564
|
+
];
|
|
615
565
|
/**
|
|
616
566
|
* Convert our config profile schema to NIP-01 content format.
|
|
617
567
|
* Strips undefined fields and validates URLs.
|
|
@@ -619,14 +569,10 @@ function createNostrIngress(options) {
|
|
|
619
569
|
function profileToContent(profile) {
|
|
620
570
|
const validated = NostrProfileSchema.parse(profile);
|
|
621
571
|
const content = {};
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
if (validated.banner !== void 0) content.banner = validated.banner;
|
|
627
|
-
if (validated.website !== void 0) content.website = validated.website;
|
|
628
|
-
if (validated.nip05 !== void 0) content.nip05 = validated.nip05;
|
|
629
|
-
if (validated.lud16 !== void 0) content.lud16 = validated.lud16;
|
|
572
|
+
for (const [configKey, contentKey] of PROFILE_FIELDS) {
|
|
573
|
+
const value = validated[configKey];
|
|
574
|
+
if (value !== void 0) content[contentKey] = value;
|
|
575
|
+
}
|
|
630
576
|
return content;
|
|
631
577
|
}
|
|
632
578
|
/**
|
|
@@ -635,76 +581,36 @@ function profileToContent(profile) {
|
|
|
635
581
|
*/
|
|
636
582
|
function contentToProfile(content) {
|
|
637
583
|
const profile = {};
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
if (content.banner !== void 0) profile.banner = content.banner;
|
|
643
|
-
if (content.website !== void 0) profile.website = content.website;
|
|
644
|
-
if (content.nip05 !== void 0) profile.nip05 = content.nip05;
|
|
645
|
-
if (content.lud16 !== void 0) profile.lud16 = content.lud16;
|
|
584
|
+
for (const [configKey, contentKey] of PROFILE_FIELDS) {
|
|
585
|
+
const value = content[contentKey];
|
|
586
|
+
if (value !== void 0) profile[configKey] = value;
|
|
587
|
+
}
|
|
646
588
|
return profile;
|
|
647
589
|
}
|
|
648
590
|
//#endregion
|
|
649
591
|
//#region extensions/nostr/src/nostr-profile.ts
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
* This module handles profile event creation and publishing.
|
|
655
|
-
*/
|
|
656
|
-
/**
|
|
657
|
-
* Create a signed kind:0 profile event.
|
|
658
|
-
*
|
|
659
|
-
* @param sk - Private key as Uint8Array (32 bytes)
|
|
660
|
-
* @param profile - Profile data to include
|
|
661
|
-
* @param lastPublishedAt - Previous profile timestamp (for monotonic guarantee)
|
|
662
|
-
* @returns Signed Nostr event
|
|
663
|
-
*/
|
|
664
|
-
function createProfileEvent(sk, profile, lastPublishedAt) {
|
|
665
|
-
const content = profileToContent(profile);
|
|
666
|
-
const contentJson = JSON.stringify(content);
|
|
592
|
+
const RELAY_PUBLISH_TIMEOUT_MS = 5e3;
|
|
593
|
+
/** Publish one signed kind:0 event, reporting each relay's result without retrying. */
|
|
594
|
+
async function publishProfile(pool, sk, relays, profile, lastPublishedAt) {
|
|
595
|
+
const content = JSON.stringify(profileToContent(profile));
|
|
667
596
|
const now = Math.floor(Date.now() / 1e3);
|
|
668
|
-
const
|
|
669
|
-
return finalizeEvent({
|
|
597
|
+
const event = finalizeEvent({
|
|
670
598
|
kind: 0,
|
|
671
|
-
content
|
|
599
|
+
content,
|
|
672
600
|
tags: [],
|
|
673
|
-
created_at:
|
|
601
|
+
created_at: lastPublishedAt !== void 0 ? Math.max(now, lastPublishedAt + 1) : now
|
|
674
602
|
}, sk);
|
|
675
|
-
}
|
|
676
|
-
/** Per-relay publish timeout (ms) */
|
|
677
|
-
const RELAY_PUBLISH_TIMEOUT_MS = 5e3;
|
|
678
|
-
/**
|
|
679
|
-
* Publish a profile event to multiple relays.
|
|
680
|
-
*
|
|
681
|
-
* Best-effort: publishes to all relays in parallel, reports per-relay results.
|
|
682
|
-
* Does NOT retry automatically - caller should handle retries if needed.
|
|
683
|
-
*
|
|
684
|
-
* @param pool - SimplePool instance for relay connections
|
|
685
|
-
* @param relays - Array of relay WebSocket URLs
|
|
686
|
-
* @param event - Signed profile event (kind:0)
|
|
687
|
-
* @returns Publish results with successes and failures
|
|
688
|
-
*/
|
|
689
|
-
async function publishProfileEvent(pool, relays, event) {
|
|
690
603
|
const successes = [];
|
|
691
604
|
const failures = [];
|
|
692
605
|
const publishPromises = relays.map(async (relay) => {
|
|
693
|
-
let timer;
|
|
694
606
|
try {
|
|
695
|
-
|
|
696
|
-
timer = setTimeout(() => reject(/* @__PURE__ */ new Error("timeout")), RELAY_PUBLISH_TIMEOUT_MS);
|
|
697
|
-
});
|
|
698
|
-
await Promise.race([pool.publish([relay], event)[0], timeoutPromise]);
|
|
607
|
+
await withTimeout(Promise.resolve(pool.publish([relay], event)[0]), RELAY_PUBLISH_TIMEOUT_MS, { message: "timeout" });
|
|
699
608
|
successes.push(relay);
|
|
700
609
|
} catch (err) {
|
|
701
|
-
const errorMessage = formatErrorMessage(err);
|
|
702
610
|
failures.push({
|
|
703
611
|
relay,
|
|
704
|
-
error:
|
|
612
|
+
error: formatErrorMessage(err)
|
|
705
613
|
});
|
|
706
|
-
} finally {
|
|
707
|
-
if (timer) clearTimeout(timer);
|
|
708
614
|
}
|
|
709
615
|
});
|
|
710
616
|
await Promise.all(publishPromises);
|
|
@@ -715,19 +621,6 @@ async function publishProfileEvent(pool, relays, event) {
|
|
|
715
621
|
createdAt: event.created_at
|
|
716
622
|
};
|
|
717
623
|
}
|
|
718
|
-
/**
|
|
719
|
-
* Create and publish a profile event in one call.
|
|
720
|
-
*
|
|
721
|
-
* @param pool - SimplePool instance
|
|
722
|
-
* @param sk - Private key as Uint8Array
|
|
723
|
-
* @param relays - Array of relay URLs
|
|
724
|
-
* @param profile - Profile data
|
|
725
|
-
* @param lastPublishedAt - Previous timestamp for monotonic ordering
|
|
726
|
-
* @returns Publish results
|
|
727
|
-
*/
|
|
728
|
-
async function publishProfile(pool, sk, relays, profile, lastPublishedAt) {
|
|
729
|
-
return publishProfileEvent(pool, relays, createProfileEvent(sk, profile, lastPublishedAt));
|
|
730
|
-
}
|
|
731
624
|
//#endregion
|
|
732
625
|
//#region extensions/nostr/src/nostr-relay-subscription.ts
|
|
733
626
|
const DEFAULT_EOSE_CONFIRM_DEADLINE_MS = 1e4;
|
|
@@ -793,6 +686,13 @@ function createNostrRelaySubscriptionGroup(options) {
|
|
|
793
686
|
};
|
|
794
687
|
}
|
|
795
688
|
//#endregion
|
|
689
|
+
//#region extensions/nostr/src/state-account-id.ts
|
|
690
|
+
function normalizeNostrStateAccountId(accountId) {
|
|
691
|
+
const trimmed = accountId?.trim();
|
|
692
|
+
if (!trimmed) return "default";
|
|
693
|
+
return trimmed.replace(/[^a-z0-9._-]+/gi, "_");
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
796
696
|
//#region extensions/nostr/src/nostr-state-store.ts
|
|
797
697
|
const STORE_VERSION = 2;
|
|
798
698
|
const PROFILE_STATE_VERSION = 1;
|
|
@@ -851,22 +751,19 @@ const STARTUP_LOOKBACK_SEC = 120;
|
|
|
851
751
|
const STATE_PERSIST_DEBOUNCE_MS = 5e3;
|
|
852
752
|
const NOSTR_INGRESS_ENVELOPE_OVERHEAD_BYTES = 16384;
|
|
853
753
|
const NOSTR_INGRESS_MAX_PENDING_EVENTS = 1e3;
|
|
854
|
-
const DEFAULT_INBOUND_GUARD_POLICY = createDirectDmPreCryptoGuardPolicy();
|
|
855
754
|
const CIRCUIT_BREAKER_THRESHOLD = 5;
|
|
856
755
|
const CIRCUIT_BREAKER_RESET_MS = 3e4;
|
|
857
756
|
const HEALTH_WINDOW_MS = 6e4;
|
|
858
|
-
function createCircuitBreaker(relay, metrics
|
|
757
|
+
function createCircuitBreaker(relay, metrics) {
|
|
859
758
|
const state = {
|
|
860
759
|
state: "closed",
|
|
861
760
|
failures: 0,
|
|
862
|
-
lastFailure: 0
|
|
863
|
-
lastSuccess: Date.now()
|
|
761
|
+
lastFailure: 0
|
|
864
762
|
};
|
|
865
763
|
return {
|
|
866
764
|
canAttempt() {
|
|
867
|
-
if (state.state === "closed") return true;
|
|
868
765
|
if (state.state === "open") {
|
|
869
|
-
if (Date.now() - state.lastFailure >=
|
|
766
|
+
if (Date.now() - state.lastFailure >= CIRCUIT_BREAKER_RESET_MS) {
|
|
870
767
|
state.state = "half_open";
|
|
871
768
|
metrics.emit("relay.circuit_breaker.half_open", 1, { relay });
|
|
872
769
|
return true;
|
|
@@ -881,21 +778,14 @@ function createCircuitBreaker(relay, metrics, threshold = CIRCUIT_BREAKER_THRESH
|
|
|
881
778
|
state.failures = 0;
|
|
882
779
|
metrics.emit("relay.circuit_breaker.close", 1, { relay });
|
|
883
780
|
} else if (state.state === "closed") state.failures = 0;
|
|
884
|
-
state.lastSuccess = Date.now();
|
|
885
781
|
},
|
|
886
782
|
recordFailure() {
|
|
887
783
|
state.failures++;
|
|
888
784
|
state.lastFailure = Date.now();
|
|
889
|
-
if (state.state === "half_open") {
|
|
890
|
-
state.state = "open";
|
|
891
|
-
metrics.emit("relay.circuit_breaker.open", 1, { relay });
|
|
892
|
-
} else if (state.state === "closed" && state.failures >= threshold) {
|
|
785
|
+
if (state.state === "half_open" || state.state === "closed" && state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
893
786
|
state.state = "open";
|
|
894
787
|
metrics.emit("relay.circuit_breaker.open", 1, { relay });
|
|
895
788
|
}
|
|
896
|
-
},
|
|
897
|
-
getState() {
|
|
898
|
-
return state.state;
|
|
899
789
|
}
|
|
900
790
|
};
|
|
901
791
|
}
|
|
@@ -908,7 +798,6 @@ function createRelayHealthTracker() {
|
|
|
908
798
|
successCount: 0,
|
|
909
799
|
failureCount: 0,
|
|
910
800
|
latencySum: 0,
|
|
911
|
-
latencyCount: 0,
|
|
912
801
|
lastSuccess: 0,
|
|
913
802
|
lastFailure: 0
|
|
914
803
|
};
|
|
@@ -921,7 +810,6 @@ function createRelayHealthTracker() {
|
|
|
921
810
|
const s = getOrCreate(relay);
|
|
922
811
|
s.successCount++;
|
|
923
812
|
s.latencySum += latencyMs;
|
|
924
|
-
s.latencyCount++;
|
|
925
813
|
s.lastSuccess = Date.now();
|
|
926
814
|
},
|
|
927
815
|
recordFailure(relay) {
|
|
@@ -937,18 +825,16 @@ function createRelayHealthTracker() {
|
|
|
937
825
|
const successRate = s.successCount / total;
|
|
938
826
|
const now = Date.now();
|
|
939
827
|
const recencyBonus = s.lastSuccess > s.lastFailure ? Math.max(0, 1 - (now - s.lastSuccess) / HEALTH_WINDOW_MS) * .2 : 0;
|
|
940
|
-
const avgLatency = s.
|
|
828
|
+
const avgLatency = s.successCount > 0 ? s.latencySum / s.successCount : 1e3;
|
|
941
829
|
const latencyPenalty = Math.min(.2, avgLatency / 1e4);
|
|
942
830
|
return Math.max(0, Math.min(1, successRate + recencyBonus - latencyPenalty));
|
|
943
831
|
},
|
|
944
832
|
getSortedRelays(relays) {
|
|
945
|
-
return
|
|
833
|
+
return relays.toSorted((a, b) => this.getScore(b) - this.getScore(a));
|
|
946
834
|
}
|
|
947
835
|
};
|
|
948
836
|
}
|
|
949
|
-
/**
|
|
950
|
-
* Start the Nostr DM bus - subscribes to NIP-04 encrypted DMs
|
|
951
|
-
*/
|
|
837
|
+
/** Subscribe to NIP-04 encrypted DMs. */
|
|
952
838
|
async function startNostrBus(options) {
|
|
953
839
|
const { privateKey, relays = DEFAULT_RELAYS, onMessage, authorizeSender, onError, onEose, onMetric } = options;
|
|
954
840
|
const sk = validatePrivateKey(privateKey);
|
|
@@ -957,14 +843,7 @@ async function startNostrBus(options) {
|
|
|
957
843
|
pool.onRelayConnectionSuccess = options.onConnect;
|
|
958
844
|
const accountId = options.accountId ?? pk.slice(0, 16);
|
|
959
845
|
const gatewayStartedAt = Math.floor(Date.now() / 1e3);
|
|
960
|
-
const guardPolicy = createDirectDmPreCryptoGuardPolicy(
|
|
961
|
-
...DEFAULT_INBOUND_GUARD_POLICY,
|
|
962
|
-
...options.guardPolicy,
|
|
963
|
-
rateLimit: {
|
|
964
|
-
...DEFAULT_INBOUND_GUARD_POLICY.rateLimit,
|
|
965
|
-
...options.guardPolicy?.rateLimit
|
|
966
|
-
}
|
|
967
|
-
});
|
|
846
|
+
const guardPolicy = createDirectDmPreCryptoGuardPolicy(options.guardPolicy);
|
|
968
847
|
const metrics = onMetric ? createMetrics(onMetric) : createNoopMetrics();
|
|
969
848
|
const circuitBreakers = /* @__PURE__ */ new Map();
|
|
970
849
|
const healthTracker = createRelayHealthTracker();
|
|
@@ -1005,27 +884,15 @@ async function startNostrBus(options) {
|
|
|
1005
884
|
const updateRateLimiterSizeMetric = () => {
|
|
1006
885
|
metrics.emit("memory.rate_limiter_entries", perSenderRateLimiter.size() + globalRateLimiter.size());
|
|
1007
886
|
};
|
|
1008
|
-
const
|
|
1009
|
-
updateRateLimiterSizeMetric();
|
|
1010
|
-
if (globalRateLimiter.isRateLimited("global")) {
|
|
1011
|
-
metrics.emit("rate_limit.global");
|
|
1012
|
-
metrics.emit("event.rejected.rate_limited");
|
|
1013
|
-
updateRateLimiterSizeMetric();
|
|
1014
|
-
return true;
|
|
1015
|
-
}
|
|
1016
|
-
updateRateLimiterSizeMetric();
|
|
1017
|
-
return false;
|
|
1018
|
-
};
|
|
1019
|
-
const rejectIfVerifiedSenderRateLimited = (senderPubkey) => {
|
|
887
|
+
const rejectIfRateLimited = (limiter, key, metric) => {
|
|
1020
888
|
updateRateLimiterSizeMetric();
|
|
1021
|
-
|
|
1022
|
-
|
|
889
|
+
const limited = limiter.isRateLimited(key);
|
|
890
|
+
if (limited) {
|
|
891
|
+
metrics.emit(metric);
|
|
1023
892
|
metrics.emit("event.rejected.rate_limited");
|
|
1024
|
-
updateRateLimiterSizeMetric();
|
|
1025
|
-
return true;
|
|
1026
893
|
}
|
|
1027
894
|
updateRateLimiterSizeMetric();
|
|
1028
|
-
return
|
|
895
|
+
return limited;
|
|
1029
896
|
};
|
|
1030
897
|
async function dispatchEvent(event, lifecycle) {
|
|
1031
898
|
if (event.pubkey === pk) {
|
|
@@ -1040,12 +907,7 @@ async function startNostrBus(options) {
|
|
|
1040
907
|
metrics.emit("event.rejected.wrong_kind");
|
|
1041
908
|
return;
|
|
1042
909
|
}
|
|
1043
|
-
|
|
1044
|
-
for (const tag of event.tags) if (tag[0] === "p" && tag[1] === pk) {
|
|
1045
|
-
targetsUs = true;
|
|
1046
|
-
break;
|
|
1047
|
-
}
|
|
1048
|
-
if (!targetsUs) {
|
|
910
|
+
if (!event.tags.some((tag) => tag[0] === "p" && tag[1] === pk)) {
|
|
1049
911
|
metrics.emit("event.rejected.wrong_kind");
|
|
1050
912
|
return;
|
|
1051
913
|
}
|
|
@@ -1053,18 +915,18 @@ async function startNostrBus(options) {
|
|
|
1053
915
|
await sendEncryptedDm(pool, sk, event.pubkey, text, relays, metrics, circuitBreakers, healthTracker, onError, { replyToEventId: event.id });
|
|
1054
916
|
};
|
|
1055
917
|
if (Buffer.byteLength(event.content, "utf8") > guardPolicy.maxCiphertextBytes) {
|
|
1056
|
-
if (
|
|
918
|
+
if (rejectIfRateLimited(globalRateLimiter, "global", "rate_limit.global")) throw new Error(`Nostr event ${event.id} hit the global rate limit.`);
|
|
1057
919
|
metrics.emit("event.rejected.oversized_ciphertext");
|
|
1058
920
|
return;
|
|
1059
921
|
}
|
|
1060
|
-
if (
|
|
922
|
+
if (rejectIfRateLimited(globalRateLimiter, "global", "rate_limit.global")) throw new Error(`Nostr event ${event.id} hit the global rate limit.`);
|
|
1061
923
|
if (!verifyEvent(event)) {
|
|
1062
924
|
metrics.emit("event.rejected.invalid_signature");
|
|
1063
925
|
const error = new NostrIngressPermanentError("invalid-signature", `Nostr event ${event.id} has an invalid signature.`);
|
|
1064
926
|
onError?.(error, `event ${event.id}`);
|
|
1065
927
|
throw error;
|
|
1066
928
|
}
|
|
1067
|
-
if (
|
|
929
|
+
if (rejectIfRateLimited(perSenderRateLimiter, event.pubkey, "rate_limit.per_sender")) throw new Error(`Nostr sender ${event.pubkey} hit the rate limit.`);
|
|
1068
930
|
if (authorizeSender) {
|
|
1069
931
|
if (await authorizeSender({
|
|
1070
932
|
senderPubkey: event.pubkey,
|
|
@@ -1138,9 +1000,6 @@ async function startNostrBus(options) {
|
|
|
1138
1000
|
const cursor = durableCursor.recordTransientRejection(event);
|
|
1139
1001
|
if (cursor !== void 0) await cursorWriter.persistNow(cursor);
|
|
1140
1002
|
};
|
|
1141
|
-
const recoverCursorPersistence = async () => {
|
|
1142
|
-
await cursorWriter.flushUntilSuccess();
|
|
1143
|
-
};
|
|
1144
1003
|
const handleRelayEvent = async (event) => {
|
|
1145
1004
|
metrics.emit("event.received");
|
|
1146
1005
|
if (typeof event.created_at === "number" && event.created_at < since) {
|
|
@@ -1161,7 +1020,7 @@ async function startNostrBus(options) {
|
|
|
1161
1020
|
} catch (cursorError) {
|
|
1162
1021
|
onError?.(cursorError, "persist transient replay cursor");
|
|
1163
1022
|
await stopRelays("cursor persistence failed");
|
|
1164
|
-
await
|
|
1023
|
+
await cursorWriter.flushUntilSuccess();
|
|
1165
1024
|
}
|
|
1166
1025
|
return;
|
|
1167
1026
|
}
|
|
@@ -1174,7 +1033,7 @@ async function startNostrBus(options) {
|
|
|
1174
1033
|
cursorPersistenceFailed = true;
|
|
1175
1034
|
}
|
|
1176
1035
|
await stopRelays("durable admission failed");
|
|
1177
|
-
if (cursorPersistenceFailed) await
|
|
1036
|
+
if (cursorPersistenceFailed) await cursorWriter.flushUntilSuccess();
|
|
1178
1037
|
}
|
|
1179
1038
|
};
|
|
1180
1039
|
let backfillFinalizePromise;
|
|
@@ -1214,9 +1073,6 @@ async function startNostrBus(options) {
|
|
|
1214
1073
|
await Promise.allSettled([stopRelays("startup failed"), ingress.stop()]);
|
|
1215
1074
|
throw error;
|
|
1216
1075
|
}
|
|
1217
|
-
const sendDm = async (toPubkey, text, sendOptions) => {
|
|
1218
|
-
return await sendEncryptedDm(pool, sk, toPubkey, text, relays, metrics, circuitBreakers, healthTracker, onError, sendOptions);
|
|
1219
|
-
};
|
|
1220
1076
|
const publishProfile$1 = async (profile) => {
|
|
1221
1077
|
const lastPublishedAt = (await readNostrProfileState({ accountId }))?.lastPublishedAt ?? void 0;
|
|
1222
1078
|
const result = await publishProfile(pool, sk, relays, profile, lastPublishedAt);
|
|
@@ -1254,15 +1110,12 @@ async function startNostrBus(options) {
|
|
|
1254
1110
|
return {
|
|
1255
1111
|
close,
|
|
1256
1112
|
publicKey: pk,
|
|
1257
|
-
sendDm,
|
|
1113
|
+
sendDm: (toPubkey, text, sendOptions) => sendEncryptedDm(pool, sk, toPubkey, text, relays, metrics, circuitBreakers, healthTracker, onError, sendOptions),
|
|
1258
1114
|
getMetrics: () => metrics.getSnapshot(),
|
|
1259
1115
|
publishProfile: publishProfile$1,
|
|
1260
1116
|
getProfileState
|
|
1261
1117
|
};
|
|
1262
1118
|
}
|
|
1263
|
-
/**
|
|
1264
|
-
* Send an encrypted DM to a pubkey
|
|
1265
|
-
*/
|
|
1266
1119
|
async function sendEncryptedDm(pool, sk, toPubkey, text, relays, metrics, circuitBreakers, healthTracker, onError, options) {
|
|
1267
1120
|
const ciphertext = encrypt(sk, toPubkey, text);
|
|
1268
1121
|
const tags = [["p", toPubkey]];
|
|
@@ -1367,7 +1220,7 @@ const startNostrGatewayAccount = async (ctx) => {
|
|
|
1367
1220
|
channel: "nostr",
|
|
1368
1221
|
accountId: account.accountId
|
|
1369
1222
|
});
|
|
1370
|
-
const resolveInboundAccess = async (senderPubkey, rawBody, contextBinding) => await
|
|
1223
|
+
const resolveInboundAccess = async (senderPubkey, rawBody, contextBinding) => await channelRuntime.inbound.ingress.resolveStable({
|
|
1371
1224
|
channelId: "nostr",
|
|
1372
1225
|
accountId: account.accountId,
|
|
1373
1226
|
identity: nostrIngressIdentity,
|
|
@@ -1421,7 +1274,7 @@ const startNostrGatewayAccount = async (ctx) => {
|
|
|
1421
1274
|
ctx.log?.warn?.(`[${account.accountId}] dropping Nostr DM after preflight drift (${senderPubkey}, ${resolvedAccess.senderAccess.reasonCode})`);
|
|
1422
1275
|
return;
|
|
1423
1276
|
}
|
|
1424
|
-
const { dispatchInboundDirectDm } = await import("
|
|
1277
|
+
const { dispatchInboundDirectDm } = await import("openclaw/plugin-sdk/channel-inbound");
|
|
1425
1278
|
await dispatchInboundDirectDm({
|
|
1426
1279
|
channelRuntime,
|
|
1427
1280
|
resolveChannelIngress: async (contextBinding) => {
|
|
@@ -1447,8 +1300,7 @@ const startNostrGatewayAccount = async (ctx) => {
|
|
|
1447
1300
|
commandAuthorized: resolvedAccess.commandAccess.requested ? resolvedAccess.commandAccess.authorized : void 0,
|
|
1448
1301
|
turnAdoptionLifecycle: bindIngressLifecycleToReplyOptions(lifecycle).turnAdoptionLifecycle,
|
|
1449
1302
|
deliver: async (payload) => {
|
|
1450
|
-
const
|
|
1451
|
-
const sanitizedText = sanitizeAssistantVisibleText(outboundText);
|
|
1303
|
+
const sanitizedText = sanitizeAssistantVisibleText(payload.text ?? "");
|
|
1452
1304
|
if (!sanitizedText) return;
|
|
1453
1305
|
const tableMode = runtime.channel.text.resolveMarkdownTableMode({
|
|
1454
1306
|
cfg: ctx.cfg,
|
|
@@ -1628,10 +1480,7 @@ const nostrConfigAdapter = createTopLevelChannelConfigAdapter({
|
|
|
1628
1480
|
"profile"
|
|
1629
1481
|
],
|
|
1630
1482
|
resolveAllowFrom: (account) => account.config.allowFrom,
|
|
1631
|
-
formatAllowFrom: (allowFrom) => normalizeStringEntries(allowFrom).map((
|
|
1632
|
-
if (entry === "*") return "*";
|
|
1633
|
-
return normalizeNostrTarget(entry);
|
|
1634
|
-
}).filter(Boolean)
|
|
1483
|
+
formatAllowFrom: (allowFrom) => normalizeStringEntries(allowFrom).map(normalizeNostrTarget).filter(Boolean)
|
|
1635
1484
|
});
|
|
1636
1485
|
const nostrMessageAdapter = createChannelMessageAdapterFromOutbound({
|
|
1637
1486
|
id: "nostr",
|
|
@@ -1699,10 +1548,10 @@ const nostrPlugin = createChatChannelPlugin({
|
|
|
1699
1548
|
},
|
|
1700
1549
|
hint: NOSTR_TARGET_HINT
|
|
1701
1550
|
},
|
|
1702
|
-
resolveOutboundSessionRoute:
|
|
1551
|
+
resolveOutboundSessionRoute: resolveNostrOutboundSessionRoute
|
|
1703
1552
|
},
|
|
1704
1553
|
message: nostrMessageAdapter,
|
|
1705
|
-
status:
|
|
1554
|
+
status: createComputedAccountStatusAdapter({
|
|
1706
1555
|
defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID),
|
|
1707
1556
|
collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("nostr", accounts),
|
|
1708
1557
|
buildChannelSummary: ({ snapshot }) => buildPassiveChannelStatusSummary(snapshot, { publicKey: snapshot.publicKey ?? null }),
|
|
@@ -1717,31 +1566,19 @@ const nostrPlugin = createChatChannelPlugin({
|
|
|
1717
1566
|
...buildTrafficStatusSummary(runtime)
|
|
1718
1567
|
}
|
|
1719
1568
|
})
|
|
1720
|
-
})
|
|
1569
|
+
}),
|
|
1721
1570
|
gateway: { startAccount: startNostrGatewayAccount }
|
|
1722
1571
|
},
|
|
1723
1572
|
pairing: { text: nostrPairingTextAdapter },
|
|
1724
1573
|
security: { resolveDmPolicy: resolveNostrDmPolicy },
|
|
1725
1574
|
outbound: nostrPluginOutboundAdapter
|
|
1726
1575
|
});
|
|
1727
|
-
/**
|
|
1728
|
-
* Publish a profile (kind:0) for a Nostr account.
|
|
1729
|
-
* @param accountId - Account ID (defaults to "default")
|
|
1730
|
-
* @param profile - Profile data to publish
|
|
1731
|
-
* @returns Publish results with successes and failures
|
|
1732
|
-
* @throws Error if account is not running
|
|
1733
|
-
*/
|
|
1734
1576
|
async function publishNostrProfile(accountId, profile) {
|
|
1735
1577
|
const resolvedAccountId = accountId ?? DEFAULT_ACCOUNT_ID;
|
|
1736
1578
|
const bus = getActiveNostrBuses().get(resolvedAccountId);
|
|
1737
1579
|
if (!bus) throw new Error(`Nostr bus not running for account ${resolvedAccountId}`);
|
|
1738
1580
|
return bus.publishProfile(profile);
|
|
1739
1581
|
}
|
|
1740
|
-
/**
|
|
1741
|
-
* Get profile publish state for a Nostr account.
|
|
1742
|
-
* @param accountId - Account ID (defaults to "default")
|
|
1743
|
-
* @returns Profile publish state or null if account not running
|
|
1744
|
-
*/
|
|
1745
1582
|
async function getNostrProfileState(accountId = DEFAULT_ACCOUNT_ID) {
|
|
1746
1583
|
const bus = getActiveNostrBuses().get(accountId);
|
|
1747
1584
|
if (!bus) return null;
|