@polkadot/rpc-core 9.14.2 → 10.1.1
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/bundle.d.ts +2 -2
- package/bundle.js +339 -365
- package/cjs/bundle.js +346 -420
- package/cjs/detectOther.js +4 -11
- package/cjs/detectPackage.js +6 -11
- package/cjs/index.js +4 -16
- package/cjs/packageInfo.js +2 -16
- package/cjs/types/base.js +2 -1
- package/cjs/types/index.js +4 -26
- package/cjs/types/jsonrpc.js +2 -1
- package/cjs/util/drr.js +19 -31
- package/cjs/util/index.js +5 -37
- package/cjs/util/memo.js +16 -32
- package/cjs/util/refCountDelay.js +39 -43
- package/detectOther.js +0 -3
- package/detectPackage.js +2 -7
- package/index.d.ts +2 -2
- package/index.js +2 -5
- package/package.json +11 -8
- package/packageInfo.js +1 -11
- package/types/index.d.ts +1 -1
- package/types/index.js +1 -7
- package/util/drr.js +13 -22
- package/util/index.d.ts +3 -3
- package/util/index.js +3 -6
- package/util/memo.js +10 -19
- package/util/refCountDelay.js +33 -35
package/bundle.js
CHANGED
|
@@ -1,51 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var _RpcCore_instanceId, _RpcCore_registryDefault, _RpcCore_getBlockRegistry, _RpcCore_getBlockHash, _RpcCore_storageCache;
|
|
2
|
+
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
4
3
|
import { Observable, publishReplay, refCount } from 'rxjs';
|
|
5
4
|
import { rpcDefinitions } from '@polkadot/types';
|
|
6
5
|
import { hexToU8a, isFunction, isNull, isUndefined, lazyMethod, logger, memoize, objectSpread, u8aConcat, u8aToU8a } from '@polkadot/util';
|
|
7
|
-
import { drr, refCountDelay } from
|
|
8
|
-
export { packageInfo } from
|
|
9
|
-
export * from
|
|
6
|
+
import { drr, refCountDelay } from './util/index.js';
|
|
7
|
+
export { packageInfo } from './packageInfo.js';
|
|
8
|
+
export * from './util/index.js';
|
|
10
9
|
const l = logger('rpc-core');
|
|
11
10
|
const EMPTY_META = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
linked: {
|
|
19
|
-
isTrue: false
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
isMap: false
|
|
23
|
-
}
|
|
11
|
+
fallback: undefined,
|
|
12
|
+
modifier: { isOptional: true },
|
|
13
|
+
type: {
|
|
14
|
+
asMap: { linked: { isTrue: false } },
|
|
15
|
+
isMap: false
|
|
16
|
+
}
|
|
24
17
|
};
|
|
25
|
-
|
|
26
|
-
// utility method to create a nicely-formatted error
|
|
27
18
|
/** @internal */
|
|
28
|
-
function logErrorMessage(method, {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const inputs = params.map(({
|
|
37
|
-
isOptional,
|
|
38
|
-
name,
|
|
39
|
-
type
|
|
40
|
-
}) => `${name}${isOptional ? '?' : ''}: ${type}`).join(', ');
|
|
41
|
-
l.error(`${method}(${inputs}): ${type}:: ${error.message}`);
|
|
19
|
+
function logErrorMessage(method, { noErrorLog, params, type }, error) {
|
|
20
|
+
if (noErrorLog) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const inputs = params.map(({ isOptional, name, type }) => `${name}${isOptional ? '?' : ''}: ${type}`).join(', ');
|
|
24
|
+
l.error(`${method}(${inputs}): ${type}:: ${error.message}`);
|
|
42
25
|
}
|
|
43
26
|
function isTreatAsHex(key) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
27
|
+
// :code is problematic - it does not have the length attached, which is
|
|
28
|
+
// unlike all other storage entries where it is indeed properly encoded
|
|
29
|
+
return ['0x3a636f6465'].includes(key.toHex());
|
|
47
30
|
}
|
|
48
|
-
|
|
49
31
|
/**
|
|
50
32
|
* @name Rpc
|
|
51
33
|
* @summary The API may use a HTTP or WebSockets provider.
|
|
@@ -70,340 +52,332 @@ function isTreatAsHex(key) {
|
|
|
70
52
|
* ```
|
|
71
53
|
*/
|
|
72
54
|
export class RpcCore {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
55
|
+
/**
|
|
56
|
+
* @constructor
|
|
57
|
+
* Default constructor for the Api Object
|
|
58
|
+
* @param {ProviderInterface} provider An API provider using HTTP or WebSocket
|
|
59
|
+
*/
|
|
60
|
+
constructor(instanceId, registry, provider, userRpc = {}) {
|
|
61
|
+
_RpcCore_instanceId.set(this, void 0);
|
|
62
|
+
_RpcCore_registryDefault.set(this, void 0);
|
|
63
|
+
_RpcCore_getBlockRegistry.set(this, void 0);
|
|
64
|
+
_RpcCore_getBlockHash.set(this, void 0);
|
|
65
|
+
_RpcCore_storageCache.set(this, new Map());
|
|
66
|
+
this.mapping = new Map();
|
|
67
|
+
this.sections = [];
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
69
|
+
if (!provider || !isFunction(provider.send)) {
|
|
70
|
+
throw new Error('Expected Provider to API create');
|
|
71
|
+
}
|
|
72
|
+
__classPrivateFieldSet(this, _RpcCore_instanceId, instanceId, "f");
|
|
73
|
+
__classPrivateFieldSet(this, _RpcCore_registryDefault, registry, "f");
|
|
74
|
+
this.provider = provider;
|
|
75
|
+
const sectionNames = Object.keys(rpcDefinitions);
|
|
76
|
+
// these are the base keys (i.e. part of jsonrpc)
|
|
77
|
+
this.sections.push(...sectionNames);
|
|
78
|
+
// decorate all interfaces, defined and user on this instance
|
|
79
|
+
this.addUserInterfaces(userRpc);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @description Returns the connected status of a provider
|
|
83
|
+
*/
|
|
84
|
+
get isConnected() {
|
|
85
|
+
return this.provider.isConnected;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* @description Manually connect from the attached provider
|
|
89
|
+
*/
|
|
90
|
+
connect() {
|
|
91
|
+
return this.provider.connect();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* @description Manually disconnect from the attached provider
|
|
95
|
+
*/
|
|
96
|
+
disconnect() {
|
|
97
|
+
return this.provider.disconnect();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* @description Sets a registry swap (typically from Api)
|
|
101
|
+
*/
|
|
102
|
+
setRegistrySwap(registrySwap) {
|
|
103
|
+
__classPrivateFieldSet(this, _RpcCore_getBlockRegistry, memoize(registrySwap, {
|
|
104
|
+
getInstanceId: () => __classPrivateFieldGet(this, _RpcCore_instanceId, "f")
|
|
105
|
+
}), "f");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* @description Sets a function to resolve block hash from block number
|
|
109
|
+
*/
|
|
110
|
+
setResolveBlockHash(resolveBlockHash) {
|
|
111
|
+
__classPrivateFieldSet(this, _RpcCore_getBlockHash, memoize(resolveBlockHash, {
|
|
112
|
+
getInstanceId: () => __classPrivateFieldGet(this, _RpcCore_instanceId, "f")
|
|
113
|
+
}), "f");
|
|
90
114
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
connect() {
|
|
114
|
-
return this.provider.connect();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @description Manually disconnect from the attached provider
|
|
119
|
-
*/
|
|
120
|
-
disconnect() {
|
|
121
|
-
return this.provider.disconnect();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* @description Sets a registry swap (typically from Api)
|
|
126
|
-
*/
|
|
127
|
-
setRegistrySwap(registrySwap) {
|
|
128
|
-
this.#getBlockRegistry = memoize(registrySwap, {
|
|
129
|
-
getInstanceId: () => this.#instanceId
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @description Sets a function to resolve block hash from block number
|
|
135
|
-
*/
|
|
136
|
-
setResolveBlockHash(resolveBlockHash) {
|
|
137
|
-
this.#getBlockHash = memoize(resolveBlockHash, {
|
|
138
|
-
getInstanceId: () => this.#instanceId
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
addUserInterfaces(userRpc) {
|
|
142
|
-
// add any extra user-defined sections
|
|
143
|
-
this.sections.push(...Object.keys(userRpc).filter(k => !this.sections.includes(k)));
|
|
144
|
-
for (let s = 0; s < this.sections.length; s++) {
|
|
145
|
-
const section = this.sections[s];
|
|
146
|
-
const defs = objectSpread({}, rpcDefinitions[section], userRpc[section]);
|
|
147
|
-
const methods = Object.keys(defs);
|
|
148
|
-
for (let m = 0; m < methods.length; m++) {
|
|
149
|
-
const method = methods[m];
|
|
150
|
-
const def = defs[method];
|
|
151
|
-
const jsonrpc = def.endpoint || `${section}_${method}`;
|
|
152
|
-
if (!this.mapping.has(jsonrpc)) {
|
|
153
|
-
const isSubscription = !!def.pubsub;
|
|
154
|
-
if (!this[section]) {
|
|
155
|
-
this[section] = {};
|
|
156
|
-
}
|
|
157
|
-
this.mapping.set(jsonrpc, objectSpread({}, def, {
|
|
158
|
-
isSubscription,
|
|
159
|
-
jsonrpc,
|
|
160
|
-
method,
|
|
161
|
-
section
|
|
162
|
-
}));
|
|
163
|
-
lazyMethod(this[section], method, () => isSubscription ? this._createMethodSubscribe(section, method, def) : this._createMethodSend(section, method, def));
|
|
115
|
+
addUserInterfaces(userRpc) {
|
|
116
|
+
// add any extra user-defined sections
|
|
117
|
+
this.sections.push(...Object.keys(userRpc).filter((k) => !this.sections.includes(k)));
|
|
118
|
+
for (let s = 0; s < this.sections.length; s++) {
|
|
119
|
+
const section = this.sections[s];
|
|
120
|
+
const defs = objectSpread({}, rpcDefinitions[section], userRpc[section]);
|
|
121
|
+
const methods = Object.keys(defs);
|
|
122
|
+
for (let m = 0; m < methods.length; m++) {
|
|
123
|
+
const method = methods[m];
|
|
124
|
+
const def = defs[method];
|
|
125
|
+
const jsonrpc = def.endpoint || `${section}_${method}`;
|
|
126
|
+
if (!this.mapping.has(jsonrpc)) {
|
|
127
|
+
const isSubscription = !!def.pubsub;
|
|
128
|
+
if (!this[section]) {
|
|
129
|
+
this[section] = {};
|
|
130
|
+
}
|
|
131
|
+
this.mapping.set(jsonrpc, objectSpread({}, def, { isSubscription, jsonrpc, method, section }));
|
|
132
|
+
lazyMethod(this[section], method, () => isSubscription
|
|
133
|
+
? this._createMethodSubscribe(section, method, def)
|
|
134
|
+
: this._createMethodSend(section, method, def));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
164
137
|
}
|
|
165
|
-
}
|
|
166
138
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
// only cache .at(<blockHash>) queries, e.g. where valid blockHash was supplied
|
|
200
|
-
const result = await this.provider.send(rpcName, params.map(p => p.toJSON()), !!blockHash);
|
|
201
|
-
return this._formatResult(isScale, registry, blockHash, method, def, params, result);
|
|
202
|
-
};
|
|
203
|
-
const creator = isScale => (...values) => {
|
|
204
|
-
const isDelayed = isScale && hashIndex !== -1 && !!values[hashIndex];
|
|
205
|
-
return new Observable(observer => {
|
|
206
|
-
callWithRegistry(isScale, values).then(value => {
|
|
207
|
-
observer.next(value);
|
|
208
|
-
observer.complete();
|
|
209
|
-
}).catch(error => {
|
|
210
|
-
logErrorMessage(method, def, error);
|
|
211
|
-
observer.error(error);
|
|
212
|
-
observer.complete();
|
|
213
|
-
});
|
|
214
|
-
return () => {
|
|
215
|
-
// delete old results from cache
|
|
216
|
-
if (isScale) {
|
|
217
|
-
var _memoized;
|
|
218
|
-
(_memoized = memoized) == null ? void 0 : _memoized.unmemoize(...values);
|
|
219
|
-
} else {
|
|
220
|
-
var _memoized2;
|
|
221
|
-
(_memoized2 = memoized) == null ? void 0 : _memoized2.raw.unmemoize(...values);
|
|
222
|
-
}
|
|
139
|
+
_memomize(creator, def) {
|
|
140
|
+
const memoOpts = { getInstanceId: () => __classPrivateFieldGet(this, _RpcCore_instanceId, "f") };
|
|
141
|
+
const memoized = memoize(creator(true), memoOpts);
|
|
142
|
+
memoized.raw = memoize(creator(false), memoOpts);
|
|
143
|
+
memoized.meta = def;
|
|
144
|
+
return memoized;
|
|
145
|
+
}
|
|
146
|
+
_formatResult(isScale, registry, blockHash, method, def, params, result) {
|
|
147
|
+
return isScale
|
|
148
|
+
? this._formatOutput(registry, blockHash, method, def, params, result)
|
|
149
|
+
: result;
|
|
150
|
+
}
|
|
151
|
+
_createMethodSend(section, method, def) {
|
|
152
|
+
const rpcName = def.endpoint || `${section}_${method}`;
|
|
153
|
+
const hashIndex = def.params.findIndex(({ isHistoric }) => isHistoric);
|
|
154
|
+
let memoized = null;
|
|
155
|
+
// execute the RPC call, doing a registry swap for historic as applicable
|
|
156
|
+
const callWithRegistry = async (isScale, values) => {
|
|
157
|
+
const blockId = hashIndex === -1
|
|
158
|
+
? null
|
|
159
|
+
: values[hashIndex];
|
|
160
|
+
const blockHash = blockId && def.params[hashIndex].type === 'BlockNumber'
|
|
161
|
+
? await __classPrivateFieldGet(this, _RpcCore_getBlockHash, "f")?.call(this, blockId)
|
|
162
|
+
: blockId;
|
|
163
|
+
const { registry } = isScale && blockHash && __classPrivateFieldGet(this, _RpcCore_getBlockRegistry, "f")
|
|
164
|
+
? await __classPrivateFieldGet(this, _RpcCore_getBlockRegistry, "f").call(this, u8aToU8a(blockHash))
|
|
165
|
+
: { registry: __classPrivateFieldGet(this, _RpcCore_registryDefault, "f") };
|
|
166
|
+
const params = this._formatInputs(registry, null, def, values);
|
|
167
|
+
// only cache .at(<blockHash>) queries, e.g. where valid blockHash was supplied
|
|
168
|
+
const result = await this.provider.send(rpcName, params.map((p) => p.toJSON()), !!blockHash);
|
|
169
|
+
return this._formatResult(isScale, registry, blockHash, method, def, params, result);
|
|
223
170
|
};
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const unsubName = `${section}_${unsubMethod}`;
|
|
254
|
-
const subType = `${section}_${updateType}`;
|
|
255
|
-
let memoized = null;
|
|
256
|
-
const creator = isScale => (...values) => {
|
|
257
|
-
return new Observable(observer => {
|
|
258
|
-
// Have at least an empty promise, as used in the unsubscribe
|
|
259
|
-
let subscriptionPromise = Promise.resolve(null);
|
|
260
|
-
const registry = this.#registryDefault;
|
|
261
|
-
const errorHandler = error => {
|
|
262
|
-
logErrorMessage(method, def, error);
|
|
263
|
-
observer.error(error);
|
|
171
|
+
const creator = (isScale) => (...values) => {
|
|
172
|
+
const isDelayed = isScale && hashIndex !== -1 && !!values[hashIndex];
|
|
173
|
+
return new Observable((observer) => {
|
|
174
|
+
callWithRegistry(isScale, values)
|
|
175
|
+
.then((value) => {
|
|
176
|
+
observer.next(value);
|
|
177
|
+
observer.complete();
|
|
178
|
+
})
|
|
179
|
+
.catch((error) => {
|
|
180
|
+
logErrorMessage(method, def, error);
|
|
181
|
+
observer.error(error);
|
|
182
|
+
observer.complete();
|
|
183
|
+
});
|
|
184
|
+
return () => {
|
|
185
|
+
// delete old results from cache
|
|
186
|
+
if (isScale) {
|
|
187
|
+
memoized?.unmemoize(...values);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
memoized?.raw.unmemoize(...values);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}).pipe(
|
|
194
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
195
|
+
publishReplay(1), // create a Replay(1)
|
|
196
|
+
isDelayed
|
|
197
|
+
? refCountDelay() // Unsubscribe after delay
|
|
198
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
199
|
+
: refCount());
|
|
264
200
|
};
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
201
|
+
memoized = this._memomize(creator, def);
|
|
202
|
+
return memoized;
|
|
203
|
+
}
|
|
204
|
+
// create a subscriptor, it subscribes once and resolves with the id as subscribe
|
|
205
|
+
_createSubscriber({ paramsJson, subName, subType, update }, errorHandler) {
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
this.provider
|
|
208
|
+
.subscribe(subType, subName, paramsJson, update)
|
|
209
|
+
.then(resolve)
|
|
210
|
+
.catch((error) => {
|
|
211
|
+
errorHandler(error);
|
|
212
|
+
reject(error);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
_createMethodSubscribe(section, method, def) {
|
|
217
|
+
const [updateType, subMethod, unsubMethod] = def.pubsub;
|
|
218
|
+
const subName = `${section}_${subMethod}`;
|
|
219
|
+
const unsubName = `${section}_${unsubMethod}`;
|
|
220
|
+
const subType = `${section}_${updateType}`;
|
|
221
|
+
let memoized = null;
|
|
222
|
+
const creator = (isScale) => (...values) => {
|
|
223
|
+
return new Observable((observer) => {
|
|
224
|
+
// Have at least an empty promise, as used in the unsubscribe
|
|
225
|
+
let subscriptionPromise = Promise.resolve(null);
|
|
226
|
+
const registry = __classPrivateFieldGet(this, _RpcCore_registryDefault, "f");
|
|
227
|
+
const errorHandler = (error) => {
|
|
228
|
+
logErrorMessage(method, def, error);
|
|
229
|
+
observer.error(error);
|
|
230
|
+
};
|
|
231
|
+
try {
|
|
232
|
+
const params = this._formatInputs(registry, null, def, values);
|
|
233
|
+
const paramsJson = params.map((p) => p.toJSON());
|
|
234
|
+
const update = (error, result) => {
|
|
235
|
+
if (error) {
|
|
236
|
+
logErrorMessage(method, def, error);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
observer.next(this._formatResult(isScale, registry, null, method, def, params, result));
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
observer.error(error);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
subscriptionPromise = this._createSubscriber({ paramsJson, subName, subType, update }, errorHandler);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
errorHandler(error);
|
|
250
|
+
}
|
|
251
|
+
// Teardown logic
|
|
252
|
+
return () => {
|
|
253
|
+
// Delete from cache, so old results don't hang around
|
|
254
|
+
if (isScale) {
|
|
255
|
+
memoized?.unmemoize(...values);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
memoized?.raw.unmemoize(...values);
|
|
259
|
+
}
|
|
260
|
+
// Unsubscribe from provider
|
|
261
|
+
subscriptionPromise
|
|
262
|
+
.then((subscriptionId) => isNull(subscriptionId)
|
|
263
|
+
? Promise.resolve(false)
|
|
264
|
+
: this.provider.unsubscribe(subType, unsubName, subscriptionId))
|
|
265
|
+
.catch((error) => logErrorMessage(method, def, error));
|
|
266
|
+
};
|
|
267
|
+
}).pipe(drr());
|
|
302
268
|
};
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
269
|
+
memoized = this._memomize(creator, def);
|
|
270
|
+
return memoized;
|
|
271
|
+
}
|
|
272
|
+
_formatInputs(registry, blockHash, def, inputs) {
|
|
273
|
+
const reqArgCount = def.params.filter(({ isOptional }) => !isOptional).length;
|
|
274
|
+
const optText = reqArgCount === def.params.length
|
|
275
|
+
? ''
|
|
276
|
+
: ` (${def.params.length - reqArgCount} optional)`;
|
|
277
|
+
if (inputs.length < reqArgCount || inputs.length > def.params.length) {
|
|
278
|
+
throw new Error(`Expected ${def.params.length} parameters${optText}, ${inputs.length} found instead`);
|
|
279
|
+
}
|
|
280
|
+
return inputs.map((input, index) => registry.createTypeUnsafe(def.params[index].type, [input], { blockHash }));
|
|
281
|
+
}
|
|
282
|
+
_formatOutput(registry, blockHash, method, rpc, params, result) {
|
|
283
|
+
if (rpc.type === 'StorageData') {
|
|
284
|
+
const key = params[0];
|
|
285
|
+
return this._formatStorageData(registry, blockHash, key, result);
|
|
286
|
+
}
|
|
287
|
+
else if (rpc.type === 'StorageChangeSet') {
|
|
288
|
+
const keys = params[0];
|
|
289
|
+
return keys
|
|
290
|
+
? this._formatStorageSet(registry, result.block, keys, result.changes)
|
|
291
|
+
: registry.createType('StorageChangeSet', result);
|
|
292
|
+
}
|
|
293
|
+
else if (rpc.type === 'Vec<StorageChangeSet>') {
|
|
294
|
+
const mapped = result.map(({ block, changes }) => [
|
|
295
|
+
registry.createType('Hash', block),
|
|
296
|
+
this._formatStorageSet(registry, block, params[0], changes)
|
|
297
|
+
]);
|
|
298
|
+
// we only query at a specific block, not a range - flatten
|
|
299
|
+
return method === 'queryStorageAt'
|
|
300
|
+
? mapped[0][1]
|
|
301
|
+
: mapped;
|
|
302
|
+
}
|
|
303
|
+
return registry.createTypeUnsafe(rpc.type, [result], { blockHash });
|
|
304
|
+
}
|
|
305
|
+
_formatStorageData(registry, blockHash, key, value) {
|
|
306
|
+
const isEmpty = isNull(value);
|
|
307
|
+
// we convert to Uint8Array since it maps to the raw encoding, all
|
|
308
|
+
// data will be correctly encoded (incl. numbers, excl. :code)
|
|
309
|
+
const input = isEmpty
|
|
310
|
+
? null
|
|
311
|
+
: isTreatAsHex(key)
|
|
312
|
+
? value
|
|
313
|
+
: u8aToU8a(value);
|
|
314
|
+
return this._newType(registry, blockHash, key, input, isEmpty);
|
|
315
315
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
} else if (rpc.type === 'Vec<StorageChangeSet>') {
|
|
328
|
-
const mapped = result.map(({
|
|
329
|
-
block,
|
|
330
|
-
changes
|
|
331
|
-
}) => [registry.createType('Hash', block), this._formatStorageSet(registry, block, params[0], changes)]);
|
|
332
|
-
|
|
333
|
-
// we only query at a specific block, not a range - flatten
|
|
334
|
-
return method === 'queryStorageAt' ? mapped[0][1] : mapped;
|
|
316
|
+
_formatStorageSet(registry, blockHash, keys, changes) {
|
|
317
|
+
// For StorageChangeSet, the changes has the [key, value] mappings
|
|
318
|
+
const withCache = keys.length !== 1;
|
|
319
|
+
// multiple return values (via state.storage subscription), decode the values
|
|
320
|
+
// one at a time, all based on the query types. Three values can be returned -
|
|
321
|
+
// - Codec - There is a valid value, non-empty
|
|
322
|
+
// - null - The storage key is empty
|
|
323
|
+
return keys.reduce((results, key, index) => {
|
|
324
|
+
results.push(this._formatStorageSetEntry(registry, blockHash, key, changes, withCache, index));
|
|
325
|
+
return results;
|
|
326
|
+
}, []);
|
|
335
327
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
const found = changes.find(([key]) => key === hexKey);
|
|
364
|
-
const isNotFound = isUndefined(found);
|
|
365
|
-
|
|
366
|
-
// if we don't find the value, this is our fallback
|
|
367
|
-
// - in the case of an array of values, fill the hole from the cache
|
|
368
|
-
// - if a single result value, don't fill - it is not an update hole
|
|
369
|
-
// - fallback to an empty option in all cases
|
|
370
|
-
if (isNotFound && withCache) {
|
|
371
|
-
const cached = this.#storageCache.get(hexKey);
|
|
372
|
-
if (cached) {
|
|
373
|
-
return cached;
|
|
374
|
-
}
|
|
328
|
+
_formatStorageSetEntry(registry, blockHash, key, changes, withCache, entryIndex) {
|
|
329
|
+
const hexKey = key.toHex();
|
|
330
|
+
const found = changes.find(([key]) => key === hexKey);
|
|
331
|
+
const isNotFound = isUndefined(found);
|
|
332
|
+
// if we don't find the value, this is our fallback
|
|
333
|
+
// - in the case of an array of values, fill the hole from the cache
|
|
334
|
+
// - if a single result value, don't fill - it is not an update hole
|
|
335
|
+
// - fallback to an empty option in all cases
|
|
336
|
+
if (isNotFound && withCache) {
|
|
337
|
+
const cached = __classPrivateFieldGet(this, _RpcCore_storageCache, "f").get(hexKey);
|
|
338
|
+
if (cached) {
|
|
339
|
+
return cached;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const value = isNotFound
|
|
343
|
+
? null
|
|
344
|
+
: found[1];
|
|
345
|
+
const isEmpty = isNull(value);
|
|
346
|
+
const input = isEmpty || isTreatAsHex(key)
|
|
347
|
+
? value
|
|
348
|
+
: u8aToU8a(value);
|
|
349
|
+
const codec = this._newType(registry, blockHash, key, input, isEmpty, entryIndex);
|
|
350
|
+
// store the retrieved result - the only issue with this cache is that there is no
|
|
351
|
+
// clearing of it, so very long running processes (not just a couple of hours, longer)
|
|
352
|
+
// will increase memory beyond what is allowed.
|
|
353
|
+
__classPrivateFieldGet(this, _RpcCore_storageCache, "f").set(hexKey, codec);
|
|
354
|
+
return codec;
|
|
375
355
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
isFallback: isEmpty && !!meta.fallback,
|
|
402
|
-
isOptional: meta.modifier.isOptional,
|
|
403
|
-
isPedantic: !meta.modifier.isOptional
|
|
404
|
-
});
|
|
405
|
-
} catch (error) {
|
|
406
|
-
throw new Error(`Unable to decode storage ${key.section || 'unknown'}.${key.method || 'unknown'}:${entryNum}: ${error.message}`);
|
|
356
|
+
_newType(registry, blockHash, key, input, isEmpty, entryIndex = -1) {
|
|
357
|
+
// single return value (via state.getStorage), decode the value based on the
|
|
358
|
+
// outputType that we have specified. Fallback to Raw on nothing
|
|
359
|
+
const type = key.outputType || 'Raw';
|
|
360
|
+
const meta = key.meta || EMPTY_META;
|
|
361
|
+
const entryNum = entryIndex === -1
|
|
362
|
+
? ''
|
|
363
|
+
: ` entry ${entryIndex}:`;
|
|
364
|
+
try {
|
|
365
|
+
return registry.createTypeUnsafe(type, [
|
|
366
|
+
isEmpty
|
|
367
|
+
? meta.fallback
|
|
368
|
+
// For old-style Linkage, we add an empty linkage at the end
|
|
369
|
+
? type.includes('Linkage<')
|
|
370
|
+
? u8aConcat(hexToU8a(meta.fallback.toHex()), new Uint8Array(2))
|
|
371
|
+
: hexToU8a(meta.fallback.toHex())
|
|
372
|
+
: undefined
|
|
373
|
+
: meta.modifier.isOptional
|
|
374
|
+
? registry.createTypeUnsafe(type, [input], { blockHash, isPedantic: true })
|
|
375
|
+
: input
|
|
376
|
+
], { blockHash, isFallback: isEmpty && !!meta.fallback, isOptional: meta.modifier.isOptional, isPedantic: !meta.modifier.isOptional });
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
throw new Error(`Unable to decode storage ${key.section || 'unknown'}.${key.method || 'unknown'}:${entryNum}: ${error.message}`);
|
|
380
|
+
}
|
|
407
381
|
}
|
|
408
|
-
|
|
409
|
-
|
|
382
|
+
}
|
|
383
|
+
_RpcCore_instanceId = new WeakMap(), _RpcCore_registryDefault = new WeakMap(), _RpcCore_getBlockRegistry = new WeakMap(), _RpcCore_getBlockHash = new WeakMap(), _RpcCore_storageCache = new WeakMap();
|