Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

retry submitting ETH one time #489

Merged
merged 1 commit into from
Oct 18, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 80 additions & 66 deletions src/app/buy-deso-page/buy-deso-eth/buy-deso-eth.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Messages {
static CONFIRM_BUY_DESO = `Are you ready to exchange %s ETH for %s DESO?`;
static ZERO_DESO_ERROR = `You must purchase a non-zero amount DESO`;
static NEGATIVE_DESO_ERROR = `You must purchase a non-negative amount of DESO`;
static RPC_ERROR = `RPC Error`;
}

@Component({
Expand Down Expand Up @@ -165,75 +166,88 @@ export class BuyDeSoEthComponent implements OnInit {
reverseButtons: true,
}).then((res: any) => {
if (res.isConfirmed) {
return Promise.all([this.getTransactionCount(this.ethDepositAddress(), "pending"), this.getFees()]).then(
([transactionCount, fees]) => {
const nonce = toHex(transactionCount);
let txData: FeeMarketEIP1559TxData = {
nonce: nonce,
to: this.globalVars.buyETHAddress,
gasLimit: toHex(21000),
maxPriorityFeePerGas: fees.maxPriorityFeePerGasHex,
maxFeePerGas: fees.maxFeePerGas,
value: toHex(toWei(this.ethToExchange.toString(), "ether")),
chainId: toHex(this.getChain()),
accessList: [],
return this.signAndSubmitETH(1);
}
});
}

signAndSubmitETH(retryAttemptsRemaining: number = 0): Promise<any> {
return Promise.all([this.getTransactionCount(this.ethDepositAddress(), "pending"), this.getFees()]).then(
([transactionCount, fees]) => {
const nonce = toHex(transactionCount);
let txData: FeeMarketEIP1559TxData = {
nonce: nonce,
to: this.globalVars.buyETHAddress,
gasLimit: toHex(21000),
maxPriorityFeePerGas: fees.maxPriorityFeePerGasHex,
maxFeePerGas: fees.maxFeePerGas,
value: toHex(toWei(this.ethToExchange.toString(), "ether")),
chainId: toHex(this.getChain()),
accessList: [],
};
const options = { common: this.common };
// Generate an Unsigned EIP 1559 Fee Market Transaction from the data and generated a hash message to sign.
let tx = feeMarketTransaction.fromTxData(txData, options);
const toSign = [tx.getMessageToSign(true).toString("hex")];
// Have identity generate a signature for this transaction.
this.identityService
.signETH({
...this.identityService.identityServiceParamsForKey(this.globalVars.loggedInUser.PublicKeyBase58Check),
unsignedHashes: toSign,
})
.subscribe((res) => {
// Get the signature and merge it into the TxData defined above.
const signature: { s: any; r: any; v: number | null } = res.signatures[0];
const signedTxData: FeeMarketEIP1559TxData = {
...txData,
...signature,
};
const options = { common: this.common };
// Generate an Unsigned EIP 1559 Fee Market Transaction from the data and generated a hash message to sign.
let tx = feeMarketTransaction.fromTxData(txData, options);
const toSign = [tx.getMessageToSign(true).toString("hex")];
// Have identity generate a signature for this transaction.
this.identityService
.signETH({
...this.identityService.identityServiceParamsForKey(this.globalVars.loggedInUser.PublicKeyBase58Check),
unsignedHashes: toSign,
})
.subscribe((res) => {
// Get the signature and merge it into the TxData defined above.
const signature: { s: any; r: any; v: number | null } = res.signatures[0];
const signedTxData: FeeMarketEIP1559TxData = {
...txData,
...signature,
};
// Construct and serialize the transaction.
const signedTx = FeeMarketEIP1559Transaction.fromTxData(signedTxData, options);
const signedHash = signedTx.serialize().toString("hex");
// Submit the transaction.
this.parentComponent.waitingOnTxnConfirmation = true;
this.backendApi
.SubmitETHTx(
this.globalVars.localNode,
this.globalVars.loggedInUser.PublicKeyBase58Check,
signedTx,
toSign,
[signedHash]
)
.subscribe(
(res) => {
this.globalVars.logEvent("deso : buy : eth");
// Reset all the form fields
this.error = "";
this.desoToBuy = 0;
this.ethToExchange = 0;

// This will update the balance and a bunch of other things.
this.globalVars.updateEverything(
res.DESOTxHash,
this.parentComponent._clickBuyDeSoSuccess,
this.parentComponent._clickBuyDeSoSuccessButTimeout,
this.parentComponent
);
},
(err) => {
this.globalVars.logEvent("deso : buy : eth : error");
this.parentComponent._clickBuyDeSoFailure(this.parentComponent, this.extractError(err));
}
// Construct and serialize the transaction.
const signedTx = FeeMarketEIP1559Transaction.fromTxData(signedTxData, options);
const signedHash = signedTx.serialize().toString("hex");
// Submit the transaction.
this.parentComponent.waitingOnTxnConfirmation = true;
this.backendApi
.SubmitETHTx(
this.globalVars.localNode,
this.globalVars.loggedInUser.PublicKeyBase58Check,
signedTx,
toSign,
[signedHash]
)
.subscribe(
(res) => {
this.globalVars.logEvent("deso : buy : eth");
// Reset all the form fields
this.error = "";
this.desoToBuy = 0;
this.ethToExchange = 0;

// This will update the balance and a bunch of other things.
this.globalVars.updateEverything(
res.DESOTxHash,
this.parentComponent._clickBuyDeSoSuccess,
this.parentComponent._clickBuyDeSoSuccessButTimeout,
this.parentComponent
);
});
}
);
},
(err) => {
this.globalVars.logEvent("deso : buy : eth : error");
if (err.error?.error.includes("RPC Error") && retryAttemptsRemaining > 0) {
console.error(err);
this.globalVars.logEvent("deso : buy : eth : retry");
// Sometimes fees will change between the time they were fetched and the transaction was broadcasted.
// To combat this, we will retry by fetching fees again and constructing/signing/broadcasting the
// transaction again.
return this.signAndSubmitETH(retryAttemptsRemaining--);
} else {
this.parentComponent._clickBuyDeSoFailure(this.parentComponent, this.extractError(err));
}
}
);
});
}
});
);
}

extractError(err: any): string {
Expand Down