@cello-protocol/protocol-types 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +27 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js.map +1 -1
- package/dist/submission.d.ts +121 -0
- package/dist/submission.d.ts.map +1 -0
- package/dist/submission.js +157 -0
- package/dist/submission.js.map +1 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { encodeCbor, decodeCbor } from "./cbor.js";
|
|
2
2
|
export { TRUST_SIGNAL_DOMAIN, encodeTrustSignalEnvelope, decodeTrustSignalEnvelope, hashTrustSignalEnvelope, verifyTrustSignalHash, } from "./trust-signal.js";
|
|
3
3
|
export type { TrustSignalEnvelope, SignalSubjectKind, SignalIssuerKind, } from "./trust-signal.js";
|
|
4
|
+
export { SUBMISSION_DOMAIN, buildSubmissionTbs, encodeSubmission, decodeSubmission, submissionId, } from "./submission.js";
|
|
5
|
+
export type { SubmissionBody, SubmissionOp, SignedSubmission } from "./submission.js";
|
|
4
6
|
export type { MessageEnvelope, MessageEnvelopeV1, EnvelopeError, BuildResult, BuildResultV1, ValidateResult, ValidateResultV1, DeserializeResult, DeserializeResultV1, } from "./types.js";
|
|
5
7
|
export { MAX_CONTENT_BYTES } from "./limits.js";
|
|
6
8
|
export { encodeStructure1, STRUCTURE1_VERSION } from "./structure1.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAKnD,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAKnD,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEtF,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACjK,YAAY,EACV,iBAAiB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EACnH,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,YAAY,EAChI,eAAe,EAAE,cAAc,EAAE,yBAAyB,EAAE,0BAA0B,GACvF,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,2BAA2B,EAC3B,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EACV,eAAe,EACf,WAAW,EACX,QAAQ,EACR,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACnF,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,4BAA4B,EAC5B,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAGvB,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,10 @@ export { encodeCbor, decodeCbor } from "./cbor.js";
|
|
|
3
3
|
// portal (mint), the directory (submission + presentation), and both daemons (receipt +
|
|
4
4
|
// verification) — M10-D16.
|
|
5
5
|
export { TRUST_SIGNAL_DOMAIN, encodeTrustSignalEnvelope, decodeTrustSignalEnvelope, hashTrustSignalEnvelope, verifyTrustSignalHash, } from "./trust-signal.js";
|
|
6
|
+
// M10B / DOD-END-SUBMIT-1 — the sealed submission wire contract (M10B-D2). ONE implementation,
|
|
7
|
+
// because the daemon signs these bytes and the portal verifies and re-derives them; a byte-identical
|
|
8
|
+
// local copy on each side is how two implementations drift into disagreeing (M10B-D28).
|
|
9
|
+
export { SUBMISSION_DOMAIN, buildSubmissionTbs, encodeSubmission, decodeSubmission, submissionId, } from "./submission.js";
|
|
6
10
|
export { MAX_CONTENT_BYTES } from "./limits.js";
|
|
7
11
|
export { encodeStructure1, STRUCTURE1_VERSION } from "./structure1.js";
|
|
8
12
|
export { SCAN_RESULT_SENTINEL, buildStructure2, encodeStructure2, encodeScanResultSentinel, verifyStructure2Signature, } from "./structure2.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,8FAA8F;AAC9F,wFAAwF;AACxF,2BAA2B;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,8FAA8F;AAC9F,wFAAwF;AACxF,2BAA2B;AAC3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAO3B,+FAA+F;AAC/F,qGAAqG;AACrG,wFAAwF;AACxF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGvE,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AA0BjK,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAmBjC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AA8DnF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAuBvB,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/manifest.d.ts
CHANGED
|
@@ -62,6 +62,20 @@ export interface OfficerSignature {
|
|
|
62
62
|
signature: string;
|
|
63
63
|
}
|
|
64
64
|
/** The full consortium manifest with threshold signatures. */
|
|
65
|
+
/**
|
|
66
|
+
* The portal's intake encryption key, as published in the manifest (M10B-D11).
|
|
67
|
+
*
|
|
68
|
+
* OPTIONAL, and a daemon that does not find it must REFUSE to submit and name the reason — never
|
|
69
|
+
* fall back to sending unsealed (§5a ABSENT IS NOT FINE). An unsealed submission hands the directory
|
|
70
|
+
* every endorsement in the clear, which is the one property the sealed queue exists to provide.
|
|
71
|
+
*/
|
|
72
|
+
export interface ManifestIntakeKey {
|
|
73
|
+
/** Which key this is. Recorded on every queue row, so a rotated-out private key can be retained
|
|
74
|
+
* until no undrained row references it — retention driven by the queue, not by a timer. */
|
|
75
|
+
key_id: string;
|
|
76
|
+
/** Ed25519 public key, hex. Submissions are sealed to this. */
|
|
77
|
+
pubkey: string;
|
|
78
|
+
}
|
|
65
79
|
export interface ConsortiumManifest {
|
|
66
80
|
version: number;
|
|
67
81
|
/** ISO 8601 timestamp — manifest is not valid before this time. */
|
|
@@ -70,6 +84,19 @@ export interface ConsortiumManifest {
|
|
|
70
84
|
expires: string;
|
|
71
85
|
nodes: ConsortiumNode[];
|
|
72
86
|
signatures: OfficerSignature[];
|
|
87
|
+
/**
|
|
88
|
+
* M10B-D11 — the portal's intake key. Additive and optional: manifests written before it still
|
|
89
|
+
* verify byte-for-byte, because `canonicalManifestBody` builds the signed body from
|
|
90
|
+
* `Object.keys(manifest)` minus `signatures`, an OPEN field set. So a new top-level field is
|
|
91
|
+
* automatically covered by the officer signatures — which is the whole reason the manifest is the
|
|
92
|
+
* right channel for a SEALING key. An unauthenticated channel (a `/bootstrap` route, client
|
|
93
|
+
* config) is not a shortcut here: a substituted intake key means every endorsement is sealed to
|
|
94
|
+
* the attacker.
|
|
95
|
+
*
|
|
96
|
+
* Rotation is a manifest version bump the daemon's existing poll rolls forward, under its
|
|
97
|
+
* `manifest_version_rollback` guard.
|
|
98
|
+
*/
|
|
99
|
+
intake_key?: ManifestIntakeKey;
|
|
73
100
|
}
|
|
74
101
|
/** Distinct error codes for manifest verification failures. */
|
|
75
102
|
export type ManifestError = "manifest_signature_invalid" | "manifest_version_rollback" | "manifest_expired";
|
package/dist/manifest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/C,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAEvD;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CAEjF;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GACrB,4BAA4B,GAC5B,2BAA2B,GAC3B,kBAAkB,CAAC;AAEvB,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,aAA4C,CAAC;AAEtF,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,EAAE,aAA2C,CAAC;AAEpF,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAE,aAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/C,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAEvD;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CAEjF;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8DAA8D;AAC9D;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC;gGAC4F;IAC5F,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GACrB,4BAA4B,GAC5B,2BAA2B,GAC3B,kBAAkB,CAAC;AAEvB,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,aAA4C,CAAC;AAEtF,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,EAAE,aAA2C,CAAC;AAEpF,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAE,aAAkC,CAAC"}
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAoB;IAC3C,OAAQ,IAAI,CAAC,IAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;AACxE,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,IAAoB;IAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAoB;IAC3C,OAAQ,IAAI,CAAC,IAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;AACxE,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,IAAoB;IAC9C,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAuDD,qDAAqD;AACrD,MAAM,CAAC,MAAM,0BAA0B,GAAkB,4BAA4B,CAAC;AAEtF,mFAAmF;AACnF,MAAM,CAAC,MAAM,yBAAyB,GAAkB,2BAA2B,CAAC;AAEpF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAkB,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M10B / DOD-END-SUBMIT-1 — the sealed submission wire contract (M10B-D2, D-20, D-28, D-31).
|
|
3
|
+
*
|
|
4
|
+
* The client-supplied source's only wire shape. Bob's daemon builds a body, signs the canonical TBS
|
|
5
|
+
* with his agent's K_local, and seals the encoded pair to the portal's intake key; the directory
|
|
6
|
+
* carries the ciphertext without being able to read it; the portal opens it, verifies, and mints.
|
|
7
|
+
*
|
|
8
|
+
* IT LIVES HERE, NOT IN THE DAEMON, AND THAT IS LOAD-BEARING. Three parties rebuild these bytes
|
|
9
|
+
* independently — the daemon signing, the portal verifying, the portal re-deriving `submission_id`
|
|
10
|
+
* to dedupe a retry. A byte-identical local copy on each side is exactly how two implementations
|
|
11
|
+
* drift apart, and the failure it produces is a signature that will not verify, which reads as a bad
|
|
12
|
+
* key rather than as an encoder disagreement (M10B-D28).
|
|
13
|
+
*
|
|
14
|
+
* THE TBS IS AN ARRAY, NOT A MAP. `cbor.ts` is not deterministic for maps — keys follow insertion
|
|
15
|
+
* order and map headers are not minimal-length — so two parties building the same map in a different
|
|
16
|
+
* field order produce different bytes. Every signed structure in CELLO is a fixed-order array for
|
|
17
|
+
* this reason (`buildAgentRevocationTbs`, `buildPrimaryTransferTbs`, `buildSealTbs`).
|
|
18
|
+
*
|
|
19
|
+
* FIELD ORDER IS THE WIRE FORMAT and the field set is CLOSED. Reordering is a breaking signature
|
|
20
|
+
* change, not a refactor; an unknown field is REJECTED rather than ignored, because silently
|
|
21
|
+
* dropping it would let two parties who disagree about the field set still agree on the signature —
|
|
22
|
+
* making the extra field unauthenticated data riding inside a "verified" submission (spec §4).
|
|
23
|
+
*
|
|
24
|
+
* WHAT IS *NOT* HERE: nothing that names a signal TYPE. The discriminator is `op` — a protocol verb
|
|
25
|
+
* the directory already branches on — and `subject_kind`, which is envelope data. A second
|
|
26
|
+
* client-sourced type sends this identical structure (INV-ZEROBUMP).
|
|
27
|
+
*
|
|
28
|
+
* Crypto: Ed25519 → RFC 8032, CBOR → RFC 8949, SHA-256 → FIPS 180-4.
|
|
29
|
+
*/
|
|
30
|
+
import type { SignalSubjectKind } from "./trust-signal.js";
|
|
31
|
+
/** Domain separation, bound as element 0 — the house convention. Distinct from `CELLO-TSIG-v1` (the
|
|
32
|
+
* envelope preimage) and `CELLO-TSIG-REQ-v1` (the directory's request TBS), so a signature over one
|
|
33
|
+
* can never be replayed as another. */
|
|
34
|
+
export declare const SUBMISSION_DOMAIN = "CELLO-SUBMIT-v1";
|
|
35
|
+
/**
|
|
36
|
+
* What the submitter is ASKING FOR — an operation, never a signal type (M10B-D28).
|
|
37
|
+
*
|
|
38
|
+
* `signal-write.ts` already discriminates its request bodies this way, and the distinction matters
|
|
39
|
+
* for INV-ZEROBUMP: branching on what a signal *means* is forbidden; branching on what the caller is
|
|
40
|
+
* *asking for* is what a protocol verb is. It rides INSIDE the seal, so the directory still cannot
|
|
41
|
+
* tell a withdrawal from an endorsement.
|
|
42
|
+
*
|
|
43
|
+
* `refuse` (M10B-D4) carries the SUBJECT's optional message back to the issuer after she refuses an
|
|
44
|
+
* endorsement about her. It is a third verb rather than a new structure, and widening this union
|
|
45
|
+
* changes no field and no order — so every signature already made over a `submit` or `withdraw`
|
|
46
|
+
* body still verifies. For `refuse` and `withdraw` alike, `subject` is the TARGET SIGNAL HASH: both
|
|
47
|
+
* act on an existing signal instead of asserting a fact about a party.
|
|
48
|
+
*/
|
|
49
|
+
export type SubmissionOp = "submit" | "withdraw" | "refuse";
|
|
50
|
+
/**
|
|
51
|
+
* The signed part of a submission. Every field is inside the TBS — a field outside it is
|
|
52
|
+
* unauthenticated data an attacker can edit in flight while the signature still verifies.
|
|
53
|
+
*/
|
|
54
|
+
export interface SubmissionBody {
|
|
55
|
+
/** Wire version. Signed, so it cannot be downgraded in flight. */
|
|
56
|
+
v: number;
|
|
57
|
+
op: SubmissionOp;
|
|
58
|
+
/** Whose fact this is. The portal resolves an agent subject to an account when it needs one — no
|
|
59
|
+
* account identifier ever crosses the wire (the directory is hash-only by design). */
|
|
60
|
+
subject_kind: SignalSubjectKind;
|
|
61
|
+
/** For `subject_kind: "agent"`, the subject's K_local pubkey hex — the only identifier a contact
|
|
62
|
+
* actually holds. For a withdrawal, the target signal hash. */
|
|
63
|
+
subject: string;
|
|
64
|
+
/**
|
|
65
|
+
* The submitter's K_local pubkey hex.
|
|
66
|
+
*
|
|
67
|
+
* **This field is worthless until the signature verifies against it, and it must never be read for
|
|
68
|
+
* any other purpose.** Ed25519 has no key recovery (RFC 8032), so "derive `issuer_pubkey` from the
|
|
69
|
+
* signature" cannot mean literal recovery — it means the pubkey is present but carries no
|
|
70
|
+
* authority on its own. A body claiming P together with a valid signature by P proves possession
|
|
71
|
+
* of P's private key; a body claiming P with any other signature proves nothing and must be
|
|
72
|
+
* refused. Reading it before verification is the INV-ATTRIBUTION defect: anyone could mint an
|
|
73
|
+
* endorsement attributed to anyone, permanently, inside the hash.
|
|
74
|
+
*/
|
|
75
|
+
submitter_pubkey: string;
|
|
76
|
+
/** The operator's own words, untrusted and unscanned at this layer. Scanned at intake, BEFORE
|
|
77
|
+
* hashing (spec §6), and never restated in the portal's attested voice (INV-UNTRUSTED). */
|
|
78
|
+
body: string;
|
|
79
|
+
/** Integer epoch SECONDS. Inside the TBS, so the verifier's clock-skew bound applies — without it
|
|
80
|
+
* a signature is a permanent bearer capability replayable at every node forever (M10B-D28). */
|
|
81
|
+
issued_at: number;
|
|
82
|
+
}
|
|
83
|
+
/** A decoded submission: the body as signed, plus the detached signature over its TBS. */
|
|
84
|
+
export interface SignedSubmission {
|
|
85
|
+
body: SubmissionBody;
|
|
86
|
+
signature: Uint8Array;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Canonical to-be-signed bytes. Field order is LOAD-BEARING — the daemon signing and the portal
|
|
90
|
+
* verifying must produce identical bytes, across two repos, forever.
|
|
91
|
+
*/
|
|
92
|
+
export declare function buildSubmissionTbs(body: SubmissionBody): Uint8Array;
|
|
93
|
+
/** The sealed plaintext: the TBS fields followed by the detached signature. */
|
|
94
|
+
export declare function encodeSubmission(body: SubmissionBody, signature: Uint8Array): Uint8Array;
|
|
95
|
+
/**
|
|
96
|
+
* Decode a sealed submission's plaintext.
|
|
97
|
+
*
|
|
98
|
+
* THROWS on anything it does not fully recognise, and that is the design. A submission that cannot
|
|
99
|
+
* be decoded is POISON — the identity is derived from the signature, so an unparseable body has no
|
|
100
|
+
* known sender and there is nobody to reply to (M10B-D22b). The failure must therefore be loud
|
|
101
|
+
* HERE, not a partly-populated body that flows onward and gets attributed to whatever
|
|
102
|
+
* `submitter_pubkey` happened to decode as.
|
|
103
|
+
*/
|
|
104
|
+
export declare function decodeSubmission(bytes: Uint8Array): SignedSubmission;
|
|
105
|
+
/**
|
|
106
|
+
* `submission_id` — sha256 over the ENCODED signed submission (M10B-D20), lowercase hex.
|
|
107
|
+
*
|
|
108
|
+
* Content-derived, which is what makes retry-across-nodes safe rather than a duplication mechanism:
|
|
109
|
+
* a daemon that fails over to a second node produces the same id, so the second row is a strict
|
|
110
|
+
* no-op. A legitimate re-issue after a refusal differs, because `issued_at` is inside the signed
|
|
111
|
+
* body — otherwise the portal would dedupe Bob's correction away as a retry and Alice would never
|
|
112
|
+
* see it.
|
|
113
|
+
*
|
|
114
|
+
* **At the directory this id is a ROUTING HINT and nothing more.** The directory cannot open the
|
|
115
|
+
* seal, so it cannot check that the id matches the bytes; the portal re-derives it from the opened
|
|
116
|
+
* body and discards any row whose id disagrees. A daemon writing the same body under two different
|
|
117
|
+
* ids to two nodes would otherwise get two mints and double quota consumption (M10B-D20's
|
|
118
|
+
* second-review correction).
|
|
119
|
+
*/
|
|
120
|
+
export declare function submissionId(encodedSubmission: Uint8Array): string;
|
|
121
|
+
//# sourceMappingURL=submission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;wCAEwC;AACxC,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAO5D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,YAAY,CAAC;IACjB;2FACuF;IACvF,YAAY,EAAE,iBAAiB,CAAC;IAChC;oEACgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;gGAC4F;IAC5F,IAAI,EAAE,MAAM,CAAC;IACb;oGACgG;IAChG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,0FAA0F;AAC1F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAWnE;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAYxF;AAeD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,CA6CpE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,EAAE,UAAU,GAAG,MAAM,CAElE"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M10B / DOD-END-SUBMIT-1 — the sealed submission wire contract (M10B-D2, D-20, D-28, D-31).
|
|
3
|
+
*
|
|
4
|
+
* The client-supplied source's only wire shape. Bob's daemon builds a body, signs the canonical TBS
|
|
5
|
+
* with his agent's K_local, and seals the encoded pair to the portal's intake key; the directory
|
|
6
|
+
* carries the ciphertext without being able to read it; the portal opens it, verifies, and mints.
|
|
7
|
+
*
|
|
8
|
+
* IT LIVES HERE, NOT IN THE DAEMON, AND THAT IS LOAD-BEARING. Three parties rebuild these bytes
|
|
9
|
+
* independently — the daemon signing, the portal verifying, the portal re-deriving `submission_id`
|
|
10
|
+
* to dedupe a retry. A byte-identical local copy on each side is exactly how two implementations
|
|
11
|
+
* drift apart, and the failure it produces is a signature that will not verify, which reads as a bad
|
|
12
|
+
* key rather than as an encoder disagreement (M10B-D28).
|
|
13
|
+
*
|
|
14
|
+
* THE TBS IS AN ARRAY, NOT A MAP. `cbor.ts` is not deterministic for maps — keys follow insertion
|
|
15
|
+
* order and map headers are not minimal-length — so two parties building the same map in a different
|
|
16
|
+
* field order produce different bytes. Every signed structure in CELLO is a fixed-order array for
|
|
17
|
+
* this reason (`buildAgentRevocationTbs`, `buildPrimaryTransferTbs`, `buildSealTbs`).
|
|
18
|
+
*
|
|
19
|
+
* FIELD ORDER IS THE WIRE FORMAT and the field set is CLOSED. Reordering is a breaking signature
|
|
20
|
+
* change, not a refactor; an unknown field is REJECTED rather than ignored, because silently
|
|
21
|
+
* dropping it would let two parties who disagree about the field set still agree on the signature —
|
|
22
|
+
* making the extra field unauthenticated data riding inside a "verified" submission (spec §4).
|
|
23
|
+
*
|
|
24
|
+
* WHAT IS *NOT* HERE: nothing that names a signal TYPE. The discriminator is `op` — a protocol verb
|
|
25
|
+
* the directory already branches on — and `subject_kind`, which is envelope data. A second
|
|
26
|
+
* client-sourced type sends this identical structure (INV-ZEROBUMP).
|
|
27
|
+
*
|
|
28
|
+
* Crypto: Ed25519 → RFC 8032, CBOR → RFC 8949, SHA-256 → FIPS 180-4.
|
|
29
|
+
*/
|
|
30
|
+
import { hash as sha256 } from "@cello-protocol/crypto";
|
|
31
|
+
import { encodeCbor, decodeCbor } from "./cbor.js";
|
|
32
|
+
/** Domain separation, bound as element 0 — the house convention. Distinct from `CELLO-TSIG-v1` (the
|
|
33
|
+
* envelope preimage) and `CELLO-TSIG-REQ-v1` (the directory's request TBS), so a signature over one
|
|
34
|
+
* can never be replayed as another. */
|
|
35
|
+
export const SUBMISSION_DOMAIN = "CELLO-SUBMIT-v1";
|
|
36
|
+
/** The number of elements in the TBS array, INCLUDING the domain tag. Bump only with the wire. */
|
|
37
|
+
const TBS_ARITY = 8;
|
|
38
|
+
/** The encoded submission is the TBS fields plus the detached signature. */
|
|
39
|
+
const ENCODED_ARITY = TBS_ARITY + 1;
|
|
40
|
+
/**
|
|
41
|
+
* Canonical to-be-signed bytes. Field order is LOAD-BEARING — the daemon signing and the portal
|
|
42
|
+
* verifying must produce identical bytes, across two repos, forever.
|
|
43
|
+
*/
|
|
44
|
+
export function buildSubmissionTbs(body) {
|
|
45
|
+
return encodeCbor([
|
|
46
|
+
SUBMISSION_DOMAIN,
|
|
47
|
+
body.v,
|
|
48
|
+
body.op,
|
|
49
|
+
body.subject_kind,
|
|
50
|
+
body.subject,
|
|
51
|
+
body.submitter_pubkey,
|
|
52
|
+
body.body,
|
|
53
|
+
body.issued_at,
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
/** The sealed plaintext: the TBS fields followed by the detached signature. */
|
|
57
|
+
export function encodeSubmission(body, signature) {
|
|
58
|
+
return encodeCbor([
|
|
59
|
+
SUBMISSION_DOMAIN,
|
|
60
|
+
body.v,
|
|
61
|
+
body.op,
|
|
62
|
+
body.subject_kind,
|
|
63
|
+
body.subject,
|
|
64
|
+
body.submitter_pubkey,
|
|
65
|
+
body.body,
|
|
66
|
+
body.issued_at,
|
|
67
|
+
signature,
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
function str(v, field) {
|
|
71
|
+
if (typeof v !== "string")
|
|
72
|
+
throw new Error(`submission_malformed: ${field} must be a string`);
|
|
73
|
+
return v;
|
|
74
|
+
}
|
|
75
|
+
function int(v, field) {
|
|
76
|
+
const n = typeof v === "bigint" ? Number(v) : v;
|
|
77
|
+
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
78
|
+
throw new Error(`submission_malformed: ${field} must be an integer`);
|
|
79
|
+
}
|
|
80
|
+
return n;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Decode a sealed submission's plaintext.
|
|
84
|
+
*
|
|
85
|
+
* THROWS on anything it does not fully recognise, and that is the design. A submission that cannot
|
|
86
|
+
* be decoded is POISON — the identity is derived from the signature, so an unparseable body has no
|
|
87
|
+
* known sender and there is nobody to reply to (M10B-D22b). The failure must therefore be loud
|
|
88
|
+
* HERE, not a partly-populated body that flows onward and gets attributed to whatever
|
|
89
|
+
* `submitter_pubkey` happened to decode as.
|
|
90
|
+
*/
|
|
91
|
+
export function decodeSubmission(bytes) {
|
|
92
|
+
let decoded;
|
|
93
|
+
try {
|
|
94
|
+
decoded = decodeCbor(bytes);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
throw new Error(`submission_malformed: not valid CBOR: ${err instanceof Error ? err.message : String(err)}`);
|
|
98
|
+
}
|
|
99
|
+
if (!Array.isArray(decoded))
|
|
100
|
+
throw new Error("submission_malformed: expected an array");
|
|
101
|
+
if (decoded.length !== ENCODED_ARITY) {
|
|
102
|
+
// Closed field set: a longer array is an unknown field, a shorter one is a missing field, and
|
|
103
|
+
// both must refuse rather than be read positionally into the wrong slots.
|
|
104
|
+
throw new Error(`submission_malformed: expected ${ENCODED_ARITY} elements, got ${decoded.length}`);
|
|
105
|
+
}
|
|
106
|
+
if (decoded[0] !== SUBMISSION_DOMAIN) {
|
|
107
|
+
throw new Error(`submission_malformed: wrong domain tag — refusing to read a foreign structure`);
|
|
108
|
+
}
|
|
109
|
+
const op = str(decoded[2], "op");
|
|
110
|
+
if (op !== "submit" && op !== "withdraw" && op !== "refuse") {
|
|
111
|
+
throw new Error(`submission_malformed: unknown op '${op}'`);
|
|
112
|
+
}
|
|
113
|
+
const subjectKind = str(decoded[3], "subject_kind");
|
|
114
|
+
if (subjectKind !== "agent" && subjectKind !== "account") {
|
|
115
|
+
throw new Error(`submission_malformed: unknown subject_kind '${subjectKind}'`);
|
|
116
|
+
}
|
|
117
|
+
const signature = decoded[8];
|
|
118
|
+
if (!(signature instanceof Uint8Array)) {
|
|
119
|
+
throw new Error("submission_malformed: signature must be bytes");
|
|
120
|
+
}
|
|
121
|
+
// The CBOR decoder hands back a Node `Buffer` (a Uint8Array SUBCLASS). Normalise it, so the
|
|
122
|
+
// declared type is the actual type: a caller that received a Buffer here could come to depend on
|
|
123
|
+
// Buffer-only methods, and the same code would then break in any runtime whose decoder returns a
|
|
124
|
+
// plain view. Copying 64 bytes is not a cost worth trading that for.
|
|
125
|
+
const signatureBytes = new Uint8Array(signature);
|
|
126
|
+
return {
|
|
127
|
+
body: {
|
|
128
|
+
v: int(decoded[1], "v"),
|
|
129
|
+
op,
|
|
130
|
+
subject_kind: subjectKind,
|
|
131
|
+
subject: str(decoded[4], "subject"),
|
|
132
|
+
submitter_pubkey: str(decoded[5], "submitter_pubkey"),
|
|
133
|
+
body: str(decoded[6], "body"),
|
|
134
|
+
issued_at: int(decoded[7], "issued_at"),
|
|
135
|
+
},
|
|
136
|
+
signature: signatureBytes,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* `submission_id` — sha256 over the ENCODED signed submission (M10B-D20), lowercase hex.
|
|
141
|
+
*
|
|
142
|
+
* Content-derived, which is what makes retry-across-nodes safe rather than a duplication mechanism:
|
|
143
|
+
* a daemon that fails over to a second node produces the same id, so the second row is a strict
|
|
144
|
+
* no-op. A legitimate re-issue after a refusal differs, because `issued_at` is inside the signed
|
|
145
|
+
* body — otherwise the portal would dedupe Bob's correction away as a retry and Alice would never
|
|
146
|
+
* see it.
|
|
147
|
+
*
|
|
148
|
+
* **At the directory this id is a ROUTING HINT and nothing more.** The directory cannot open the
|
|
149
|
+
* seal, so it cannot check that the id matches the bytes; the portal re-derives it from the opened
|
|
150
|
+
* body and discards any row whose id disagrees. A daemon writing the same body under two different
|
|
151
|
+
* ids to two nodes would otherwise get two mints and double quota consumption (M10B-D20's
|
|
152
|
+
* second-review correction).
|
|
153
|
+
*/
|
|
154
|
+
export function submissionId(encodedSubmission) {
|
|
155
|
+
return Buffer.from(sha256(encodedSubmission)).toString("hex");
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=submission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submission.js","sourceRoot":"","sources":["../src/submission.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cello-protocol/protocol-types",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"cbor-x": "^1.6.4",
|
|
29
|
-
"@cello-protocol/crypto": "0.0.
|
|
29
|
+
"@cello-protocol/crypto": "0.0.26"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@claude-flow/testing": "3.0.0-alpha.6",
|