@ottochain/sdk 2.2.4 → 2.2.5
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,41 +3,32 @@
|
|
|
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
|
-
*
|
|
6
|
+
* Scala metagraph. Specifically, ensures all `Option[A]=None` fields are
|
|
7
|
+
* present as explicit `null` values, matching what circe's magnolia encoder
|
|
8
|
+
* produces on the Scala side.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* This is necessary because metakit's `JsonBinaryCodec.deriveDataUpdate`
|
|
11
|
+
* (rc.8) canonicalizes the circe-encoded JSON **including null fields**.
|
|
12
|
+
* If the TypeScript client omits optional fields (undefined), the canonical
|
|
13
|
+
* JSON won't match and signature verification will fail.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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)
|
|
15
|
+
* Schema mapping (Scala → TypeScript):
|
|
16
|
+
* - `Option[A] = None` → `null` (must be explicit, not undefined/absent)
|
|
20
17
|
* - `Option[A] = Some(v)` → `v`
|
|
21
|
-
* - `List.empty`
|
|
18
|
+
* - `List.empty` → `[]`
|
|
22
19
|
* - `Map.empty` → `{}`
|
|
23
|
-
* - `Boolean = false` → `false` (always include, not a null/Option)
|
|
24
20
|
*/
|
|
25
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
22
|
exports.normalizeMessage = exports.normalizeArchiveStateMachine = exports.normalizeTransitionStateMachine = exports.normalizeCreateStateMachine = void 0;
|
|
27
23
|
/**
|
|
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).
|
|
24
|
+
* Normalize a State object for wire format
|
|
31
25
|
*/
|
|
32
26
|
function normalizeState(state) {
|
|
33
|
-
|
|
27
|
+
return {
|
|
34
28
|
id: state.id,
|
|
35
29
|
isFinal: state.isFinal ?? false,
|
|
30
|
+
metadata: state.metadata ?? null,
|
|
36
31
|
};
|
|
37
|
-
if (state.metadata != null) {
|
|
38
|
-
result.metadata = state.metadata;
|
|
39
|
-
}
|
|
40
|
-
return result;
|
|
41
32
|
}
|
|
42
33
|
/**
|
|
43
34
|
* Normalize a Transition object for wire format
|
|
@@ -89,54 +80,41 @@ function normalizeDefinition(def) {
|
|
|
89
80
|
}
|
|
90
81
|
const transitions = def.transitions ?? [];
|
|
91
82
|
// Strip FiberAppMetadata if present — it's TypeScript-only, not part of wire format.
|
|
92
|
-
//
|
|
93
|
-
const wireMetadata = isFiberAppMetadata(def.metadata) ?
|
|
94
|
-
|
|
83
|
+
// The Scala schema has `metadata: Option[Json] = None`, so use null for wire format.
|
|
84
|
+
const wireMetadata = isFiberAppMetadata(def.metadata) ? null : (def.metadata ?? null);
|
|
85
|
+
return {
|
|
95
86
|
states: normalizedStates,
|
|
96
87
|
initialState: def.initialState,
|
|
97
88
|
transitions: transitions.map(normalizeTransition),
|
|
89
|
+
metadata: wireMetadata,
|
|
98
90
|
};
|
|
99
|
-
if (wireMetadata != null) {
|
|
100
|
-
result.metadata = wireMetadata;
|
|
101
|
-
}
|
|
102
|
-
return result;
|
|
103
91
|
}
|
|
104
92
|
/**
|
|
105
93
|
* Normalize a CreateStateMachine message for wire format
|
|
106
94
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* -
|
|
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)
|
|
95
|
+
* Ensures all Option/default fields are explicit in wire format:
|
|
96
|
+
* - definition.metadata → null when absent
|
|
97
|
+
* - definition.states[*].metadata → null when absent
|
|
98
|
+
* - definition.transitions[*].dependencies → [] when absent
|
|
99
|
+
* - parentFiberId → null when absent
|
|
116
100
|
*
|
|
117
101
|
* @example
|
|
118
102
|
* ```typescript
|
|
119
103
|
* const message = normalizeCreateStateMachine({
|
|
120
104
|
* fiberId: '...',
|
|
121
|
-
* definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
|
|
105
|
+
* definition: { states: { INIT: { id: { value: 'INIT' }, isFinal: false } }, ... },
|
|
122
106
|
* initialData: {}
|
|
123
107
|
* });
|
|
124
|
-
* //
|
|
108
|
+
* // message now has parentFiberId: null, definition.metadata: null, etc.
|
|
125
109
|
* ```
|
|
126
110
|
*/
|
|
127
111
|
function normalizeCreateStateMachine(msg) {
|
|
128
|
-
|
|
112
|
+
return {
|
|
129
113
|
fiberId: msg.fiberId,
|
|
130
114
|
definition: normalizeDefinition(msg.definition),
|
|
131
115
|
initialData: msg.initialData ?? {},
|
|
116
|
+
parentFiberId: msg.parentFiberId ?? null,
|
|
132
117
|
};
|
|
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;
|
|
140
118
|
}
|
|
141
119
|
exports.normalizeCreateStateMachine = normalizeCreateStateMachine;
|
|
142
120
|
/**
|
|
@@ -2,39 +2,30 @@
|
|
|
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
|
-
*
|
|
5
|
+
* Scala metagraph. Specifically, ensures all `Option[A]=None` fields are
|
|
6
|
+
* present as explicit `null` values, matching what circe's magnolia encoder
|
|
7
|
+
* produces on the Scala side.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* This is necessary because metakit's `JsonBinaryCodec.deriveDataUpdate`
|
|
10
|
+
* (rc.8) canonicalizes the circe-encoded JSON **including null fields**.
|
|
11
|
+
* If the TypeScript client omits optional fields (undefined), the canonical
|
|
12
|
+
* JSON won't match and signature verification will fail.
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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)
|
|
14
|
+
* Schema mapping (Scala → TypeScript):
|
|
15
|
+
* - `Option[A] = None` → `null` (must be explicit, not undefined/absent)
|
|
19
16
|
* - `Option[A] = Some(v)` → `v`
|
|
20
|
-
* - `List.empty`
|
|
17
|
+
* - `List.empty` → `[]`
|
|
21
18
|
* - `Map.empty` → `{}`
|
|
22
|
-
* - `Boolean = false` → `false` (always include, not a null/Option)
|
|
23
19
|
*/
|
|
24
20
|
/**
|
|
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).
|
|
21
|
+
* Normalize a State object for wire format
|
|
28
22
|
*/
|
|
29
23
|
function normalizeState(state) {
|
|
30
|
-
|
|
24
|
+
return {
|
|
31
25
|
id: state.id,
|
|
32
26
|
isFinal: state.isFinal ?? false,
|
|
27
|
+
metadata: state.metadata ?? null,
|
|
33
28
|
};
|
|
34
|
-
if (state.metadata != null) {
|
|
35
|
-
result.metadata = state.metadata;
|
|
36
|
-
}
|
|
37
|
-
return result;
|
|
38
29
|
}
|
|
39
30
|
/**
|
|
40
31
|
* Normalize a Transition object for wire format
|
|
@@ -86,54 +77,41 @@ function normalizeDefinition(def) {
|
|
|
86
77
|
}
|
|
87
78
|
const transitions = def.transitions ?? [];
|
|
88
79
|
// Strip FiberAppMetadata if present — it's TypeScript-only, not part of wire format.
|
|
89
|
-
//
|
|
90
|
-
const wireMetadata = isFiberAppMetadata(def.metadata) ?
|
|
91
|
-
|
|
80
|
+
// The Scala schema has `metadata: Option[Json] = None`, so use null for wire format.
|
|
81
|
+
const wireMetadata = isFiberAppMetadata(def.metadata) ? null : (def.metadata ?? null);
|
|
82
|
+
return {
|
|
92
83
|
states: normalizedStates,
|
|
93
84
|
initialState: def.initialState,
|
|
94
85
|
transitions: transitions.map(normalizeTransition),
|
|
86
|
+
metadata: wireMetadata,
|
|
95
87
|
};
|
|
96
|
-
if (wireMetadata != null) {
|
|
97
|
-
result.metadata = wireMetadata;
|
|
98
|
-
}
|
|
99
|
-
return result;
|
|
100
88
|
}
|
|
101
89
|
/**
|
|
102
90
|
* Normalize a CreateStateMachine message for wire format
|
|
103
91
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* -
|
|
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)
|
|
92
|
+
* Ensures all Option/default fields are explicit in wire format:
|
|
93
|
+
* - definition.metadata → null when absent
|
|
94
|
+
* - definition.states[*].metadata → null when absent
|
|
95
|
+
* - definition.transitions[*].dependencies → [] when absent
|
|
96
|
+
* - parentFiberId → null when absent
|
|
113
97
|
*
|
|
114
98
|
* @example
|
|
115
99
|
* ```typescript
|
|
116
100
|
* const message = normalizeCreateStateMachine({
|
|
117
101
|
* fiberId: '...',
|
|
118
|
-
* definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
|
|
102
|
+
* definition: { states: { INIT: { id: { value: 'INIT' }, isFinal: false } }, ... },
|
|
119
103
|
* initialData: {}
|
|
120
104
|
* });
|
|
121
|
-
* //
|
|
105
|
+
* // message now has parentFiberId: null, definition.metadata: null, etc.
|
|
122
106
|
* ```
|
|
123
107
|
*/
|
|
124
108
|
export function normalizeCreateStateMachine(msg) {
|
|
125
|
-
|
|
109
|
+
return {
|
|
126
110
|
fiberId: msg.fiberId,
|
|
127
111
|
definition: normalizeDefinition(msg.definition),
|
|
128
112
|
initialData: msg.initialData ?? {},
|
|
113
|
+
parentFiberId: msg.parentFiberId ?? null,
|
|
129
114
|
};
|
|
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;
|
|
137
115
|
}
|
|
138
116
|
/**
|
|
139
117
|
* Normalize a TransitionStateMachine message for wire format
|
|
@@ -2,46 +2,38 @@
|
|
|
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
|
-
*
|
|
5
|
+
* Scala metagraph. Specifically, ensures all `Option[A]=None` fields are
|
|
6
|
+
* present as explicit `null` values, matching what circe's magnolia encoder
|
|
7
|
+
* produces on the Scala side.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* This is necessary because metakit's `JsonBinaryCodec.deriveDataUpdate`
|
|
10
|
+
* (rc.8) canonicalizes the circe-encoded JSON **including null fields**.
|
|
11
|
+
* If the TypeScript client omits optional fields (undefined), the canonical
|
|
12
|
+
* JSON won't match and signature verification will fail.
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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)
|
|
14
|
+
* Schema mapping (Scala → TypeScript):
|
|
15
|
+
* - `Option[A] = None` → `null` (must be explicit, not undefined/absent)
|
|
19
16
|
* - `Option[A] = Some(v)` → `v`
|
|
20
|
-
* - `List.empty`
|
|
17
|
+
* - `List.empty` → `[]`
|
|
21
18
|
* - `Map.empty` → `{}`
|
|
22
|
-
* - `Boolean = false` → `false` (always include, not a null/Option)
|
|
23
19
|
*/
|
|
24
20
|
/**
|
|
25
21
|
* Normalize a CreateStateMachine message for wire format
|
|
26
22
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* -
|
|
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)
|
|
23
|
+
* Ensures all Option/default fields are explicit in wire format:
|
|
24
|
+
* - definition.metadata → null when absent
|
|
25
|
+
* - definition.states[*].metadata → null when absent
|
|
26
|
+
* - definition.transitions[*].dependencies → [] when absent
|
|
27
|
+
* - parentFiberId → null when absent
|
|
36
28
|
*
|
|
37
29
|
* @example
|
|
38
30
|
* ```typescript
|
|
39
31
|
* const message = normalizeCreateStateMachine({
|
|
40
32
|
* fiberId: '...',
|
|
41
|
-
* definition: { states: { INIT: { id: 'INIT', isFinal: false } }, ... },
|
|
33
|
+
* definition: { states: { INIT: { id: { value: 'INIT' }, isFinal: false } }, ... },
|
|
42
34
|
* initialData: {}
|
|
43
35
|
* });
|
|
44
|
-
* //
|
|
36
|
+
* // message now has parentFiberId: null, definition.metadata: null, etc.
|
|
45
37
|
* ```
|
|
46
38
|
*/
|
|
47
39
|
export declare function normalizeCreateStateMachine(msg: Record<string, unknown>): Record<string, unknown>;
|
package/package.json
CHANGED