@ottochain/sdk 2.2.3 → 2.2.4
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.
|
@@ -3,32 +3,41 @@
|
|
|
3
3
|
* Normalize OttoChain Messages for Signing
|
|
4
4
|
*
|
|
5
5
|
* Converts OttoChain message objects to the wire format expected by the
|
|
6
|
-
* Scala metagraph.
|
|
7
|
-
*
|
|
8
|
-
* produces on the Scala side.
|
|
6
|
+
* Scala metagraph. Metakit's JsonBinaryCodec (used by OttoChain for data
|
|
7
|
+
* transaction signing) canonicalizes JSON with dropNullValues = true.
|
|
9
8
|
*
|
|
10
|
-
* This is
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* JSON won't match and signature verification will fail.
|
|
9
|
+
* NOTE: This is Metakit's codec, NOT tessellation's JsonSerializer (which
|
|
10
|
+
* uses Brotli compression for snapshots/consensus — a different layer).
|
|
11
|
+
* Different layers use different byte-sequence encoders.
|
|
14
12
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Because Metakit drops null fields during canonicalization, the canonical
|
|
14
|
+
* JSON used for signature verification **omits** null fields entirely.
|
|
15
|
+
* If the TypeScript client includes explicit nulls (e.g., `"metadata": null`),
|
|
16
|
+
* the canonical form won't match and signature verification will fail.
|
|
17
|
+
*
|
|
18
|
+
* Schema mapping (Scala → TypeScript wire format):
|
|
19
|
+
* - `Option[A] = None` → field OMITTED (not null, not undefined)
|
|
17
20
|
* - `Option[A] = Some(v)` → `v`
|
|
18
|
-
* - `List.empty` → `[]`
|
|
21
|
+
* - `List.empty` / `Set.empty` → `[]`
|
|
19
22
|
* - `Map.empty` → `{}`
|
|
23
|
+
* - `Boolean = false` → `false` (always include, not a null/Option)
|
|
20
24
|
*/
|
|
21
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
26
|
exports.normalizeMessage = exports.normalizeArchiveStateMachine = exports.normalizeTransitionStateMachine = exports.normalizeCreateStateMachine = void 0;
|
|
23
27
|
/**
|
|
24
|
-
* Normalize a State object for wire format
|
|
28
|
+
* Normalize a State object for wire format.
|
|
29
|
+
* State: id (required), isFinal (default false), metadata (Option = None)
|
|
30
|
+
* Omit metadata when null/undefined (dropNullValues).
|
|
25
31
|
*/
|
|
26
32
|
function normalizeState(state) {
|
|
27
|
-
|
|
33
|
+
const result = {
|
|
28
34
|
id: state.id,
|
|
29
35
|
isFinal: state.isFinal ?? false,
|
|
30
|
-
metadata: state.metadata ?? null,
|
|
31
36
|
};
|
|
37
|
+
if (state.metadata != null) {
|
|
38
|
+
result.metadata = state.metadata;
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
43
|
* Normalize a Transition object for wire format
|
|
@@ -80,43 +89,54 @@ function normalizeDefinition(def) {
|
|
|
80
89
|
}
|
|
81
90
|
const transitions = def.transitions ?? [];
|
|
82
91
|
// Strip FiberAppMetadata if present — it's TypeScript-only, not part of wire format.
|
|
83
|
-
//
|
|
84
|
-
const wireMetadata = isFiberAppMetadata(def.metadata) ?
|
|
85
|
-
|
|
92
|
+
// Omit metadata entirely when null/FiberAppMetadata (dropNullValues = true on Scala side).
|
|
93
|
+
const wireMetadata = isFiberAppMetadata(def.metadata) ? undefined : def.metadata;
|
|
94
|
+
const result = {
|
|
86
95
|
states: normalizedStates,
|
|
87
96
|
initialState: def.initialState,
|
|
88
97
|
transitions: transitions.map(normalizeTransition),
|
|
89
|
-
metadata: wireMetadata,
|
|
90
98
|
};
|
|
99
|
+
if (wireMetadata != null) {
|
|
100
|
+
result.metadata = wireMetadata;
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
91
103
|
}
|
|
92
104
|
/**
|
|
93
105
|
* Normalize a CreateStateMachine message for wire format
|
|
94
106
|
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* -
|
|
100
|
-
* -
|
|
107
|
+
* Metakit's JsonBinaryCodec uses dropNullValues = true for canonicalization.
|
|
108
|
+
* Optional fields at their defaults must be OMITTED (not set to null)
|
|
109
|
+
* to match the canonical JSON used for signature verification.
|
|
110
|
+
*
|
|
111
|
+
* - definition.metadata → OMITTED when absent/FiberAppMetadata
|
|
112
|
+
* - definition.states[*].metadata → OMITTED when absent
|
|
113
|
+
* - definition.transitions[*].dependencies → [] (Set.empty default, always included)
|
|
114
|
+
* - parentFiberId → OMITTED when absent (Option[UUID] = None)
|
|
115
|
+
* - participants → OMITTED when absent (Option[Set[Address]] = None)
|
|
101
116
|
*
|
|
102
117
|
* @example
|
|
103
118
|
* ```typescript
|
|
104
119
|
* const message = normalizeCreateStateMachine({
|
|
105
120
|
* fiberId: '...',
|
|
106
|
-
* definition: { states: { INIT: { id:
|
|
121
|
+
* definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
|
|
107
122
|
* initialData: {}
|
|
108
123
|
* });
|
|
109
|
-
* //
|
|
124
|
+
* // Optional fields are absent (not null): no parentFiberId, no metadata, etc.
|
|
110
125
|
* ```
|
|
111
126
|
*/
|
|
112
127
|
function normalizeCreateStateMachine(msg) {
|
|
113
|
-
|
|
128
|
+
const result = {
|
|
114
129
|
fiberId: msg.fiberId,
|
|
115
130
|
definition: normalizeDefinition(msg.definition),
|
|
116
131
|
initialData: msg.initialData ?? {},
|
|
117
|
-
parentFiberId: msg.parentFiberId ?? null,
|
|
118
|
-
participants: msg.participants ?? null,
|
|
119
132
|
};
|
|
133
|
+
if (msg.parentFiberId != null) {
|
|
134
|
+
result.parentFiberId = msg.parentFiberId;
|
|
135
|
+
}
|
|
136
|
+
if (msg.participants != null) {
|
|
137
|
+
result.participants = msg.participants;
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
120
140
|
}
|
|
121
141
|
exports.normalizeCreateStateMachine = normalizeCreateStateMachine;
|
|
122
142
|
/**
|
|
@@ -2,30 +2,39 @@
|
|
|
2
2
|
* Normalize OttoChain Messages for Signing
|
|
3
3
|
*
|
|
4
4
|
* Converts OttoChain message objects to the wire format expected by the
|
|
5
|
-
* Scala metagraph.
|
|
6
|
-
*
|
|
7
|
-
* produces on the Scala side.
|
|
5
|
+
* Scala metagraph. Metakit's JsonBinaryCodec (used by OttoChain for data
|
|
6
|
+
* transaction signing) canonicalizes JSON with dropNullValues = true.
|
|
8
7
|
*
|
|
9
|
-
* This is
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* JSON won't match and signature verification will fail.
|
|
8
|
+
* NOTE: This is Metakit's codec, NOT tessellation's JsonSerializer (which
|
|
9
|
+
* uses Brotli compression for snapshots/consensus — a different layer).
|
|
10
|
+
* Different layers use different byte-sequence encoders.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Because Metakit drops null fields during canonicalization, the canonical
|
|
13
|
+
* JSON used for signature verification **omits** null fields entirely.
|
|
14
|
+
* If the TypeScript client includes explicit nulls (e.g., `"metadata": null`),
|
|
15
|
+
* the canonical form won't match and signature verification will fail.
|
|
16
|
+
*
|
|
17
|
+
* Schema mapping (Scala → TypeScript wire format):
|
|
18
|
+
* - `Option[A] = None` → field OMITTED (not null, not undefined)
|
|
16
19
|
* - `Option[A] = Some(v)` → `v`
|
|
17
|
-
* - `List.empty` → `[]`
|
|
20
|
+
* - `List.empty` / `Set.empty` → `[]`
|
|
18
21
|
* - `Map.empty` → `{}`
|
|
22
|
+
* - `Boolean = false` → `false` (always include, not a null/Option)
|
|
19
23
|
*/
|
|
20
24
|
/**
|
|
21
|
-
* Normalize a State object for wire format
|
|
25
|
+
* Normalize a State object for wire format.
|
|
26
|
+
* State: id (required), isFinal (default false), metadata (Option = None)
|
|
27
|
+
* Omit metadata when null/undefined (dropNullValues).
|
|
22
28
|
*/
|
|
23
29
|
function normalizeState(state) {
|
|
24
|
-
|
|
30
|
+
const result = {
|
|
25
31
|
id: state.id,
|
|
26
32
|
isFinal: state.isFinal ?? false,
|
|
27
|
-
metadata: state.metadata ?? null,
|
|
28
33
|
};
|
|
34
|
+
if (state.metadata != null) {
|
|
35
|
+
result.metadata = state.metadata;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
29
38
|
}
|
|
30
39
|
/**
|
|
31
40
|
* Normalize a Transition object for wire format
|
|
@@ -77,43 +86,54 @@ function normalizeDefinition(def) {
|
|
|
77
86
|
}
|
|
78
87
|
const transitions = def.transitions ?? [];
|
|
79
88
|
// Strip FiberAppMetadata if present — it's TypeScript-only, not part of wire format.
|
|
80
|
-
//
|
|
81
|
-
const wireMetadata = isFiberAppMetadata(def.metadata) ?
|
|
82
|
-
|
|
89
|
+
// Omit metadata entirely when null/FiberAppMetadata (dropNullValues = true on Scala side).
|
|
90
|
+
const wireMetadata = isFiberAppMetadata(def.metadata) ? undefined : def.metadata;
|
|
91
|
+
const result = {
|
|
83
92
|
states: normalizedStates,
|
|
84
93
|
initialState: def.initialState,
|
|
85
94
|
transitions: transitions.map(normalizeTransition),
|
|
86
|
-
metadata: wireMetadata,
|
|
87
95
|
};
|
|
96
|
+
if (wireMetadata != null) {
|
|
97
|
+
result.metadata = wireMetadata;
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
88
100
|
}
|
|
89
101
|
/**
|
|
90
102
|
* Normalize a CreateStateMachine message for wire format
|
|
91
103
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* -
|
|
97
|
-
* -
|
|
104
|
+
* Metakit's JsonBinaryCodec uses dropNullValues = true for canonicalization.
|
|
105
|
+
* Optional fields at their defaults must be OMITTED (not set to null)
|
|
106
|
+
* to match the canonical JSON used for signature verification.
|
|
107
|
+
*
|
|
108
|
+
* - definition.metadata → OMITTED when absent/FiberAppMetadata
|
|
109
|
+
* - definition.states[*].metadata → OMITTED when absent
|
|
110
|
+
* - definition.transitions[*].dependencies → [] (Set.empty default, always included)
|
|
111
|
+
* - parentFiberId → OMITTED when absent (Option[UUID] = None)
|
|
112
|
+
* - participants → OMITTED when absent (Option[Set[Address]] = None)
|
|
98
113
|
*
|
|
99
114
|
* @example
|
|
100
115
|
* ```typescript
|
|
101
116
|
* const message = normalizeCreateStateMachine({
|
|
102
117
|
* fiberId: '...',
|
|
103
|
-
* definition: { states: { INIT: { id:
|
|
118
|
+
* definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
|
|
104
119
|
* initialData: {}
|
|
105
120
|
* });
|
|
106
|
-
* //
|
|
121
|
+
* // Optional fields are absent (not null): no parentFiberId, no metadata, etc.
|
|
107
122
|
* ```
|
|
108
123
|
*/
|
|
109
124
|
export function normalizeCreateStateMachine(msg) {
|
|
110
|
-
|
|
125
|
+
const result = {
|
|
111
126
|
fiberId: msg.fiberId,
|
|
112
127
|
definition: normalizeDefinition(msg.definition),
|
|
113
128
|
initialData: msg.initialData ?? {},
|
|
114
|
-
parentFiberId: msg.parentFiberId ?? null,
|
|
115
|
-
participants: msg.participants ?? null,
|
|
116
129
|
};
|
|
130
|
+
if (msg.parentFiberId != null) {
|
|
131
|
+
result.parentFiberId = msg.parentFiberId;
|
|
132
|
+
}
|
|
133
|
+
if (msg.participants != null) {
|
|
134
|
+
result.participants = msg.participants;
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
117
137
|
}
|
|
118
138
|
/**
|
|
119
139
|
* Normalize a TransitionStateMachine message for wire format
|
|
@@ -2,39 +2,46 @@
|
|
|
2
2
|
* Normalize OttoChain Messages for Signing
|
|
3
3
|
*
|
|
4
4
|
* Converts OttoChain message objects to the wire format expected by the
|
|
5
|
-
* Scala metagraph.
|
|
6
|
-
*
|
|
7
|
-
* produces on the Scala side.
|
|
5
|
+
* Scala metagraph. Metakit's JsonBinaryCodec (used by OttoChain for data
|
|
6
|
+
* transaction signing) canonicalizes JSON with dropNullValues = true.
|
|
8
7
|
*
|
|
9
|
-
* This is
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* JSON won't match and signature verification will fail.
|
|
8
|
+
* NOTE: This is Metakit's codec, NOT tessellation's JsonSerializer (which
|
|
9
|
+
* uses Brotli compression for snapshots/consensus — a different layer).
|
|
10
|
+
* Different layers use different byte-sequence encoders.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Because Metakit drops null fields during canonicalization, the canonical
|
|
13
|
+
* JSON used for signature verification **omits** null fields entirely.
|
|
14
|
+
* If the TypeScript client includes explicit nulls (e.g., `"metadata": null`),
|
|
15
|
+
* the canonical form won't match and signature verification will fail.
|
|
16
|
+
*
|
|
17
|
+
* Schema mapping (Scala → TypeScript wire format):
|
|
18
|
+
* - `Option[A] = None` → field OMITTED (not null, not undefined)
|
|
16
19
|
* - `Option[A] = Some(v)` → `v`
|
|
17
|
-
* - `List.empty` → `[]`
|
|
20
|
+
* - `List.empty` / `Set.empty` → `[]`
|
|
18
21
|
* - `Map.empty` → `{}`
|
|
22
|
+
* - `Boolean = false` → `false` (always include, not a null/Option)
|
|
19
23
|
*/
|
|
20
24
|
/**
|
|
21
25
|
* Normalize a CreateStateMachine message for wire format
|
|
22
26
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* -
|
|
28
|
-
* -
|
|
27
|
+
* Metakit's JsonBinaryCodec uses dropNullValues = true for canonicalization.
|
|
28
|
+
* Optional fields at their defaults must be OMITTED (not set to null)
|
|
29
|
+
* to match the canonical JSON used for signature verification.
|
|
30
|
+
*
|
|
31
|
+
* - definition.metadata → OMITTED when absent/FiberAppMetadata
|
|
32
|
+
* - definition.states[*].metadata → OMITTED when absent
|
|
33
|
+
* - definition.transitions[*].dependencies → [] (Set.empty default, always included)
|
|
34
|
+
* - parentFiberId → OMITTED when absent (Option[UUID] = None)
|
|
35
|
+
* - participants → OMITTED when absent (Option[Set[Address]] = None)
|
|
29
36
|
*
|
|
30
37
|
* @example
|
|
31
38
|
* ```typescript
|
|
32
39
|
* const message = normalizeCreateStateMachine({
|
|
33
40
|
* fiberId: '...',
|
|
34
|
-
* definition: { states: { INIT: { id:
|
|
41
|
+
* definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
|
|
35
42
|
* initialData: {}
|
|
36
43
|
* });
|
|
37
|
-
* //
|
|
44
|
+
* // Optional fields are absent (not null): no parentFiberId, no metadata, etc.
|
|
38
45
|
* ```
|
|
39
46
|
*/
|
|
40
47
|
export declare function normalizeCreateStateMachine(msg: Record<string, unknown>): Record<string, unknown>;
|
package/package.json
CHANGED