diff --git a/packages/api-observable/src/Combined.ts b/packages/api-observable/src/Combined.ts
index 6cb269d086..b0a7c590df 100644
--- a/packages/api-observable/src/Combined.ts
+++ b/packages/api-observable/src/Combined.ts
@@ -135,11 +135,12 @@ export default class ApiCombined extends ApiCalls {
this.sessionsPerEra(),
this.eraLastLengthChange()
],
- ([sessionBlockProgress, sessionLength, sessionCurrentIndex, sessionsPerEra, eraLastLengthChange = new BlockNumber(0)]: [BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined]): BlockNumber | undefined =>
- sessionsPerEra && sessionCurrentIndex && sessionLength && sessionBlockProgress && eraLastLengthChange
+ ([sessionBlockProgress, sessionLength, sessionCurrentIndex, sessionsPerEra, eraLastLengthChange]: [BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined]): BlockNumber | undefined =>
+ sessionsPerEra && sessionCurrentIndex && sessionLength && sessionBlockProgress
? new BlockNumber(
sessionCurrentIndex
- .sub(eraLastLengthChange)
+ // last era can be null (i.e. new chain, valid key, no value set yet)
+ .sub(eraLastLengthChange || new BlockNumber(0))
.mod(sessionsPerEra.toBn())
.mul(sessionLength.toBn())
.add(sessionBlockProgress.toBn())
@@ -171,10 +172,11 @@ export default class ApiCombined extends ApiCalls {
this.sessionLastLengthChange()
],
([bestNumber, sessionLength, lastSessionLengthChange]: [BlockNumber | undefined, BlockNumber | undefined, BlockNumber | undefined]): BlockNumber | undefined =>
- bestNumber && sessionLength && lastSessionLengthChange
+ bestNumber && sessionLength
? new BlockNumber(
bestNumber
- .sub(lastSessionLengthChange)
+ // last change can be null (i.e. new chain, valid key, no value set yet)
+ .sub(lastSessionLengthChange || new BlockNumber(0))
.add(sessionLength.toBn())
.mod(sessionLength.toBn())
)
diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts
index 812bf04dfa..66e0ea0a68 100644
--- a/packages/api/src/index.ts
+++ b/packages/api/src/index.ts
@@ -169,7 +169,7 @@ export default class Api implements ApiInterface {
);
}
- private formatOutput (method: RpcMethod, params: Array, result?: any): Base | Array {
+ private formatOutput (method: RpcMethod, params: Array, result?: any): Base | Array {
const base = createType(method.type as string).fromJSON(result);
if (method.type === 'StorageData') {
@@ -182,7 +182,10 @@ export default class Api implements ApiInterface {
}
} else if (method.type === 'StorageChangeSet') {
// multiple return values (via state.storage subscription), decode the values
- // one at a time, all based on the query types
+ // one at a time, all based on the query types. Three values can be returned -
+ // - Base - There is a valid value, non-empty
+ // - null - The storage key is empty (but in the resultset)
+ // - undefined - The storage value is not in the resultset
return (params[0] as Vector).reduce((result, _key: StorageKey) => {
const type = _key.outputType;
@@ -199,13 +202,17 @@ export default class Api implements ApiInterface {
// if we don't have a value, do not fill in the entry, it will be up to the
// caller to sort this out, either ignoring or having a cache for older values
result.push(
- item && !item.value.isEmpty
- ? createType(type, item.value.value)
- : undefined
+ !item
+ ? undefined
+ : (
+ item.value.isEmpty
+ ? null
+ : createType(type, item.value.value)
+ )
);
return result;
- }, [] as Array);
+ }, [] as Array);
}
return base;