OSDN Git Service

update the build-chain-transactions function.
[bytom/bytom-electron.git] / src / features / transactions / actions.js
index f2254eb..d883334 100644 (file)
@@ -1,8 +1,9 @@
 import uuid from 'uuid'
-import {chainClient} from 'utility/environment'
+import {chainClient, btmID} from 'utility/environment'
 import {parseNonblankJSON} from 'utility/string'
 import {push} from 'react-router-redux'
 import {baseCreateActions, baseListActions} from 'features/shared/actions'
+import { normalTxActionBuilder, issueAssetTxActionBuilder } from './transactions'
 
 const type = 'transaction'
 
@@ -15,35 +16,20 @@ function preprocessTransaction(formParams) {
   const copy = JSON.parse(JSON.stringify(formParams))
   const builder = {
     baseTransaction: copy.baseTransaction,
-    actions: copy.actions,
+    actions: copy.actions || [],
   }
 
-  const normalT = formParams.normalTransaction
-  if (builder.actions.length == 0) {
-    builder.actions.push({
-      accountAlias: normalT.accountAlias,
-      accountId: normalT.accountId,
-      assetAlias: 'BTM',
-      amount: Number(normalT.gas.price),
-      type: 'spend_account'
-    })
-    builder.actions.push({
-      accountAlias: normalT.accountAlias,
-      accountId: normalT.accountId,
-      assetAlias: normalT.assetAlias,
-      assetId: normalT.assetId,
-      amount: normalT.amount,
-      type: 'spend_account'
-    })
-    builder.actions.push({
-      address: normalT.address,
-      assetAlias: normalT.assetAlias,
-      assetId: normalT.assetId,
-      amount: normalT.amount,
-      type: 'control_address'
-    })
+  if (formParams.form === 'normalTx') {
+    const gasPrice = formParams.state.estimateGas * Number(formParams.gasLevel)
+    builder.actions = normalTxActionBuilder(formParams,  Number(gasPrice), 'amount')
+  }
+
+  if (formParams.form === 'issueAssetTx') {
+    const gasPrice = formParams.state.estimateGas * Number(formParams.gasLevel)
+    builder.actions = issueAssetTxActionBuilder(formParams, Number(gasPrice), 'amount')
   }
 
+
   if (builder.baseTransaction == '') {
     delete builder.baseTransaction
   }
@@ -84,52 +70,18 @@ function preprocessTransaction(formParams) {
 }
 
 form.submitForm = (formParams) => function (dispatch) {
-  const buildPromise = chainClient().transactions.build(builder => {
+  const client = chainClient()
+
+  const builderFunction = ( builder ) => {
     const processed = preprocessTransaction(formParams)
 
-    builder.actions = processed.actions.map(action => {
-      let result = {
-        address: action.address,
-        amount: action.amount,
-        account_id: action.accountId,
-        account_alias: action.accountAlias,
-        asset_id: action.assetId,
-        asset_alias: action.assetAlias,
-        type: action.type,
-      }
-      if (action.receiver) {
-        result.receiver = {
-          control_program: action.receiver.controlProgram,
-          expires_at: action.receiver.expiresAt
-        }
-      }
-      return result
-    })
+    builder.actions = processed.actions
     if (processed.baseTransaction) {
       builder.baseTransaction = processed.baseTransaction
     }
-  })
-
-  const signAndSubmitTransaction = (transaction, password) => {
-    const connection = chainClient().connection
-    return connection.request('/sign-transaction', {
-      password,
-      transaction
-    }, true).then(resp => {
-      if (resp.status === 'fail') {
-        throw new Error(resp.msg)
-      }
-
-      const raw_transaction = resp.data.transaction.raw_transaction
-      return connection.request('/submit-transaction', {raw_transaction})
-    }).then(dealSignSubmitResp)
   }
 
-  const dealSignSubmitResp = resp => {
-    if (resp.status === 'fail') {
-      throw new Error(resp.msg)
-    }
-
+  const submitSucceeded = () => {
     dispatch(form.created())
     dispatch(push({
       pathname: '/transactions',
@@ -139,47 +91,164 @@ form.submitForm = (formParams) => function (dispatch) {
     }))
   }
 
-  if (formParams.state.showAdvanceTx && formParams.state.showAdvanced && formParams.baseTransaction) {
-    const transaction = JSON.parse(formParams.baseTransaction)
-    return signAndSubmitTransaction(transaction, formParams.password)
-  }
+  // normal transactions
+  if( formParams.form === 'normalTx'){
 
-  if (formParams.submitAction == 'submit') {
-    return buildPromise
-      .then((resp) => {
-        if (resp.status === 'fail') {
-          throw new Error(resp.msg)
-        }
+    const accountId = formParams.accountId
+    const accountAlias = formParams.accountAlias
+    const accountInfo = Object.assign({},  accountAlias!== ''? {alias: accountAlias}: {id: accountId})
+
+    const isBTM = (formParams.assetId === btmID) || (formParams.assetAlias === 'BTM')
 
-        return signAndSubmitTransaction(resp.data, formParams.password)
+    return client.accounts.query(accountInfo)
+      .then( resp => {
+        if(resp.data[0].xpubs.length > 1){
+          throw {code: 'F_BTM003'}
+        }
+        const body = Object.assign({}, {xpub: resp.data[0].xpubs[0], password: formParams.password})
+        return client.mockHsm.keys.checkPassword(body)
+      })
+      .then( result => {
+        if(!result.data.checkResult){
+          throw new Error('PasswordWrong')
+        }
+        if(isBTM)
+          return client.transactions.buildChain(builderFunction)
+        else
+          return client.transactions.build(builderFunction)
+      })
+      .then( tpl => {
+        if(isBTM){
+          const body = Object.assign({}, {password: formParams.password, transactions: tpl.data})
+          return client.transactions.signBatch(body)
+        }
+        else{
+          const body = Object.assign({}, {password: formParams.password, transaction: tpl.data})
+          return client.transactions.sign(body)
+        }
+      })
+      .then(signed => {
+        if(!signed.data.signComplete){
+          throw {code: 'F_BTM100'}
+        }
+        if(isBTM){
+          const rawTransactions = signed.data.transaction.map(tx => tx.rawTransaction)
+          return client.transactions.submitBatch(rawTransactions)
+        }
+        else{
+          return client.transactions.submit(signed.data.transaction.rawTransaction)
+        }
       })
+      .then(submitSucceeded)
   }
 
-  // submitAction == 'generate'
-  return buildPromise.then(resp => {
-    if (resp.status === 'fail') {
-      throw new Error(resp.msg)
+  //advanced transactions
+  else if( formParams.form === 'advancedTx' ){
+    const buildPromise = (formParams.state.showAdvanced && formParams.signTransaction) ? null :
+      client.transactions.build(builderFunction)
+
+    if (formParams.submitAction == 'submit') {
+      const signAndSubmitTransaction = (transaction) => {
+        const body = Object.assign({}, {password: formParams.password, transaction: transaction})
+        return client.transactions.sign(body)
+          .then( signed => client.transactions.submit(signed.data.transaction.rawTransaction) )
+          .then(submitSucceeded)
+      }
+
+      if( formParams.state.showAdvanced
+        && formParams.signTransaction ){
+        const transaction = JSON.parse(formParams.signTransaction)
+        return signAndSubmitTransaction(transaction)
+      }
+
+      return buildPromise
+        .then(tpl => signAndSubmitTransaction(tpl.data))
     }
 
-    const body = Object.assign({}, {password: formParams.password, 'transaction': resp.data})
-    return chainClient().connection.request('/sign-transaction', body, true)
-  }).then(resp => {
-    if (resp.status === 'fail') {
-      throw new Error(resp.msg)
+    // submitAction == 'generate'
+    const signAndSubmitGeneratedTransaction = (transaction) => {
+      const body = Object.assign({}, {password: formParams.password, transaction: transaction})
+      return client.transactions.sign(body)
+        .then(resp => {
+          const id = uuid.v4()
+          dispatch({
+            type: 'GENERATED_TX_HEX',
+            generated: {
+              id: id,
+              hex: JSON.stringify(resp.data.transaction),
+            },
+          })
+          dispatch(push(`/transactions/generated/${id}`))
+        })
     }
-    const id = uuid.v4()
-    dispatch({
-      type: 'GENERATED_TX_HEX',
-      generated: {
-        id: id,
-        hex: JSON.stringify(resp.data.transaction),
-      },
-    })
-    dispatch(push(`/transactions/generated/${id}`))
-  })
+
+    if (formParams.state.showAdvanced
+      && formParams.signTransaction) {
+      const transaction = JSON.parse(formParams.signTransaction)
+      return signAndSubmitGeneratedTransaction(transaction)
+    }
+
+    return buildPromise
+      .then(resp => signAndSubmitGeneratedTransaction(resp.data))
+  }
+
+  //issue Asset transactions
+  else if( formParams.form === 'issueAssetTx'){
+    //submit action
+    const signAndSubmitTransaction = (transaction) => {
+      const body = Object.assign({}, {password: formParams.password, transaction: transaction})
+      return client.transactions.sign(body)
+        .then( signed =>{
+          if(!signed.data.signComplete){
+            const id = uuid.v4()
+            dispatch({
+              type: 'GENERATED_TX_HEX',
+              generated: {
+                id: id,
+                hex: JSON.stringify(signed.data.transaction),
+              },
+            })
+            dispatch(push(`/transactions/generated/${id}`))
+
+          }else{
+            return client.transactions.submit(signed.data.transaction.rawTransaction)
+              .then(submitSucceeded)
+          }
+        })
+    }
+
+    if (formParams.submitAction == 'submit') {
+      return client.transactions.build(builderFunction)
+        .then(tpl => signAndSubmitTransaction(tpl.data))
+    }
+
+    if( formParams.submitAction == 'sign' ){
+      const transaction = JSON.parse(formParams.signTransaction)
+      return signAndSubmitTransaction(transaction)
+    }
+
+  }
+}
+
+const decode = (data) => {
+  return (dispatch) => {
+    return  chainClient().transactions.decodeTransaction(data)
+      .then((resp) => {
+        if (resp.status === 'fail') {
+          dispatch({type: 'ERROR', payload: {'message': resp.msg}})
+        } else {
+          dispatch({type: 'DECODE_TRANSACTION', data:resp.data})
+        }
+      })
+      .catch(err => {
+        dispatch({type: 'DECODE_TRANSACTION', data:[]})
+        throw {_error: err}
+      })
+  }
 }
 
 export default {
   ...list,
   ...form,
+  decode,
 }