1// /lib/tank: functions for funding transactions
3import retry from 'async-retry';
4import { toBN } from 'web3-utils';
5import { RETRY_OPTIONS, waitForTransactionConfirm } from './txn';
6import { WALLET_TYPES } from 'lib/wallet';
8const TANK_ADDRESS = '0x40f0A6db85f8D7A54fF3eA915b040dE8Cd4A0Eb5';
10//NOTE if accessing this in a localhost configuration fails with "CORS request
11// did not succeed", you might need to visit localhost:3001 or whatever
12// explicitly and tell your browser that's safe to access.
13// https://stackoverflow.com/a/53011185/1334324
14const baseUrl = 'https://gas-tank.urbit.org:3001';
16function sendRequest(where, what) {
17 return new Promise((resolve, reject) => {
18 fetch(baseUrl + where, {
22 'Content-Type': 'application/json',
24 body: JSON.stringify(what),
28 resolve(response.json());
37const remainingTransactions = point => {
38 if (typeof point === 'string') point = Number(point);
39 return sendRequest('/point', { point: point });
42const fundTransactions = signedTxs => {
43 return sendRequest('/request', { txs: signedTxs });
46// resolves when address has at least cost balance
47// returns true if gas tank was used, false otherwise
48// askForFunding: callback that takes (address, requiredBalance, currentBalance)
49// and tells the user to get that address the required balance
50// gotFunding: optional callback that stops telling the user to go get funding
51const ensureFundsFor = async (
61 if (typeof signedTxs !== 'object' || signedTxs.length === 0) {
62 throw new Error('tank: no transactions provided!');
65 const balance = toBN(await web3.eth.getBalance(address));
68 if (balance.gte(cost)) {
70 `tank: already have sufficient funds: ${address} proposed ` +
71 `transaction(s) that will cost ${cost.toString()}wei but it ` +
72 `already has ${balance.toString()}wei`
77 if (walletType === WALLET_TYPES.METAMASK) {
78 console.log('tank: disabling for metamask login');
83 // TODO: if we can't always (easily) provide a point, and the
84 // fundTransactions call is gonna fail anyway, should we maybe
85 // just not bother doing this check in the first place?
87 const fundsRemaining = await remainingTransactions(point);
88 if (fundsRemaining < signedTxs.length) {
89 throw new Error('tank: request invalid');
92 console.log('tank: no point provided. skipping remaining-funds check...');
95 const res = await fundTransactions(signedTxs);
97 throw new Error(`tank: request rejected ${JSON.stringify(res)}`);
100 await waitForTransactionConfirm(web3, res.txHash);
102 const newBalance = toBN(await web3.eth.getBalance(address));
105 if (newBalance.lt(cost)) {
107 `tank: transaction funded but the new balance of ` +
108 `${newBalance.toString()}wei is still less than ` +
109 `${cost.toString()}wei.`
114 `tank: funds have confirmed: ${address} now has ` +
115 `${newBalance.toString()}wei, up from ${balance.toString()}wei`
119 console.error(error);
120 await waitForBalance(
132// returns a promise that resolves when address has at least minBalance
133function waitForBalance(web3, address, minBalance, askForFunding, gotFunding) {
134 minBalance = toBN(minBalance);
135 return retry(async (bail, n) => {
136 const balance = toBN(await web3.eth.getBalance(address));
137 if (balance.gte(minBalance)) {
138 gotFunding && gotFunding();
141 askForFunding(address, minBalance.toString(), balance);
142 throw new Error('retrying');
149 remainingTransactions,
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