From 33a428002831bd301577ef50627091b03631cd08 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 19 Dec 2018 13:39:20 +0100 Subject: [PATCH] Expand ExtrinsicStatus to mirror Rust types (#494) * Expand ExtrinsicStatus to mirror Rust types * Remove .only * Update test expectation * typo * Invalid extends Null * Remove debug log --- CHANGELOG.md | 2 +- .../api/src/promise/SubmittableExtrinsic.ts | 5 ++- packages/api/src/rx/SubmittableExtrinsic.ts | 5 ++- packages/api/test/e2e/promise-tx.spec.js | 14 ++++----- packages/api/test/e2e/rx-tx.spec.js | 4 +-- packages/types/src/ExtrinsicStatus.ts | 31 +++++++++++++++++-- packages/types/src/codec/EnumType.spec.ts | 10 ++++++ packages/types/src/codec/EnumType.ts | 25 +++++++++------ 8 files changed, 68 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65eb893acb..eb39ece63b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ # 0.34.1 -- Changed the send signature (for future expansion of eg. events) to return `result: { status: ExtrinsicStatus }` instead of `status: ExtrinsicStatus`. For most cases where only status `toString` checks are used, i.e. `status.toString() === 'Finalised'` this should not be a breaking change. Deep inspection of the status object however will need to adapt. +- Changed the send signature (for future expansion of eg. events) to return `result: { status: ExtrinsicStatus }` instead of `status: ExtrinsicStatus`. For most cases where only status `type` checks are used, i.e. `status.type === 'Finalised'` this should not be a breaking change. Deep inspection of the status object however will need to adapt. diff --git a/packages/api/src/promise/SubmittableExtrinsic.ts b/packages/api/src/promise/SubmittableExtrinsic.ts index 4b9d9b9952..5621ae103d 100644 --- a/packages/api/src/promise/SubmittableExtrinsic.ts +++ b/packages/api/src/promise/SubmittableExtrinsic.ts @@ -10,8 +10,7 @@ import { Extrinsic, ExtrinsicStatus, Hash } from '@polkadot/types/index'; type SendResult = { status: ExtrinsicStatus, - // toString for backwards compat, i.e. result.toString() === 'finalised' - toString (): string + type: string }; export default class SubmittableExtrinsic extends Extrinsic { @@ -31,7 +30,7 @@ export default class SubmittableExtrinsic extends Extrinsic { return this._api.rpc.author.submitAndWatchExtrinsic(this, (status: ExtrinsicStatus) => statusCb({ status, - toString: status.toString + type: status.type }) ); } diff --git a/packages/api/src/rx/SubmittableExtrinsic.ts b/packages/api/src/rx/SubmittableExtrinsic.ts index 8804f61009..49e4d2ed52 100644 --- a/packages/api/src/rx/SubmittableExtrinsic.ts +++ b/packages/api/src/rx/SubmittableExtrinsic.ts @@ -12,8 +12,7 @@ import { Extrinsic, ExtrinsicStatus } from '@polkadot/types/index'; type SendResult = { status: ExtrinsicStatus, - // toString for backwards compat, i.e. result.toString() === 'finalised' - toString (): string + type: string }; export default class SubmittableExtrinsic extends Extrinsic { @@ -31,7 +30,7 @@ export default class SubmittableExtrinsic extends Extrinsic { .pipe( map((status: ExtrinsicStatus) => ({ status, - toString: status.toString + type: status.type })) ); } diff --git a/packages/api/test/e2e/promise-tx.spec.js b/packages/api/test/e2e/promise-tx.spec.js index 774781da77..3eb17291c0 100644 --- a/packages/api/test/e2e/promise-tx.spec.js +++ b/packages/api/test/e2e/promise-tx.spec.js @@ -22,17 +22,15 @@ describe.skip('e2e transactions', () => { }); it('makes a transfer', async (done) => { - const nonce = await api.query.system.accountNonce(keyring.alice.address()); + const nonce = await api.query.system.accountNonce(keyring.dave.address()); await api.tx.balances - .transfer(keyring.bob.address(), 12345) - .sign(keyring.alice, nonce) + .transfer('12ghjsRJpeJpUQaCQeHcBv9pRQA3tdcMxeL8cVk9JHWJGHjd', 12345) + .sign(keyring.dave, nonce) .send((status) => { - expect( - status.type.toString() - ).toEqual('Finalised'); - - done(); + if (status.type === 'Finalised') { + done(); + } }); }); diff --git a/packages/api/test/e2e/rx-tx.spec.js b/packages/api/test/e2e/rx-tx.spec.js index 7f1ab1a6cc..99cecec186 100644 --- a/packages/api/test/e2e/rx-tx.spec.js +++ b/packages/api/test/e2e/rx-tx.spec.js @@ -34,7 +34,7 @@ describe.skip('e2e transactions', () => { ) ) .subscribe((status) => { - if (status && status.type.toString() === 'Finalised') { + if (status.type === 'Finalised') { done(); } }); @@ -53,7 +53,7 @@ describe.skip('e2e transactions', () => { ) ) .subscribe((status) => { - if (status && status.type.toString() === 'Finalised') { + if (status && status.type === 'Finalised') { done(); } }); diff --git a/packages/types/src/ExtrinsicStatus.ts b/packages/types/src/ExtrinsicStatus.ts index 3b7d63a131..f1948e32e5 100644 --- a/packages/types/src/ExtrinsicStatus.ts +++ b/packages/types/src/ExtrinsicStatus.ts @@ -32,6 +32,30 @@ export class Dropped extends Null { export class Finalised extends Hash { } +/** + * @name Future + * @description + * An [[ExtrinsicStatus]] indicating that the [[Extrinsic]] has been added to the future queue + */ +export class Future extends Null { +} + +/** + * @name Ready + * @description + * An [[ExtrinsicStatus]] indicating that the [[Extrinsic]] has been added to the ready queue + */ +export class Ready extends Null { +} + +/** + * @name Invalid + * @description + * An [[ExtrinsicStatus]] indicating that the [[Extrinsic]] is invalid + */ +export class Invalid extends Null { +} + /** * @name Usurped * @description @@ -45,13 +69,16 @@ export class Usurped extends Hash { * @description * An [[EnumType]] that indicates the status of the [[Extrinsic]] as been submitted */ -export default class ExtrinsicStatus extends EnumType { +export default class ExtrinsicStatus extends EnumType { constructor (value: any, index?: number) { super({ + Future, + Ready, Finalised, Usurped, Broadcast, - Dropped + Dropped, + Invalid }, value, index); } } diff --git a/packages/types/src/codec/EnumType.spec.ts b/packages/types/src/codec/EnumType.spec.ts index f9d7d96f3f..9c0f79ecf8 100644 --- a/packages/types/src/codec/EnumType.spec.ts +++ b/packages/types/src/codec/EnumType.spec.ts @@ -3,6 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import EnumType from './EnumType'; +import Null from '../Null'; import Text from '../Text'; import U32 from '../U32'; @@ -43,6 +44,15 @@ describe('Struct', () => { ).toEqual('42'); }); + it('decodes from JSON string', () => { + expect( + new EnumType( + { Null, U32 }, + 'null' + ).type + ).toEqual('Null'); + }); + // We are currently not using this approach, none of the types in Substrate currently // have any overrides. Insteda of trying to support it (just-in-case), rather have it // removed to simplyfy the code - it can be pulled-back if needed diff --git a/packages/types/src/codec/EnumType.ts b/packages/types/src/codec/EnumType.ts index fd0690aecc..1b18dd296d 100644 --- a/packages/types/src/codec/EnumType.ts +++ b/packages/types/src/codec/EnumType.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { assert, isNumber, isObject, isU8a, u8aConcat, u8aToHex } from '@polkadot/util'; +import { assert, isNumber, isObject, isString, isU8a, u8aConcat, u8aToHex } from '@polkadot/util'; import Base from './Base'; import Null from '../Null'; @@ -60,23 +60,30 @@ export default class EnumType extends Base implements Codec { return EnumType.createValue(def, value[0], value.subarray(1)); } else if (isNumber(value)) { return EnumType.createValue(def, value); + } else if (isString(value)) { + return EnumType.createViaJSON(def, value.toString()); } else if (isObject(value)) { - // JSON comes in the form of { "": "" }, here we - // additionally force to lower to ensure forward compat const key = Object.keys(value)[0]; - const lowerKey = key.toLowerCase(); - const keys = Object.keys(def).map((k) => k.toLowerCase()); - const index = keys.indexOf(lowerKey); - assert(index !== -1, 'Unable to reliably map input on JSON'); - - return EnumType.createValue(def, index, value[key]); + return EnumType.createViaJSON(def, key, value[key]); } // Worst-case scenario, return the first with default return EnumType.createValue(def, 0); } + private static createViaJSON (def: TypesDef, key: string, value?: any) { + // JSON comes in the form of { "": "" }, here we + // additionally force to lower to ensure forward compat + const lowerKey = key.toLowerCase(); + const keys = Object.keys(def).map((k) => k.toLowerCase()); + const index = keys.indexOf(lowerKey); + + assert(index !== -1, 'Unable to reliably map input on JSON'); + + return EnumType.createValue(def, index, value); + } + private static createValue (def: TypesDef, index: number, value?: any): Decoded { return { index,