UNPKG

3.51 kBJavaScriptView Raw
1const { sleep, loop } = require('../utils');
2const LazyPromise = require('./LazyPromise');
3
4class PendingTransaction extends LazyPromise {
5 constructor(cfx, func, params) {
6 super(func, params);
7 this.cfx = cfx;
8 }
9
10 /**
11 * Get transaction by hash.
12 *
13 * @param [options] {object}
14 * @param [options.delay=0] {number} - Defer execute after `delay` ms.
15 * @return {Promise<Object|null>} See `Conflux.getTransactionByHash`
16 */
17 async get({ delay = 0 } = {}) {
18 await sleep(delay);
19 const txHash = await this;
20 return this.cfx.getTransactionByHash(txHash);
21 }
22
23 /**
24 * Async wait till transaction been mined.
25 *
26 * - blockHash !== null
27 *
28 * @param [options] {object}
29 * @param [options.delta=1000] {number} - Loop transaction interval in ms.
30 * @param [options.timeout=30*1000] {number} - Loop timeout in ms.
31 * @return {Promise<object>} See `Conflux.getTransactionByHash`
32 */
33 async mined({ delta = 1000, timeout = 60 * 1000 } = {}) {
34 return loop({ delta, timeout }, async () => {
35 const tx = await this.get();
36 if (tx.blockHash) {
37 return tx;
38 }
39
40 return undefined;
41 });
42 }
43
44 /**
45 * Async wait till transaction been executed.
46 *
47 * - mined
48 * - receipt !== null
49 * - receipt.outcomeStatus === 0
50 *
51 * @param [options] {object}
52 * @param [options.delta=1000] {number} - Loop transaction interval in ms.
53 * @param [options.timeout=60*1000] {number} - Loop timeout in ms.
54 * @return {Promise<object>} See `Conflux.getTransactionReceipt`
55 */
56 async executed({ delta = 1000, timeout = 5 * 60 * 1000 } = {}) {
57 const txHash = await this;
58 return loop({ delta, timeout }, async () => {
59 const receipt = await this.cfx.getTransactionReceipt(txHash);
60 if (receipt) {
61 if (receipt.outcomeStatus === 0) {
62 return receipt;
63 }
64 throw new Error(`transaction "${txHash}" executed failed, outcomeStatus ${receipt.outcomeStatus}`);
65 }
66
67 return undefined;
68 });
69 }
70
71 /**
72 * Async wait till transaction been confirmed.
73 *
74 * - executed
75 * - transaction block risk coefficient < threshold
76 *
77 * @param [options] {object}
78 * @param [options.delta=1000] {number} - Loop transaction interval in ms.
79 * @param [options.timeout=5*60*1000] {number} - Loop timeout in ms.
80 * @param [options.threshold=0.01] {number} - Number in range (0,1)
81 * @return {Promise<object>} See `Conflux.getTransactionReceipt`
82 */
83 async confirmed({ threshold = 0.01, delta = 1000, timeout = 30 * 60 * 1000 } = {}) {
84 return loop({ delta, timeout }, async () => {
85 const receipt = await this.executed({ delta, timeout });
86 const risk = await this.cfx.getRiskCoefficient(receipt.epochNumber);
87 if (risk < threshold) {
88 return receipt;
89 }
90
91 return undefined;
92 });
93 }
94
95 /**
96 * Async wait till contract create transaction deployed.
97 * - transaction confirmed
98 *
99 * @param [options] {object} - See `PendingTransaction.confirmed`
100 * @return {Promise<string>} The contract address.
101 */
102 async deployed(options) {
103 const { transactionHash, outcomeStatus, contractCreated } = await this.confirmed(options);
104 if (outcomeStatus === 0) {
105 return contractCreated;
106 }
107 throw new Error(`transaction "${transactionHash}" deploy failed with ${outcomeStatus}`);
108 }
109}
110
111module.exports = PendingTransaction;