nervur 0.22.0 → 0.22.2-3
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/AUTHORING.md +741 -0
- package/KIT-SPEC.md +286 -0
- package/LICENSE +1 -1
- package/NOTICE +6 -2
- package/README.md +97 -424
- package/dist/app/app-ground.d.ts +18 -0
- package/dist/app/app-ground.js +25 -0
- package/dist/app/index.d.ts +2 -0
- package/dist/app/index.js +5 -0
- package/dist/app/native.d.ts +46 -0
- package/dist/app/native.js +101 -0
- package/dist/being/being.d.ts +229 -0
- package/dist/being/being.js +20 -0
- package/dist/being/covers.d.ts +9 -0
- package/dist/being/covers.js +21 -0
- package/dist/being/index.d.ts +3 -0
- package/dist/being/index.js +5 -0
- package/dist/being/need.d.ts +49 -0
- package/dist/being/need.js +33 -0
- package/dist/being/schema.d.ts +100 -0
- package/dist/being/schema.js +132 -0
- package/dist/being/table.d.ts +42 -0
- package/dist/being/table.js +288 -0
- package/dist/bench/bench-ground.d.ts +55 -0
- package/dist/bench/bench-ground.js +101 -0
- package/dist/bench/bench.d.ts +87 -0
- package/dist/bench/bench.js +260 -0
- package/dist/bench/fake-carry.d.ts +32 -0
- package/dist/bench/fake-carry.js +56 -0
- package/dist/bench/fake-clock.d.ts +17 -0
- package/dist/bench/fake-clock.js +34 -0
- package/dist/bench/fake-custody.d.ts +9 -0
- package/dist/bench/fake-custody.js +10 -0
- package/dist/bench/fake-faculty.d.ts +25 -0
- package/dist/bench/fake-faculty.js +48 -0
- package/dist/bench/fake-keys.d.ts +5 -0
- package/dist/bench/fake-keys.js +9 -0
- package/dist/bench/fake-memory.d.ts +14 -0
- package/dist/bench/fake-memory.js +46 -0
- package/dist/bench/fake-network.d.ts +57 -0
- package/dist/bench/fake-network.js +169 -0
- package/dist/bench/index.d.ts +11 -0
- package/dist/bench/index.js +13 -0
- package/dist/bench/seeded.d.ts +11 -0
- package/dist/bench/seeded.js +37 -0
- package/dist/bench/settle.d.ts +2 -0
- package/dist/bench/settle.js +49 -0
- package/dist/bench/stewards.d.ts +17 -0
- package/dist/bench/stewards.js +20 -0
- package/dist/bodies/class-list.d.ts +14 -0
- package/dist/bodies/class-list.js +33 -0
- package/dist/bodies/joined-carry.d.ts +23 -0
- package/dist/bodies/joined-carry.js +42 -0
- package/dist/bodies/noble-crypto.d.ts +22 -0
- package/dist/bodies/noble-crypto.js +88 -0
- package/dist/bodies/seed-keys.d.ts +10 -0
- package/dist/bodies/seed-keys.js +42 -0
- package/dist/bodies/strict-tools.d.ts +10 -0
- package/dist/bodies/strict-tools.js +306 -0
- package/dist/bodies/web-carry.d.ts +65 -0
- package/dist/bodies/web-carry.js +224 -0
- package/dist/bodies/web-clock.d.ts +12 -0
- package/dist/bodies/web-clock.js +33 -0
- package/dist/browser/browser-ground.d.ts +69 -0
- package/dist/browser/browser-ground.js +219 -0
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +7 -0
- package/dist/browser/indexeddb-memory.d.ts +17 -0
- package/dist/browser/indexeddb-memory.js +97 -0
- package/dist/browser/locked-custody.d.ts +25 -0
- package/dist/browser/locked-custody.js +89 -0
- package/dist/browser/origin-classes.d.ts +7 -0
- package/dist/browser/origin-classes.js +31 -0
- package/dist/foundation.d.ts +150 -0
- package/dist/foundation.js +4 -0
- package/dist/ground/ground.d.ts +177 -0
- package/dist/ground/ground.js +363 -0
- package/dist/house/crossing.d.ts +37 -0
- package/dist/house/crossing.js +131 -0
- package/dist/house/house.d.ts +80 -0
- package/dist/house/house.js +1753 -0
- package/dist/house/rows-shape.d.ts +103 -0
- package/dist/house/rows-shape.js +12 -0
- package/dist/house/rows.d.ts +27 -0
- package/dist/house/rows.js +168 -0
- package/dist/index.d.ts +29 -1
- package/dist/index.js +25 -14
- package/dist/node/bridge.d.ts +17 -0
- package/dist/node/bridge.js +188 -0
- package/dist/node/cli.js +170 -0
- package/dist/node/custody.d.ts +20 -0
- package/dist/node/custody.js +34 -0
- package/dist/node/file-keys.d.ts +7 -0
- package/dist/node/file-keys.js +30 -0
- package/dist/node/file-memory.d.ts +13 -0
- package/dist/node/file-memory.js +91 -0
- package/dist/node/folder-classes.d.ts +5 -0
- package/dist/node/folder-classes.js +40 -0
- package/dist/node/gone.d.ts +2 -0
- package/dist/node/gone.js +7 -0
- package/dist/node/hand.d.ts +29 -0
- package/dist/node/hand.js +85 -0
- package/dist/node/held-keys.d.ts +14 -0
- package/dist/node/held-keys.js +36 -0
- package/dist/node/http.d.ts +11 -0
- package/dist/node/http.js +90 -0
- package/dist/node/index.d.ts +13 -0
- package/dist/node/index.js +15 -0
- package/dist/node/keychain-keys.d.ts +10 -0
- package/dist/node/keychain-keys.js +51 -0
- package/dist/node/ledger-memory.d.ts +17 -0
- package/dist/node/ledger-memory.js +151 -0
- package/dist/node/lock.d.ts +10 -0
- package/dist/node/lock.js +78 -0
- package/dist/node/node-ground.d.ts +33 -0
- package/dist/node/node-ground.js +147 -0
- package/dist/node/notify.d.ts +1 -0
- package/dist/node/notify.js +18 -0
- package/dist/node/tcp-carry.d.ts +39 -0
- package/dist/node/tcp-carry.js +216 -0
- package/dist/node/websocket.d.ts +6 -0
- package/dist/node/websocket.js +118 -0
- package/dist/quo/frame.d.ts +20 -0
- package/dist/quo/frame.js +48 -0
- package/dist/quo/room.d.ts +154 -0
- package/dist/quo/room.js +362 -0
- package/dist/serve/index.d.ts +27 -0
- package/dist/serve/index.js +55 -0
- package/package.json +49 -47
- package/dist/browser.d.ts +0 -1
- package/dist/browser.js +0 -8
- package/dist/cli.js +0 -16
- package/dist/core/being/being.d.ts +0 -17
- package/dist/core/being/being.js +0 -72
- package/dist/core/being/digest.d.ts +0 -3
- package/dist/core/being/digest.js +0 -17
- package/dist/core/being/faculty.d.ts +0 -10
- package/dist/core/being/faculty.js +0 -77
- package/dist/core/being/index.d.ts +0 -6
- package/dist/core/being/index.js +0 -8
- package/dist/core/being/kind.d.ts +0 -6
- package/dist/core/being/kind.js +0 -34
- package/dist/core/being/types.d.ts +0 -61
- package/dist/core/being/types.js +0 -4
- package/dist/core/being/words.d.ts +0 -13
- package/dist/core/being/words.js +0 -14
- package/dist/core/browser/index.d.ts +0 -37
- package/dist/core/browser/index.js +0 -196
- package/dist/core/browser/worker.d.ts +0 -11
- package/dist/core/browser/worker.js +0 -37
- package/dist/core/cli/command.d.ts +0 -13
- package/dist/core/cli/command.js +0 -330
- package/dist/core/cli/edge.d.ts +0 -7
- package/dist/core/cli/edge.js +0 -79
- package/dist/core/cli/harbor.d.ts +0 -25
- package/dist/core/cli/harbor.js +0 -115
- package/dist/core/contract/index.d.ts +0 -42
- package/dist/core/contract/index.js +0 -34
- package/dist/core/contract/link.d.ts +0 -4
- package/dist/core/contract/link.js +0 -45
- package/dist/core/crypto/aes.d.ts +0 -3
- package/dist/core/crypto/aes.js +0 -24
- package/dist/core/crypto/bytes.d.ts +0 -6
- package/dist/core/crypto/bytes.js +0 -33
- package/dist/core/crypto/ed25519.d.ts +0 -3
- package/dist/core/crypto/ed25519.js +0 -93
- package/dist/core/crypto/hash.d.ts +0 -2
- package/dist/core/crypto/hash.js +0 -11
- package/dist/core/crypto/index.d.ts +0 -7
- package/dist/core/crypto/index.js +0 -10
- package/dist/core/crypto/json.d.ts +0 -8
- package/dist/core/crypto/json.js +0 -250
- package/dist/core/crypto/mlkem.d.ts +0 -12
- package/dist/core/crypto/mlkem.js +0 -36
- package/dist/core/crypto/subtle.d.ts +0 -3
- package/dist/core/crypto/subtle.js +0 -11
- package/dist/core/crypto/x25519.d.ts +0 -2
- package/dist/core/crypto/x25519.js +0 -24
- package/dist/core/edge/index.d.ts +0 -164
- package/dist/core/edge/index.js +0 -739
- package/dist/core/edge/kit.d.ts +0 -2
- package/dist/core/edge/kit.js +0 -2
- package/dist/core/folder/index.d.ts +0 -18
- package/dist/core/folder/index.js +0 -130
- package/dist/core/git/http.d.ts +0 -6
- package/dist/core/git/http.js +0 -102
- package/dist/core/git/index.d.ts +0 -5
- package/dist/core/git/index.js +0 -10
- package/dist/core/git/object.d.ts +0 -40
- package/dist/core/git/object.js +0 -103
- package/dist/core/git/pack.d.ts +0 -9
- package/dist/core/git/pack.js +0 -171
- package/dist/core/git/store.d.ts +0 -23
- package/dist/core/git/store.js +0 -120
- package/dist/core/git/zlib.d.ts +0 -6
- package/dist/core/git/zlib.js +0 -210
- package/dist/core/harbor/carrying.d.ts +0 -51
- package/dist/core/harbor/carrying.js +0 -69
- package/dist/core/harbor/catalogue.d.ts +0 -33
- package/dist/core/harbor/catalogue.js +0 -365
- package/dist/core/harbor/dna.d.ts +0 -13
- package/dist/core/harbor/dna.js +0 -120
- package/dist/core/harbor/dock.d.ts +0 -62
- package/dist/core/harbor/dock.js +0 -381
- package/dist/core/harbor/harbor.d.ts +0 -16
- package/dist/core/harbor/harbor.js +0 -438
- package/dist/core/harbor/index.d.ts +0 -11
- package/dist/core/harbor/index.js +0 -14
- package/dist/core/harbor/memory.d.ts +0 -10
- package/dist/core/harbor/memory.js +0 -25
- package/dist/core/harbor/package.d.ts +0 -20
- package/dist/core/harbor/package.js +0 -172
- package/dist/core/harbor/probe.d.ts +0 -22
- package/dist/core/harbor/probe.js +0 -15
- package/dist/core/harbor/registry.d.ts +0 -15
- package/dist/core/harbor/registry.js +0 -110
- package/dist/core/harbor/root-line.d.ts +0 -7
- package/dist/core/harbor/root-line.js +0 -9
- package/dist/core/harbor/terrain.d.ts +0 -25
- package/dist/core/harbor/terrain.js +0 -28
- package/dist/core/http/index.d.ts +0 -2
- package/dist/core/http/index.js +0 -154
- package/dist/core/http/websocket.d.ts +0 -29
- package/dist/core/http/websocket.js +0 -133
- package/dist/core/line/answer.d.ts +0 -8
- package/dist/core/line/answer.js +0 -60
- package/dist/core/line/frame.d.ts +0 -29
- package/dist/core/line/frame.js +0 -77
- package/dist/core/line/ground.d.ts +0 -3
- package/dist/core/line/ground.js +0 -7
- package/dist/core/line/index.d.ts +0 -4
- package/dist/core/line/index.js +0 -8
- package/dist/core/line/web.d.ts +0 -12
- package/dist/core/line/web.js +0 -117
- package/dist/core/node/index.d.ts +0 -23
- package/dist/core/node/index.js +0 -124
- package/dist/core/pointer/bodies.d.ts +0 -31
- package/dist/core/pointer/bodies.js +0 -118
- package/dist/core/pointer/index.d.ts +0 -2
- package/dist/core/pointer/index.js +0 -4
- package/dist/core/pointer/world.d.ts +0 -45
- package/dist/core/pointer/world.js +0 -106
- package/dist/core/proof/contracts.d.ts +0 -19
- package/dist/core/proof/contracts.js +0 -116
- package/dist/core/proof/expect.d.ts +0 -6
- package/dist/core/proof/expect.js +0 -18
- package/dist/core/proof/index.d.ts +0 -3
- package/dist/core/proof/index.js +0 -14
- package/dist/core/proof/law.d.ts +0 -25
- package/dist/core/proof/law.js +0 -715
- package/dist/core/quo/address.d.ts +0 -19
- package/dist/core/quo/address.js +0 -84
- package/dist/core/quo/door.d.ts +0 -34
- package/dist/core/quo/door.js +0 -174
- package/dist/core/quo/index.d.ts +0 -9
- package/dist/core/quo/index.js +0 -12
- package/dist/core/quo/invitation.d.ts +0 -8
- package/dist/core/quo/invitation.js +0 -19
- package/dist/core/quo/keys.d.ts +0 -40
- package/dist/core/quo/keys.js +0 -79
- package/dist/core/quo/payload.d.ts +0 -15
- package/dist/core/quo/payload.js +0 -55
- package/dist/core/quo/relations.d.ts +0 -40
- package/dist/core/quo/relations.js +0 -33
- package/dist/core/quo/reply.d.ts +0 -13
- package/dist/core/quo/reply.js +0 -35
- package/dist/core/quo/seal.d.ts +0 -42
- package/dist/core/quo/seal.js +0 -78
- package/dist/core/quo/standing.d.ts +0 -39
- package/dist/core/quo/standing.js +0 -90
- package/dist/core/tcp/index.d.ts +0 -27
- package/dist/core/tcp/index.js +0 -209
- package/dist/core/ward/allowance.d.ts +0 -14
- package/dist/core/ward/allowance.js +0 -32
- package/dist/core/ward/cells.d.ts +0 -7
- package/dist/core/ward/cells.js +0 -74
- package/dist/core/ward/house.d.ts +0 -67
- package/dist/core/ward/house.js +0 -473
- package/dist/core/ward/index.d.ts +0 -5
- package/dist/core/ward/index.js +0 -7
- package/dist/core/ward/partition.d.ts +0 -50
- package/dist/core/ward/partition.js +0 -66
- package/dist/core/ward/stance.d.ts +0 -29
- package/dist/core/ward/stance.js +0 -186
- package/dist/core/ward/ward.d.ts +0 -44
- package/dist/core/ward/ward.js +0 -140
- package/dist/core.d.ts +0 -10
- package/dist/core.js +0 -19
- package/dist/defaults/dock/index.d.ts +0 -4
- package/dist/defaults/dock/index.js +0 -11
- package/dist/defaults/index.d.ts +0 -5
- package/dist/defaults/index.js +0 -10
- package/dist/defaults/memory/index.d.ts +0 -12
- package/dist/defaults/memory/index.js +0 -39
- package/dist/defaults/tcp/index.d.ts +0 -16
- package/dist/defaults/tcp/index.js +0 -82
- package/dist/defaults/ward/index.d.ts +0 -4
- package/dist/defaults/ward/index.js +0 -11
- package/dist/defaults/web/index.d.ts +0 -15
- package/dist/defaults/web/index.js +0 -90
- package/dist/edge.d.ts +0 -1
- package/dist/edge.js +0 -9
- package/dist/kit.d.ts +0 -4
- package/dist/kit.js +0 -12
- package/dist/node.d.ts +0 -1
- package/dist/node.js +0 -8
- package/src/browser.ts +0 -10
- package/src/cli.ts +0 -15
- package/src/core/being/being.ts +0 -84
- package/src/core/being/digest.ts +0 -18
- package/src/core/being/faculty.ts +0 -76
- package/src/core/being/index.ts +0 -8
- package/src/core/being/kind.ts +0 -37
- package/src/core/being/types.ts +0 -74
- package/src/core/being/words.ts +0 -31
- package/src/core/browser/index.ts +0 -219
- package/src/core/browser/worker.ts +0 -63
- package/src/core/cli/command.ts +0 -311
- package/src/core/cli/edge.ts +0 -86
- package/src/core/cli/harbor.ts +0 -120
- package/src/core/contract/index.ts +0 -82
- package/src/core/contract/link.ts +0 -58
- package/src/core/crypto/aes.ts +0 -26
- package/src/core/crypto/bytes.ts +0 -37
- package/src/core/crypto/ed25519.ts +0 -92
- package/src/core/crypto/hash.ts +0 -14
- package/src/core/crypto/index.ts +0 -10
- package/src/core/crypto/json.ts +0 -241
- package/src/core/crypto/mlkem.ts +0 -38
- package/src/core/crypto/subtle.ts +0 -13
- package/src/core/crypto/x25519.ts +0 -23
- package/src/core/edge/index.ts +0 -865
- package/src/core/folder/index.ts +0 -137
- package/src/core/git/http.ts +0 -103
- package/src/core/git/index.ts +0 -10
- package/src/core/git/object.ts +0 -116
- package/src/core/git/pack.ts +0 -147
- package/src/core/git/store.ts +0 -122
- package/src/core/git/zlib.ts +0 -197
- package/src/core/harbor/carrying.ts +0 -124
- package/src/core/harbor/catalogue.ts +0 -386
- package/src/core/harbor/dna.ts +0 -116
- package/src/core/harbor/dock.ts +0 -420
- package/src/core/harbor/harbor.ts +0 -433
- package/src/core/harbor/index.ts +0 -14
- package/src/core/harbor/memory.ts +0 -31
- package/src/core/harbor/package.ts +0 -195
- package/src/core/harbor/probe.ts +0 -39
- package/src/core/harbor/registry.ts +0 -107
- package/src/core/harbor/root-line.ts +0 -19
- package/src/core/harbor/terrain.ts +0 -54
- package/src/core/http/index.ts +0 -147
- package/src/core/http/websocket.ts +0 -124
- package/src/core/line/answer.ts +0 -60
- package/src/core/line/frame.ts +0 -83
- package/src/core/line/ground.ts +0 -18
- package/src/core/line/index.ts +0 -8
- package/src/core/line/web.ts +0 -123
- package/src/core/node/index.ts +0 -139
- package/src/core/pointer/bodies.ts +0 -122
- package/src/core/pointer/index.ts +0 -4
- package/src/core/pointer/world.ts +0 -134
- package/src/core/proof/contracts.ts +0 -134
- package/src/core/proof/expect.ts +0 -25
- package/src/core/proof/index.ts +0 -14
- package/src/core/proof/law.ts +0 -742
- package/src/core/quo/address.ts +0 -87
- package/src/core/quo/door.ts +0 -180
- package/src/core/quo/index.ts +0 -12
- package/src/core/quo/invitation.ts +0 -19
- package/src/core/quo/keys.ts +0 -91
- package/src/core/quo/payload.ts +0 -61
- package/src/core/quo/relations.ts +0 -62
- package/src/core/quo/reply.ts +0 -38
- package/src/core/quo/seal.ts +0 -101
- package/src/core/quo/standing.ts +0 -111
- package/src/core/stand/main.ts +0 -20
- package/src/core/stand/stand.ts +0 -259
- package/src/core/tcp/index.ts +0 -227
- package/src/core/ward/allowance.ts +0 -47
- package/src/core/ward/cells.ts +0 -77
- package/src/core/ward/house.ts +0 -524
- package/src/core/ward/index.ts +0 -7
- package/src/core/ward/partition.ts +0 -117
- package/src/core/ward/stance.ts +0 -207
- package/src/core/ward/ward.ts +0 -166
- package/src/core.ts +0 -55
- package/src/defaults/dock/index.ts +0 -12
- package/src/defaults/index.ts +0 -10
- package/src/defaults/memory/index.ts +0 -50
- package/src/defaults/tcp/index.ts +0 -89
- package/src/defaults/ward/index.ts +0 -12
- package/src/defaults/web/index.ts +0 -97
- package/src/edge.ts +0 -11
- package/src/index.ts +0 -18
- package/src/kit.ts +0 -15
- package/src/node.ts +0 -10
- /package/dist/{cli.d.ts → node/cli.d.ts} +0 -0
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export declare const schemeOf: (s: unknown) => string | null;
|
|
2
|
-
export type TcpAddress = {
|
|
3
|
-
host: string;
|
|
4
|
-
port: number;
|
|
5
|
-
};
|
|
6
|
-
export declare const tcpAddress: (s: unknown) => TcpAddress | null;
|
|
7
|
-
export declare const tcpAt: (host: string, port: number) => string;
|
|
8
|
-
export type WebAddress = {
|
|
9
|
-
scheme: 'http' | 'https' | 'ws' | 'wss';
|
|
10
|
-
secure: boolean;
|
|
11
|
-
held: boolean;
|
|
12
|
-
host: string;
|
|
13
|
-
port: number;
|
|
14
|
-
path: string;
|
|
15
|
-
href: string;
|
|
16
|
-
};
|
|
17
|
-
export declare const webAddress: (s: unknown) => WebAddress | null;
|
|
18
|
-
export declare const unspecified: (s: unknown) => boolean;
|
|
19
|
-
export declare const readAt: (value: unknown) => string[];
|
package/dist/core/quo/address.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// Addresses, as `SPEC.md` names them in an invitation's `at`: a URI of
|
|
3
|
-
// RFC 3986 whose scheme, read in any case, names a carrier.
|
|
4
|
-
// `CARRIER-TCP.md` writes `tcp://host:port`, and `CARRIER-WEB.md` writes
|
|
5
|
-
// `http` and `https` for the post and `ws` and `wss` for the held line.
|
|
6
|
-
// RFC 3986 appendix B, with the characters a URI may hold checked apart.
|
|
7
|
-
const SPLIT = /^(?:([^:/?#]+):)?(?:\/\/([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?$/;
|
|
8
|
-
const URI_CHARS = /^(?:[A-Za-z0-9\-._~:/?#[\]@!$&'()*+,;=]|%[0-9A-Fa-f]{2})*$/;
|
|
9
|
-
const SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/;
|
|
10
|
-
const REG_NAME = /^(?:[A-Za-z0-9\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*$/;
|
|
11
|
-
const IP_LITERAL = /^\[(?:[0-9A-Fa-f:.]+|v[0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)\]$/;
|
|
12
|
-
// A URI with a scheme, taken apart, or null. `host` is as written,
|
|
13
|
-
// brackets included, and `port` the digits as written.
|
|
14
|
-
const parse = (s) => {
|
|
15
|
-
if (typeof s !== 'string' || !URI_CHARS.test(s))
|
|
16
|
-
return null;
|
|
17
|
-
const m = SPLIT.exec(s);
|
|
18
|
-
if (!m || m[1] === undefined || !SCHEME.test(m[1]))
|
|
19
|
-
return null;
|
|
20
|
-
const out = { scheme: m[1].toLowerCase(), authority: m[2] ?? null, userinfo: null, host: null, port: null, path: m[3] ?? '', query: m[4] ?? null, fragment: m[5] ?? null };
|
|
21
|
-
if (out.authority === null)
|
|
22
|
-
return out;
|
|
23
|
-
let rest = out.authority;
|
|
24
|
-
const at = rest.lastIndexOf('@');
|
|
25
|
-
if (at >= 0) {
|
|
26
|
-
out.userinfo = rest.slice(0, at);
|
|
27
|
-
rest = rest.slice(at + 1);
|
|
28
|
-
}
|
|
29
|
-
const hp = /^(\[[^\]]*\]|[^:[\]]*)(?::([0-9]*))?$/.exec(rest);
|
|
30
|
-
if (!hp)
|
|
31
|
-
return null;
|
|
32
|
-
const host = hp[1];
|
|
33
|
-
if (host.startsWith('[') ? !IP_LITERAL.test(host) : !REG_NAME.test(host))
|
|
34
|
-
return null;
|
|
35
|
-
out.host = host;
|
|
36
|
-
out.port = hp[2] ?? null;
|
|
37
|
-
return out;
|
|
38
|
-
};
|
|
39
|
-
// The host as a socket takes it: an IPv6 literal without its brackets.
|
|
40
|
-
const bare = (host) => (host.startsWith('[') ? host.slice(1, -1) : host);
|
|
41
|
-
// The scheme an address names, lowercase, or null for what is no URI.
|
|
42
|
-
export const schemeOf = (s) => parse(s)?.scheme ?? null;
|
|
43
|
-
// A `tcp` address as `CARRIER-TCP.md` writes one, or null.
|
|
44
|
-
export const tcpAddress = (s) => {
|
|
45
|
-
const a = parse(s);
|
|
46
|
-
if (!a || a.scheme !== 'tcp' || a.authority === null)
|
|
47
|
-
return null;
|
|
48
|
-
if (a.userinfo !== null || a.path !== '' || a.query !== null || a.fragment !== null)
|
|
49
|
-
return null;
|
|
50
|
-
if (!a.host || a.port === null || !/^[0-9]+$/.test(a.port))
|
|
51
|
-
return null;
|
|
52
|
-
const port = Number(a.port);
|
|
53
|
-
if (port < 1 || port > 65_535)
|
|
54
|
-
return null;
|
|
55
|
-
return { host: bare(a.host), port };
|
|
56
|
-
};
|
|
57
|
-
// The `tcp` address of a host and port.
|
|
58
|
-
export const tcpAt = (host, port) => `tcp://${host.includes(':') ? `[${host}]` : host}:${port}`;
|
|
59
|
-
const WEB = new Set(['http', 'https', 'ws', 'wss']);
|
|
60
|
-
// An address of `CARRIER-WEB.md`, or null. `path` is the path and query
|
|
61
|
-
// a request names, `/` when both are empty.
|
|
62
|
-
export const webAddress = (s) => {
|
|
63
|
-
const a = parse(s);
|
|
64
|
-
if (!a || !WEB.has(a.scheme) || a.authority === null)
|
|
65
|
-
return null;
|
|
66
|
-
if (a.userinfo !== null || a.fragment !== null || !a.host)
|
|
67
|
-
return null;
|
|
68
|
-
if (a.port !== null && a.port !== '' && (!/^[0-9]+$/.test(a.port) || Number(a.port) > 65_535))
|
|
69
|
-
return null;
|
|
70
|
-
const scheme = a.scheme;
|
|
71
|
-
const secure = scheme === 'https' || scheme === 'wss';
|
|
72
|
-
const port = a.port ? Number(a.port) : secure ? 443 : 80;
|
|
73
|
-
const path = `${a.path || '/'}${a.query !== null ? `?${a.query}` : ''}`;
|
|
74
|
-
return { scheme, secure, held: scheme === 'ws' || scheme === 'wss', host: bare(a.host), port, path, href: s };
|
|
75
|
-
};
|
|
76
|
-
// Whether a tcp or web address names the unspecified host, where a
|
|
77
|
-
// listener binds every interface and no caller can dial.
|
|
78
|
-
export const unspecified = (s) => {
|
|
79
|
-
const host = (tcpAddress(s) ?? webAddress(s))?.host;
|
|
80
|
-
return host === '0.0.0.0' || host === '::';
|
|
81
|
-
};
|
|
82
|
-
// An invitation's `at` as `SPEC.md` reads it: the strings that are URIs
|
|
83
|
-
// with a scheme, in their order. A value that is no array is absent.
|
|
84
|
-
export const readAt = (value) => (Array.isArray(value) ? value.filter((s) => parse(s) !== null) : []);
|
package/dist/core/quo/door.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { type Draw, type WardKey } from './keys.ts';
|
|
2
|
-
import type { Invitation } from './invitation.ts';
|
|
3
|
-
import { type Payload } from './payload.ts';
|
|
4
|
-
import type { Relations } from './relations.ts';
|
|
5
|
-
export declare const SPAN = 64;
|
|
6
|
-
export type Choice = {
|
|
7
|
-
readonly object: string;
|
|
8
|
-
readonly seen: string | null;
|
|
9
|
-
} | {
|
|
10
|
-
readonly silence: true;
|
|
11
|
-
};
|
|
12
|
-
export interface Behind {
|
|
13
|
-
readonly zero: boolean;
|
|
14
|
-
answer(heir: string | null, payload: Payload): Promise<Choice>;
|
|
15
|
-
}
|
|
16
|
-
export type Judged = {
|
|
17
|
-
bytes: Uint8Array;
|
|
18
|
-
case: number;
|
|
19
|
-
heard: boolean;
|
|
20
|
-
};
|
|
21
|
-
export declare class Door {
|
|
22
|
-
#private;
|
|
23
|
-
readonly key: WardKey;
|
|
24
|
-
readonly relations: Relations;
|
|
25
|
-
readonly behind: Behind;
|
|
26
|
-
readonly draw: Draw;
|
|
27
|
-
constructor(key: WardKey, relations: Relations, behind: Behind, draw: Draw);
|
|
28
|
-
invite(at?: readonly string[]): Promise<{
|
|
29
|
-
heir: string;
|
|
30
|
-
invitation: Invitation;
|
|
31
|
-
}>;
|
|
32
|
-
remove(heir: string): boolean;
|
|
33
|
-
arrive(bytes: Uint8Array): Promise<Judged>;
|
|
34
|
-
}
|
package/dist/core/quo/door.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The door: an ask's box in, a reply's box out, judged by the thirteen cases
|
|
3
|
-
// of the spec in their order. A stranger hears one silence whatever the
|
|
4
|
-
// case. The case is handed back beside the bytes, for the kit's own eyes,
|
|
5
|
-
// with `heard`: whether a key the door holds or keeps spoke.
|
|
6
|
-
import { decapsulate, hex, unhex, utf8, x25519Public, zero } from '../crypto/index.js';
|
|
7
|
-
import { drawLock, SigningKey } from './keys.js';
|
|
8
|
-
import { readPayload } from './payload.js';
|
|
9
|
-
import { writeReply } from './reply.js';
|
|
10
|
-
import { checkBody, follow, HEAD, knockEdge, openBody, openHead, replyKey, sealReply, signBody, SIZE, splitBody, splitKnock, ZERO_EDGE } from './seal.js';
|
|
11
|
-
// The count numbers below the highest a door still honours: those within
|
|
12
|
-
// this span that it has not seen.
|
|
13
|
-
export const SPAN = 64;
|
|
14
|
-
export class Door {
|
|
15
|
-
key;
|
|
16
|
-
relations;
|
|
17
|
-
behind;
|
|
18
|
-
draw;
|
|
19
|
-
constructor(key, relations, behind, draw) {
|
|
20
|
-
this.key = key;
|
|
21
|
-
this.relations = relations;
|
|
22
|
-
this.behind = behind;
|
|
23
|
-
this.draw = draw;
|
|
24
|
-
}
|
|
25
|
-
// A new heir, held fresh, and its invitation. The lock is drawn at the
|
|
26
|
-
// first invitation that names an heir, before the heir's secret.
|
|
27
|
-
// A new heir, and its invitation, naming in `at` the addresses given.
|
|
28
|
-
async invite(at = []) {
|
|
29
|
-
let lock = this.relations.lock();
|
|
30
|
-
if (!lock)
|
|
31
|
-
this.relations.setLock((lock = drawLock(this.draw)));
|
|
32
|
-
const heir = await SigningKey.draw(this.draw);
|
|
33
|
-
this.relations.set(heir.id, { state: 'fresh' });
|
|
34
|
-
const invitation = { ward: this.key.pk, heir: heir.id, secret: hex(heir.secret), lock: hex(lock.ek), ...(at.length > 0 ? { at: [...at] } : {}) };
|
|
35
|
-
return { heir: heir.id, invitation };
|
|
36
|
-
}
|
|
37
|
-
// The door stops holding an heir. A fresh one leaves nothing, a spent one
|
|
38
|
-
// leaves the keys kept at removal.
|
|
39
|
-
remove(heir) {
|
|
40
|
-
const record = this.relations.get(heir);
|
|
41
|
-
if (record === undefined || record.state === 'kept')
|
|
42
|
-
return false;
|
|
43
|
-
if (record.state === 'fresh')
|
|
44
|
-
this.relations.delete(heir);
|
|
45
|
-
else
|
|
46
|
-
this.relations.set(heir, { state: 'kept', held: record.held, vouched: record.vouched, open: record.open, offered: record.offered });
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
async arrive(bytes) {
|
|
50
|
-
const stranger = async (n) => ({ bytes: await this.#silence(bytes), case: n, heard: false });
|
|
51
|
-
if (bytes.length > SIZE || bytes.length < HEAD)
|
|
52
|
-
return stranger(1);
|
|
53
|
-
const agreement = await this.key.open(bytes.subarray(0, HEAD));
|
|
54
|
-
const opened = agreement && (await openHead(bytes, agreement));
|
|
55
|
-
if (!opened)
|
|
56
|
-
return stranger(1);
|
|
57
|
-
const isZero = zero(opened.head);
|
|
58
|
-
const heir = hex(opened.head);
|
|
59
|
-
const record = isZero ? undefined : this.relations.get(heir);
|
|
60
|
-
const body = await this.#body(opened, record);
|
|
61
|
-
if (!body)
|
|
62
|
-
return stranger(1);
|
|
63
|
-
const read = readPayload(body.text);
|
|
64
|
-
if ('fault' in read)
|
|
65
|
-
return stranger(read.fault === 'not an object' ? 2 : 3);
|
|
66
|
-
const p = read.payload;
|
|
67
|
-
if (isZero ? p.to !== null : p.to !== heir)
|
|
68
|
-
return stranger(3);
|
|
69
|
-
if (isZero) {
|
|
70
|
-
if (!this.behind.zero)
|
|
71
|
-
return stranger(4);
|
|
72
|
-
if (!(await checkBody(unhex(p.by), body)))
|
|
73
|
-
return stranger(5);
|
|
74
|
-
const choice = await this.#choose(null, p);
|
|
75
|
-
return { bytes: await this.#sealed(opened, choice), case: 'object' in choice ? 12 : 13, heard: false };
|
|
76
|
-
}
|
|
77
|
-
if (record === undefined)
|
|
78
|
-
return stranger(6);
|
|
79
|
-
if (!admits(record, heir, p.by))
|
|
80
|
-
return stranger(7);
|
|
81
|
-
if (!(await checkBody(unhex(p.by), body)))
|
|
82
|
-
return stranger(8);
|
|
83
|
-
const reply = await replyKey(this.draw, opened.lid);
|
|
84
|
-
if (!reply)
|
|
85
|
-
return stranger(1);
|
|
86
|
-
const offered = await follow(body.edge, reply.agreement);
|
|
87
|
-
// Checked again, since another arrival may have moved the keys while
|
|
88
|
-
// this one was checking its signature.
|
|
89
|
-
const now = this.relations.get(heir);
|
|
90
|
-
if (now === undefined || !admits(now, heir, p.by) || !opensUnder(now, body.edge))
|
|
91
|
-
return stranger(7);
|
|
92
|
-
if (now.state === 'kept')
|
|
93
|
-
return this.#heard(reply, { quo: 'removed' }, 9);
|
|
94
|
-
if (now.state === 'fresh' && (p.next === null || p.next === heir))
|
|
95
|
-
return this.#heard(reply, { quo: 'unannounced' }, 10);
|
|
96
|
-
if (now.state === 'spent' && !honours(now, p.seq))
|
|
97
|
-
return this.#heard(reply, { quo: 'repeated' }, 11);
|
|
98
|
-
this.relations.set(heir, move(now, heir, p, hex(body.edge), hex(offered)));
|
|
99
|
-
const choice = await this.#choose(heir, p);
|
|
100
|
-
const kept = await this.relations.kept().catch(() => false);
|
|
101
|
-
return this.#heard(reply, kept ? choice : { silence: true }, kept && 'object' in choice ? 12 : 13);
|
|
102
|
-
}
|
|
103
|
-
async #heard(key, reply, n) {
|
|
104
|
-
return { bytes: await sealReply(key, await this.#signed(reply)), case: n, heard: true };
|
|
105
|
-
}
|
|
106
|
-
#signed(reply) {
|
|
107
|
-
return signBody(utf8(writeReply(reply)), this.key.signing);
|
|
108
|
-
}
|
|
109
|
-
async #choose(heir, p) {
|
|
110
|
-
try {
|
|
111
|
-
return await this.behind.answer(heir, p);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
return { silence: true };
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
async #sealed(opened, reply) {
|
|
118
|
-
const key = await replyKey(this.draw, opened.lid);
|
|
119
|
-
return key ? sealReply(key, await this.#signed(reply)) : this.#silence(opened.lid);
|
|
120
|
-
}
|
|
121
|
-
// The body, opened under the edge keys the door takes for this head.
|
|
122
|
-
async #body(opened, record) {
|
|
123
|
-
const tries = [];
|
|
124
|
-
if (record?.state === 'fresh') {
|
|
125
|
-
const knock = splitKnock(opened.rest);
|
|
126
|
-
const lock = this.relations.lock();
|
|
127
|
-
const shared = knock && lock ? decapsulate(lock.dk, knock.ciphertext) : null;
|
|
128
|
-
if (!knock || !shared)
|
|
129
|
-
return null;
|
|
130
|
-
tries.push({ edge: await knockEdge(shared), sealed: knock.sealedBody });
|
|
131
|
-
}
|
|
132
|
-
else if (record === undefined)
|
|
133
|
-
tries.push({ edge: ZERO_EDGE, sealed: opened.rest });
|
|
134
|
-
else
|
|
135
|
-
for (const edge of [record.open, record.offered])
|
|
136
|
-
tries.push({ edge: unhex(edge), sealed: opened.rest });
|
|
137
|
-
for (const { edge, sealed } of tries) {
|
|
138
|
-
const plain = await openBody(opened, edge, sealed);
|
|
139
|
-
if (plain === null)
|
|
140
|
-
continue;
|
|
141
|
-
const body = splitBody(plain);
|
|
142
|
-
return body && { edge, ...body };
|
|
143
|
-
}
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
// A stranger's silence: sealed to the first thirty-two bytes that arrived
|
|
147
|
-
// when they take a seal, and otherwise to a lid nobody holds.
|
|
148
|
-
async #silence(arrived) {
|
|
149
|
-
const text = await this.#signed({ silence: true });
|
|
150
|
-
const candidates = [arrived.length >= HEAD ? arrived.subarray(0, HEAD) : null, this.draw(HEAD)];
|
|
151
|
-
for (const lid of candidates) {
|
|
152
|
-
const key = lid && (await replyKey(this.draw, lid));
|
|
153
|
-
if (key)
|
|
154
|
-
return sealReply(key, text);
|
|
155
|
-
}
|
|
156
|
-
return sealReply((await replyKey(this.draw, await x25519Public(this.draw(HEAD)))), text);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const admits = (record, heir, by) => (record.state === 'fresh' ? by === heir : by === record.held || by === record.vouched);
|
|
160
|
-
const opensUnder = (record, edge) => record.state === 'fresh' || hex(edge) === record.open || hex(edge) === record.offered;
|
|
161
|
-
const honours = (record, seq) => seq > record.highest || (seq > record.highest - SPAN && seq !== record.highest && !record.honoured.includes(seq));
|
|
162
|
-
// The move tables: the keys and edge keys after a choice, and the count.
|
|
163
|
-
const move = (record, heir, p, edge, offered) => {
|
|
164
|
-
const announced = p.next !== null && p.next !== heir && p.next !== p.by ? p.next : null;
|
|
165
|
-
if (record.state === 'fresh')
|
|
166
|
-
return { state: 'spent', held: announced, vouched: null, open: edge, offered, highest: p.seq, honoured: [] };
|
|
167
|
-
if (record.state !== 'spent')
|
|
168
|
-
return record;
|
|
169
|
-
if (p.seq < record.highest)
|
|
170
|
-
return { ...record, honoured: [...record.honoured, p.seq] };
|
|
171
|
-
const keys = p.by === record.held ? { held: record.held, vouched: announced ?? record.vouched, open: edge, offered } : { held: p.by, vouched: announced, open: edge, offered };
|
|
172
|
-
const honoured = [...record.honoured, record.highest].filter((n) => n > p.seq - SPAN);
|
|
173
|
-
return { state: 'spent', ...keys, highest: p.seq, honoured };
|
|
174
|
-
};
|
package/dist/core/quo/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { readAt, schemeOf, tcpAddress, tcpAt, unspecified, webAddress, type TcpAddress, type WebAddress } from './address.ts';
|
|
2
|
-
export { Door, SPAN, type Behind, type Choice, type Judged } from './door.ts';
|
|
3
|
-
export { readInvitation, type Invitation } from './invitation.ts';
|
|
4
|
-
export { Ephemeral, SigningKey, WardKey, type Draw } from './keys.ts';
|
|
5
|
-
export { readPayload, writePayload, type Payload } from './payload.ts';
|
|
6
|
-
export { GONE, keptLock, lockOf, MemoryRelations, type HeirRecord, type KeptLock, type Relations } from './relations.ts';
|
|
7
|
-
export { readReply, SILENCE, WORDS, writeReply, type Reply, type Word } from './reply.ts';
|
|
8
|
-
export { SIZE } from './seal.ts';
|
|
9
|
-
export { freshStanding, Standing, type Read, type Sent, type StandingState } from './standing.ts';
|
package/dist/core/quo/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// Quo's wire: keys, the invitation, the payload, the reply, the boxes, the
|
|
3
|
-
// door and the standing. It knows no being, no ward and no terrain.
|
|
4
|
-
export { readAt, schemeOf, tcpAddress, tcpAt, unspecified, webAddress } from './address.js';
|
|
5
|
-
export { Door, SPAN } from './door.js';
|
|
6
|
-
export { readInvitation } from './invitation.js';
|
|
7
|
-
export { Ephemeral, SigningKey, WardKey } from './keys.js';
|
|
8
|
-
export { readPayload, writePayload } from './payload.js';
|
|
9
|
-
export { GONE, keptLock, lockOf, MemoryRelations } from './relations.js';
|
|
10
|
-
export { readReply, SILENCE, WORDS, writeReply } from './reply.js';
|
|
11
|
-
export { SIZE } from './seal.js';
|
|
12
|
-
export { freshStanding, Standing } from './standing.js';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The invitation: `{ ward, heir, secret, lock, at? }`. A door reads no
|
|
3
|
-
// route from it; `at`, when present, names where the ward is reached.
|
|
4
|
-
import { EK, encapsulate, isHex, unhex } from '../crypto/index.js';
|
|
5
|
-
import { readAt } from './address.js';
|
|
6
|
-
// An invitation, or null for any other shape. A field beside the five is
|
|
7
|
-
// ignored, the lock is held to the modulus check, and `at` keeps the
|
|
8
|
-
// addresses it holds, an `at` with none or of another shape being absent.
|
|
9
|
-
export const readInvitation = (value) => {
|
|
10
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
11
|
-
return null;
|
|
12
|
-
const { ward, heir, secret, lock, at } = value;
|
|
13
|
-
if (!isHex(ward, 64) || !isHex(heir, 32) || !isHex(secret, 32) || !isHex(lock, EK))
|
|
14
|
-
return null;
|
|
15
|
-
if (encapsulate(unhex(lock), new Uint8Array(32)) === null)
|
|
16
|
-
return null;
|
|
17
|
-
const addresses = readAt(at);
|
|
18
|
-
return { ward, heir, secret, lock, ...(addresses.length > 0 ? { at: addresses } : {}) };
|
|
19
|
-
};
|
package/dist/core/quo/keys.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { type Lock } from '../crypto/index.ts';
|
|
2
|
-
export type Draw = (length: number) => Uint8Array;
|
|
3
|
-
export declare const LABEL: {
|
|
4
|
-
readonly seal: Uint8Array<ArrayBufferLike>;
|
|
5
|
-
readonly edgeSeal: Uint8Array<ArrayBufferLike>;
|
|
6
|
-
readonly lock: Uint8Array<ArrayBufferLike>;
|
|
7
|
-
readonly edge: Uint8Array<ArrayBufferLike>;
|
|
8
|
-
readonly wardSign: Uint8Array<ArrayBufferLike>;
|
|
9
|
-
readonly wardSeal: Uint8Array<ArrayBufferLike>;
|
|
10
|
-
};
|
|
11
|
-
export declare class SigningKey {
|
|
12
|
-
readonly secret: Uint8Array;
|
|
13
|
-
readonly pk: Uint8Array;
|
|
14
|
-
private constructor();
|
|
15
|
-
static from(secret: Uint8Array): Promise<SigningKey>;
|
|
16
|
-
static draw(draw: Draw): Promise<SigningKey>;
|
|
17
|
-
get id(): string;
|
|
18
|
-
}
|
|
19
|
-
export declare class Ephemeral {
|
|
20
|
-
readonly secret: Uint8Array;
|
|
21
|
-
readonly pk: Uint8Array;
|
|
22
|
-
private constructor();
|
|
23
|
-
static from(secret: Uint8Array): Promise<Ephemeral>;
|
|
24
|
-
static draw(draw: Draw): Promise<Ephemeral>;
|
|
25
|
-
agree(pk: Uint8Array): Promise<Uint8Array | null>;
|
|
26
|
-
}
|
|
27
|
-
export declare class WardKey {
|
|
28
|
-
readonly signing: SigningKey;
|
|
29
|
-
readonly sealSecret: Uint8Array;
|
|
30
|
-
readonly padlock: Uint8Array;
|
|
31
|
-
private constructor();
|
|
32
|
-
static from(seed: Uint8Array | string): Promise<WardKey>;
|
|
33
|
-
get pk(): string;
|
|
34
|
-
open(lid: Uint8Array): Promise<Uint8Array | null>;
|
|
35
|
-
}
|
|
36
|
-
export declare const wardHalves: (pk: string) => {
|
|
37
|
-
signing: string;
|
|
38
|
-
padlock: string;
|
|
39
|
-
};
|
|
40
|
-
export declare const drawLock: (draw: Draw) => Lock;
|
package/dist/core/quo/keys.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The keys of Quo: the ward key derived from a seed, and every other key
|
|
3
|
-
// drawn. A draw is the caller's, so this layer names no source of bytes.
|
|
4
|
-
import { agree, ed25519Public, hex, hkdf, lockFrom, sha256, utf8, x25519Public } from '../crypto/index.js';
|
|
5
|
-
export const LABEL = {
|
|
6
|
-
seal: utf8('quo-seal'),
|
|
7
|
-
edgeSeal: utf8('quo-edge-seal'),
|
|
8
|
-
lock: utf8('quo-lock'),
|
|
9
|
-
edge: utf8('quo-edge'),
|
|
10
|
-
wardSign: utf8('quo-ward-sign'),
|
|
11
|
-
wardSeal: utf8('quo-ward-seal'),
|
|
12
|
-
};
|
|
13
|
-
// An Ed25519 pair: an heir, or a standing's own key.
|
|
14
|
-
export class SigningKey {
|
|
15
|
-
secret;
|
|
16
|
-
pk;
|
|
17
|
-
constructor(secret, pk) {
|
|
18
|
-
this.secret = secret;
|
|
19
|
-
this.pk = pk;
|
|
20
|
-
}
|
|
21
|
-
static async from(secret) {
|
|
22
|
-
return new SigningKey(secret, await ed25519Public(secret));
|
|
23
|
-
}
|
|
24
|
-
static draw(draw) {
|
|
25
|
-
return SigningKey.from(draw(32));
|
|
26
|
-
}
|
|
27
|
-
get id() {
|
|
28
|
-
return hex(this.pk);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
// An X25519 pair used for one box.
|
|
32
|
-
export class Ephemeral {
|
|
33
|
-
secret;
|
|
34
|
-
pk;
|
|
35
|
-
constructor(secret, pk) {
|
|
36
|
-
this.secret = secret;
|
|
37
|
-
this.pk = pk;
|
|
38
|
-
}
|
|
39
|
-
static async from(secret) {
|
|
40
|
-
return new Ephemeral(secret, await x25519Public(secret));
|
|
41
|
-
}
|
|
42
|
-
static draw(draw) {
|
|
43
|
-
return Ephemeral.from(draw(32));
|
|
44
|
-
}
|
|
45
|
-
agree(pk) {
|
|
46
|
-
return agree(this.secret, pk);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// The ward key: a signing pair and a padlock, both from the seed.
|
|
50
|
-
export class WardKey {
|
|
51
|
-
signing;
|
|
52
|
-
sealSecret;
|
|
53
|
-
padlock;
|
|
54
|
-
constructor(signing, sealSecret, padlock) {
|
|
55
|
-
this.signing = signing;
|
|
56
|
-
this.sealSecret = sealSecret;
|
|
57
|
-
this.padlock = padlock;
|
|
58
|
-
}
|
|
59
|
-
// Thirty-two bytes are the seed. Text, and bytes of any other length, are
|
|
60
|
-
// hashed to it first.
|
|
61
|
-
static async from(seed) {
|
|
62
|
-
const bytes = typeof seed === 'string' ? await sha256(utf8(seed)) : seed.length === 32 ? seed : await sha256(seed);
|
|
63
|
-
const sealSecret = await hkdf(bytes, LABEL.wardSeal, 32);
|
|
64
|
-
return new WardKey(await SigningKey.from(await hkdf(bytes, LABEL.wardSign, 32)), sealSecret, await x25519Public(sealSecret));
|
|
65
|
-
}
|
|
66
|
-
get pk() {
|
|
67
|
-
return hex(this.signing.pk) + hex(this.padlock);
|
|
68
|
-
}
|
|
69
|
-
open(lid) {
|
|
70
|
-
return agree(this.sealSecret, lid);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// A ward pk's two halves.
|
|
74
|
-
export const wardHalves = (pk) => ({ signing: pk.slice(0, 64), padlock: pk.slice(64) });
|
|
75
|
-
// A lock from sixty-four drawn bytes.
|
|
76
|
-
export const drawLock = (draw) => {
|
|
77
|
-
const bytes = draw(64);
|
|
78
|
-
return lockFrom(bytes.subarray(0, 32), bytes.subarray(32));
|
|
79
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export type Payload = {
|
|
2
|
-
readonly to: string | null;
|
|
3
|
-
readonly by: string;
|
|
4
|
-
readonly next: string | null;
|
|
5
|
-
readonly seq: number;
|
|
6
|
-
readonly method?: string;
|
|
7
|
-
readonly args?: string;
|
|
8
|
-
};
|
|
9
|
-
export declare const writePayload: (p: Payload) => string;
|
|
10
|
-
export type PayloadRead = {
|
|
11
|
-
payload: Payload;
|
|
12
|
-
} | {
|
|
13
|
-
fault: 'not an object' | 'not well formed';
|
|
14
|
-
};
|
|
15
|
-
export declare const readPayload: (bytes: Uint8Array) => PayloadRead;
|
package/dist/core/quo/payload.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The payload: `{ to, by, next, seq, method?, args? }`. `args` is carried as
|
|
3
|
-
// the text it was written in, since Quo reads nothing inside it.
|
|
4
|
-
import { isCount, isHex, readObject } from '../crypto/index.js';
|
|
5
|
-
const OWED = ['to', 'by', 'next', 'seq'];
|
|
6
|
-
const ZERO = '0'.repeat(64);
|
|
7
|
-
const isPk = (text) => isHex(text, 32) && text !== ZERO;
|
|
8
|
-
// A pk written as a JSON string, or null written as null.
|
|
9
|
-
const pkOrNull = (text, nullable) => {
|
|
10
|
-
if (nullable && text === 'null')
|
|
11
|
-
return null;
|
|
12
|
-
if (!/^"[0-9a-f]{64}"$/.test(text))
|
|
13
|
-
return undefined;
|
|
14
|
-
const pk = text.slice(1, -1);
|
|
15
|
-
return isPk(pk) ? pk : undefined;
|
|
16
|
-
};
|
|
17
|
-
export const writePayload = (p) => {
|
|
18
|
-
const parts = [`"to":${JSON.stringify(p.to)}`, `"by":"${p.by}"`, `"next":${JSON.stringify(p.next)}`, `"seq":${p.seq}`];
|
|
19
|
-
if (p.method !== undefined)
|
|
20
|
-
parts.push(`"method":${JSON.stringify(p.method)}`);
|
|
21
|
-
if (p.args !== undefined)
|
|
22
|
-
parts.push(`"args":${p.args}`);
|
|
23
|
-
return `{${parts.join(',')}}`;
|
|
24
|
-
};
|
|
25
|
-
// Cases 2 and 3 of the door, before the head is compared.
|
|
26
|
-
export const readPayload = (bytes) => {
|
|
27
|
-
const fields = readObject(bytes);
|
|
28
|
-
if (fields === null)
|
|
29
|
-
return { fault: 'not an object' };
|
|
30
|
-
const bad = { fault: 'not well formed' };
|
|
31
|
-
if (!OWED.every((f) => fields.has(f)))
|
|
32
|
-
return bad;
|
|
33
|
-
const to = pkOrNull(fields.get('to'), true);
|
|
34
|
-
const by = pkOrNull(fields.get('by'), false);
|
|
35
|
-
const next = pkOrNull(fields.get('next'), true);
|
|
36
|
-
const seq = fields.get('seq');
|
|
37
|
-
if (to === undefined || !by || next === undefined || !isCount(seq))
|
|
38
|
-
return bad;
|
|
39
|
-
const method = fields.get('method');
|
|
40
|
-
if (method !== undefined && !method.startsWith('"'))
|
|
41
|
-
return bad;
|
|
42
|
-
const args = fields.get('args');
|
|
43
|
-
if (args !== undefined && !args.startsWith('{'))
|
|
44
|
-
return bad;
|
|
45
|
-
return {
|
|
46
|
-
payload: {
|
|
47
|
-
to,
|
|
48
|
-
by,
|
|
49
|
-
next,
|
|
50
|
-
seq: Number(seq),
|
|
51
|
-
...(method === undefined ? {} : { method: JSON.parse(method) }),
|
|
52
|
-
...(args === undefined ? {} : { args }),
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { Lock } from '../crypto/index.ts';
|
|
2
|
-
export type Keys = {
|
|
3
|
-
readonly held: string;
|
|
4
|
-
readonly vouched: string | null;
|
|
5
|
-
readonly open: string;
|
|
6
|
-
readonly offered: string;
|
|
7
|
-
};
|
|
8
|
-
export type HeirRecord = {
|
|
9
|
-
readonly state: 'fresh';
|
|
10
|
-
} | ({
|
|
11
|
-
readonly state: 'spent';
|
|
12
|
-
readonly highest: number;
|
|
13
|
-
readonly honoured: readonly number[];
|
|
14
|
-
} & Keys) | ({
|
|
15
|
-
readonly state: 'kept';
|
|
16
|
-
} & Keys);
|
|
17
|
-
export type KeptLock = {
|
|
18
|
-
readonly ek: string;
|
|
19
|
-
readonly dk: string;
|
|
20
|
-
};
|
|
21
|
-
export interface Relations {
|
|
22
|
-
lock(): Lock | undefined;
|
|
23
|
-
setLock(lock: Lock): void;
|
|
24
|
-
get(heir: string): HeirRecord | undefined;
|
|
25
|
-
set(heir: string, record: HeirRecord): void;
|
|
26
|
-
delete(heir: string): void;
|
|
27
|
-
kept(): Promise<boolean>;
|
|
28
|
-
}
|
|
29
|
-
export declare const lockOf: (kept: KeptLock | undefined) => Lock | undefined;
|
|
30
|
-
export declare const keptLock: (lock: Lock) => KeptLock;
|
|
31
|
-
export declare const GONE = 256;
|
|
32
|
-
export declare class MemoryRelations implements Relations {
|
|
33
|
-
#private;
|
|
34
|
-
lock(): Lock | undefined;
|
|
35
|
-
setLock(lock: Lock): void;
|
|
36
|
-
get(heir: string): HeirRecord | undefined;
|
|
37
|
-
set(heir: string, record: HeirRecord): void;
|
|
38
|
-
delete(heir: string): void;
|
|
39
|
-
kept(): Promise<boolean>;
|
|
40
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { hex, unhex } from '../crypto/index.js';
|
|
2
|
-
export const lockOf = (kept) => (kept ? { ek: unhex(kept.ek), dk: unhex(kept.dk) } : undefined);
|
|
3
|
-
export const keptLock = (lock) => ({ ek: hex(lock.ek), dk: hex(lock.dk) });
|
|
4
|
-
// A bound on the kept records of removed relations, oldest out.
|
|
5
|
-
export const GONE = 256;
|
|
6
|
-
export class MemoryRelations {
|
|
7
|
-
#lock;
|
|
8
|
-
#heirs = new Map();
|
|
9
|
-
#gone = [];
|
|
10
|
-
lock() {
|
|
11
|
-
return lockOf(this.#lock);
|
|
12
|
-
}
|
|
13
|
-
setLock(lock) {
|
|
14
|
-
this.#lock = keptLock(lock);
|
|
15
|
-
}
|
|
16
|
-
get(heir) {
|
|
17
|
-
return this.#heirs.get(heir);
|
|
18
|
-
}
|
|
19
|
-
set(heir, record) {
|
|
20
|
-
this.#heirs.set(heir, record);
|
|
21
|
-
if (record.state !== 'kept')
|
|
22
|
-
return;
|
|
23
|
-
this.#gone.push(heir);
|
|
24
|
-
while (this.#gone.length > GONE)
|
|
25
|
-
this.#heirs.delete(this.#gone.shift());
|
|
26
|
-
}
|
|
27
|
-
delete(heir) {
|
|
28
|
-
this.#heirs.delete(heir);
|
|
29
|
-
}
|
|
30
|
-
kept() {
|
|
31
|
-
return Promise.resolve(true);
|
|
32
|
-
}
|
|
33
|
-
}
|
package/dist/core/quo/reply.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export declare const WORDS: readonly ['removed', 'unannounced', 'repeated'];
|
|
2
|
-
export type Word = (typeof WORDS)[number];
|
|
3
|
-
export type Reply = {
|
|
4
|
-
readonly object: string;
|
|
5
|
-
readonly seen: string | null;
|
|
6
|
-
} | {
|
|
7
|
-
readonly silence: true;
|
|
8
|
-
} | {
|
|
9
|
-
readonly quo: Word;
|
|
10
|
-
};
|
|
11
|
-
export declare const SILENCE = "{\"silence\":true}";
|
|
12
|
-
export declare const writeReply: (reply: Reply) => string;
|
|
13
|
-
export declare const readReply: (bytes: Uint8Array) => Reply | null;
|