1// /lib/tank: functions for funding transactions
3import retry from 'async-retry';
4import { RETRY_OPTIONS, waitForTransactionConfirm } from './txn';
6//NOTE if accessing this in a localhost configuration fails with "CORS request
7// did not succeed", you might need to visit localhost:3001 or whatever
8// explicitly and tell your browser that's safe to access.
9// https://stackoverflow.com/a/53011185/1334324
10const baseUrl = 'https://localhost:3001';
12function sendRequest(where, what) {
13 return new Promise((resolve, reject) => {
14 fetch(baseUrl + where, {
18 'Content-Type': 'application/json',
20 body: JSON.stringify(what),
24 resolve(response.json());
33const remainingTransactions = point => {
34 if (typeof point === 'string') point = Number(point);
35 return sendRequest('/point', { point: point });
38const fundTransactions = signedTxs => {
39 return sendRequest('/request', { txs: signedTxs });
42// resolves when address has at least cost balance
43// returns true if gas tank was used, false otherwise
44// askForFunding: callback that takes (address, requiredBalance, currentBalance)
45// and tells the user to get that address the required balance
46// gotFunding: optional callback that stops telling the user to go get funding
47const ensureFundsFor = async (
56 let balance = await web3.eth.getBalance(address);
61 const fundsRemaining = await remainingTransactions(point);
62 if (fundsRemaining < signedTxs.length) {
63 throw new Error('tank: request invalid');
66 console.log('tank: skipping remaining-funds check');
67 //TODO if we can't always (easily) provide a point, and the
68 // fundTransactions call is gonna fail anyway, should we maybe
69 // just not bother doing this check in the first place?
72 const res = await fundTransactions(signedTxs);
74 throw new Error('tank: request rejected');
76 await waitForTransactionConfirm(web3, res.txHash);
77 let newBalance = await web3.eth.getBalance(address);
79 'tank: funds have confirmed',
87 console.log('tank: funding failed', e);
88 await waitForBalance(web3, address, cost, askForFunding, gotFunding);
91 console.log('tank: already have sufficient funds');
96// returns a promise that resolves when address has at least minBalance
97function waitForBalance(web3, address, minBalance, askForFunding, gotFunding) {
98 let oldBalance = null;
99 return retry(async (bail, n) => {
100 const balance = await web3.eth.getBalance(address);
101 if (balance >= minBalance) {
102 // if we ever asked for funding, retract that request now
103 if (gotFunding && oldBalance !== null) {
108 if (balance !== oldBalance) {
109 // TODO: minBalance is a `number` type
110 // but we want to display ETH, which will never accept a number
111 // but instead wants string or BN/BigNumber.
112 // this will be heavily refactored to correctly do BN math, but until
113 // then we'll manually convert this number to an integer string
114 askForFunding(address, minBalance.toFixed(), balance);
116 throw new Error('retrying');
121export { remainingTransactions, fundTransactions, ensureFundsFor };
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