@dedot/api 0.1.1 → 0.3.0

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.
Files changed (41) hide show
  1. package/chaintypes/substrate/consts.js +0 -1
  2. package/chaintypes/substrate/errors.js +0 -1
  3. package/chaintypes/substrate/events.js +0 -1
  4. package/chaintypes/substrate/index.js +0 -1
  5. package/chaintypes/substrate/json-rpc.js +0 -1
  6. package/chaintypes/substrate/query.js +0 -1
  7. package/chaintypes/substrate/runtime.js +0 -1
  8. package/chaintypes/substrate/tx.js +0 -1
  9. package/chaintypes/substrate/types.js +0 -1
  10. package/cjs/chaintypes/substrate/consts.js +0 -1
  11. package/cjs/chaintypes/substrate/errors.js +0 -1
  12. package/cjs/chaintypes/substrate/events.js +0 -1
  13. package/cjs/chaintypes/substrate/index.js +0 -1
  14. package/cjs/chaintypes/substrate/json-rpc.js +0 -1
  15. package/cjs/chaintypes/substrate/query.js +0 -1
  16. package/cjs/chaintypes/substrate/runtime.js +0 -1
  17. package/cjs/chaintypes/substrate/tx.js +0 -1
  18. package/cjs/chaintypes/substrate/types.js +0 -1
  19. package/cjs/client/BaseSubstrateClient.js +3 -0
  20. package/cjs/executor/EventExecutor.js +33 -12
  21. package/cjs/executor/index.js +1 -0
  22. package/cjs/executor/utils.js +46 -0
  23. package/cjs/extrinsic/submittable/BaseSubmittableExtrinsic.js +4 -1
  24. package/cjs/extrinsic/submittable/SubmittableExtrinsic.js +2 -1
  25. package/cjs/extrinsic/submittable/SubmittableExtrinsicV2.js +7 -5
  26. package/cjs/extrinsic/submittable/utils.js +6 -6
  27. package/client/BaseSubstrateClient.d.ts +2 -0
  28. package/client/BaseSubstrateClient.js +3 -0
  29. package/executor/EventExecutor.d.ts +1 -1
  30. package/executor/EventExecutor.js +33 -12
  31. package/executor/index.d.ts +1 -0
  32. package/executor/index.js +1 -0
  33. package/executor/utils.d.ts +30 -0
  34. package/executor/utils.js +41 -0
  35. package/extrinsic/submittable/BaseSubmittableExtrinsic.js +4 -1
  36. package/extrinsic/submittable/SubmittableExtrinsic.js +2 -1
  37. package/extrinsic/submittable/SubmittableExtrinsicV2.js +7 -5
  38. package/extrinsic/submittable/utils.d.ts +7 -2
  39. package/extrinsic/submittable/utils.js +6 -6
  40. package/package.json +10 -10
  41. package/types.d.ts +11 -0
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export * from './types.js';
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,2 +1 @@
1
- // Generated by dedot cli
2
1
  export {};
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
3
  if (k2 === undefined) k2 = k;
5
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // Generated by dedot cli
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -274,5 +274,8 @@ class BaseSubstrateClient extends index_js_2.JsonRpcClient {
274
274
  at(hash) {
275
275
  throw new Error('Unimplemented!');
276
276
  }
277
+ setSigner(signer) {
278
+ this._options.signer = signer;
279
+ }
277
280
  }
278
281
  exports.BaseSubstrateClient = BaseSubstrateClient;
@@ -3,37 +3,58 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventExecutor = void 0;
4
4
  const utils_1 = require("@dedot/utils");
5
5
  const Executor_js_1 = require("./Executor.js");
6
+ const utils_js_1 = require("./utils.js");
6
7
  /**
7
8
  * @name EventExecutor
8
9
  * @description Find pallet event information from metadata
9
10
  */
10
11
  class EventExecutor extends Executor_js_1.Executor {
11
- doExecute(pallet, errorName) {
12
+ doExecute(pallet, eventName) {
12
13
  const targetPallet = this.getPallet(pallet);
13
14
  const eventTypeId = targetPallet.event;
14
15
  (0, utils_1.assert)(eventTypeId, new utils_1.UnknownApiError(`Not found event with id ${eventTypeId} in pallet ${pallet}`));
15
- const eventDef = this.#getEventDef(eventTypeId, errorName);
16
+ const eventDef = this.#getEventDef(eventTypeId, eventName);
16
17
  const is = (event) => {
18
+ if ((0, utils_js_1.isEventRecord)(event)) {
19
+ event = event.event;
20
+ }
17
21
  const palletCheck = (0, utils_1.stringCamelCase)(event.pallet) === pallet;
18
22
  if (typeof event.palletEvent === 'string') {
19
- return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent) === errorName;
23
+ return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent) === eventName;
20
24
  }
21
25
  else if (typeof event.palletEvent === 'object') {
22
- return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent.name) === errorName;
26
+ return palletCheck && (0, utils_1.stringPascalCase)(event.palletEvent.name) === eventName;
23
27
  }
24
28
  return false;
25
29
  };
26
- const as = (event) => {
27
- return is(event) ? event : undefined;
30
+ const find = (events) => {
31
+ if (!events || events.length === 0)
32
+ return undefined;
33
+ if ((0, utils_js_1.isEventRecord)(events[0])) {
34
+ return events.map(({ event }) => event).find(is);
35
+ }
36
+ else {
37
+ return events.find(is);
38
+ }
39
+ };
40
+ const filter = (events) => {
41
+ if ((0, utils_js_1.isEventRecord)(events[0])) {
42
+ return events.map(({ event }) => event).filter(is);
43
+ }
44
+ else {
45
+ return events.filter(is);
46
+ }
47
+ };
48
+ const meta = {
49
+ ...eventDef,
50
+ pallet: targetPallet.name,
51
+ palletIndex: targetPallet.index,
28
52
  };
29
53
  return {
30
54
  is,
31
- as,
32
- meta: {
33
- ...eventDef,
34
- pallet: targetPallet.name,
35
- palletIndex: targetPallet.index,
36
- },
55
+ find,
56
+ filter,
57
+ meta,
37
58
  };
38
59
  }
39
60
  #getEventDef(eventTypeId, errorName) {
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./utils.js"), exports);
17
18
  __exportStar(require("./Executor.js"), exports);
18
19
  __exportStar(require("./ConstantExecutor.js"), exports);
19
20
  __exportStar(require("./StorageQueryExecutor.js"), exports);
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEventRecord = exports.isPalletEvent = void 0;
4
+ /**
5
+ * Checks if the provided object is a valid `PalletEvent`.
6
+ *
7
+ * @param event - The object to be checked.
8
+ * @returns `true` if the object is a valid `PalletEvent`, `false` otherwise.
9
+ *
10
+ * @remarks
11
+ * A `PalletEvent` is expected to have the following properties:
12
+ * - `pallet`: A string representing the name of the pallet associated with the event.
13
+ * - `palletEvent`: An object or string representing the details of the pallet event.
14
+ *
15
+ * This function validates the presence and type of these properties in the provided object.
16
+ */
17
+ const isPalletEvent = (event) => {
18
+ return ('pallet' in event &&
19
+ typeof event['pallet'] === 'string' &&
20
+ 'palletEvent' in event &&
21
+ (typeof event['palletEvent'] === 'object' || typeof event['palletEvent'] === 'string'));
22
+ };
23
+ exports.isPalletEvent = isPalletEvent;
24
+ /**
25
+ * Checks if the provided object is a valid `IEventRecord`.
26
+ *
27
+ * @param event - The object to be checked.
28
+ * @returns `true` if the object is a valid `IEventRecord`, `false` otherwise.
29
+ *
30
+ * @remarks
31
+ * An `IEventRecord` is expected to have the following properties:
32
+ * - `phase`: An object representing the phase of the event.
33
+ * - `event`: An object representing the event details.
34
+ * - `topics`: An array of topics associated with the event.
35
+ *
36
+ * This function validates the presence and type of these properties in the provided object.
37
+ */
38
+ const isEventRecord = (event) => {
39
+ return ('phase' in event &&
40
+ typeof event['phase'] === 'object' &&
41
+ 'event' in event &&
42
+ (0, exports.isPalletEvent)(event['event']) &&
43
+ 'topics' in event &&
44
+ Array.isArray(event['topics']));
45
+ };
46
+ exports.isEventRecord = isEventRecord;
@@ -26,7 +26,7 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
26
26
  payloadOptions: options,
27
27
  });
28
28
  await extra.init();
29
- const { signer } = options || {};
29
+ const signer = this.#getSigner(options);
30
30
  let signature, alteredTx;
31
31
  if ((0, utils_js_1.isKeyringPair)(fromAccount)) {
32
32
  signature = (0, utils_1.u8aToHex)((0, utils_js_1.signRaw)(fromAccount, extra.toRawPayload(this.callHex).data));
@@ -96,5 +96,8 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
96
96
  throw new utils_1.DedotError('Call data does not match, signer is not allowed to change tx call data.');
97
97
  }
98
98
  }
99
+ #getSigner(options) {
100
+ return options?.signer || this.api.options.signer;
101
+ }
99
102
  }
100
103
  exports.BaseSubmittableExtrinsic = BaseSubmittableExtrinsic;
@@ -33,7 +33,8 @@ class SubmittableExtrinsic extends BaseSubmittableExtrinsic_js_1.BaseSubmittable
33
33
  const txIndex = signedBlock.block.extrinsics.indexOf(txHex);
34
34
  (0, utils_1.assert)(txIndex >= 0, 'Extrinsic not found!');
35
35
  const events = blockEvents.filter(({ phase }) => phase.type === 'ApplyExtrinsic' && phase.value === txIndex);
36
- const status = (0, utils_js_1.toTxStatus)(txStatus, txIndex);
36
+ const blockNumber = signedBlock.block.header.number;
37
+ const status = (0, utils_js_1.toTxStatus)(txStatus, { txIndex, blockNumber });
37
38
  return callback(new SubmittableResult_js_1.SubmittableResult({ status, txHash, events, txIndex }));
38
39
  }
39
40
  else {
@@ -36,15 +36,17 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
36
36
  const checkTxIsOnChain = async (blockHash) => {
37
37
  if (blockHash === finalizedHash)
38
38
  return;
39
+ const block = api.chainHead.findBlock(blockHash);
39
40
  const txs = await api.chainHead.body(blockHash);
40
41
  const txIndex = txs.indexOf(txHex);
41
42
  if (txIndex < 0) {
42
- return checkTxIsOnChain(api.chainHead.findBlock(blockHash).parent);
43
+ return checkTxIsOnChain(block.parent);
43
44
  }
44
45
  const events = await this.getSystemEventsAt(blockHash);
45
46
  const txEvents = events.filter(({ phase }) => phase.type == 'ApplyExtrinsic' && phase.value === txIndex);
46
47
  return {
47
48
  blockHash,
49
+ blockNumber: block.number,
48
50
  index: txIndex,
49
51
  events: txEvents,
50
52
  };
@@ -99,9 +101,9 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
99
101
  return;
100
102
  }
101
103
  txFound = inBlock;
102
- const { index: txIndex, events, blockHash } = inBlock;
104
+ const { index: txIndex, events, blockHash, blockNumber } = inBlock;
103
105
  callback(new SubmittableResult_js_1.SubmittableResult({
104
- status: { type: 'BestChainBlockIncluded', value: { blockHash, txIndex } },
106
+ status: { type: 'BestChainBlockIncluded', value: { blockHash, blockNumber, txIndex } },
105
107
  txHash,
106
108
  events,
107
109
  txIndex,
@@ -132,9 +134,9 @@ class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic_js_1.BaseSubmittab
132
134
  const checkFinalizedBlockIncluded = async (block) => {
133
135
  const inBlock = await checkTxIsOnChain(block.hash);
134
136
  if (inBlock) {
135
- const { index: txIndex, events, blockHash } = inBlock;
137
+ const { index: txIndex, events, blockHash, blockNumber } = inBlock;
136
138
  callback(new SubmittableResult_js_1.SubmittableResult({
137
- status: { type: 'Finalized', value: { blockHash, txIndex } },
139
+ status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
138
140
  txHash,
139
141
  events,
140
142
  txIndex,
@@ -23,9 +23,9 @@ exports.signRaw = signRaw;
23
23
  *
24
24
  * Ref: https://github.com/paritytech/polkadot-sdk/blob/98a364fe6e7abf10819f5fddd3de0588f7c38700/substrate/client/rpc-spec-v2/src/transaction/transaction.rs#L132-L159
25
25
  * @param txStatus
26
- * @param txIndex
26
+ * @param txInfo
27
27
  */
28
- function toTxStatus(txStatus, txIndex) {
28
+ function toTxStatus(txStatus, txInfo) {
29
29
  switch (txStatus.type) {
30
30
  case 'Ready':
31
31
  case 'Future':
@@ -35,21 +35,21 @@ function toTxStatus(txStatus, txIndex) {
35
35
  case 'Retracted':
36
36
  return { type: 'NoLongerInBestChain' };
37
37
  case 'InBlock':
38
- (0, utils_1.assert)(txIndex, 'TxIndex is required');
38
+ (0, utils_1.assert)(txInfo, 'TxInfo is required');
39
39
  return {
40
40
  type: 'BestChainBlockIncluded',
41
41
  value: {
42
42
  blockHash: txStatus.value,
43
- txIndex,
43
+ ...txInfo,
44
44
  },
45
45
  };
46
46
  case 'Finalized':
47
- (0, utils_1.assert)(txIndex, 'TxIndex is required');
47
+ (0, utils_1.assert)(txInfo, 'TxInfo is required');
48
48
  return {
49
49
  type: 'Finalized',
50
50
  value: {
51
51
  blockHash: txStatus.value,
52
- txIndex,
52
+ ...txInfo,
53
53
  },
54
54
  };
55
55
  case 'FinalityTimeout':
@@ -1,3 +1,4 @@
1
+ import { Signer } from '@polkadot/types/types';
1
2
  import { BlockHash, Hash, Metadata, PortableRegistry, RuntimeVersion } from '@dedot/codecs';
2
3
  import type { JsonRpcProvider } from '@dedot/providers';
3
4
  import { type IStorage } from '@dedot/storage';
@@ -68,4 +69,5 @@ export declare abstract class BaseSubstrateClient<Rv extends RpcVersion, ChainAp
68
69
  protected callAt(hash?: BlockHash): ChainApi[Rv]['call'];
69
70
  get tx(): ChainApi[Rv]['tx'];
70
71
  at<ChainApiAt extends GenericSubstrateApi = ChainApi[Rv]>(hash: BlockHash): Promise<ISubstrateClientAt<ChainApiAt>>;
72
+ setSigner(signer?: Signer): void;
71
73
  }
@@ -270,4 +270,7 @@ export class BaseSubstrateClient extends JsonRpcClient {
270
270
  at(hash) {
271
271
  throw new Error('Unimplemented!');
272
272
  }
273
+ setSigner(signer) {
274
+ this._options.signer = signer;
275
+ }
273
276
  }
@@ -6,5 +6,5 @@ import { Executor } from './Executor.js';
6
6
  */
7
7
  export declare class EventExecutor<ChainApi extends GenericSubstrateApi = GenericSubstrateApi> extends Executor<ChainApi> {
8
8
  #private;
9
- doExecute(pallet: string, errorName: string): GenericPalletEvent;
9
+ doExecute(pallet: string, eventName: string): GenericPalletEvent;
10
10
  }
@@ -1,36 +1,57 @@
1
1
  import { assert, stringCamelCase, stringPascalCase, UnknownApiError } from '@dedot/utils';
2
2
  import { Executor } from './Executor.js';
3
+ import { isEventRecord } from './utils.js';
3
4
  /**
4
5
  * @name EventExecutor
5
6
  * @description Find pallet event information from metadata
6
7
  */
7
8
  export class EventExecutor extends Executor {
8
- doExecute(pallet, errorName) {
9
+ doExecute(pallet, eventName) {
9
10
  const targetPallet = this.getPallet(pallet);
10
11
  const eventTypeId = targetPallet.event;
11
12
  assert(eventTypeId, new UnknownApiError(`Not found event with id ${eventTypeId} in pallet ${pallet}`));
12
- const eventDef = this.#getEventDef(eventTypeId, errorName);
13
+ const eventDef = this.#getEventDef(eventTypeId, eventName);
13
14
  const is = (event) => {
15
+ if (isEventRecord(event)) {
16
+ event = event.event;
17
+ }
14
18
  const palletCheck = stringCamelCase(event.pallet) === pallet;
15
19
  if (typeof event.palletEvent === 'string') {
16
- return palletCheck && stringPascalCase(event.palletEvent) === errorName;
20
+ return palletCheck && stringPascalCase(event.palletEvent) === eventName;
17
21
  }
18
22
  else if (typeof event.palletEvent === 'object') {
19
- return palletCheck && stringPascalCase(event.palletEvent.name) === errorName;
23
+ return palletCheck && stringPascalCase(event.palletEvent.name) === eventName;
20
24
  }
21
25
  return false;
22
26
  };
23
- const as = (event) => {
24
- return is(event) ? event : undefined;
27
+ const find = (events) => {
28
+ if (!events || events.length === 0)
29
+ return undefined;
30
+ if (isEventRecord(events[0])) {
31
+ return events.map(({ event }) => event).find(is);
32
+ }
33
+ else {
34
+ return events.find(is);
35
+ }
36
+ };
37
+ const filter = (events) => {
38
+ if (isEventRecord(events[0])) {
39
+ return events.map(({ event }) => event).filter(is);
40
+ }
41
+ else {
42
+ return events.filter(is);
43
+ }
44
+ };
45
+ const meta = {
46
+ ...eventDef,
47
+ pallet: targetPallet.name,
48
+ palletIndex: targetPallet.index,
25
49
  };
26
50
  return {
27
51
  is,
28
- as,
29
- meta: {
30
- ...eventDef,
31
- pallet: targetPallet.name,
32
- palletIndex: targetPallet.index,
33
- },
52
+ find,
53
+ filter,
54
+ meta,
34
55
  };
35
56
  }
36
57
  #getEventDef(eventTypeId, errorName) {
@@ -1,3 +1,4 @@
1
+ export * from './utils.js';
1
2
  export * from './Executor.js';
2
3
  export * from './ConstantExecutor.js';
3
4
  export * from './StorageQueryExecutor.js';
package/executor/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './utils.js';
1
2
  export * from './Executor.js';
2
3
  export * from './ConstantExecutor.js';
3
4
  export * from './StorageQueryExecutor.js';
@@ -0,0 +1,30 @@
1
+ import type { IEventRecord, PalletEvent } from '@dedot/types';
2
+ /**
3
+ * Checks if the provided object is a valid `PalletEvent`.
4
+ *
5
+ * @param event - The object to be checked.
6
+ * @returns `true` if the object is a valid `PalletEvent`, `false` otherwise.
7
+ *
8
+ * @remarks
9
+ * A `PalletEvent` is expected to have the following properties:
10
+ * - `pallet`: A string representing the name of the pallet associated with the event.
11
+ * - `palletEvent`: An object or string representing the details of the pallet event.
12
+ *
13
+ * This function validates the presence and type of these properties in the provided object.
14
+ */
15
+ export declare const isPalletEvent: (event: any) => event is PalletEvent<string, string, any>;
16
+ /**
17
+ * Checks if the provided object is a valid `IEventRecord`.
18
+ *
19
+ * @param event - The object to be checked.
20
+ * @returns `true` if the object is a valid `IEventRecord`, `false` otherwise.
21
+ *
22
+ * @remarks
23
+ * An `IEventRecord` is expected to have the following properties:
24
+ * - `phase`: An object representing the phase of the event.
25
+ * - `event`: An object representing the event details.
26
+ * - `topics`: An array of topics associated with the event.
27
+ *
28
+ * This function validates the presence and type of these properties in the provided object.
29
+ */
30
+ export declare const isEventRecord: (event: any) => event is IEventRecord<import("@dedot/types").IRuntimeEvent, `0x${string}`>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Checks if the provided object is a valid `PalletEvent`.
3
+ *
4
+ * @param event - The object to be checked.
5
+ * @returns `true` if the object is a valid `PalletEvent`, `false` otherwise.
6
+ *
7
+ * @remarks
8
+ * A `PalletEvent` is expected to have the following properties:
9
+ * - `pallet`: A string representing the name of the pallet associated with the event.
10
+ * - `palletEvent`: An object or string representing the details of the pallet event.
11
+ *
12
+ * This function validates the presence and type of these properties in the provided object.
13
+ */
14
+ export const isPalletEvent = (event) => {
15
+ return ('pallet' in event &&
16
+ typeof event['pallet'] === 'string' &&
17
+ 'palletEvent' in event &&
18
+ (typeof event['palletEvent'] === 'object' || typeof event['palletEvent'] === 'string'));
19
+ };
20
+ /**
21
+ * Checks if the provided object is a valid `IEventRecord`.
22
+ *
23
+ * @param event - The object to be checked.
24
+ * @returns `true` if the object is a valid `IEventRecord`, `false` otherwise.
25
+ *
26
+ * @remarks
27
+ * An `IEventRecord` is expected to have the following properties:
28
+ * - `phase`: An object representing the phase of the event.
29
+ * - `event`: An object representing the event details.
30
+ * - `topics`: An array of topics associated with the event.
31
+ *
32
+ * This function validates the presence and type of these properties in the provided object.
33
+ */
34
+ export const isEventRecord = (event) => {
35
+ return ('phase' in event &&
36
+ typeof event['phase'] === 'object' &&
37
+ 'event' in event &&
38
+ isPalletEvent(event['event']) &&
39
+ 'topics' in event &&
40
+ Array.isArray(event['topics']));
41
+ };
@@ -23,7 +23,7 @@ export class BaseSubmittableExtrinsic extends Extrinsic {
23
23
  payloadOptions: options,
24
24
  });
25
25
  await extra.init();
26
- const { signer } = options || {};
26
+ const signer = this.#getSigner(options);
27
27
  let signature, alteredTx;
28
28
  if (isKeyringPair(fromAccount)) {
29
29
  signature = u8aToHex(signRaw(fromAccount, extra.toRawPayload(this.callHex).data));
@@ -93,4 +93,7 @@ export class BaseSubmittableExtrinsic extends Extrinsic {
93
93
  throw new DedotError('Call data does not match, signer is not allowed to change tx call data.');
94
94
  }
95
95
  }
96
+ #getSigner(options) {
97
+ return options?.signer || this.api.options.signer;
98
+ }
96
99
  }
@@ -30,7 +30,8 @@ export class SubmittableExtrinsic extends BaseSubmittableExtrinsic {
30
30
  const txIndex = signedBlock.block.extrinsics.indexOf(txHex);
31
31
  assert(txIndex >= 0, 'Extrinsic not found!');
32
32
  const events = blockEvents.filter(({ phase }) => phase.type === 'ApplyExtrinsic' && phase.value === txIndex);
33
- const status = toTxStatus(txStatus, txIndex);
33
+ const blockNumber = signedBlock.block.header.number;
34
+ const status = toTxStatus(txStatus, { txIndex, blockNumber });
34
35
  return callback(new SubmittableResult({ status, txHash, events, txIndex }));
35
36
  }
36
37
  else {
@@ -33,15 +33,17 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
33
33
  const checkTxIsOnChain = async (blockHash) => {
34
34
  if (blockHash === finalizedHash)
35
35
  return;
36
+ const block = api.chainHead.findBlock(blockHash);
36
37
  const txs = await api.chainHead.body(blockHash);
37
38
  const txIndex = txs.indexOf(txHex);
38
39
  if (txIndex < 0) {
39
- return checkTxIsOnChain(api.chainHead.findBlock(blockHash).parent);
40
+ return checkTxIsOnChain(block.parent);
40
41
  }
41
42
  const events = await this.getSystemEventsAt(blockHash);
42
43
  const txEvents = events.filter(({ phase }) => phase.type == 'ApplyExtrinsic' && phase.value === txIndex);
43
44
  return {
44
45
  blockHash,
46
+ blockNumber: block.number,
45
47
  index: txIndex,
46
48
  events: txEvents,
47
49
  };
@@ -96,9 +98,9 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
96
98
  return;
97
99
  }
98
100
  txFound = inBlock;
99
- const { index: txIndex, events, blockHash } = inBlock;
101
+ const { index: txIndex, events, blockHash, blockNumber } = inBlock;
100
102
  callback(new SubmittableResult({
101
- status: { type: 'BestChainBlockIncluded', value: { blockHash, txIndex } },
103
+ status: { type: 'BestChainBlockIncluded', value: { blockHash, blockNumber, txIndex } },
102
104
  txHash,
103
105
  events,
104
106
  txIndex,
@@ -129,9 +131,9 @@ export class SubmittableExtrinsicV2 extends BaseSubmittableExtrinsic {
129
131
  const checkFinalizedBlockIncluded = async (block) => {
130
132
  const inBlock = await checkTxIsOnChain(block.hash);
131
133
  if (inBlock) {
132
- const { index: txIndex, events, blockHash } = inBlock;
134
+ const { index: txIndex, events, blockHash, blockNumber } = inBlock;
133
135
  callback(new SubmittableResult({
134
- status: { type: 'Finalized', value: { blockHash, txIndex } },
136
+ status: { type: 'Finalized', value: { blockHash, blockNumber, txIndex } },
135
137
  txHash,
136
138
  events,
137
139
  txIndex,
@@ -9,11 +9,16 @@ export declare function isKeyringPair(account: AddressOrPair): account is IKeyri
9
9
  * @param raw
10
10
  */
11
11
  export declare function signRaw(signerPair: IKeyringPair, raw: HexString): Uint8Array;
12
+ type TxInfo = {
13
+ txIndex: number;
14
+ blockNumber: number;
15
+ };
12
16
  /**
13
17
  * Convert transaction status to transaction event
14
18
  *
15
19
  * Ref: https://github.com/paritytech/polkadot-sdk/blob/98a364fe6e7abf10819f5fddd3de0588f7c38700/substrate/client/rpc-spec-v2/src/transaction/transaction.rs#L132-L159
16
20
  * @param txStatus
17
- * @param txIndex
21
+ * @param txInfo
18
22
  */
19
- export declare function toTxStatus(txStatus: TransactionStatus, txIndex?: number): TxStatus;
23
+ export declare function toTxStatus(txStatus: TransactionStatus, txInfo?: TxInfo): TxStatus;
24
+ export {};
@@ -18,9 +18,9 @@ export function signRaw(signerPair, raw) {
18
18
  *
19
19
  * Ref: https://github.com/paritytech/polkadot-sdk/blob/98a364fe6e7abf10819f5fddd3de0588f7c38700/substrate/client/rpc-spec-v2/src/transaction/transaction.rs#L132-L159
20
20
  * @param txStatus
21
- * @param txIndex
21
+ * @param txInfo
22
22
  */
23
- export function toTxStatus(txStatus, txIndex) {
23
+ export function toTxStatus(txStatus, txInfo) {
24
24
  switch (txStatus.type) {
25
25
  case 'Ready':
26
26
  case 'Future':
@@ -30,21 +30,21 @@ export function toTxStatus(txStatus, txIndex) {
30
30
  case 'Retracted':
31
31
  return { type: 'NoLongerInBestChain' };
32
32
  case 'InBlock':
33
- assert(txIndex, 'TxIndex is required');
33
+ assert(txInfo, 'TxInfo is required');
34
34
  return {
35
35
  type: 'BestChainBlockIncluded',
36
36
  value: {
37
37
  blockHash: txStatus.value,
38
- txIndex,
38
+ ...txInfo,
39
39
  },
40
40
  };
41
41
  case 'Finalized':
42
- assert(txIndex, 'TxIndex is required');
42
+ assert(txInfo, 'TxInfo is required');
43
43
  return {
44
44
  type: 'Finalized',
45
45
  value: {
46
46
  blockHash: txStatus.value,
47
- txIndex,
47
+ ...txInfo,
48
48
  },
49
49
  };
50
50
  case 'FinalityTimeout':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedot/api",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
5
5
  "author": "Thang X. Vu <thang@coongcrafts.io>",
6
6
  "homepage": "https://github.com/dedotdev/dedot/tree/main/packages/api",
@@ -13,13 +13,13 @@
13
13
  "type": "module",
14
14
  "sideEffects": false,
15
15
  "dependencies": {
16
- "@dedot/codecs": "0.1.1",
17
- "@dedot/providers": "0.1.1",
18
- "@dedot/runtime-specs": "0.1.1",
19
- "@dedot/shape": "0.1.1",
20
- "@dedot/storage": "0.1.1",
21
- "@dedot/types": "0.1.1",
22
- "@dedot/utils": "0.1.1"
16
+ "@dedot/codecs": "0.3.0",
17
+ "@dedot/providers": "0.3.0",
18
+ "@dedot/runtime-specs": "0.3.0",
19
+ "@dedot/shape": "0.3.0",
20
+ "@dedot/storage": "0.3.0",
21
+ "@dedot/types": "0.3.0",
22
+ "@dedot/utils": "0.3.0"
23
23
  },
24
24
  "scripts": {
25
25
  "build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
@@ -46,9 +46,9 @@
46
46
  },
47
47
  "license": "Apache-2.0",
48
48
  "devDependencies": {
49
- "@polkadot/types": "^12.2.1"
49
+ "@polkadot/types": "^12.2.3"
50
50
  },
51
- "gitHead": "ea6d1e7ba00a5931b86a7946afba820101a06fc2",
51
+ "gitHead": "40d0f3c7eee292b7615649e6a5d54887bee75fe2",
52
52
  "module": "./index.js",
53
53
  "types": "./index.d.ts"
54
54
  }
package/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Signer } from '@polkadot/types/types';
1
2
  import { BlockHash, Hash, Metadata, PortableRegistry } from '@dedot/codecs';
2
3
  import type { ConnectionStatus, JsonRpcProvider, ProviderEvent } from '@dedot/providers';
3
4
  import type { AnyShape } from '@dedot/shape';
@@ -55,6 +56,10 @@ export interface ApiOptions extends JsonRpcClientOptions {
55
56
  * @default blake2_256
56
57
  */
57
58
  hasher?: HashFn;
59
+ /**
60
+ * A signer instance to use for signing transactions
61
+ */
62
+ signer?: Signer;
58
63
  }
59
64
  export type ApiEvent = ProviderEvent | 'ready' | 'runtimeUpgraded';
60
65
  export interface SubstrateRuntimeVersion {
@@ -109,6 +114,12 @@ export interface ISubstrateClient<ChainApi extends GenericSubstrateApi = Generic
109
114
  * This is helpful when you want to check runtime version to prepare for runtime upgrade
110
115
  */
111
116
  getRuntimeVersion(): Promise<SubstrateRuntimeVersion>;
117
+ /**
118
+ * Update the signer instance for signing transactions
119
+ *
120
+ * @param signer
121
+ */
122
+ setSigner(signer?: Signer): void;
112
123
  }
113
124
  /**
114
125
  * A generic interface for broadcasting transactions