-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathPartial.tsx
125 lines (109 loc) · 3.71 KB
/
Partial.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright 2017-2023 @polkadot/app-preimages authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ApiPromise } from '@polkadot/api';
import type { SubmittableExtrinsic } from '@polkadot/api/types';
import type { BN } from '@polkadot/util';
import type { HexString } from '@polkadot/util/types';
import type { HashState } from './types.js';
import React, { useCallback, useState } from 'react';
import { InputBalance, Modal, Static } from '@polkadot/react-components';
import { useApi } from '@polkadot/react-hooks';
import { Extrinsic } from '@polkadot/react-params';
import { BN_ZERO } from '@polkadot/util';
import { blake2AsHex } from '@polkadot/util-crypto';
import { useTranslation } from '../../translate.js';
interface Props {
className?: string;
onChange: (state: HashState) => void;
}
const EMPTY_HASH = blake2AsHex('');
export const EMPTY_PROPOSAL: HashState = {
encodedHash: EMPTY_HASH,
encodedLength: 0,
encodedProposal: null,
notePreimageTx: null,
storageFee: BN_ZERO
};
function getState (api: ApiPromise, proposal?: SubmittableExtrinsic<'promise'>): HashState {
let encodedHash = EMPTY_HASH;
let encodedProposal: HexString | null = null;
let encodedLength = 0;
let notePreimageTx: SubmittableExtrinsic<'promise'> | null = null;
let storageFee = BN_ZERO;
if (proposal) {
encodedProposal = proposal.method.toHex();
encodedLength = Math.ceil((encodedProposal.length - 2) / 2);
encodedHash = blake2AsHex(encodedProposal);
notePreimageTx = api.tx.preimage.notePreimage(encodedProposal);
// we currently don't have a constant exposed, however match to Substrate
storageFee = ((api.consts.preimage?.baseDeposit || BN_ZERO) as unknown as BN).add(
((api.consts.preimage?.byteDeposit || BN_ZERO) as unknown as BN).muln(encodedLength)
);
}
return {
encodedHash,
encodedLength,
encodedProposal,
notePreimageTx,
storageFee
};
}
function Partial ({ className, onChange }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api, apiDefaultTxSudo } = useApi();
const [{ encodedHash, encodedLength, storageFee }, setState] = useState<HashState>(EMPTY_PROPOSAL);
const changeState = useCallback(
(state: HashState): void => {
setState(state);
onChange(state);
},
[onChange]
);
const setProposal = useCallback(
(proposal?: SubmittableExtrinsic<'promise'>) =>
changeState(getState(api, proposal)),
[api, changeState]
);
return (
<>
<Modal.Columns
className={className}
hint={
<>
<p>{t<string>('The image (proposal) will be stored on-chain against the hash of the contents.')}</p>
<p>{t<string>('When submitting a proposal the hash needs to be known. Proposals can be submitted with hash-only, but upon dispatch the preimage needs to be available.')}</p>
</>
}
>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t<string>('propose')}
onChange={setProposal}
/>
<Static
label={t<string>('preimage hash')}
value={encodedHash}
withCopy
/>
<Static
label={t<string>('preimage length')}
value={encodedLength || '0'}
withCopy
/>
</Modal.Columns>
{!storageFee.isZero() && (
<Modal.Columns
className={className}
hint={t<string>('The calculated storage costs based on the base and the per-bytes fee.')}
>
<InputBalance
defaultValue={storageFee}
isDisabled
label={t<string>('calculated storage fee')}
/>
</Modal.Columns>
)}
</>
);
}
export default React.memo(Partial);