Add specVersion to SignedExtra payload (#1324)
* Add specVersion to SignedExtra payload * Update ExtrinsicPayload.ts * Cleanup linting & tests (code-only) * Update after e2e testing in apps * Check and fix tests * Grrr... case sensitivity * Use interfaces where available * Case sensitive fixes
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
import '@polkadot/types/injector';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import testingPairs from '@polkadot/keyring/testingPairs';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
@@ -19,7 +20,15 @@ describe('extrinsics', (): void => {
|
||||
).sign(keyring.alice, {
|
||||
blockHash: '0xec7afaf1cca720ce88c1d1b689d81f0583cc15a97d621cf046dd9abf605ef22f',
|
||||
genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b',
|
||||
nonce: 0
|
||||
nonce: 0,
|
||||
runtimeVersion: {
|
||||
apis: [],
|
||||
authoringVersion: new BN(123),
|
||||
implName: 'test',
|
||||
implVersion: new BN(123),
|
||||
specName: 'test',
|
||||
specVersion: new BN(123)
|
||||
}
|
||||
}).toHex()
|
||||
).toEqual(
|
||||
'0x' +
|
||||
|
||||
@@ -16,6 +16,7 @@ describe('SignerPayload', (): void => {
|
||||
genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b',
|
||||
method: '0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c',
|
||||
nonce: '0x00001234',
|
||||
specVersion: '0x00000000',
|
||||
tip: '0x00000000000000000000000000005678',
|
||||
version: 3
|
||||
};
|
||||
@@ -45,6 +46,7 @@ describe('SignerPayload', (): void => {
|
||||
genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b',
|
||||
method: '0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c',
|
||||
nonce: '0x00001234',
|
||||
specVersion: '0x00000000',
|
||||
tip: '0x00000000000000000000000000005678',
|
||||
version: 3
|
||||
});
|
||||
|
||||
@@ -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 { Address, Balance, BlockNumber, Call, ExtrinsicEra, Hash, Index } from '@polkadot/types/interfaces';
|
||||
import { Address, Balance, BlockNumber, Call, ExtrinsicEra, Hash, Index, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { Constructor } from '@polkadot/types/types';
|
||||
import { SignerPayload, SignerPayloadRaw } from './types';
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface SignerPayloadType {
|
||||
genesisHash: Hash;
|
||||
method: Call;
|
||||
nonce: Compact<Index>;
|
||||
runtimeVersion: RuntimeVersion;
|
||||
tip: Compact<Balance>;
|
||||
version: u8;
|
||||
}
|
||||
@@ -30,6 +31,7 @@ const _Payload: Constructor<SignerPayloadType> = Struct.with({
|
||||
genesisHash: 'Hash',
|
||||
method: 'Call',
|
||||
nonce: 'Compact<Index>',
|
||||
runtimeVersion: 'RuntimeVersion',
|
||||
tip: 'Compact<Balance>',
|
||||
version: u8
|
||||
});
|
||||
@@ -46,7 +48,7 @@ export default class Payload extends _Payload {
|
||||
* @description Creates an representation of the structure as an ISignerPayload JSON
|
||||
*/
|
||||
public toPayload (): SignerPayload {
|
||||
const { address, blockHash, blockNumber, era, genesisHash, method, nonce, tip, version } = this.self;
|
||||
const { address, blockHash, blockNumber, era, genesisHash, method, nonce, runtimeVersion: { specVersion }, tip, version } = this.self;
|
||||
|
||||
return {
|
||||
address: address.toString(),
|
||||
@@ -56,6 +58,7 @@ export default class Payload extends _Payload {
|
||||
genesisHash: genesisHash.toHex(),
|
||||
method: method.toHex(),
|
||||
nonce: nonce.toHex(),
|
||||
specVersion: specVersion.toHex(),
|
||||
tip: tip.toHex(),
|
||||
version: version.toNumber()
|
||||
};
|
||||
|
||||
@@ -176,10 +176,11 @@ export default function createSubmittableExtrinsic<ApiType> (
|
||||
function expandOptions (options: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions {
|
||||
return {
|
||||
blockHash: api.genesisHash,
|
||||
version: api.runtimeVersion,
|
||||
...options,
|
||||
...extras,
|
||||
genesisHash: api.genesisHash
|
||||
genesisHash: api.genesisHash,
|
||||
runtimeVersion: api.runtimeVersion,
|
||||
version: api.extrinsicType
|
||||
} as unknown as SignatureOptions;
|
||||
}
|
||||
|
||||
@@ -272,9 +273,7 @@ export default function createSubmittableExtrinsic<ApiType> (
|
||||
...eraOptions,
|
||||
address,
|
||||
method: _extrinsic.method,
|
||||
blockNumber: header ? header.number : 0,
|
||||
genesisHash: api.genesisHash,
|
||||
version: api.extrinsicType
|
||||
blockNumber: header ? header.number : 0
|
||||
});
|
||||
|
||||
if (api.signer.signPayload) {
|
||||
|
||||
@@ -246,6 +246,11 @@ export interface SignerPayload {
|
||||
*/
|
||||
nonce: string;
|
||||
|
||||
/**
|
||||
* @description The current spec version for the runtime
|
||||
*/
|
||||
specVersion: string;
|
||||
|
||||
/**
|
||||
* @description The tip for this transaction, in hex
|
||||
*/
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { FunctionMetadataV7 } from '../../interfaces/metadata/types';
|
||||
import { Balance, Index } from '../../interfaces/runtime';
|
||||
import { Address, Balance, Call, Index } from '../../interfaces/runtime';
|
||||
import { AnyU8a, ArgsDef, Codec, ExtrinsicPayloadValue, IExtrinsic, IHash, IKeyringPair, SignatureOptions } from '../../types';
|
||||
|
||||
import { assert, isHex, isU8a, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { ClassOf } from '../../codec/create';
|
||||
import Base from '../../codec/Base';
|
||||
import Compact from '../../codec/Compact';
|
||||
import Address from '../Generic/Address';
|
||||
import Call from '../Generic/Call';
|
||||
import ExtrinsicV1, { ExtrinsicValueV1 } from './v1/Extrinsic';
|
||||
import ExtrinsicV2, { ExtrinsicValueV2 } from './v2/Extrinsic';
|
||||
import ExtrinsicV3, { ExtrinsicValueV3 } from './v3/Extrinsic';
|
||||
@@ -85,7 +84,7 @@ export default class Extrinsic extends Base<ExtrinsicV1 | ExtrinsicV2 | Extrinsi
|
||||
assert(total <= value.length, `Extrinsic: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return Extrinsic.decodeU8a(value.subarray(offset, total));
|
||||
} else if (value instanceof Call) {
|
||||
} else if (value instanceof ClassOf('Call')) {
|
||||
return Extrinsic.newFromValue({ method: value }, version);
|
||||
}
|
||||
|
||||
@@ -234,6 +233,7 @@ export default class Extrinsic extends Base<ExtrinsicV1 | ExtrinsicV2 | Extrinsi
|
||||
genesisHash: new Uint8Array(),
|
||||
method: this.method.toHex(),
|
||||
nonce: args[0] as string,
|
||||
specVersion: 0,
|
||||
tip: 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { createType } from '../../codec/create';
|
||||
import Base from '../../codec/Base';
|
||||
import Compact from '../../codec/Compact';
|
||||
import U8a from '../../codec/U8a';
|
||||
import u32 from '../../primitive/U32';
|
||||
import ExtrinsicPayloadV1 from './v1/ExtrinsicPayload';
|
||||
import ExtrinsicPayloadV2 from './v2/ExtrinsicPayload';
|
||||
import ExtrinsicPayloadV3 from './v3/ExtrinsicPayload';
|
||||
@@ -83,6 +84,14 @@ export default class ExtrinsicPayload extends Base<ExtrinsicPayloadV1 | Extrinsi
|
||||
return this.raw.nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The specVersion as a [[u32]] for this payload
|
||||
*/
|
||||
public get specVersion (): u32 {
|
||||
// NOTE only v3
|
||||
return (this.raw as ExtrinsicPayloadV3).specVersion || createType('u32');
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Balance]]
|
||||
*/
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Address, Call } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicOptions } from '../types';
|
||||
|
||||
import { isU8a } from '@polkadot/util';
|
||||
|
||||
import { createType } from '../../../codec/create';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
import Address from '../../Generic/Address';
|
||||
import ExtrinsicSignature from './ExtrinsicSignature';
|
||||
import ExtrinsicSignatureV1 from './ExtrinsicSignature';
|
||||
|
||||
export interface ExtrinsicValueV1 {
|
||||
method?: Call;
|
||||
signature?: ExtrinsicSignature;
|
||||
signature?: ExtrinsicSignatureV1;
|
||||
}
|
||||
|
||||
const TRANSACTION_VERSION = 1;
|
||||
@@ -27,8 +27,8 @@ const TRANSACTION_VERSION = 1;
|
||||
export default class ExtrinsicV1 extends Struct implements IExtrinsicImpl {
|
||||
public constructor (value?: Uint8Array | ExtrinsicValueV1, { isSigned }: ExtrinsicOptions = {}) {
|
||||
super({
|
||||
signature: ExtrinsicSignature,
|
||||
method: Call
|
||||
signature: ExtrinsicSignatureV1,
|
||||
method: 'Call'
|
||||
}, ExtrinsicV1.decodeExtrinsic(value, isSigned));
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsicImpl {
|
||||
return value;
|
||||
} else if (isU8a(value)) {
|
||||
// here we decode manually since we need to pull through the version information
|
||||
const signature = new ExtrinsicSignature(value, { isSigned });
|
||||
const method = new Call(value.subarray(signature.encodedLength));
|
||||
const signature = new ExtrinsicSignatureV1(value, { isSigned });
|
||||
const method = createType('Call', value.subarray(signature.encodedLength));
|
||||
|
||||
return {
|
||||
method,
|
||||
@@ -66,10 +66,10 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsicImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ExtrinsicSignature]]
|
||||
* @description The [[ExtrinsicSignatureV1]]
|
||||
*/
|
||||
public get signature (): ExtrinsicSignature {
|
||||
return this.get('signature') as ExtrinsicSignature;
|
||||
public get signature (): ExtrinsicSignatureV1 {
|
||||
return this.get('signature') as ExtrinsicSignatureV1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ export default class ExtrinsicV1 extends Struct implements IExtrinsicImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Add an [[ExtrinsicSignature]] to the extrinsic (already generated)
|
||||
* @description Add an [[ExtrinsicSignatureV1]] to the extrinsic (already generated)
|
||||
*/
|
||||
public addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, payload: ExtrinsicPayloadValue | Uint8Array | string): ExtrinsicV1 {
|
||||
this.signature.addSignature(signer, signature, payload);
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Hash, Index } from '../../../interfaces/runtime';
|
||||
import { Hash, ExtrinsicEra, Index } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IKeyringPair } from '../../../types';
|
||||
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Bytes from '../../../primitive/Bytes';
|
||||
import ExtrinsicEra from '../ExtrinsicEra';
|
||||
import { sign } from '../util';
|
||||
|
||||
/**
|
||||
@@ -27,7 +26,7 @@ export default class ExtrinsicPayloadV1 extends Struct {
|
||||
super({
|
||||
nonce: 'Compact<Index>',
|
||||
method: 'Bytes',
|
||||
era: ExtrinsicEra,
|
||||
era: 'ExtrinsicEra',
|
||||
blockHash: 'Hash'
|
||||
}, value);
|
||||
}
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Address, Balance, Index, Signature } from '../../../interfaces/runtime';
|
||||
import { Address, Balance, Call, ExtrinsicEra, Index, Signature } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicSignatureOptions } from '../types';
|
||||
|
||||
import { createType } from '../../../codec/create';
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
import ExtrinsicEra from '../ExtrinsicEra';
|
||||
import { EMPTY_U8A, IMMORTAL_ERA } from '../constants';
|
||||
import ExtrinsicPayloadV1 from './ExtrinsicPayload';
|
||||
|
||||
@@ -30,7 +28,7 @@ export default class ExtrinsicSignatureV1 extends Struct implements IExtrinsicSi
|
||||
signer: 'Address',
|
||||
signature: 'Signature',
|
||||
nonce: 'Compact<Index>',
|
||||
era: ExtrinsicEra
|
||||
era: 'ExtrinsicEra'
|
||||
}, ExtrinsicSignatureV1.decodeExtrinsicSignature(value, isSigned));
|
||||
}
|
||||
|
||||
@@ -128,6 +126,7 @@ export default class ExtrinsicSignatureV1 extends Struct implements IExtrinsicSi
|
||||
genesisHash,
|
||||
method: method.toHex(),
|
||||
nonce,
|
||||
specVersion: 0, // unsed for v1, added for compat
|
||||
tip: 0
|
||||
});
|
||||
const signature = createType('Signature', payload.sign(account));
|
||||
|
||||
@@ -2,6 +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 BN from 'bn.js';
|
||||
import extrinsics from '@polkadot/api-metadata/extrinsics/static';
|
||||
import testingPairs from '@polkadot/keyring/testingPairs';
|
||||
|
||||
@@ -43,6 +44,14 @@ describe('ExtrinsicV2', (): void => {
|
||||
blockHash: '0xec7afaf1cca720ce88c1d1b689d81f0583cc15a97d621cf046dd9abf605ef22f',
|
||||
genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b',
|
||||
nonce: 1,
|
||||
runtimeVersion: {
|
||||
apis: [],
|
||||
authoringVersion: new BN(123),
|
||||
implName: 'test',
|
||||
implVersion: new BN(123),
|
||||
specName: 'test',
|
||||
specVersion: new BN(123)
|
||||
},
|
||||
tip: 2
|
||||
}).toHex()
|
||||
).toEqual(
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Address, Call } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicOptions } from '../types';
|
||||
|
||||
import { isU8a } from '@polkadot/util';
|
||||
|
||||
import { createType, ClassOf } from '../../../codec/create';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
import Address from '../../Generic/Address';
|
||||
import ExtrinsicSignature from './ExtrinsicSignature';
|
||||
import ExtrinsicSignatureV2 from './ExtrinsicSignature';
|
||||
|
||||
const TRANSACTION_VERSION = 2;
|
||||
|
||||
export interface ExtrinsicValueV2 {
|
||||
method?: Call;
|
||||
signature?: ExtrinsicSignature;
|
||||
signature?: ExtrinsicSignatureV2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,8 +27,8 @@ export interface ExtrinsicValueV2 {
|
||||
export default class ExtrinsicV2 extends Struct implements IExtrinsicImpl {
|
||||
public constructor (value?: Uint8Array | ExtrinsicValueV2 | Call, { isSigned }: ExtrinsicOptions = {}) {
|
||||
super({
|
||||
signature: ExtrinsicSignature,
|
||||
method: Call
|
||||
signature: ExtrinsicSignatureV2,
|
||||
method: 'Call'
|
||||
}, ExtrinsicV2.decodeExtrinsic(value, isSigned));
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ export default class ExtrinsicV2 extends Struct implements IExtrinsicImpl {
|
||||
return {};
|
||||
} else if (value instanceof ExtrinsicV2) {
|
||||
return value;
|
||||
} else if (value instanceof Call) {
|
||||
} else if (value instanceof ClassOf('Call')) {
|
||||
return { method: value };
|
||||
} else if (isU8a(value)) {
|
||||
// here we decode manually since we need to pull through the version information
|
||||
const signature = new ExtrinsicSignature(value, { isSigned });
|
||||
const method = new Call(value.subarray(signature.encodedLength));
|
||||
const signature = new ExtrinsicSignatureV2(value, { isSigned });
|
||||
const method = createType('Call', value.subarray(signature.encodedLength));
|
||||
|
||||
return {
|
||||
method,
|
||||
@@ -68,10 +68,10 @@ export default class ExtrinsicV2 extends Struct implements IExtrinsicImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ExtrinsicSignature]]
|
||||
* @description The [[ExtrinsicSignatureV2]]
|
||||
*/
|
||||
public get signature (): ExtrinsicSignature {
|
||||
return this.get('signature') as ExtrinsicSignature;
|
||||
public get signature (): ExtrinsicSignatureV2 {
|
||||
return this.get('signature') as ExtrinsicSignatureV2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ export default class ExtrinsicV2 extends Struct implements IExtrinsicImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Add an [[ExtrinsicSignature]] to the extrinsic (already generated)
|
||||
* @description Add an [[ExtrinsicSignatureV2]] to the extrinsic (already generated)
|
||||
*/
|
||||
public addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, payload: ExtrinsicPayloadValue | Uint8Array | string): ExtrinsicV2 {
|
||||
this.signature.addSignature(signer, signature, payload);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../../../injector';
|
||||
|
||||
import ExtrinsicExtra from './ExtrinsicExtra';
|
||||
|
||||
describe('ExtrinsicExtraV2', (): void => {
|
||||
it('encodes to a sane Uint8Array (default construction)', (): void => {
|
||||
expect(
|
||||
new ExtrinsicExtra().toU8a()
|
||||
).toEqual(new Uint8Array([0, 0, 0]));
|
||||
});
|
||||
|
||||
it('encodes to a sane Uint8Array (struct in)', (): void => {
|
||||
expect(
|
||||
new ExtrinsicExtra({ nonce: 1, tip: 2 }).toU8a()
|
||||
).toEqual(new Uint8Array([0, 4, 8])); // numbers are Compact
|
||||
});
|
||||
|
||||
it('encodes to a sane Uint8Array (Uint8Array in)', (): void => {
|
||||
expect(
|
||||
new ExtrinsicExtra(new Uint8Array([0, 8, 4])).toU8a()
|
||||
).toEqual(new Uint8Array([0, 8, 4]));
|
||||
});
|
||||
});
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Balance, Index } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicExtraValue } from '../types';
|
||||
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Address from '../../Generic/Address';
|
||||
import ExtrinsicEra from '../ExtrinsicEra';
|
||||
|
||||
/**
|
||||
* @name ExtrinsicExtraV2
|
||||
* @description
|
||||
* A container for the extra information in an extrinsic
|
||||
*/
|
||||
export default class ExtrinsicExtraV2 extends Struct {
|
||||
public constructor (value?: ExtrinsicExtraValue | Uint8Array) {
|
||||
super({
|
||||
era: ExtrinsicEra,
|
||||
nonce: 'Compact<Index>',
|
||||
tip: 'Compact<Balance>'
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ExtrinsicEra]] (mortal or immortal) this signature applies to
|
||||
*/
|
||||
public get era (): ExtrinsicEra {
|
||||
return this.get('era') as ExtrinsicEra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Index]] for the signature
|
||||
*/
|
||||
public get nonce (): Compact<Index> {
|
||||
return this.get('nonce') as Compact<Index>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Address]] that signed
|
||||
*/
|
||||
public get signer (): Address {
|
||||
return this.get('signer') as Address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Balance]] tip
|
||||
*/
|
||||
public get tip (): Compact<Balance> {
|
||||
return this.get('tip') as Compact<Balance>;
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,23 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Balance, Hash, Index } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IKeyringPair } from '../../../types';
|
||||
import { Balance, ExtrinsicEra, Hash, Index } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IKeyringPair, InterfaceTypes } from '../../../types';
|
||||
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Bytes from '../../../primitive/Bytes';
|
||||
import ExtrinsicEra from '../ExtrinsicEra';
|
||||
import { sign } from '../util';
|
||||
|
||||
// SignedExtra adds the following fields to the payload
|
||||
const SignedExtraV2: Record<string, InterfaceTypes> = {
|
||||
// system::CheckEra<Runtime>
|
||||
blockHash: 'Hash'
|
||||
// system::CheckNonce<Runtime>
|
||||
// system::CheckWeight<Runtime>
|
||||
// balances::TakeFees<Runtime>
|
||||
};
|
||||
|
||||
/**
|
||||
* @name ExtrinsicPayloadV2
|
||||
* @description
|
||||
@@ -21,10 +29,10 @@ export default class ExtrinsicPayloadV2 extends Struct {
|
||||
public constructor (value?: ExtrinsicPayloadValue | Uint8Array | string) {
|
||||
super({
|
||||
method: 'Bytes',
|
||||
era: ExtrinsicEra,
|
||||
era: 'ExtrinsicEra',
|
||||
nonce: 'Compact<Index>',
|
||||
tip: 'Compact<Balance>',
|
||||
blockHash: 'Hash'
|
||||
...SignedExtraV2
|
||||
}, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Address, Balance, Index, Signature } from '../../../interfaces/runtime';
|
||||
import { Address, Balance, Call, ExtrinsicEra, Index, Signature } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicSignatureOptions } from '../types';
|
||||
|
||||
import { createType } from '../../../codec/create';
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
import ExtrinsicEra from '../ExtrinsicEra';
|
||||
import { EMPTY_U8A, IMMORTAL_ERA } from '../constants';
|
||||
import ExtrinsicExtraV2 from './ExtrinsicExtra';
|
||||
import ExtrinsicPayloadV2 from './ExtrinsicPayload';
|
||||
|
||||
/**
|
||||
@@ -25,7 +22,9 @@ export default class ExtrinsicSignatureV2 extends Struct implements IExtrinsicSi
|
||||
super({
|
||||
signer: 'Address',
|
||||
signature: 'Signature',
|
||||
extra: ExtrinsicExtraV2
|
||||
era: 'ExtrinsicEra',
|
||||
nonce: 'Compact<Index>',
|
||||
tip: 'Compact<Balance>'
|
||||
}, ExtrinsicSignatureV2.decodeExtrinsicSignature(value, isSigned));
|
||||
}
|
||||
|
||||
@@ -57,25 +56,18 @@ export default class ExtrinsicSignatureV2 extends Struct implements IExtrinsicSi
|
||||
return !this.signature.isEmpty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the extra extrinsic info
|
||||
*/
|
||||
public get extra (): ExtrinsicExtraV2 {
|
||||
return this.get('extra') as ExtrinsicExtraV2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ExtrinsicEra]] (mortal or immortal) this signature applies to
|
||||
*/
|
||||
public get era (): ExtrinsicEra {
|
||||
return this.extra.era;
|
||||
return this.get('era') as ExtrinsicEra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[Index]] for the signature
|
||||
*/
|
||||
public get nonce (): Compact<Index> {
|
||||
return this.extra.nonce;
|
||||
return this.get('nonce') as Compact<Index>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,16 +88,15 @@ export default class ExtrinsicSignatureV2 extends Struct implements IExtrinsicSi
|
||||
* @description The [[Balance]] tip
|
||||
*/
|
||||
public get tip (): Compact<Balance> {
|
||||
return this.extra.tip;
|
||||
return this.get('tip') as Compact<Balance>;
|
||||
}
|
||||
|
||||
protected injectSignature (signer: Address, signature: Signature, { era, nonce, tip }: ExtrinsicPayloadV2): IExtrinsicSignature {
|
||||
this.extra.set('era', era);
|
||||
this.extra.set('nonce', nonce);
|
||||
this.extra.set('tip', tip);
|
||||
|
||||
this.set('era', era);
|
||||
this.set('nonce', nonce);
|
||||
this.set('signer', signer);
|
||||
this.set('signature', signature);
|
||||
this.set('tip', tip);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -132,6 +123,7 @@ export default class ExtrinsicSignatureV2 extends Struct implements IExtrinsicSi
|
||||
genesisHash,
|
||||
method: method.toHex(),
|
||||
nonce,
|
||||
specVersion: 0, // unused for v2
|
||||
tip: tip || 0
|
||||
});
|
||||
const signature = createType('Signature', payload.sign(account));
|
||||
|
||||
@@ -2,6 +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 BN from 'bn.js';
|
||||
import extrinsics from '@polkadot/api-metadata/extrinsics/static';
|
||||
import testingPairs from '@polkadot/keyring/testingPairs';
|
||||
|
||||
@@ -43,14 +44,22 @@ describe('ExtrinsicV3', (): void => {
|
||||
blockHash: '0xec7afaf1cca720ce88c1d1b689d81f0583cc15a97d621cf046dd9abf605ef22f',
|
||||
genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b',
|
||||
nonce: 1,
|
||||
runtimeVersion: {
|
||||
apis: [],
|
||||
authoringVersion: new BN(123),
|
||||
implName: 'test',
|
||||
implVersion: new BN(123),
|
||||
specName: 'test',
|
||||
specVersion: new BN(123)
|
||||
},
|
||||
tip: 2
|
||||
}).toHex()
|
||||
).toEqual(
|
||||
'0x' +
|
||||
'ff' +
|
||||
'd172a74cda4c865912c32ba0a80a57ae69abae410e5ccb59dee84e2f4432db4f' +
|
||||
'2bb401483999053d2d69a4aebefb9682c8710ddd495d1298d4eedd241c73869f' +
|
||||
'9d32c82dba98b12ef74bea5f987851b592956de3cf3e946533da815e3b6a2904' +
|
||||
'21de8ff3cae3ee72ced565ed5f79fd153dc84a3be9166b7904eecde8045ba59a' +
|
||||
'd2f998cc970e59157f168ec762eea061f4930b5288f57a45a1c1911863860208' +
|
||||
'000408' + // era. nonce, tip
|
||||
'0500' +
|
||||
'ff' +
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Address, Call } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IExtrinsicImpl, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicOptions } from '../types';
|
||||
|
||||
import { isU8a } from '@polkadot/util';
|
||||
|
||||
import { createType, ClassOf } from '../../../codec/create';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
import Address from '../../Generic/Address';
|
||||
import ExtrinsicSignature from './ExtrinsicSignature';
|
||||
import ExtrinsicSignatureV3 from './ExtrinsicSignature';
|
||||
|
||||
const TRANSACTION_VERSION = 3;
|
||||
|
||||
export interface ExtrinsicValueV3 {
|
||||
method?: Call;
|
||||
signature?: ExtrinsicSignature;
|
||||
signature?: ExtrinsicSignatureV3;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,8 +27,8 @@ export interface ExtrinsicValueV3 {
|
||||
export default class ExtrinsicV3 extends Struct implements IExtrinsicImpl {
|
||||
public constructor (value?: Uint8Array | ExtrinsicValueV3 | Call, { isSigned }: ExtrinsicOptions = {}) {
|
||||
super({
|
||||
signature: ExtrinsicSignature,
|
||||
method: Call
|
||||
signature: ExtrinsicSignatureV3,
|
||||
method: 'Call'
|
||||
}, ExtrinsicV3.decodeExtrinsic(value, isSigned));
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ export default class ExtrinsicV3 extends Struct implements IExtrinsicImpl {
|
||||
return {};
|
||||
} else if (value instanceof ExtrinsicV3) {
|
||||
return value;
|
||||
} else if (value instanceof Call) {
|
||||
} else if (value instanceof ClassOf('Call')) {
|
||||
return { method: value };
|
||||
} else if (isU8a(value)) {
|
||||
// here we decode manually since we need to pull through the version information
|
||||
const signature = new ExtrinsicSignature(value, { isSigned });
|
||||
const method = new Call(value.subarray(signature.encodedLength));
|
||||
const signature = new ExtrinsicSignatureV3(value, { isSigned });
|
||||
const method = createType('Call', value.subarray(signature.encodedLength));
|
||||
|
||||
return {
|
||||
method,
|
||||
@@ -68,10 +68,10 @@ export default class ExtrinsicV3 extends Struct implements IExtrinsicImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The [[ExtrinsicSignature]]
|
||||
* @description The [[ExtrinsicSignatureV3]]
|
||||
*/
|
||||
public get signature (): ExtrinsicSignature {
|
||||
return this.get('signature') as ExtrinsicSignature;
|
||||
public get signature (): ExtrinsicSignatureV3 {
|
||||
return this.get('signature') as ExtrinsicSignatureV3;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ export default class ExtrinsicV3 extends Struct implements IExtrinsicImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Add an [[ExtrinsicSignature]] to the extrinsic (already generated)
|
||||
* @description Add an [[ExtrinsicSignatureV3]] to the extrinsic (already generated)
|
||||
*/
|
||||
public addSignature (signer: Address | Uint8Array | string, signature: Uint8Array | string, payload: ExtrinsicPayloadValue | Uint8Array | string): ExtrinsicV3 {
|
||||
this.signature.addSignature(signer, signature, payload);
|
||||
|
||||
@@ -2,15 +2,28 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Balance, Hash, Index } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IKeyringPair } from '../../../types';
|
||||
import { Balance, ExtrinsicEra, Hash, Index } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IKeyringPair, InterfaceTypes } from '../../../types';
|
||||
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Bytes from '../../../primitive/Bytes';
|
||||
import ExtrinsicEra from '../ExtrinsicEra';
|
||||
import u32 from '../../../primitive/U32';
|
||||
import { sign } from '../util';
|
||||
|
||||
// SignedExtra adds the following fields to the payload
|
||||
const SignedExtraV3: Record<string, InterfaceTypes> = {
|
||||
// system::CheckVersion<Runtime>
|
||||
specVersion: 'u32',
|
||||
// system::CheckGenesis<Runtime>
|
||||
genesisHash: 'Hash',
|
||||
// system::CheckEra<Runtime>
|
||||
blockHash: 'Hash'
|
||||
// system::CheckNonce<Runtime>
|
||||
// system::CheckWeight<Runtime>
|
||||
// balances::TakeFees<Runtime>
|
||||
};
|
||||
|
||||
/**
|
||||
* @name ExtrinsicPayloadV3
|
||||
* @description
|
||||
@@ -21,11 +34,10 @@ export default class ExtrinsicPayloadV3 extends Struct {
|
||||
public constructor (value?: ExtrinsicPayloadValue | Uint8Array | string) {
|
||||
super({
|
||||
method: 'Bytes',
|
||||
era: ExtrinsicEra,
|
||||
era: 'ExtrinsicEra',
|
||||
nonce: 'Compact<Index>',
|
||||
tip: 'Compact<Balance>',
|
||||
genesisHash: 'Hash',
|
||||
blockHash: 'Hash'
|
||||
...SignedExtraV3
|
||||
}, value);
|
||||
}
|
||||
|
||||
@@ -64,6 +76,13 @@ export default class ExtrinsicPayloadV3 extends Struct {
|
||||
return this.get('nonce') as Compact<Index>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The specVersion for this signature
|
||||
*/
|
||||
public get specVersion (): u32 {
|
||||
return this.get('specVersion') as u32;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The tip [[Balance]]
|
||||
*/
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Address } from '../../../interfaces/runtime';
|
||||
import { Address, Call } from '../../../interfaces/runtime';
|
||||
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
|
||||
import { createType } from '../../../codec/create';
|
||||
import Call from '../../Generic/Call';
|
||||
import { IMMORTAL_ERA } from '../constants';
|
||||
import ExtrinsicSignatureV2 from '../v2/ExtrinsicSignature';
|
||||
import ExtrinsicPayloadV3 from './ExtrinsicPayload';
|
||||
@@ -31,7 +30,7 @@ export default class ExtrinsicSignatureV3 extends ExtrinsicSignatureV2 {
|
||||
/**
|
||||
* @description Generate a payload and pplies the signature from a keypair
|
||||
*/
|
||||
public sign (method: Call, account: IKeyringPair, { blockHash, era, genesisHash, nonce, tip }: SignatureOptions): IExtrinsicSignature {
|
||||
public sign (method: Call, account: IKeyringPair, { blockHash, era, genesisHash, nonce, tip, runtimeVersion: { specVersion } }: SignatureOptions): IExtrinsicSignature {
|
||||
const signer = createType('Address', account.publicKey);
|
||||
const payload = new ExtrinsicPayloadV3({
|
||||
blockHash,
|
||||
@@ -39,6 +38,7 @@ export default class ExtrinsicSignatureV3 extends ExtrinsicSignatureV2 {
|
||||
genesisHash,
|
||||
method: method.toHex(),
|
||||
nonce,
|
||||
specVersion,
|
||||
tip: tip || 0
|
||||
});
|
||||
const signature = createType('Signature', payload.sign(account));
|
||||
|
||||
@@ -148,8 +148,8 @@ export interface SignatureOptions {
|
||||
era?: IExtrinsicEra;
|
||||
genesisHash: AnyU8a;
|
||||
nonce: AnyNumber;
|
||||
runtimeVersion: RuntimeVersionInterface;
|
||||
tip?: AnyNumber;
|
||||
version?: RuntimeVersionInterface;
|
||||
}
|
||||
|
||||
export type ArgsDef = Record<string, Constructor>;
|
||||
@@ -180,6 +180,7 @@ export interface ExtrinsicPayloadValue {
|
||||
genesisHash: AnyU8a;
|
||||
method: AnyU8a | IMethod;
|
||||
nonce: AnyNumber;
|
||||
specVersion: AnyNumber;
|
||||
tip: AnyNumber;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user