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

Colw/transaction service #3180

Merged
merged 52 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
67221ce
Simple round trip
Nov 20, 2019
9222ada
Get gas estimate from transaction api
Nov 22, 2019
0f4d233
Modify gas estimate route to /transaction/estimate
Nov 22, 2019
d4cadb4
Remove console logs
Nov 22, 2019
6d284dc
Merge branch 'develop' into colw/transaction-service
Nov 25, 2019
6e06af3
Sign and broadcast messages
Nov 25, 2019
7eb642e
Lint
Nov 25, 2019
a4940ff
Enable TX service in config
Nov 26, 2019
f8546ff
Combine object
Nov 26, 2019
c054853
Add message type for broadcast.
Nov 26, 2019
851af2a
Support withdrawal
Nov 26, 2019
52d2475
Lint
Nov 26, 2019
072591b
changelog
Nov 26, 2019
d954630
Throw error on unsuccessful broadcast
Nov 28, 2019
86984ba
Remove logs, and capitalise error message
Nov 28, 2019
c415bf2
Merge branch 'develop' into colw/transaction-service
Nov 28, 2019
73bc34a
update lock file
faboweb Dec 2, 2019
526eaac
WIP
Dec 3, 2019
9fd94a4
Lint
Dec 3, 2019
8d234db
Move function around
Dec 3, 2019
900e171
fixed missin import
faboweb Dec 3, 2019
b5f5ebc
mocked fetch
faboweb Dec 3, 2019
4700e9a
Move request func to class
Dec 4, 2019
6448460
Update tests
Dec 4, 2019
03bb78c
Cover withdraw message type
Dec 4, 2019
8272b84
Use correct variable
Dec 4, 2019
b46b3c5
Test ignore all message types.
Dec 4, 2019
6a91a59
Ignore functions - will be imported from library
Dec 4, 2019
d09d9f5
Move ignore comment line to return statement
Dec 4, 2019
3fda07b
Missed one
Dec 4, 2019
dc67620
Ignore GraphQL
Dec 4, 2019
002f7fa
Merge branch 'develop' into colw/transaction-service
Dec 4, 2019
7f2506a
Test simulate tx service
Dec 4, 2019
6b30390
Set data
Dec 4, 2019
7636917
Use data variable for tx service flag
Dec 4, 2019
efb2f43
Removed unused method
Dec 4, 2019
a7f58ab
Ignore
Dec 4, 2019
95aecac
More ignore
Dec 4, 2019
da20247
Test send
Dec 4, 2019
938e51d
Fake test for throwing an error. TODO Remove not
Dec 4, 2019
8970d2a
Expect throw
Dec 4, 2019
64d0f64
Test tx failure
Dec 5, 2019
6f89092
Clean and test estimate failure
Dec 5, 2019
3aeb05d
Fix test
Dec 5, 2019
51c7b26
Test for messageconstructor
Dec 5, 2019
59d0697
Update variable name
Dec 5, 2019
06e8b5b
Test all networks
Dec 5, 2019
2c31435
Test status edge cases for page validator
Dec 5, 2019
4f1aeaa
Ignore watch and Apollo lines
Dec 5, 2019
e831877
Test transaction signer retrieval
Dec 5, 2019
379bcd3
Merge branch 'develop' into colw/transaction-service
Dec 5, 2019
6470d24
Lnt
Dec 5, 2019
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
1 change: 1 addition & 0 deletions changes/colw_transaction-service
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Added] [#3180](https://github.com/cosmos/lunie/pull/3180) Use Lunie Transaction service to estimate an broadcast transactions @colw
3 changes: 2 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export default {

graphqlHost: graphql,

e2e: process.env.VUE_APP_E2E || false
e2e: process.env.VUE_APP_E2E || false,
enableTxAPI: process.env.VUE_APP_ENABLE_TX_API === "true" || false
}
45 changes: 35 additions & 10 deletions src/ActionModal/components/ActionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@ export default {
totalRewards: this.overview.totalRewards, // getters.totalRewards,
delegations: this.delegations, // state.delegates.delegates,
bondDenom: this.network.stakingDenom, // getters.bondDenom,
isExtensionAccount: this.isExtensionAccount
isExtensionAccount: this.isExtensionAccount,
account: this.overview.accountInformation
}
},
confirmModalOpen() {
Expand Down Expand Up @@ -618,7 +619,16 @@ export default {
const { type, memo, ...properties } = this.transactionData
await this.actionManager.setMessage(type, properties)
try {
this.gasEstimate = await this.actionManager.simulate(memo)
if (!config.enableTxAPI) {
this.gasEstimate = await this.actionManager.simulate(memo)
} else {
this.gasEstimate = await this.actionManager.simulateTxAPI(
this.createContext(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do @colw?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old functionality is still there, and you can opt-in to the transaction service by setting an environment variable when building the front end.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

he meant the context maybe. that is like a bunch of variables you need for the tx to be build

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, that's what i meant. but i don't see the function anywhere.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's around, line ~500. Not part of this PR though.

type,
properties,
memo
)
}
this.step = feeStep
} catch ({ message }) {
this.submissionError = `${this.submissionErrorPrefix}: ${message}.`
Expand All @@ -644,22 +654,33 @@ export default {
}
}

const { memo } = this.transactionData

const gasPrice = {
amount: this.gasPrice,
denom: this.network.stakingDenom
}
const { type, memo, ...properties } = this.transactionData

const feeProperties = {
gasEstimate: this.gasEstimate,
gasPrice: gasPrice,
gasPrice: {
amount: this.gasPrice,
denom: this.network.stakingDenom
},
submitType: this.selectedSignMethod,
password: this.password
}

try {
const { hash } = await this.actionManager.send(memo, feeProperties)
let hashResult
if (!config.enableTxAPI) {
hashResult = await this.actionManager.send(memo)
} else {
hashResult = await this.actionManager.sendTxAPI(
this.createContext(),
type,
memo,
properties,
feeProperties
)
}

const { hash } = hashResult
this.txHash = hash
this.step = inclusionStep
} catch ({ message }) {
Expand Down Expand Up @@ -715,6 +736,10 @@ export default {
totalRewards
liquidStake
totalStake
accountInformation {
accountNumber
sequence
}
}
}
`,
Expand Down
107 changes: 106 additions & 1 deletion src/ActionModal/utils/ActionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,34 @@ import { getSigner } from "./signer"
import transaction from "./transactionTypes"
import { uatoms } from "scripts/num"
import { toMicroDenom } from "src/scripts/common"
import { getMessage, getMultiMessage } from "./MessageConstructor.js"
import {
getMessage,
getMultiMessage,
getTransactionSigner,
transformMessage
} from "./MessageConstructor.js"

const txFetchOptions = {
method: "POST",
headers: {
"Content-Type": "application/json"
}
}

async function transactionAPIRequest(payload) {
// console.log(config)
const options = {
...txFetchOptions,
body: JSON.stringify({ payload })
}

const command = payload.simulate ? "estimate" : "broadcast"

return fetch(
`${config.graphqlHost}/transaction/${command}`,
options
).then(r => r.json())
}

export default class ActionManager {
constructor() {
Expand Down Expand Up @@ -49,12 +76,30 @@ export default class ActionManager {
if (!this.context) {
throw Error("This modal has no context.")
}
this.txProps = transactionProperties

this.messageTypeCheck(type)
this.messageType = type
this.message = await getMessage(type, transactionProperties, this.context)
}

async simulateTxAPI(context, type, txProps, memo) {
const txPayload = {
simulate: true,
networkId: context.networkId,
messageType: type,
address: context.userAddress,
txProperties: txProps,
memo
}
const result = await transactionAPIRequest(txPayload)
if (result.success) {
return result.gasEstimate
} else {
throw Error("Simulation unsuccessful")
}
}

async simulate(memo) {
this.readyCheck()
const gasEstimate = await this.message.simulate({
Expand Down Expand Up @@ -87,6 +132,66 @@ export default class ActionManager {
return { included, hash }
}

async sendTxAPI(context, type, memo, transactionProperties, txMetaData) {
const { gasEstimate, gasPrice, submitType, password } = txMetaData
const signer = await getSigner(config, submitType, {
address: context.userAddress,
password
})

const messageMetadata = {
gas: String(gasEstimate),
gasPrices: convertCurrencyData([gasPrice]),
memo
}

let txMessages = []
if (this.messageType === transaction.WITHDRAW) {
const validators = getTop5RewardsValidators(
context.bondDenom,
context.rewards
)
validators.forEach(validator => {
const txMessage = transformMessage(type, context.userAddress, {
validatorAddress: validator
})
txMessages.push(txMessage)
})
} else {
const txMessage = transformMessage(
type,
context.userAddress,
transactionProperties
)
txMessages.push(txMessage)
}

const createSignedTransaction = await getTransactionSigner(context)
const signedMessage = await createSignedTransaction(
messageMetadata,
txMessages,
signer,
context.chainId,
context.account.accountNumber,
context.account.sequence
)

const txPayload = {
simulate: false,
messageType: type,
networkId: context.networkId,
signedMessage
}

const result = await transactionAPIRequest(txPayload)
if (result.success) {
return { hash: result.hash }
} else {
throw Error('Broadcast was not successfull')
}

}

async createWithdrawTransaction() {
const addresses = getTop5RewardsValidators(
this.context.bondDenom,
Expand Down
Loading