UNPKG

5.6 kBJavaScriptView Raw
1import { AbstractBase } from '@polkadot/types-codec';
2import { hexToU8a, isHex, u8aToHex } from '@polkadot/util';
3import { DEFAULT_PREAMBLE, LATEST_EXTRINSIC_VERSION } from './constants.js';
4const VERSIONS = [
5 'ExtrinsicPayloadUnknown', // v0 is unknown
6 'ExtrinsicPayloadUnknown',
7 'ExtrinsicPayloadUnknown',
8 'ExtrinsicPayloadUnknown',
9 'ExtrinsicPayloadV4',
10 'ExtrinsicPayloadV5'
11];
12const PREAMBLES = {
13 bare: 'ExtrinsicPayloadV5',
14 // Not supported yet
15 general: 'ExtrinsicPayloadV5',
16 signed: 'ExtrinsicPayloadV5'
17};
18/** @internal */
19function decodeExtrinsicPayload(registry, value, version = LATEST_EXTRINSIC_VERSION, preamble = DEFAULT_PREAMBLE) {
20 if (value instanceof GenericExtrinsicPayload) {
21 return value.unwrap();
22 }
23 const extVersion = version === 5 ? PREAMBLES[preamble] : VERSIONS[version] || VERSIONS[0];
24 /**
25 * HACK: In order to change the assetId from `number | object` to HexString (While maintaining the true type ie Option<TAssetConversion>),
26 * to allow for easier generalization of the SignerPayloadJSON interface the below check is necessary. The ExtrinsicPayloadV4 class does not like
27 * a value passed in as an Option, and can't decode it properly. Therefore, we ensure to convert the following below, and then pass the option as a unwrapped
28 * JSON value.
29 *
30 * ref: https://github.com/polkadot-js/api/pull/5968
31 * ref: https://github.com/polkadot-js/api/pull/5967
32 */
33 if (value && value.assetId && isHex(value.assetId)) {
34 const adjustedPayload = {
35 ...value,
36 assetId: registry.createType('TAssetConversion', hexToU8a(value.assetId)).toJSON()
37 };
38 return registry.createTypeUnsafe(extVersion, [adjustedPayload, { version }]);
39 }
40 return registry.createTypeUnsafe(extVersion, [value, { version }]);
41}
42/**
43 * @name GenericExtrinsicPayload
44 * @description
45 * A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based
46 * on the contents included
47 */
48export class GenericExtrinsicPayload extends AbstractBase {
49 constructor(registry, value, { preamble, version } = {}) {
50 super(registry, decodeExtrinsicPayload(registry, value, version, preamble));
51 }
52 /**
53 * @description The block [[BlockHash]] the signature applies to (mortal/immortal)
54 */
55 get blockHash() {
56 return this.inner.blockHash;
57 }
58 /**
59 * @description The [[ExtrinsicEra]]
60 */
61 get era() {
62 return this.inner.era;
63 }
64 /**
65 * @description The genesis block [[BlockHash]] the signature applies to
66 */
67 get genesisHash() {
68 // NOTE only v3+
69 return this.inner.genesisHash || this.registry.createTypeUnsafe('Hash', []);
70 }
71 /**
72 * @description The [[Bytes]] contained in the payload
73 */
74 get method() {
75 return this.inner.method;
76 }
77 /**
78 * @description The [[Index]]
79 */
80 get nonce() {
81 return this.inner.nonce;
82 }
83 /**
84 * @description The specVersion as a [[u32]] for this payload
85 */
86 get specVersion() {
87 // NOTE only v3+
88 return this.inner.specVersion || this.registry.createTypeUnsafe('u32', []);
89 }
90 /**
91 * @description The [[Balance]]
92 */
93 get tip() {
94 // NOTE from v2+
95 return this.inner.tip || this.registry.createTypeUnsafe('Compact<Balance>', []);
96 }
97 /**
98 * @description The transaction version as a [[u32]] for this payload
99 */
100 get transactionVersion() {
101 // NOTE only v4+
102 return this.inner.transactionVersion || this.registry.createTypeUnsafe('u32', []);
103 }
104 /**
105 * @description The (optional) asset id as a [[u32]] or [[MultiLocation]] for this payload
106 */
107 get assetId() {
108 return this.inner.assetId;
109 }
110 /**
111 * @description The (optional) [[Hash]] of the genesis metadata for this payload
112 */
113 get metadataHash() {
114 return this.inner.metadataHash;
115 }
116 /**
117 * @description Compares the value of the input to see if there is a match
118 */
119 eq(other) {
120 return this.inner.eq(other);
121 }
122 /**
123 * @description Sign the payload with the keypair
124 */
125 sign(signerPair) {
126 const signature = this.inner.sign(signerPair);
127 // This is extensible, so we could quite readily extend to send back extra
128 // information, such as for instance the payload, i.e. `payload: this.toHex()`
129 // For the case here we sign via the extrinsic, we ignore the return, so generally
130 // this is applicable for external signing
131 return {
132 signature: u8aToHex(signature)
133 };
134 }
135 /**
136 * @description Converts the Object to to a human-friendly JSON, with additional fields, expansion and formatting of information
137 */
138 toHuman(isExtended, disableAscii) {
139 return this.inner.toHuman(isExtended, disableAscii);
140 }
141 /**
142 * @description Converts the Object to JSON, typically used for RPC transfers
143 */
144 toJSON() {
145 return this.toHex();
146 }
147 /**
148 * @description Returns the base runtime type name for this instance
149 */
150 toRawType() {
151 return 'ExtrinsicPayload';
152 }
153 /**
154 * @description Returns the string representation of the value
155 */
156 toString() {
157 return this.toHex();
158 }
159 /**
160 * @description Returns a serialized u8a form
161 */
162 toU8a(isBare) {
163 // call our parent, with only the method stripped
164 return super.toU8a(isBare ? { method: true } : false);
165 }
166}