1import { Just, Nothing } from 'folktale/maybe';
2import React, { useCallback, useState, useEffect } from 'react';
3import * as azimuth from 'azimuth-js';
4import * as ob from 'urbit-ob';
5import * as kg from 'urbit-key-generation/dist/index';
6import { Input, Grid, CheckboxInput } from 'indigo-react';
8import { useNetwork } from 'store/network';
9import { useWallet } from 'store/wallet';
10import { usePointCursor } from 'store/pointCursor';
17} from 'lib/useInputs';
18import * as need from 'lib/need';
19import { WALLET_TYPES, urbitWalletFromTicket } from 'lib/wallet';
20import useImpliedPoint from 'lib/useImpliedPoint';
21import useLoginView from 'lib/useLoginView';
23export default function Ticket({ className }) {
24 useLoginView(WALLET_TYPES.TICKET);
26 const { contracts } = useNetwork();
27 const { setUrbitWallet } = useWallet();
28 const { setPointCursor } = usePointCursor();
29 const impliedPoint = useImpliedPoint();
32 const [pointInput, { data: pointName }] = usePointInput({
34 initialValue: impliedPoint || '',
39 const [passphraseInput, { data: passphrase }] = usePassphraseInput({
41 label: 'Wallet Passphrase',
44 const [hasPassphraseInput] = useCheckboxInput({
45 name: 'has-passphrase',
51 const [error, setError] = useState();
52 const [deriving, setDeriving] = useState(false);
53 const [ticketInput, { data: ticket, pass: validTicket }] = useTicketInput({
55 label: 'Master Ticket',
61 const [shardsInput, { data: isUsingShards }] = useCheckboxInput({
67 const [shard1Input, { data: shard1, pass: shard1Pass }] = useTicketInput({
72 const [shard2Input, { data: shard2, pass: shard2Pass }] = useTicketInput({
77 const [shard3Input, { data: shard3, pass: shard3Pass }] = useTicketInput({
82 const shardsReady = shard1Pass && shard2Pass && shard3Pass;
84 // TODO: maybe want to do this only on-go, because wallet derivation is slow...
85 const deriveWalletFromTicket = useCallback(async () => {
89 setUrbitWallet(Nothing());
91 if (!ob.isValidPatq(ticket) || !ob.isValidPatp(pointName)) {
96 const _contracts = need.contracts(contracts);
97 const pointNumber = ob.patp2dec(pointName);
98 const urbitWallet = await urbitWalletFromTicket(
103 const [isOwner, isTransferProxy] = await Promise.all([
104 azimuth.azimuth.isOwner(
107 urbitWallet.ownership.keys.address
109 azimuth.azimuth.isTransferProxy(
112 urbitWallet.ownership.keys.address
116 if (!isOwner && !isTransferProxy) {
117 // notify the user, but allow login regardless
119 'This ticket is not the owner of or transfer proxy for this point.'
123 setUrbitWallet(Just(urbitWallet));
124 setPointCursor(Just(ob.patp2dec(pointName)));
136 const deriveWalletFromShards = useCallback(async () => {
137 const s1 = shard1 || undefined;
138 const s2 = shard2 || undefined;
139 const s3 = shard3 || undefined;
142 const ticket = kg.combine([s1, s2, s3]);
143 const uhdw = await urbitWalletFromTicket(ticket, pointName, passphrase);
144 setUrbitWallet(Just(uhdw));
148 }, [passphrase, pointName, setUrbitWallet, shard1, shard2, shard3]);
150 // derive wallet on change
152 if (isUsingShards && shardsReady) {
153 deriveWalletFromShards();
154 } else if (validTicket) {
155 deriveWalletFromTicket();
161 deriveWalletFromShards,
162 deriveWalletFromTicket,
166 <Grid className={className}>
167 <Grid.Item full as={Input} {...pointInput} />
169 {!isUsingShards && <Grid.Item full as={Input} {...ticketInput} />}
172 <Grid.Item full as={Input} {...shard1Input} />
173 <Grid.Item full as={Input} {...shard2Input} />
174 <Grid.Item full as={Input} {...shard3Input} />
177 {hasPassphraseInput.data && (
178 <Grid.Item full as={Input} {...passphraseInput} />
181 <Grid.Item full as={CheckboxInput} {...hasPassphraseInput} />
182 <Grid.Item full as={CheckboxInput} {...shardsInput} />
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