UNPKG

5.11 kBJavaScriptView Raw
1import { Option, Struct } from '@polkadot/types-codec';
2import { objectProperty, objectSpread, u8aToHex } from '@polkadot/util';
3const knownTypes = {
4 address: 'Address',
5 assetId: 'Option<TAssetConversion>',
6 blockHash: 'Hash',
7 blockNumber: 'BlockNumber',
8 era: 'ExtrinsicEra',
9 genesisHash: 'Hash',
10 metadataHash: 'Option<[u8;32]>',
11 method: 'Call',
12 mode: 'u8',
13 nonce: 'Compact<Index>',
14 runtimeVersion: 'RuntimeVersion',
15 signedExtensions: 'Vec<Text>',
16 tip: 'Compact<Balance>',
17 version: 'u8'
18};
19/**
20 * @name GenericSignerPayload
21 * @description
22 * A generic signer payload that can be used for serialization between API and signer
23 */
24export class GenericSignerPayload extends Struct {
25 __internal__extraTypes;
26 constructor(registry, value) {
27 const extensionTypes = objectSpread({}, registry.getSignedExtensionTypes(), registry.getSignedExtensionExtra());
28 super(registry, objectSpread({}, extensionTypes, knownTypes, { withSignedTransaction: 'bool' }), value);
29 this.__internal__extraTypes = {};
30 const getter = (key) => this.get(key);
31 // add all extras that are not in the base types
32 for (const [key, type] of Object.entries(extensionTypes)) {
33 if (!knownTypes[key]) {
34 this.__internal__extraTypes[key] = type;
35 }
36 objectProperty(this, key, getter);
37 }
38 }
39 get address() {
40 return this.getT('address');
41 }
42 get blockHash() {
43 return this.getT('blockHash');
44 }
45 get blockNumber() {
46 return this.getT('blockNumber');
47 }
48 get era() {
49 return this.getT('era');
50 }
51 get genesisHash() {
52 return this.getT('genesisHash');
53 }
54 get method() {
55 return this.getT('method');
56 }
57 get nonce() {
58 return this.getT('nonce');
59 }
60 get runtimeVersion() {
61 return this.getT('runtimeVersion');
62 }
63 get signedExtensions() {
64 return this.getT('signedExtensions');
65 }
66 get tip() {
67 return this.getT('tip');
68 }
69 get assetId() {
70 return this.getT('assetId');
71 }
72 get version() {
73 return this.getT('version');
74 }
75 get mode() {
76 return this.getT('mode');
77 }
78 get metadataHash() {
79 return this.getT('metadataHash');
80 }
81 get withSignedTransaction() {
82 const val = this.getT('withSignedTransaction');
83 return val.isTrue;
84 }
85 /**
86 * @description Creates an representation of the structure as an ISignerPayload JSON
87 */
88 toPayload() {
89 const result = {};
90 const keys = Object.keys(this.__internal__extraTypes);
91 // add any explicit overrides we may have
92 for (let i = 0, count = keys.length; i < count; i++) {
93 const key = keys[i];
94 const value = this.getT(key);
95 // Don't include Option.isNone
96 if (!(value instanceof Option) || value.isSome) {
97 // NOTE In the spread below we convert (mostly) to Hex to align
98 // with the typings. In the case of "unknown" fields, we use the
99 // primitive toJSON conversion (which is serializable). Technically
100 // we can include isNone in here as well ("null" is allowed), however
101 // for empty fields we just skip it completely (historical compat)
102 result[key] = value.toJSON();
103 }
104 }
105 return objectSpread(result, {
106 // the known defaults as managed explicitly and has different
107 // formatting in cases, e.g. we mostly expose a hex format here
108 address: this.address.toString(),
109 assetId: this.assetId && this.assetId.isSome ? this.assetId.toHex() : null,
110 blockHash: this.blockHash.toHex(),
111 blockNumber: this.blockNumber.toHex(),
112 era: this.era.toHex(),
113 genesisHash: this.genesisHash.toHex(),
114 metadataHash: this.metadataHash.isSome ? this.metadataHash.toHex() : null,
115 method: this.method.toHex(),
116 mode: this.mode.toNumber(),
117 nonce: this.nonce.toHex(),
118 signedExtensions: this.signedExtensions.map((e) => e.toString()),
119 specVersion: this.runtimeVersion.specVersion.toHex(),
120 tip: this.tip.toHex(),
121 transactionVersion: this.runtimeVersion.transactionVersion.toHex(),
122 version: this.version.toNumber(),
123 withSignedTransaction: this.withSignedTransaction
124 });
125 }
126 /**
127 * @description Creates a representation of the payload in raw Exrinsic form
128 */
129 toRaw() {
130 const payload = this.toPayload();
131 const data = u8aToHex(this.registry
132 .createTypeUnsafe('ExtrinsicPayload', [payload, { version: payload.version }])
133 // NOTE Explicitly pass the bare flag so the method is encoded un-prefixed (non-decodable, for signing only)
134 .toU8a({ method: true }));
135 return {
136 address: payload.address,
137 data,
138 type: 'payload'
139 };
140 }
141}