@@ -1,4 +1,4 @@
1−import { Just, Nothing } from 'folktale/maybe';
1+import { Just } from 'folktale/maybe';
2import Tx from 'ethereumjs-tx';
2import Tx from 'ethereumjs-tx';
4import * as azimuth from 'azimuth-js';
4import * as azimuth from 'azimuth-js';
@@ -9,8 +9,7 @@ import * as tank from './tank';
9import JSZip from 'jszip';
9import JSZip from 'jszip';
10import saveAs from 'file-saver';
10import saveAs from 'file-saver';
12−import { sendSignedTransaction } from './txn';
12+import { sendSignedTransaction, hexify } from './txn';
13−import { BRIDGE_ERROR } from './error';
14import { attemptNetworkSeedDerivation } from './keys';
13import { attemptNetworkSeedDerivation } from './keys';
15import { addHexPrefix, WALLET_TYPES } from './wallet';
14import { addHexPrefix, WALLET_TYPES } from './wallet';
@@ -32,36 +31,36 @@ const WALLET_STATES = {
33const TRANSACTION_STATES = {
32const TRANSACTION_STATES = {
34 GENERATING: {
33 GENERATING: {
35− label: 'Generating transactions',
34+ label: 'Generating Transactions...',
36− pct: '0%',
35+ progress: 0.0,
38 SIGNING: {
37 SIGNING: {
39− label: 'Signing transactions',
38+ label: 'Signing Transactions...',
40− pct: '15%',
39+ progress: 0.15,
42 FUNDING_INVITE: {
41 FUNDING_INVITE: {
43− label: 'Funding invite wallet',
42+ label: 'Funding Invite Wallet...',
44− pct: '30%',
43+ progress: 0.3,
46 CLAIMING: {
45 CLAIMING: {
47− label: 'Claiming invite',
46+ label: 'Claiming Invite...',
48− pct: '55%',
47+ progress: 0.55,
50 FUNDING_RECIPIENT: {
49 FUNDING_RECIPIENT: {
51− label: 'Funding recipient wallet',
50+ label: 'Funding Recipient Wallet...',
52− pct: '65%',
51+ progress: 0.65,
54 CONFIGURING: {
53 CONFIGURING: {
55− label: 'Configuring planet',
54+ label: 'Configuring Point...',
56− pct: '85%',
55+ progress: 0.85,
58 CLEANING: {
57 CLEANING: {
59− label: 'Cleaning up',
58+ label: 'Cleaning Up...',
60− pct: '95%',
59+ progress: 0.95,
63 label: 'Done',
62 label: 'Done',
64− pct: '100%',
63+ progress: 1.0,
@@ -102,93 +101,61 @@ async function downloadWallet(paper) {
105−async function startTransactions(args) {
104+async function claimPointFromInvite({
106− let {
105+ inviteWallet,
107− realPointM,
106+ wallet,
108− web3: web3M,
108+ web3,
109− contracts: contractsM,
109+ contracts,
110− inviteWalletM,
110+ onUpdate,
111− realWalletM,
111+}) {
116− const askForFunding = (address, amount, current) => {
112+ const askForFunding = (address, minBalance, balance) =>
117− updateProgress({
113+ onUpdate({
118− type: 'notify',
114+ type: 'askFunding',
119− value: `Please make sure ${address} has at least ${amount} wei, we'll continue once that's true. Current balance: ${current}. Waiting`,
115+ value: { address, minBalance, balance },
123− if (Nothing.hasInstance(web3M)) {
118+ const gotFunding = () => onUpdate({ type: 'gotFunding' });
124− throw BRIDGE_ERROR.MISSING_WEB3;
119+ const progress = state => onUpdate({ type: 'progress', state });
126− const web3 = web3M.value;
128− if (Nothing.hasInstance(contractsM)) {
129− throw BRIDGE_ERROR.MISSING_CONTRACTS;
131− const contracts = contractsM.value;
133− if (Nothing.hasInstance(inviteWalletM)) {
134− throw BRIDGE_ERROR.MISSING_WALLET;
136− const inviteWallet = inviteWalletM.value;
138− if (Nothing.hasInstance(realWalletM)) {
139− throw BRIDGE_ERROR.MISSING_WALLET;
141− const realWallet = realWalletM.value;
143− // const realWallet = await urbitWalletFromTicket(args.realTicket, point);
145− if (Nothing.hasInstance(realPointM)) {
146− throw BRIDGE_ERROR.MISSING_POINT;
148− const point = realPointM.value;
150 const inviteAddress = inviteWallet.address;
121 const inviteAddress = inviteWallet.address;
151− console.log('working as', inviteAddress);
153− // transfer from invite wallet to new wallet
123+ progress(TRANSACTION_STATES.GENERATING);
125+ // transfer from invite wallet to new wallet
155− let transferTx = azimuth.ecliptic.transferPoint(
126+ const transferTx = azimuth.ecliptic.transferPoint(
156 contracts,
127 contracts,
158− realWallet.ownership.keys.address
129+ wallet.ownership.keys.address
160 transferTx.gas = 500000; //TODO can maybe be lower?
131 transferTx.gas = 500000; //TODO can maybe be lower?
162 // ping gas tank with txs if needed
133 // ping gas tank with txs if needed
164 let inviteNonce = await web3.eth.getTransactionCount(inviteAddress);
134 let inviteNonce = await web3.eth.getTransactionCount(inviteAddress);
165 transferTx.nonce = inviteNonce++;
135 transferTx.nonce = inviteNonce++;
166 transferTx.gasPrice = 20000000000; //NOTE we pay the premium for faster ux
136 transferTx.gasPrice = 20000000000; //NOTE we pay the premium for faster ux
167 transferTx.from = inviteAddress;
137 transferTx.from = inviteAddress;
139+ progress(TRANSACTION_STATES.SIGNING);
169− //NOTE using web3.eth.accounts.signTransaction is broken (1.0.0-beta51)
140+ // NOTE: using web3.eth.accounts.signTransaction is broken (1.0.0-beta51)
170− let transferStx = new Tx(transferTx);
141+ const transferStx = new Tx(transferTx);
171 transferStx.sign(inviteWallet.privateKey);
142 transferStx.sign(inviteWallet.privateKey);
172− let rawTransferStx = '0x' + transferStx.serialize().toString('hex');
143+ const rawTransferStx = hexify(transferStx.serialize());
174 const transferCost = transferTx.gas * transferTx.gasPrice;
144 const transferCost = transferTx.gas * transferTx.gasPrice;
175− updateProgress({
145+
177− value: TRANSACTION_STATES.FUNDING_INVITE,
146+ progress(TRANSACTION_STATES.FUNDING_INVITE);
179 let usedTank = await tank.ensureFundsFor(
148 let usedTank = await tank.ensureFundsFor(
182 inviteAddress,
151 inviteAddress,
183 transferCost,
152 transferCost,
184 [rawTransferStx],
153 [rawTransferStx],
185− askForFunding
154+ askForFunding,
190− value: TRANSACTION_STATES.CLAIMING,
158+ progress(TRANSACTION_STATES.CLAIMING);
193 // send transaction
160 // send transaction
194 await sendAndAwaitConfirm(web3, [Just(transferStx)], usedTank);
161 await sendAndAwaitConfirm(web3, [Just(transferStx)], usedTank);
@@ -197,15 +164,13 @@ async function startTransactions(args) {
197 // we're gonna be operating as the new wallet from here on out, so change
164 // we're gonna be operating as the new wallet from here on out, so change
198 // the relevant values
165 // the relevant values
200− setUrbitWallet(Just(realWallet));
201− const newAddress = realWallet.ownership.keys.address;
167+ const newAddress = wallet.ownership.keys.address;
203 // configure management proxy
169 // configure management proxy
205− let managementTx = azimuth.ecliptic.setManagementProxy(
170+ const managementTx = azimuth.ecliptic.setManagementProxy(
206 contracts,
171 contracts,
208− realWallet.management.keys.address
173+ wallet.management.keys.address
210 managementTx.gas = 200000;
175 managementTx.gas = 200000;
211 managementTx.nonce = 0;
176 managementTx.nonce = 0;
@@ -214,7 +179,7 @@ async function startTransactions(args) {
214 //TODO feels like more of this logic should live in a lib?
179 //TODO feels like more of this logic should live in a lib?
215 const seed = await attemptNetworkSeedDerivation(true, {
180 const seed = await attemptNetworkSeedDerivation(true, {
216 walletType: WALLET_TYPES.TICKET,
181 walletType: WALLET_TYPES.TICKET,
217− urbitWallet: Just(realWallet),
182+ urbitWallet: Just(wallet),
218 pointCursor: Just(point),
183 pointCursor: Just(point),
219 pointCache: { [point]: { keyRevisionNumber: 0 } },
184 pointCache: { [point]: { keyRevisionNumber: 0 } },
@@ -251,17 +216,15 @@ async function startTransactions(args) {
252 let txPairs = txs.map(tx => {
217 let txPairs = txs.map(tx => {
253 let stx = new Tx(tx);
218 let stx = new Tx(tx);
254− stx.sign(Buffer.from(realWallet.ownership.keys.private, 'hex'));
219+ stx.sign(Buffer.from(wallet.ownership.keys.private, 'hex'));
256 raw: '0x' + stx.serialize().toString('hex'),
221 raw: '0x' + stx.serialize().toString('hex'),
257 signed: stx,
222 signed: stx,
263− value: TRANSACTION_STATES.FUNDING_RECIPIENT,
226+ progress(TRANSACTION_STATES.FUNDING_RECIPIENT);
265 usedTank = await tank.ensureFundsFor(
228 usedTank = await tank.ensureFundsFor(
@@ -271,17 +234,11 @@ async function startTransactions(args) {
271 askForFunding
234 askForFunding
276− value: TRANSACTION_STATES.CONFIGURING,
237+ progress(TRANSACTION_STATES.CONFIGURING);
279 await sendAndAwaitConfirm(web3, txPairs.map(p => Just(p.signed)), usedTank);
239 await sendAndAwaitConfirm(web3, txPairs.map(p => Just(p.signed)), usedTank);
283− value: TRANSACTION_STATES.CLEANING,
241+ progress(TRANSACTION_STATES.CLEANING);
286 // if non-trivial eth left in invite wallet, transfer to new ownership
243 // if non-trivial eth left in invite wallet, transfer to new ownership
287 let balance = await web3.eth.getBalance(inviteAddress);
244 let balance = await web3.eth.getBalance(inviteAddress);
@@ -300,20 +257,14 @@ async function startTransactions(args) {
301 let stx = new Tx(tx);
258 let stx = new Tx(tx);
302 stx.sign(inviteWallet.privateKey);
259 stx.sign(inviteWallet.privateKey);
303− const rawTx = '0x' + stx.serialize().toString('hex');
260+ const rawTx = hexify(stx.serialize());
304 web3.eth.sendSignedTransaction(rawTx).catch(err => {
261 web3.eth.sendSignedTransaction(rawTx).catch(err => {
305 console.log('error sending value tx, who cares', err);
262 console.log('error sending value tx, who cares', err);
307 console.log('sent old balance');
264 console.log('sent old balance');
312− value: TRANSACTION_STATES.DONE,
267+ progress(TRANSACTION_STATES.DONE);
315− // proceed without waiting for confirm
316− setUrbitWallet(Just(realWallet));
319async function sendAndAwaitConfirm(web3, signedTxs, usedTank) {
270async function sendAndAwaitConfirm(web3, signedTxs, usedTank) {
@@ -329,7 +280,7 @@ async function sendAndAwaitConfirm(web3, signedTxs, usedTank) {
330 generateWallet,
281 generateWallet,
331 downloadWallet,
282 downloadWallet,
332− startTransactions,
283+ claimPointFromInvite,
333 INVITE_STAGES,
284 INVITE_STAGES,
334 WALLET_STATES,
285 WALLET_STATES,
335 TRANSACTION_STATES,
286 TRANSACTION_STATES,