Skip to content

Commit f5c7ccb

Browse files
committed
Added ability to wait for a specific number of confirmations (ethers-io#229).
1 parent 24335d0 commit f5c7ccb

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

src.ts/providers/abstract-provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export interface TransactionReceipt {
6969
transactionHash?: string,
7070
logs?: Array<Log>,
7171
blockNumber?: number,
72+
confirmations?: number,
7273
cumulativeGasUsed?: BigNumber,
7374
byzantium: boolean,
7475
status?: number

src.ts/providers/base-provider.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ const formatTransactionReceipt = {
315315
transactionHash: checkHash,
316316
logs: arrayOf(checkTransactionReceiptLog),
317317
blockNumber: checkNumber,
318+
confirmations: allowNull(checkNumber, null),
318319
cumulativeGasUsed: bigNumberify,
319320
status: allowNull(checkNumber)
320321
};
@@ -687,7 +688,6 @@ export class BaseProvider extends Provider {
687688

688689
// Stale block number, request a newer value
689690
if ((now - this._fastQueryDate) > 2 * this._pollingInterval) {
690-
console.log('re-poll fbn');
691691
this._fastQueryDate = now;
692692
this._fastBlockNumberPromise = this.getBlockNumber().then((blockNumber) => {
693693
if (this._fastBlockNumber == null || blockNumber > this._fastBlockNumber) {
@@ -717,10 +717,11 @@ export class BaseProvider extends Provider {
717717
// @TODO: Add .poller which must be an event emitter with a 'start', 'stop' and 'block' event;
718718
// this will be used once we move to the WebSocket or other alternatives to polling
719719

720-
waitForTransaction(transactionHash: string, timeout?: number): Promise<TransactionReceipt> {
720+
waitForTransaction(transactionHash: string, confirmations?: number): Promise<TransactionReceipt> {
721+
if (!confirmations) { confirmations = 1; }
721722
return poll(() => {
722723
return this.getTransactionReceipt(transactionHash).then((receipt) => {
723-
if (receipt == null) { return undefined; }
724+
if (receipt == null || receipt.confirmations < confirmations) { return undefined; }
724725
return receipt;
725726
});
726727
}, { onceBlock: this });
@@ -821,7 +822,7 @@ export class BaseProvider extends Provider {
821822

822823
// This should be called by any subclass wrapping a TransactionResponse
823824
_wrapTransaction(tx: Transaction, hash?: string): TransactionResponse {
824-
if (hexDataLength(hash) !== 32) { throw new Error('invalid response - sendTransaction'); }
825+
if (hash != null && hexDataLength(hash) !== 32) { throw new Error('invalid response - sendTransaction'); }
825826

826827
let result: TransactionResponse = <TransactionResponse>tx;
827828

@@ -831,12 +832,13 @@ export class BaseProvider extends Provider {
831832
}
832833

833834
this._emitted['t:' + tx.hash] = 'pending';
835+
834836
// @TODO: (confirmations? number, timeout? number)
835-
result.wait = () => {
836-
return this.waitForTransaction(hash).then((receipt) => {
837+
result.wait = (confirmations?: number) => {
838+
return this.waitForTransaction(tx.hash, confirmations).then((receipt) => {
837839
if (receipt.status === 0) {
838840
errors.throwError('transaction failed', errors.CALL_EXCEPTION, {
839-
transactionHash: hash,
841+
transactionHash: tx.hash,
840842
transaction: tx
841843
});
842844
}
@@ -956,11 +958,11 @@ export class BaseProvider extends Provider {
956958
if (confirmations <= 0) { confirmations = 1; }
957959
tx.confirmations = confirmations;
958960

959-
return tx;
961+
return this._wrapTransaction(tx);
960962
});
961963
}
962964

963-
return tx;
965+
return this._wrapTransaction(tx);
964966
});
965967
}, { onceBlock: this });
966968
});
@@ -983,7 +985,24 @@ export class BaseProvider extends Provider {
983985
// "geth-etc" returns receipts before they are ready
984986
if (result.blockHash == null) { return undefined; }
985987

986-
return checkTransactionReceipt(result);
988+
let receipt = checkTransactionReceipt(result);
989+
990+
if (receipt.blockNumber == null) {
991+
receipt.confirmations = 0;
992+
993+
} else if (receipt.confirmations == null) {
994+
return this._getFastBlockNumber().then((blockNumber) => {
995+
996+
// Add the confirmations using the fast block number (pessimistic)
997+
let confirmations = (blockNumber - receipt.blockNumber) + 1;
998+
if (confirmations <= 0) { confirmations = 1; }
999+
receipt.confirmations = confirmations;
1000+
1001+
return receipt;
1002+
});
1003+
}
1004+
1005+
return receipt;
9871006
});
9881007
}, { onceBlock: this });
9891008
});

tests/test-providers.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ function testProvider(providerName, networkName) {
302302
function testTransactionReceipt(expected) {
303303
var title = ('Receipt ' + expected.transactionHash.substring(0, 10) + ' - ');
304304
return provider.getTransactionReceipt(expected.transactionHash).then(function(receipt) {
305+
306+
// This changes with every block
307+
assert.equal(typeof(receipt.confirmations), 'number', 'confirmations is a number');
308+
delete receipt.confirmations;
309+
305310
for (var key in receipt) {
306311
equals((title + key), receipt[key], expected[key]);
307312
}
@@ -331,6 +336,9 @@ function testProvider(providerName, networkName) {
331336
assert.equal(typeof(tx.confirmations), 'number', 'confirmations is a number');
332337
delete tx.confirmations;
333338

339+
assert.equal(typeof(tx.wait), 'function', 'wait is a function');
340+
delete tx.wait
341+
334342
for (var key in tx) {
335343
equals((title + key), tx[key], expected[key]);
336344
}

0 commit comments

Comments
 (0)