on cd91628 help sign in
bridge/src/components/Inputs.js
219 lines 5.3 kB history raw
1import React, { useCallback, useState, useMemo } from 'react';
2import { AccessoryIcon, useForm } from 'indigo-react';
3import { identity } from 'lodash';
4import * as bip39 from 'bip39';
6import InputSigil from 'components/InputSigil';
8import { DEFAULT_HD_PATH } from 'lib/wallet';
9import {
10 validateNotEmpty,
11 validateMnemonic,
12 validatePoint,
13 validateTicket,
14 validateEmail,
15 validateLength,
16 validateHexString,
17} from 'lib/validators';
18import { prependSig } from 'lib/transformers';
20const EXAMPLE_PRIVATE_KEY =
21 '0xa44de2416ee6beb2f323fab48b432925c9785808d33a6ca6d7ba00b45e9370c3';
23// const RequiredInput = advancedInput({
24// WrappedComponent: Input,
25// validators: [validateNotEmpty],
26// });
28// const NetworkKeyInput = advancedInput({
29// WrappedComponent: Input,
30// validators: [validateNotEmpty, validateNetworkKey],
31// });
33// const NetworkSeedInput = advancedInput({
34// WrappedComponent: Input,
35// validators: [validateNotEmpty, validateNetworkSeed],
36// });
38// const AddressInput = advancedInput({
39// WrappedComponent: Input,
40// validators: [validateEthereumAddress, validateNotEmpty],
41// });
43// const GalaxyInput = advancedInput({
44// WrappedComponent: Input,
45// validators: [validateGalaxy, validateNotEmpty],
46// transformers: [prependSig],
47// });
49// pulls out the first input from a useForm() call
50function useFirstOf({ inputs, setValue, ...rest }, mapper = identity) {
51 // ask the mapper function for any values to overwrite
52 const input = {
53 ...inputs[0],
54 ...mapper(inputs[0]),
55 };
56 // memoize the setValue callback for manually setting the value
57 // in response to some imperative event
58 const _setValue = useCallback(value => setValue(input.name, value), [
59 setValue,
60 input.name,
61 ]);
63 // provide the first input as the first element
64 // _and_ as the second element to facilitate destructuring
65 // and then provide the pass/error/setValue/etc properties at the end
66 return [
67 input,
68 input,
69 {
70 ...rest,
71 setValue: _setValue,
72 },
73 ];
76export function usePassphraseInput(props) {
77 return useFirstOf(
78 useForm([
79 {
80 type: 'password',
81 autoComplete: 'off',
82 placeholder: 'Passphrase',
83 ...props,
84 },
85 ])
86 );
89export function useHexInput({ length, ...rest }) {
90 return useFirstOf(
91 useForm([
92 {
93 type: 'text', // or password
94 autoComplete: 'off',
95 placeholder: EXAMPLE_PRIVATE_KEY,
96 validators: useMemo(
97 () => [
98 validateHexString,
99 validateLength(length + 2),
100 validateNotEmpty,
101 ],
102 [length]
103 ),
104 ...rest,
105 },
106 ])
107 );
110const kExampleMnemonic = bip39.generateMnemonic();
111const kMnemonicValidators = [validateMnemonic, validateNotEmpty];
112export function useMnemonicInput(props) {
113 return useFirstOf(
114 useForm([
115 {
116 type: 'text',
117 autoComplete: 'off',
118 placeholder: `e.g. ${kExampleMnemonic}`,
119 validators: kMnemonicValidators,
120 ...props,
121 },
122 ])
123 );
126export function useHdPathInput(props) {
127 return useFirstOf(
128 useForm([
129 {
130 type: 'text',
131 autoComplete: 'off',
132 placeholder: `e.g. ${DEFAULT_HD_PATH}`,
133 ...props,
134 },
135 ])
136 );
139const kTicketValidators = [validateTicket, validateNotEmpty];
140const kTicketTransformers = [prependSig];
141//TODO needs to be fancier, displaying sig and dashes instead of •ing all
142export function useTicketInput({ validators = [], deriving = false, ...rest }) {
143 return useFirstOf(
144 useForm([
145 {
146 type: 'password',
147 label: 'Ticket',
148 placeholder: '~ragtyd-modwen-bostec-hinsep',
149 validators: useMemo(() => [...validators, ...kTicketValidators], [
150 validators,
151 ]),
152 transformers: kTicketTransformers,
153 mono: true,
154 ...rest,
155 },
156 ]),
157 ({ error, pass }) => ({
158 accessory: error ? (
159 <AccessoryIcon.Failure />
160 ) : deriving ? (
161 <AccessoryIcon.Pending />
162 ) : pass ? (
163 <AccessoryIcon.Success />
164 ) : null,
165 })
166 );
169const kPointValidators = [validatePoint, validateNotEmpty];
170const kPointTransformers = [prependSig];
171export function usePointInput(rest) {
172 const [lastValidPoint, setLastValidPoint] = useState('');
173 return useFirstOf(
174 useForm([
175 {
176 type: 'text',
177 label: 'Point',
178 placeholder: 'e.g. ~zod',
179 validators: kPointValidators,
180 transformers: kPointTransformers,
181 mono: true,
182 onValue: setLastValidPoint,
183 ...rest,
184 },
185 ]),
186 ({ error, pass, focused }) => ({
187 accessory: lastValidPoint ? (
188 <InputSigil
189 patp={lastValidPoint}
190 size={68}
191 margin={8}
192 pass={pass}
193 focused={focused}
194 error={error}
195 />
196 ) : null,
197 })
198 );
201export function useCheckboxInput({ initialValue, ...rest }) {
202 return useFirstOf(
203 useForm([
204 {
205 type: 'checkbox',
206 ...rest,
207 },
208 ])
209 );
212const kEmailValidators = [validateEmail, validateNotEmpty];
213export const buildEmailInputConfig = extra => ({
214 type: 'email',
215 autoComplete: 'off',
216 validators: kEmailValidators,
217 initialValue: '',
218 ...extra,
219});