Fixed sendTransaction for JsonRpcSigner.
This commit is contained in:
parent
0b35f1959a
commit
8a340c8ff3
@ -118,7 +118,7 @@ var JsonRpcSigner = /** @class */ (function (_super) {
|
||||
};
|
||||
JsonRpcSigner.prototype.sendTransaction = function (transaction) {
|
||||
var _this = this;
|
||||
var tx = hexlifyTransaction(transaction);
|
||||
var tx = properties_1.shallowCopy(transaction);
|
||||
if (tx.from == null) {
|
||||
tx.from = this.getAddress().then(function (address) {
|
||||
if (!address) {
|
||||
@ -128,7 +128,28 @@ var JsonRpcSigner = /** @class */ (function (_super) {
|
||||
});
|
||||
}
|
||||
return properties_1.resolveProperties(tx).then(function (tx) {
|
||||
return _this.provider.send('eth_sendTransaction', [tx]);
|
||||
tx = hexlifyTransaction(tx);
|
||||
return _this.provider.send('eth_sendTransaction', [tx]).then(function (hash) {
|
||||
// @TODO: Make a pollProperty method in utils
|
||||
return new Promise(function (resolve, reject) {
|
||||
var count = 0;
|
||||
var check = function () {
|
||||
_this.provider.getTransaction(hash).then(function (tx) {
|
||||
if (tx == null) {
|
||||
if (count++ > 500) {
|
||||
// @TODO: Better error
|
||||
reject(new Error('could not find transaction'));
|
||||
return;
|
||||
}
|
||||
setTimeout(check, 200);
|
||||
return;
|
||||
}
|
||||
resolve(_this.provider._wrapTransaction(tx.raw, hash));
|
||||
});
|
||||
};
|
||||
setTimeout(check, 50);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
JsonRpcSigner.prototype.signMessage = function (message) {
|
||||
|
@ -244,6 +244,7 @@ function checkTransactionResponse(transaction) {
|
||||
if (transaction.to == null && transaction.creates == null) {
|
||||
transaction.creates = address_1.getContractAddress(transaction);
|
||||
}
|
||||
// @TODO: use transaction.serialize? Have to add support for including v, r, and s...
|
||||
if (!transaction.raw) {
|
||||
// Very loose providers (e.g. TestRPC) don't provide a signature or raw
|
||||
if (transaction.v && transaction.r && transaction.s) {
|
||||
@ -797,31 +798,35 @@ var Provider = /** @class */ (function () {
|
||||
var signedTransaction = _a.signedTransaction;
|
||||
var params = { signedTransaction: bytes_1.hexlify(signedTransaction) };
|
||||
return _this.perform('sendTransaction', params).then(function (hash) {
|
||||
if (bytes_1.hexDataLength(hash) !== 32) {
|
||||
throw new Error('invalid response - sendTransaction');
|
||||
}
|
||||
// A signed transaction always has a from (and we add wait below)
|
||||
var tx = transaction_1.parse(signedTransaction);
|
||||
// Check the hash we expect is the same as the hash the server reported
|
||||
if (tx.hash !== hash) {
|
||||
errors.throwError('Transaction hash mismatch from Proivder.sendTransaction.', errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
|
||||
}
|
||||
_this._emitted['t:' + tx.hash.toLowerCase()] = 'pending';
|
||||
tx.wait = function (timeout) {
|
||||
return _this.waitForTransaction(hash, timeout).then(function (receipt) {
|
||||
if (receipt.status === 0) {
|
||||
errors.throwError('transaction failed', errors.CALL_EXCEPTION, {
|
||||
transaction: tx
|
||||
});
|
||||
}
|
||||
return receipt;
|
||||
});
|
||||
};
|
||||
return tx;
|
||||
return _this._wrapTransaction(signedTransaction, hash);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
Provider.prototype._wrapTransaction = function (signedTransaction, hash) {
|
||||
var _this = this;
|
||||
if (bytes_1.hexDataLength(hash) !== 32) {
|
||||
throw new Error('invalid response - sendTransaction');
|
||||
}
|
||||
// A signed transaction always has a from (and we add wait below)
|
||||
var tx = transaction_1.parse(signedTransaction);
|
||||
// Check the hash we expect is the same as the hash the server reported
|
||||
if (tx.hash !== hash) {
|
||||
errors.throwError('Transaction hash mismatch from Proivder.sendTransaction.', errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
|
||||
}
|
||||
this._emitted['t:' + tx.hash.toLowerCase()] = 'pending';
|
||||
tx.wait = function (timeout) {
|
||||
return _this.waitForTransaction(hash, timeout).then(function (receipt) {
|
||||
if (receipt.status === 0) {
|
||||
errors.throwError('transaction failed', errors.CALL_EXCEPTION, {
|
||||
transaction: tx
|
||||
});
|
||||
}
|
||||
return receipt;
|
||||
});
|
||||
};
|
||||
return tx;
|
||||
};
|
||||
Provider.prototype.call = function (transaction) {
|
||||
var _this = this;
|
||||
var tx = properties_1.shallowCopy(transaction);
|
||||
|
@ -9,7 +9,7 @@ import { Signer } from '../wallet/wallet';
|
||||
import { getAddress } from '../utils/address';
|
||||
import { BigNumber } from '../utils/bignumber';
|
||||
import { Arrayish, hexlify, hexStripZeros } from '../utils/bytes';
|
||||
import { defineReadOnly, resolveProperties } from '../utils/properties';
|
||||
import { defineReadOnly, resolveProperties, shallowCopy } from '../utils/properties';
|
||||
import { toUtf8Bytes } from '../utils/utf8';
|
||||
import { ConnectionInfo, fetchJson } from '../utils/web';
|
||||
|
||||
@ -109,7 +109,7 @@ export class JsonRpcSigner extends Signer {
|
||||
}
|
||||
|
||||
sendTransaction(transaction: TransactionRequest): Promise<TransactionResponse> {
|
||||
let tx = hexlifyTransaction(transaction);
|
||||
let tx = shallowCopy(transaction);
|
||||
|
||||
if (tx.from == null) {
|
||||
tx.from = this.getAddress().then((address) => {
|
||||
@ -119,7 +119,28 @@ export class JsonRpcSigner extends Signer {
|
||||
}
|
||||
|
||||
return resolveProperties(tx).then((tx) => {
|
||||
return this.provider.send('eth_sendTransaction', [ tx ]);
|
||||
tx = hexlifyTransaction(tx);
|
||||
return this.provider.send('eth_sendTransaction', [ tx ]).then((hash) => {
|
||||
// @TODO: Make a pollProperty method in utils
|
||||
return new Promise((resolve: (result: TransactionResponse) => void, reject) => {
|
||||
let count = 0;
|
||||
let check = () => {
|
||||
this.provider.getTransaction(hash).then((tx: TransactionResponse) => {
|
||||
if (tx == null) {
|
||||
if (count++ > 500) {
|
||||
// @TODO: Better error
|
||||
reject(new Error('could not find transaction'));
|
||||
return;
|
||||
}
|
||||
setTimeout(check, 200);
|
||||
return;
|
||||
}
|
||||
resolve(this.provider._wrapTransaction(tx.raw, hash));
|
||||
});
|
||||
}
|
||||
setTimeout(check, 50);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,9 @@ export interface TransactionResponse extends Transaction {
|
||||
// Not optional (as it is in Transaction)
|
||||
from: string;
|
||||
|
||||
// The raw transaction
|
||||
raw?: string,
|
||||
|
||||
// This function waits until the transaction has been mined
|
||||
wait: (timeout?: number) => Promise<TransactionReceipt>
|
||||
};
|
||||
@ -350,6 +353,7 @@ export function checkTransactionResponse(transaction: any): TransactionResponse
|
||||
transaction.creates = getContractAddress(transaction);
|
||||
}
|
||||
|
||||
// @TODO: use transaction.serialize? Have to add support for including v, r, and s...
|
||||
if (!transaction.raw) {
|
||||
// Very loose providers (e.g. TestRPC) don't provide a signature or raw
|
||||
if (transaction.v && transaction.r && transaction.s) {
|
||||
@ -960,33 +964,36 @@ export class Provider {
|
||||
return resolveProperties({ signedTransaction: signedTransaction }).then(({ signedTransaction }) => {
|
||||
var params = { signedTransaction: hexlify(signedTransaction) };
|
||||
return this.perform('sendTransaction', params).then((hash) => {
|
||||
if (hexDataLength(hash) !== 32) { throw new Error('invalid response - sendTransaction'); }
|
||||
|
||||
// A signed transaction always has a from (and we add wait below)
|
||||
var tx = <TransactionResponse>parseTransaction(signedTransaction);
|
||||
|
||||
// Check the hash we expect is the same as the hash the server reported
|
||||
if (tx.hash !== hash) {
|
||||
errors.throwError('Transaction hash mismatch from Proivder.sendTransaction.', errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
|
||||
}
|
||||
this._emitted['t:' + tx.hash.toLowerCase()] = 'pending';
|
||||
tx.wait = (timeout?: number) => {
|
||||
return this.waitForTransaction(hash, timeout).then((receipt) => {
|
||||
if (receipt.status === 0) {
|
||||
errors.throwError('transaction failed', errors.CALL_EXCEPTION, {
|
||||
transaction: tx
|
||||
});
|
||||
}
|
||||
return receipt;
|
||||
});
|
||||
};
|
||||
|
||||
return tx;
|
||||
return this._wrapTransaction(signedTransaction, hash);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_wrapTransaction(signedTransaction: string, hash?: string): TransactionResponse {
|
||||
if (hexDataLength(hash) !== 32) { throw new Error('invalid response - sendTransaction'); }
|
||||
|
||||
// A signed transaction always has a from (and we add wait below)
|
||||
var tx = <TransactionResponse>parseTransaction(signedTransaction);
|
||||
|
||||
// Check the hash we expect is the same as the hash the server reported
|
||||
if (tx.hash !== hash) {
|
||||
errors.throwError('Transaction hash mismatch from Proivder.sendTransaction.', errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
|
||||
}
|
||||
this._emitted['t:' + tx.hash.toLowerCase()] = 'pending';
|
||||
tx.wait = (timeout?: number) => {
|
||||
return this.waitForTransaction(hash, timeout).then((receipt) => {
|
||||
if (receipt.status === 0) {
|
||||
errors.throwError('transaction failed', errors.CALL_EXCEPTION, {
|
||||
transaction: tx
|
||||
});
|
||||
}
|
||||
return receipt;
|
||||
});
|
||||
};
|
||||
return tx;
|
||||
}
|
||||
|
||||
|
||||
call(transaction: TransactionRequest): Promise<string> {
|
||||
let tx: TransactionRequest = shallowCopy(transaction);
|
||||
|
Loading…
Reference in New Issue
Block a user