1import React, { useCallback, useMemo, useRef } from 'react';
2import { Just } from 'folktale/maybe';
3import cn from 'classnames';
4import * as azimuth from 'azimuth-js';
5import * as kg from 'urbit-key-generation';
13import { FORM_ERROR } from 'final-form';
15import { useNetwork } from 'store/network';
16import { useWallet } from 'store/wallet';
17import { usePointCursor } from 'store/pointCursor';
19import * as need from 'lib/need';
20import { WALLET_TYPES, urbitWalletFromTicket } from 'lib/wallet';
21import useImpliedPoint from 'lib/useImpliedPoint';
22import useLoginView from 'lib/useLoginView';
23import patp2dec from 'lib/patp2dec';
24import timeout from 'lib/timeout';
26import BridgeForm from 'form/BridgeForm';
27import Condition from 'form/Condition';
28import { TicketInput, PassphraseInput, PointInput } from 'form/Inputs';
31 buildCheckboxValidator,
33 buildPassphraseValidator,
35} from 'form/validators';
36import FormError from 'form/FormError';
37import SubmitButton from 'form/SubmitButton';
38import { WARNING } from 'form/helpers';
40import { ReactComponent as SecretShowIcon } from 'assets/secret-show.svg';
41import { ReactComponent as SecretHideIcon } from 'assets/secret-hidden.svg';
43function AdvancedOptions() {
46 <Condition when="useAdvanced" is={true}>
54 style={{ boxSizing: 'border-box' }}
63 style={{ boxSizing: 'border-box' }}
77function TicketInputAccessory({ name }) {
83 inverseLabel={<SecretShowIcon />}
84 label={<SecretHideIcon />}
90export default function Ticket({ className, goHome }) {
91 useLoginView(WALLET_TYPES.TICKET);
93 const { contracts } = useNetwork();
94 const { setUrbitWallet } = useWallet();
95 const { setPointCursor } = usePointCursor();
96 const impliedPoint = useImpliedPoint();
97 const didWarn = useRef(false);
99 const validateForm = useCallback((values, errors) => {
100 didWarn.current = false;
106 if (values.useShards) {
107 if (errors.shard1 || errors.shard2 || errors.shard3) {
117 const onSubmit = useCallback(
119 const ticket = values.useShards
120 ? kg.combine([values.shard1, values.shard2, values.shard3])
124 const _contracts = need.contracts(contracts);
125 const point = patp2dec(values.point);
127 await timeout(16); // allow ui events to flush
128 const urbitWallet = await urbitWalletFromTicket(
134 const [isOwner, isTransferProxy] = await Promise.all([
135 azimuth.azimuth.isOwner(
138 urbitWallet.ownership.keys.address
140 azimuth.azimuth.isTransferProxy(
143 urbitWallet.ownership.keys.address
147 const noPermissions = !isOwner && !isTransferProxy;
149 if (noPermissions && !didWarn.current) {
150 didWarn.current = true;
153 'This wallet is not the owner or transfer proxy for this point.',
157 setUrbitWallet(Just(urbitWallet));
158 setPointCursor(Just(patp2dec(values.point)));
160 console.error(error);
162 [FORM_ERROR]: `Unable to derive wallet from ${
163 values.useShards ? 'shards' : 'ticket'
168 [contracts, setPointCursor, setUrbitWallet]
171 const validate = useMemo(
175 useAdvanced: buildCheckboxValidator(),
176 usePassphrase: buildCheckboxValidator(),
177 useShards: buildCheckboxValidator(),
178 point: buildPointValidator(4),
179 ticket: buildPatqValidator(),
180 shard1: buildPatqValidator(),
181 shard2: buildPatqValidator(),
182 shard3: buildPatqValidator(),
183 ticketHidden: buildCheckboxValidator(),
184 passphrase: buildPassphraseValidator(),
191 const initialValues = useMemo(
193 point: impliedPoint || '',
203 <Grid className={className}>
208 initialValues={initialValues}>
209 {({ handleSubmit, values, submitting }) => (
211 <Grid.Item full as={PointInput} name="point" />
213 <Condition when="useShards" is={false}>
217 hidden={values.ticketHidden}
218 labelAccessory={<AdvancedOptions />}
219 accessory={<TicketInputAccessory name="ticketHidden" />}
222 label="Master Ticket"
226 <Condition when="useShards" is={true}>
230 accessory={<TicketInputAccessory name="ticketHidden" />}
231 hidden={values.ticketHidden}
232 labelAccessory={<AdvancedOptions />}
240 accessory={<TicketInputAccessory name="ticketHidden" />}
241 hidden={values.ticketHidden}
250 accessory={<TicketInputAccessory name="ticketHidden" />}
251 hidden={values.ticketHidden}
257 <Condition when="usePassphrase" is={true}>
263 label="Wallet Passphrase"
267 <Grid.Item full as={FormError} />
273 handleSubmit={handleSubmit}>
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list